无法在现代OpenGL中将自己创建的模型与加载的模型一起渲染



我无法同时用加载的obj渲染我自己创建的模型。我有mesh.h,它是为加载对象而设计的:

struct Vertex {
glm::vec3 Position;
glm::vec3 Normal;
};   
struct Light {
glm::vec3 position;
glm::vec3 ambient;
float diffuse;
float specular;
};
struct Material {
float shininess;
glm::vec3 ambient;
glm::vec3 diffuse;
glm::vec3 specular;
};
class Mesh {
public:
vector<Vertex>       vertices;
vector<unsigned int> indices;
Material material;
unsigned int VAO;
Mesh(vector<Vertex> vertices, vector<unsigned int> indices, Material material)
{
this->vertices = vertices;
this->indices = indices;
this->material = material;
setupMesh();
}

void Draw(Shader &shader, Camera &camera)
{
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float) 1024 / (float) 768, 0.1f,
2000.0f);
glm::mat4 view = camera.GetViewMatrix();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
shader.setFloat("material.shininess", material.shininess);
shader.setVec3("material.ambient", material.ambient);
shader.setVec3("material.diffuse", material.diffuse);
shader.setVec3("material.specular", material.specular);
shader.setVec3("light.direction", -camera.Position);
shader.setVec3("viewPos", camera.Position);
shader.setVec3("light.ambient", 1.0f, 1.0f, 1.0f);
shader.setVec3("light.diffuse", 0.8f, 0.8f, 0.8f);
shader.setVec3("light.specular", 0.8f, 0.8f, 0.8f);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
private:
unsigned int VBO, EBO;
void setupMesh()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
}
};

用于绘制对象的Model.h和main:

void Draw(Shader &shader, Camera &camera)
{
shader.use();
for(unsigned int i = 0; i < meshes.size(); i++)
meshes[i].Draw(shader, camera);
}
while (!glfwWindowShouldClose(window))
{
processInput(window, unitBox.size_x(), unitBox.size_y(), unitBox.size_z());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (auto & modelMatrice : modelMatrices)
{
ourShader.setMat4("model", modelMatrice);
moleculeModel.Draw(ourShader, camera);
}
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();

现在我想绘制并同时加载我的自定义模型立方体。我做了一个单独的课堂小隔间

class BoxMesh
{
public:
unsigned int VAO;
std::vector<float> boxVertices = {
-0.5f, -0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
0.5f, -0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
0.5f,  0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
0.5f,  0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
-0.5f,  0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
-0.5f, -0.5f, 0.0f,  0.0f,  0.0f, -1.0f,
-0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
-0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
-0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,
-0.5f,  0.5f,  1.0f, -1.0f,  0.0f,  0.0f,
-0.5f,  0.5f, 0.0f, -1.0f,  0.0f,  0.0f,
-0.5f, -0.5f, 0.0f, -1.0f,  0.0f,  0.0f,
-0.5f, -0.5f, 0.0f, -1.0f,  0.0f,  0.0f,
-0.5f, -0.5f,  1.0f, -1.0f,  0.0f,  0.0f,
-0.5f,  0.5f,  1.0f, -1.0f,  0.0f,  0.0f,
0.5f,  0.5f,  1.0f,  1.0f,  0.0f,  0.0f,
0.5f,  0.5f, 0.0f,  1.0f,  0.0f,  0.0f,
0.5f, -0.5f, 0.0f,  1.0f,  0.0f,  0.0f,
0.5f, -0.5f, 0.0f,  1.0f,  0.0f,  0.0f,
0.5f, -0.5f, 1.0f,  1.0f,  0.0f,  0.0f,
0.5f,  0.5f, 1.0f,  1.0f,  0.0f,  0.0f,
-0.5f, -0.5f, 0.0f,  0.0f, -1.0f,  0.0f,
0.5f, -0.5f, 0.0f,  0.0f, -1.0f,  0.0f,
0.5f, -0.5f,  1.0f,  0.0f, -1.0f,  0.0f,
0.5f, -0.5f,  1.0f,  0.0f, -1.0f,  0.0f,
-0.5f, -0.5f,  1.0f,  0.0f, -1.0f,  0.0f,
-0.5f, -0.5f, 0.0f,  0.0f, -1.0f,  0.0f,
-0.5f,  0.5f, 0.0f,  0.0f,  1.0f,  0.0f,
0.5f,  0.5f, 0.0f,  0.0f,  1.0f,  0.0f,
0.5f,  0.5f,  1.0f,  0.0f,  1.0f,  0.0f,
0.5f,  0.5f,  1.0f,  0.0f,  1.0f,  0.0f,
-0.5f,  0.5f,  1.0f,  0.0f,  1.0f,  0.0f,
-0.5f,  0.5f, 0.0f,  0.0f,  1.0f,  0.0f
};
BoxMesh()
{
setupBox();
}
void Draw(Shader &shader, Camera &camera)
{
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float) 1024 / (float) 768, 0.1f,
2000.0f);
glm::mat4 view = camera.GetViewMatrix();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
shader.setFloat("material.shininess", 1.0f);
shader.setVec3("material.ambient",1.0f, 1.0f, 1.0f);
shader.setVec3("material.diffuse", 1.0f, 1.0f, 1.0f);
shader.setVec3("material.specular", 1.0f, 1.0f, 1.0f);
shader.setVec3("light.direction", -camera.Position);
shader.setVec3("viewPos", camera.Position);
shader.setVec3("light.ambient", 1.0f, 1.0f, 1.0f);
shader.setVec3("light.diffuse", 0.8f, 0.8f, 0.8f);
shader.setVec3("light.specular", 0.8f, 0.8f, 0.8f);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
}
private:
unsigned int VBO;
void setupBox()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, boxVertices.size() * sizeof(boxVertices), &boxVertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
}
};

我希望它能给我画出一个立方体+许多加载的模型:

while (!glfwWindowShouldClose(window))
{
processInput(window, unitBox.size_x(), unitBox.size_y(), unitBox.size_z());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (auto & modelMatrice : modelMatrices)
{
ourShader.setMat4("model", modelMatrice);
moleculeModel.Draw(ourShader, camera);
}
BoxMesh box;
box.Draw(ourShader, camera);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();

然而我失败了,在哪里?

在每个帧中创建对象BoxMesh以及相应的VAO和VBO。除了性能损失外,VAO和VBO永远不会被删除,这会导致在每一帧中创建新对象,并耗尽内存,直到最后。BoxMesh应在应用程序循环之前安装。您只需要在绘制网格之前绑定VAO
由于box似乎没有模型矩阵,因此必须设置单位矩阵,否则最近绘制的网格的矩阵将在着色器的默认统一块中声明:

class BoxMesh {
public:
// [...]
void Draw(Shader &shader, Camera &camera)
{
// [...]

glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
BoxMesh box;
while (!glfwWindowShouldClose(window))
{
// [...]
ourShader.setMat4("model", glm:mat4(1.0f));
box.Draw(ourShader, camera);
// [...]
}

相关内容

  • 没有找到相关文章

最新更新