OpenGL – 使用模型矩阵移动对象

huangapple go评论74阅读模式
英文:

OpenGL - Moving Object using Modelmatrix

问题

I am working on an OpenGL project. In this project, I would like to simulate a 3D chess game in c++. Of course, the pieces should be movable at will. The chessboard and pieces are already displayed with textures included.

我正在进行一个OpenGL项目。在这个项目中,我想用C++模拟一个3D国际象棋游戏。当然,棋子应该可以随意移动。棋盘和棋子已经显示了纹理。

I have been working on transforming the pieces. In my model class, all important parameters such as vertices, indices, numvertices, numindices and more are read from the respective model. This happens in the constructor of this class.

我一直在处理棋子的变换。在我的模型类中,从各个模型中读取所有重要的参数,如顶点、索引、顶点数、索引数等。这发生在该类的构造函数中。

I also create an identity matrix (glm::mat4(1.0f)) for each model in the constructor of the model class.

我还在模型类的构造函数中为每个模型创建一个单位矩阵(glm::mat4(1.0f))。

After all the parameters have been read, I push them into a vector<Mesh*>.

在读取所有参数后,我将它们推入一个vector<Mesh*>中。

In the mesh class, the vertices and indices are first loaded into the vertex buffer/index buffer in the constructor.

在mesh类中,在构造函数中首先将顶点和索引加载到顶点缓冲区/索引缓冲区中。

The location of the uniform variable in the vertex shader for my model matrix is also calculated in the constructor.

在构造函数中还计算了顶点着色器中用于模型矩阵的uniform变量的位置。

In the render function of the mesh class, the vertex buffer/index buffer is bound and all uniforms are set. At the end of the function, I call glDrawElements.

在mesh类的渲染函数中,绑定了顶点缓冲区/索引缓冲区,并设置了所有uniform变量。在函数的结尾,我调用了glDrawElements。

In the vertex shader, I multiply the model matrix, the viewProjectionMatrix, and vec4(a_position, 1.0f) into gl_Position. If the identity matrix in the constructor of the model class is glm::mat4(1.0f), the model is displayed normally. But if I transform, scale or rotate the matrix in the constructor for testing purposes, nothing is displayed anymore. Did I make a mistake in the way I'm doing it or am I on the right track?

在顶点着色器中,我将模型矩阵、viewProjectionMatrix 和 vec4(a_position, 1.0f) 相乘,并将结果赋给gl_Position。如果在模型类的构造函数中使用单位矩阵glm::mat4(1.0f),模型会正常显示。但如果出于测试目的在构造函数中对矩阵进行变换、缩放或旋转,就不会显示任何内容了。我在做法上犯了错误,还是我在正确的轨道上?

英文:

I am working on an OpenGL project. In this project, I would like to simulate a 3D chess game in c++. Of course, the pieces should be movable at will. The chessboard and pieces are already displayed with textures included.

I have been working on transforming the pieces. In my model class, all important parameters such as vertices, indices, numvertices, numindices and more are read from the respective model. This happens in the constructor of this class.

I also create an identity matrix (glm::mat4(1.0f)) for each model in the constructor of the model class.

After all the parameters have been read, I push them into a vector<Mesh*>.

In the mesh class, the vertices and indices are first loaded into the vertex buffer/index buffer in the constructor.

The location of the uniform variable in the vertex shader for my model matrix is also calculated in the constructor.

In the render function of the mesh class, the vertex buffer/index buffer is bound and all uniforms are set. At the end of the function, I call glDrawElements.

In the vertex shader, I multiply the model matrix, the viewProjectionMatrix, and vec4(a_position, 1.0f) into gl_Position.
If the identity matrix in the constructor of the model class is glm::mat4(1.0f), the model is displayed normally.

But if I transform, scale or rotate the matrix in the constructor for testing purposes, nothing is displayed anymore.
Did I make a mistake in the way I'm doing it or am I on the right track?

