放置在要使用OpenGL渲染的类中的对象

Objects placed inside classes to be rendered with OpenGL

本文关键字:对象 OpenGL      更新时间:2023-10-16

我大约一周前开始学习OpenGL,现在我想创建一个网格类。我将要显示的代码会给我一个黑色屏幕(这是我填充它的颜色)。

我基本上把代码从主函数中剥离出来,放在一个类中,它在main中工作。

网状.cpp

    #include "mesh.h"
mesh::mesh(std::vector<GLfloat> vertices, std::vector<GLuint> indices)
{
    this->vertices = vertices;
    this->indices = indices;
    glGenVertexArrays(1, &vertexArrayObject);
    glGenBuffers(1, &vertexBuffer);
    glGenBuffers(1, &triangleBuffer);
    glBindVertexArray(vertexArrayObject);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(GLfloat), this->vertices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), this->indices.data(), GL_STATIC_DRAW);
    glBindVertexArray(0);
}
mesh::~mesh()
{
    glDeleteBuffers(1, &triangleBuffer);
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteVertexArrays(1, &vertexArrayObject);
}
void mesh::update(){
    glBindVertexArray(vertexArrayObject);
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

网格.h

    #ifndef MESH_H
#define MESH_H
#include <iostream>
#include <vector>
#include <GL/glew.h>
#include <glm/glm.hpp>
class mesh
{
    public:
        mesh(std::vector<GLfloat> vertices, std::vector<GLuint> triangles);
        ~mesh();
        void update();
    protected:
    private:
        GLuint vertexArrayObject, vertexBuffer, triangleBuffer;
        std::vector<GLfloat> vertices;
        std::vector<GLuint> indices;
};
#endif // MESH_H

根据这一点,这应该是正确的做法(?)。

顺便说一句,所有这些代码都是来自this和open.gl站点的mashup,下面是我传递给构造函数的变量。

对于顶点:

    std::vector<GLfloat> vertices = {
//  Position        Color             Texcoords
-0.5f,  0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
 0.5f,  0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f  // Bottom-left
};

和指数:

    std::vector<GLuint> elements = {
    0, 1, 2,
    2, 3, 0
};

另外请注意,我根据Anton的建议更改了代码片段,这似乎不起作用

您会立刻想到两个问题:

  1. this->triangles.size() * sizeof(GLfloat)

    这个问题不会影响任何事情,因为GLfloat的大小与GLuint的大小相同,但如果这不是打字错误,这表明我可能认为索引缓冲区是错误的。

    • 为了一致性,制作此triangles.size () * sizeof (GLuint)

  2. glDrawElements(GL_TRIANGLES, this->vertices.size(), GL_UNSIGNED_INT, 0);

    在类中有两个单独的列表,verticestriangles,这个调用只关心其中一个列表的大小。

    • triangles是构成三角形列表的索引数组(每个三角形3个索引)

    绘制元素数组时,传递的是该列表中的元素数,而不是网格中的顶点数。


虽然从技术上讲不是问题,但我认为在编写代码时使用this->有点太多了。

当一个作用域中的变量与类中的成员同名时(有人可能会认为这会为描述不充分的名称构建一个案例),这很有用,但在mesh::~mesh()等函数中完全没有必要。这会让你的代码更难阅读(对我来说),因为行要长得多。

按照名称描述不充分的主题,通过调用索引数组"triangles",您无意中将该网格类限制为绘制三角形。对于构建三角形网格的专用构造函数来说,这可能是一个很好的变量名,但对于类成员来说就不那么好了。如果改为使用indices,则可以消除名称冲突,并且无需使用this->来限定所有内容。