放置在 类 内的对象将使用 OpenGL 渲染

Objects placed inside classes to be rendered with OpenGL

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

我基本上从我的 main 函数中剥离了代码并将其放在 class 中,它在 main 中工作。

mesh.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);
}

mesh.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,这应该是正确的做法(?)。

顺便说一句,所有这些代码都是来自 thisopen.gl 站点的混搭,这里是我传递给构造函数的变量。

对于顶点:

    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)

    这个问题不会有任何影响,因为 GLfloatGLuint 的大小相同,但如果这不是拼写错误,这表明您可能认为索引缓冲区有误。

    • 为了保持一致性,将其设为 triangles.size () * sizeof (GLuint)

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

    您的 class、verticestriangles 中有两个单独的列表,此调用只关心其中一个列表的大小。

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

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


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

当你在一个范围内的变量与你的 class 中的成员同名时,这很有用(有人可能会争辩说名称描述不充分),但在像 mesh::~mesh() 这样的函数中完全没有必要。它使您的代码更难阅读(无论如何对我来说),因为行要长得多。

遵循描述性名称不充分的主题,通过调用索引数组“triangles”,您无意中将此网格 class 限制为绘制三角形。对于构建三角形网格的专用构造函数来说,这可能是一个很好的变量名,但对于 class 成员来说就不是那么多了。如果您改用 indices,就可以避免名称冲突以及使用 this->.

限定所有内容的需要