#pragma once
#include &lt;vector&gt;
#include &lt;fstream&gt;

#include &quot;libs/glm/glm.hpp&quot;
#include &quot;shader.h&quot;
#include &quot;vertexbuffer.h&quot;
#include &quot;indexbuffer.h&quot;
#include &quot;mesh.h&quot;
#include &lt;cassert&gt;


class Model {

public:
    Model(const char* filename, Shader* shader) {

        this-&gt;shader = shader;
        modelmatrix = glm::mat4(1.0f); 
        //modelmatrix = glm::scale(modelmatrix, glm::vec3(10));
        std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary); 
        uint64 numMeshes;
        uint64 numMaterials;

        
        input.read((char*)&amp;numMaterials, sizeof(uint64));
        for (uint64 i = 0; i &lt; numMaterials; i++) {
            Material material = {};
            input.read((char*)&amp;material, sizeof(BMFMaterial)); 

            
            uint64 diffuseMapNameLenght = 0;
            input.read((char*)&amp;diffuseMapNameLenght, sizeof(uint64)); 
            std::string diffuseMapName(diffuseMapNameLenght, &#39;
#pragma once
#include &lt;vector&gt;
#include &lt;fstream&gt;
#include &quot;libs/glm/glm.hpp&quot;
#include &quot;shader.h&quot;
#include &quot;vertexbuffer.h&quot;
#include &quot;indexbuffer.h&quot;
#include &quot;mesh.h&quot;
#include &lt;cassert&gt;
class Model {
public:
Model(const char* filename, Shader* shader) {
this-&gt;shader = shader;
modelmatrix = glm::mat4(1.0f); 
//modelmatrix = glm::scale(modelmatrix, glm::vec3(10));
std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary); 
uint64 numMeshes;
uint64 numMaterials;
input.read((char*)&amp;numMaterials, sizeof(uint64));
for (uint64 i = 0; i &lt; numMaterials; i++) {
Material material = {};
input.read((char*)&amp;material, sizeof(BMFMaterial)); 
uint64 diffuseMapNameLenght = 0;
input.read((char*)&amp;diffuseMapNameLenght, sizeof(uint64)); 
std::string diffuseMapName(diffuseMapNameLenght, &#39;\0&#39;); 
input.read((char*)&amp;diffuseMapName[0], diffuseMapNameLenght); 
uint64 normalMapNameLenght = 0;
input.read((char*)&amp;normalMapNameLenght, sizeof(uint64)); 
std::string normalMapName(normalMapNameLenght, &#39;\0&#39;); 
input.read((char*)&amp;normalMapName[0], normalMapNameLenght); 
if (diffuseMapNameLenght &gt; 0) {
std::cout &lt;&lt; filename &lt;&lt; &quot; successfully loaded&quot; &lt;&lt; std::endl;
}
else {
std::cout &lt;&lt; filename &lt;&lt; &quot; failed loading&quot; &lt;&lt; std::endl;
}
int32 textureWidth = 0;
int32 textureHeight = 0;
int32 bitsPerPixel = 0;
glGenTextures(2, &amp;material.diffuseMap); 
stbi_set_flip_vertically_on_load(true);
auto textureBuffer = stbi_load(diffuseMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer); //Texture in Grafikkarte geladen
if (textureBuffer) {
stbi_image_free(textureBuffer);
}
auto textureBuffer2 = stbi_load(normalMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
glBindTexture(GL_TEXTURE_2D, material.normalMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer2); //Texture in Grafikkarte geladen
if (textureBuffer2) {
stbi_image_free(textureBuffer2);
}
glBindTexture(GL_TEXTURE_2D, 0); 
materials.push_back(material); 
}
input.read((char*)&amp;numMeshes, sizeof(uint64)); 
for (uint64 i = 0; i &lt; numMeshes; i++) {
input.read((char*)&amp;materialIndex, sizeof(uint64)); 
input.read((char*)&amp;numVertices, sizeof(uint64)); 
input.read((char*)&amp;numIndices, sizeof(uint64)); 
for (uint64 i = 0; i &lt; numVertices; i++) {
Vertex vertex;
input.read((char*)&amp;vertex.position.x, sizeof(float));
input.read((char*)&amp;vertex.position.y, sizeof(float));
input.read((char*)&amp;vertex.position.z, sizeof(float));
input.read((char*)&amp;vertex.normal.x, sizeof(float));
input.read((char*)&amp;vertex.normal.y, sizeof(float));
input.read((char*)&amp;vertex.normal.z, sizeof(float));
input.read((char*)&amp;vertex.textureCoord.x, sizeof(float));
input.read((char*)&amp;vertex.textureCoord.y, sizeof(float));
vertices.push_back(vertex);
}
for (uint64 i = 0; i &lt; numIndices; i++) {
uint32 index;
input.read((char*)&amp;index, sizeof(uint32));
indices.push_back(index);
}
Mesh* mesh = new Mesh(vertices, numVertices, indices, numIndices, materials[materialIndex], shader, modelmatrix); //Mesh laden 
meshes.push_back(mesh);
}
}
void render() {
for (Mesh* mesh : meshes) {
mesh-&gt;render();
}
}
~Model() {
for (Mesh* mesh : meshes) {
delete mesh;
}
}
private:
std::vector&lt;Mesh*&gt; meshes; 
std::vector&lt;Material&gt; materials; 
glm::mat4 modelmatrix;
std::vector&lt;Vertex&gt; vertices;
uint64 numVertices = 0;
std::vector&lt;uint32&gt; indices;
uint64 numIndices = 0;
uint64 materialIndex = 0;
Shader* shader;
};
&#39;); input.read((char*)&amp;diffuseMapName[0], diffuseMapNameLenght); uint64 normalMapNameLenght = 0; input.read((char*)&amp;normalMapNameLenght, sizeof(uint64)); std::string normalMapName(normalMapNameLenght, &#39;
#pragma once
#include &lt;vector&gt;
#include &lt;fstream&gt;
#include &quot;libs/glm/glm.hpp&quot;
#include &quot;shader.h&quot;
#include &quot;vertexbuffer.h&quot;
#include &quot;indexbuffer.h&quot;
#include &quot;mesh.h&quot;
#include &lt;cassert&gt;
class Model {
public:
Model(const char* filename, Shader* shader) {
this-&gt;shader = shader;
modelmatrix = glm::mat4(1.0f); 
//modelmatrix = glm::scale(modelmatrix, glm::vec3(10));
std::ifstream input = std::ifstream(filename, std::ios::in | std::ios::binary); 
uint64 numMeshes;
uint64 numMaterials;
input.read((char*)&amp;numMaterials, sizeof(uint64));
for (uint64 i = 0; i &lt; numMaterials; i++) {
Material material = {};
input.read((char*)&amp;material, sizeof(BMFMaterial)); 
uint64 diffuseMapNameLenght = 0;
input.read((char*)&amp;diffuseMapNameLenght, sizeof(uint64)); 
std::string diffuseMapName(diffuseMapNameLenght, &#39;\0&#39;); 
input.read((char*)&amp;diffuseMapName[0], diffuseMapNameLenght); 
uint64 normalMapNameLenght = 0;
input.read((char*)&amp;normalMapNameLenght, sizeof(uint64)); 
std::string normalMapName(normalMapNameLenght, &#39;\0&#39;); 
input.read((char*)&amp;normalMapName[0], normalMapNameLenght); 
if (diffuseMapNameLenght &gt; 0) {
std::cout &lt;&lt; filename &lt;&lt; &quot; successfully loaded&quot; &lt;&lt; std::endl;
}
else {
std::cout &lt;&lt; filename &lt;&lt; &quot; failed loading&quot; &lt;&lt; std::endl;
}
int32 textureWidth = 0;
int32 textureHeight = 0;
int32 bitsPerPixel = 0;
glGenTextures(2, &amp;material.diffuseMap); 
stbi_set_flip_vertically_on_load(true);
auto textureBuffer = stbi_load(diffuseMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer); //Texture in Grafikkarte geladen
if (textureBuffer) {
stbi_image_free(textureBuffer);
}
auto textureBuffer2 = stbi_load(normalMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen      
glBindTexture(GL_TEXTURE_2D, material.normalMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer2); //Texture in Grafikkarte geladen
if (textureBuffer2) {
stbi_image_free(textureBuffer2);
}
glBindTexture(GL_TEXTURE_2D, 0); 
materials.push_back(material); 
}
input.read((char*)&amp;numMeshes, sizeof(uint64)); 
for (uint64 i = 0; i &lt; numMeshes; i++) {
input.read((char*)&amp;materialIndex, sizeof(uint64)); 
input.read((char*)&amp;numVertices, sizeof(uint64)); 
input.read((char*)&amp;numIndices, sizeof(uint64)); 
for (uint64 i = 0; i &lt; numVertices; i++) {
Vertex vertex;
input.read((char*)&amp;vertex.position.x, sizeof(float));
input.read((char*)&amp;vertex.position.y, sizeof(float));
input.read((char*)&amp;vertex.position.z, sizeof(float));
input.read((char*)&amp;vertex.normal.x, sizeof(float));
input.read((char*)&amp;vertex.normal.y, sizeof(float));
input.read((char*)&amp;vertex.normal.z, sizeof(float));
input.read((char*)&amp;vertex.textureCoord.x, sizeof(float));
input.read((char*)&amp;vertex.textureCoord.y, sizeof(float));
vertices.push_back(vertex);
}
for (uint64 i = 0; i &lt; numIndices; i++) {
uint32 index;
input.read((char*)&amp;index, sizeof(uint32));
indices.push_back(index);
}
Mesh* mesh = new Mesh(vertices, numVertices, indices, numIndices, materials[materialIndex], shader, modelmatrix); //Mesh laden 
meshes.push_back(mesh);
}
}
void render() {
for (Mesh* mesh : meshes) {
mesh-&gt;render();
}
}
~Model() {
for (Mesh* mesh : meshes) {
delete mesh;
}
}
private:
std::vector&lt;Mesh*&gt; meshes; 
std::vector&lt;Material&gt; materials; 
glm::mat4 modelmatrix;
std::vector&lt;Vertex&gt; vertices;
uint64 numVertices = 0;
std::vector&lt;uint32&gt; indices;
uint64 numIndices = 0;
uint64 materialIndex = 0;
Shader* shader;
};
&#39;); input.read((char*)&amp;normalMapName[0], normalMapNameLenght); if (diffuseMapNameLenght &gt; 0) { std::cout &lt;&lt; filename &lt;&lt; &quot; successfully loaded&quot; &lt;&lt; std::endl; } else { std::cout &lt;&lt; filename &lt;&lt; &quot; failed loading&quot; &lt;&lt; std::endl; } int32 textureWidth = 0; int32 textureHeight = 0; int32 bitsPerPixel = 0; glGenTextures(2, &amp;material.diffuseMap); stbi_set_flip_vertically_on_load(true); auto textureBuffer = stbi_load(diffuseMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen glBindTexture(GL_TEXTURE_2D, material.diffuseMap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer); //Texture in Grafikkarte geladen if (textureBuffer) { stbi_image_free(textureBuffer); } auto textureBuffer2 = stbi_load(normalMapName.c_str(), &amp;textureWidth, &amp;textureHeight, &amp;bitsPerPixel, 4); //Map geladen und in Buffer drinnen glBindTexture(GL_TEXTURE_2D, material.normalMap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer2); //Texture in Grafikkarte geladen if (textureBuffer2) { stbi_image_free(textureBuffer2); } glBindTexture(GL_TEXTURE_2D, 0); materials.push_back(material); } input.read((char*)&amp;numMeshes, sizeof(uint64)); for (uint64 i = 0; i &lt; numMeshes; i++) { input.read((char*)&amp;materialIndex, sizeof(uint64)); input.read((char*)&amp;numVertices, sizeof(uint64)); input.read((char*)&amp;numIndices, sizeof(uint64)); for (uint64 i = 0; i &lt; numVertices; i++) { Vertex vertex; input.read((char*)&amp;vertex.position.x, sizeof(float)); input.read((char*)&amp;vertex.position.y, sizeof(float)); input.read((char*)&amp;vertex.position.z, sizeof(float)); input.read((char*)&amp;vertex.normal.x, sizeof(float)); input.read((char*)&amp;vertex.normal.y, sizeof(float)); input.read((char*)&amp;vertex.normal.z, sizeof(float)); input.read((char*)&amp;vertex.textureCoord.x, sizeof(float)); input.read((char*)&amp;vertex.textureCoord.y, sizeof(float)); vertices.push_back(vertex); } for (uint64 i = 0; i &lt; numIndices; i++) { uint32 index; input.read((char*)&amp;index, sizeof(uint32)); indices.push_back(index); } Mesh* mesh = new Mesh(vertices, numVertices, indices, numIndices, materials[materialIndex], shader, modelmatrix); //Mesh laden meshes.push_back(mesh); } } void render() { for (Mesh* mesh : meshes) { mesh-&gt;render(); } } ~Model() { for (Mesh* mesh : meshes) { delete mesh; } } private: std::vector&lt;Mesh*&gt; meshes; std::vector&lt;Material&gt; materials; glm::mat4 modelmatrix; std::vector&lt;Vertex&gt; vertices; uint64 numVertices = 0; std::vector&lt;uint32&gt; indices; uint64 numIndices = 0; uint64 materialIndex = 0; Shader* shader; };
#pragma once
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;fstream&gt;
#include &quot;libs/glm/mat4x4.hpp&quot;
#include &quot;libs/glm/glm.hpp&quot;
#include &quot;shader.h&quot;
#include &quot;vertexbuffer.h&quot;
#include &quot;indexbuffer.h&quot;
#include &quot;libs/stb_image.h&quot;

struct BMFMaterial {
    glm::vec3 diffuse;
    glm::vec3 specular;
    glm::vec3 emissive;
    float shininess;
};

struct Material {       
    BMFMaterial material;
    GLuint diffuseMap; 
    GLuint normalMap;
};

class Mesh {
        
public:
    
    Mesh(std::vector&lt;Vertex&gt;&amp; vertices, uint64 numVertices, std::vector&lt;uint32&gt;&amp;indices, uint64 numIndices, Material material, Shader* shader, glm::mat4 modelmatrix) {
        this-&gt;material = material;
        this-&gt;shader = shader;
        this-&gt;numIndices = numIndices;
        this-&gt;modelmatrix = modelmatrix;

       
        vertexBuffer = new VertexBuffer(vertices.data(), numVertices);
        indexBuffer = new IndexBuffer(indices.data(), numIndices, sizeof(indices[0]));

        
        diffuseLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.diffuse&quot;);
        specularLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.specular&quot;);
        emissiveLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.emissive&quot;);
        shininessLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_material.shininess&quot;);
        diffuseMapLocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_diffuse_map&quot;);
        modelmatrixlocation = glGetUniformLocation(shader-&gt;getShaderID(), &quot;u_modelmatrix&quot;);
    }

    ~Mesh() { 
        delete vertexBuffer;
        delete indexBuffer;
    }

    inline void render() {
        std::cout &lt;&lt; glm::to_string(modelmatrix) &lt;&lt; std::endl;
        vertexBuffer-&gt;bind();
        indexBuffer-&gt;bind();
        
        glUniformMatrix4fv(modelmatrixlocation, 1, GL_FALSE, &amp;modelmatrix[0][0]);
        glUniform3fv(diffuseLocation, 1, (float*)&amp;material.material.diffuse[0]);
        glUniform3fv(specularLocation, 1, (float*)&amp;material.material.specular[0]);
        glUniform3fv(emissiveLocation, 1, (float*)&amp;material.material.emissive[0]);
        glUniform1f(shininessLocation, material.material.shininess);
        glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
        glUniform1i(diffuseMapLocation, 0); 
       glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0); 

    }
private:
    VertexBuffer* vertexBuffer;
    IndexBuffer* indexBuffer;
    Shader* shader;
    Material material;
    uint64 numIndices = 0;
    glm::mat4 modelmatrix;
    
    int diffuseLocation; 
    int specularLocation;
    int emissiveLocation;
    int shininessLocation;
    int diffuseMapLocation;
    int modelmatrixlocation;
};
    while (!close) { //GAMELOOP
        camera.update();
    		
    		//model = glm::rotate(model, glm::radians(rotation = 1.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    		modelViewProj = camera.getViewProj();//*model //Pro Frame jedes mal neu berechnen
    		glm::mat4 modelView = camera.getView(); //*model
    		glm::mat4 invModelView = glm::transpose(glm::inverse(modelView));
    
    		glm::vec4 sunDirectionCamera = glm::transpose(glm::inverse(camera.getView())) * glm::vec4(sunDirection, 1.0f); //sunDirection ist abh&#228;nging von Kamera, weil Licht wird im viewspace berechnet
    		glUniform3fv(directionLocationDirection, 1, (float*)&amp;sunDirectionCamera[0]); //aktivieren
    		glm::mat4 pointLightMatrix = glm::mat4(1.0f); //F&#252;r Matrixmultiplikation weil der Punkt nicht immer am gleichen Punkt bleiben soll
    		pointLightPosition = pointLightPosition * pointLightMatrix; //Position &#228;ndert sich, rotiert nun um y-Achse
    		glm::vec3 transformedPointLightPosition = (glm::vec3)(camera.getView() * pointLightPosition); //Transformierte Position im Viewspace 
    		glUniform3fv(positionLocationPoint, 1, (float*)&amp;transformedPointLightPosition[0]);
    
    		glUniformMatrix4fv(modelViewProjMatrixLocation, 1, GL_FALSE, &amp;modelViewProj[0][0]); //Matrix setzen/aktivieren
    		glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, &amp;modelView[0][0]);
    		glUniformMatrix4fv(invModelViewLocation, 1, GL_FALSE, &amp;invModelView[0][0]);
    		
    		//Brett und Figuren rendern/zeichnen
    		whitepawnA2.render();
    		board.render();
    		
    		/*
    		whitebishopright.render();
    		whitebishopleft.render();
    		whiteking.render();
    		whiteknightleft.render();
    		whiteknightright.render();
    		whiterookleft.render();
    		whiterookright.render();
    		whitequeen.render();
    		whitepawnH2.render();
    		whitepawnG2.render();
    		whitepawnF2.render();
    		whitepawnE2.render();
    		whitepawnD2.render();
    		whitepawnC2.render();
    		whitepawnB2.render();
    
    		blackknightleft.render();
    		blackknightright.render();
    		blackking.render();
    		blackbishopleft.render();
    		blackbishopright.render();
    		blackqueen.render();
    		blackrookleft.render();
    		blackrookright.render();
    		blackpawnA.render();
    		blackpawnB.render();
    		blackpawnC.render();
    		blackpawnD.render();
    		blackpawnE.render();
    		blackpawnF.render();
    		blackpawnG.render();
    		blackpawnH.render();
    */
    		SDL_GL_SwapWindow(window); //double buffer aktivieren
    
    		//FPS COUNTER
    		uint64 endCounter = SDL_GetPerformanceCounter();
    		uint64 counterElapsed = endCounter - lastCounter;
    		delta = ((float32)counterElapsed) / (float32)perfCounterFrequency; //Zeit die seit letztem Frame vergangen ist
    		uint32 FPS = (uint32)((float32)perfCounterFrequency / (float32)counterElapsed);
    		//std::cout &lt;&lt; FPS &lt;&lt; std::endl;
    		lastCounter = endCounter;
    	}
    return 0;
    }
    #include &quot;shader.h&quot;
    #include &lt;fstream&gt;
    #include &lt;iostream&gt;
    
    
    Shader::Shader(const char* vertexShaderFilename, const char* fragmentShaderFilename) {
    	shaderID = createShader(vertexShaderFilename, fragmentShaderFilename);
    }
    
    	Shader::~Shader() {
    		glDeleteProgram(shaderID);
    	}
    
    	void Shader::bind() {
    		glUseProgram(shaderID);
    	}
    
    	void Shader::unbind() {
    		glUseProgram(0);
    	}
    
    	GLuint Shader::getShaderID() {
    		return shaderID;
    	}
    
    	GLuint Shader::compile(std::string shaderSource, GLenum type) { //Shadersourcecode so kompiliert werden
    		GLuint id = glCreateShader(type);
    		const char* src = shaderSource.c_str();
    		glShaderSource(id, 1, &amp;src, 0);
    		glCompileShader(id);
    
    		int result;
    		glGetShaderiv(id, GL_COMPILE_STATUS, &amp;result);
    		if (result != GL_TRUE) {
    			int length = 0;
    			glGetShaderiv(id, GL_INFO_LOG_LENGTH, &amp;length);
    			char* message = new char[length];
    			glGetShaderInfoLog(id, length, &amp;length, message);
    			std::cout &lt;&lt; &quot;Shader compilation error: &quot; &lt;&lt; message &lt;&lt; std::endl;
    			delete[] message;
    			return 0;
    		}
    		return id;
    		
    	}
    
    	std::string Shader::parse(const char* filename) {
    		FILE* file;
    #ifdef _WIN32
    		if (fopen_s(&amp;file, filename, &quot;rb&quot;) != 0) {
    			std::cout &lt;&lt; &quot;File &quot; &lt;&lt; filename &lt;&lt; &quot; not found&quot; &lt;&lt; std::endl;
    			return &quot;&quot;;
    		}
    #else
    		file = fopen(filename, &quot;rb&quot;);
    		if (file == nullptr) {
    			std::cout &lt;&lt; &quot;File &quot; &lt;&lt; filename &lt;&lt; &quot; not found&quot; &lt;&lt; std::endl;
    			return &quot;&quot;;
    		}
    #endif
    		std::string content; //Dateininhalt
    		fseek(file, 0, SEEK_END); //ans ende der datei gehen
    		size_t filesize = ftell(file); //wie weit ist man im file
    		rewind(file); //wieder zur&#252;ckgehen
    		content.resize(filesize); //file resizen damit man nicht zu wenig oder zu viel speicher reserviert
    		fread(&amp;content[0], 1, filesize, file); //&amp;content[0] gibt adresse auf speicherbereich - 1 ganze filesize soll gelesen werden - 
    		fclose(file); //file wieder schlie&#223;en
    		return content; //code returnen
    	}
    	GLuint Shader::createShader(const char* vertexShaderFilename, const char* fragmentShaderFilename) {
    		std::string vertexShaderSource = parse(vertexShaderFilename); //Sourcecode speichern
    		std::string fragmentShaderSource = parse(fragmentShaderFilename);
    
    		GLuint program = glCreateProgram(); //program erstellen
    		GLuint vs = compile(vertexShaderSource, GL_VERTEX_SHADER); //shader erstellen
    		GLuint fs = compile(fragmentShaderSource, GL_FRAGMENT_SHADER);
    
    		glAttachShader(program, vs); //shader wird program hinzugef&#252;gt
    		glAttachShader(program, fs);
    
    		glLinkProgram(program); //executable erstellt und l&#228;uft auf vertex
    		
    		//Solange program gelinked ist, kann alles wieder deattached und gel&#246;scht werden - spart speicherplatz
    #ifdef _RELEASE
    		glDetachShader(progam, vs);
    		glDetachShader(program, fs);
    
    		glDeleteShader(vs);
    		glDeleteShader(fs);
    #endif
    		return program;
    }
    //Vertexshader soll Position von Vertex berechnen
    #version 330 core
    //INPUTS IN DEN SHADER
    layout(location = 0) in vec3 a_position; //layout location 0 -&gt; 1 Attribut
    layout(location = 1) in vec3 a_normal;
    layout(location = 2) in vec2 a_tex_coord;
    
    //OUTPUTS
    out vec3 v_normal;
    out vec3 v_position;
    out vec2 v_tex_coord;
    
    uniform mat4 u_modelmatrix;
    uniform mat4 u_modelView;
    uniform mat4 u_modelViewProj;
    
    uniform mat4 u_invModelView;
    
    
    void main()
    {
        gl_Position = u_modelmatrix * u_modelViewProj * vec4(a_position, 1.0f); //vec4 f&#252;r Matrixmultiplikationen - Position in positionsvariable - 1.0f -&gt; 4 Koordinate
        v_normal = mat3(u_invModelView) * a_normal; //Normalevktor berechnen
        v_position = vec3(u_modelView * vec4(a_position, 1.0f)); //Position des Fragments berechnen
        v_tex_coord = a_tex_coord;
    } 

答案1

得分: 0

对于任何未来的读者:

一个更准确的问题应该是:

为什么应用变换后我的对象消失了?

在我最初的猜测之后 - 你可以在下面看到 - OP发布了更详细的代码,最后我在着色器程序中找到了一个错误。

矩阵乘法的顺序错了:

// OP的原始代码
gl_Position = u_modelmatrix * u_modelViewProj * vec4(a_position, 1.0f);
// 正确的顺序
gl_Position = projection * view * model * vec4(aPos, 1.0);

根据矩阵顺序,反向顺序也可能是正确的。

关于变换坐标系统的好教程。


原始回答

你没有提供你的代码的所有部分,所以我只能猜测。
我假设在你的着色器类中,你创建了一个着色器程序,然后正确地进行了链接。

但为了在着色器中更新uniform变量,你必须告诉OpenGL,要使用哪个着色器程序,通过调用:

glUseProgram(shader->getShaderID());
//然后
glUniformMatrix4fv(...);
...

这通常在render()函数中完成(特别是如果你使用多个着色器时至关重要),但我在你的代码中看不到这一点。

如果问题不是这个(你在哪里调用render()函数以及那里发生了什么?你的着色器程序是什么样的?),可能需要附加的代码来找到问题。

英文:

For any future reader:

A more accurate question would be.

Why did my objects disappear after applying transformation?

After my initial guess - which you can see below - OP posted more detailed code and in the end I found an error in the shader program.

The matrix multiplicaton was in the wrong order:

// OP&#39;s original code
gl_Position = u_modelmatrix * u_modelViewProj * vec4(a_position, 1.0f);
// Good order
gl_Position = projection * view * model * vec4(aPos, 1.0);

Reverse order might also be good depending on matrix ordering

Good tutorial about transformations and coordinate systems


Original answer

You didn't provide every part of your code so I can only guess.
I assume in your shader class you create a shader program and then you do the linking correctly.

But in order to update uniforms in a shader, you have to tell that to OpenGL, which shader program to use, by calling:

glUseProgram(shader-&gt;getShaderID());
//and then
glUniformMatrix4fv(...);
...

That is usually done in a the render() function (especially crucial if you use multiple shaders) and I can't see that in your code.

Additional code might be needed to find the issue if it's something else (where do you call the render() function and what is happening there? how does you shader program look like?).

huangapple
  • 本文由 发表于 2023年2月14日 06:10:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75441680.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定