放置在 类 内的对象将使用 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,这应该是正确的做法(?)。
顺便说一句,所有这些代码都是来自 this 和 open.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 的建议更改了代码片段,但似乎不起作用
您会立即想到两个问题:
this->triangles.size() * sizeof(GLfloat)
这个问题不会有任何影响,因为 GLfloat
与 GLuint
的大小相同,但如果这不是拼写错误,这表明您可能认为索引缓冲区有误。
- 为了保持一致性,将其设为
triangles.size () * sizeof (GLuint)
。
glDrawElements(GL_TRIANGLES, this->vertices.size(), GL_UNSIGNED_INT, 0);
您的 class、vertices
和 triangles
中有两个单独的列表,此调用只关心其中一个列表的大小。
triangles
是构成三角形列表的索引数组(每个三角形 3 个索引)。
绘制元素数组时,传递的是该列表中的元素数,而不是网格中的顶点数。
虽然在技术上不是问题,但我认为您在编写代码时使用 this->
有点太多了。
当你在一个范围内的变量与你的 class 中的成员同名时,这很有用(有人可能会争辩说名称描述不充分),但在像 mesh::~mesh()
这样的函数中完全没有必要。它使您的代码更难阅读(无论如何对我来说),因为行要长得多。
遵循描述性名称不充分的主题,通过调用索引数组“triangles
”,您无意中将此网格 class 限制为绘制三角形。对于构建三角形网格的专用构造函数来说,这可能是一个很好的变量名,但对于 class 成员来说就不是那么多了。如果您改用 indices
,就可以避免名称冲突以及使用 this->
.
限定所有内容的需要
我大约一周前开始学习 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,这应该是正确的做法(?)。
顺便说一句,所有这些代码都是来自 this 和 open.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 的建议更改了代码片段,但似乎不起作用
您会立即想到两个问题:
this->triangles.size() * sizeof(GLfloat)
这个问题不会有任何影响,因为
GLfloat
与GLuint
的大小相同,但如果这不是拼写错误,这表明您可能认为索引缓冲区有误。- 为了保持一致性,将其设为
triangles.size () * sizeof (GLuint)
。
- 为了保持一致性,将其设为
glDrawElements(GL_TRIANGLES, this->vertices.size(), GL_UNSIGNED_INT, 0);
您的 class、
vertices
和triangles
中有两个单独的列表,此调用只关心其中一个列表的大小。triangles
是构成三角形列表的索引数组(每个三角形 3 个索引)。
绘制元素数组时,传递的是该列表中的元素数,而不是网格中的顶点数。
虽然在技术上不是问题,但我认为您在编写代码时使用 this->
有点太多了。
当你在一个范围内的变量与你的 class 中的成员同名时,这很有用(有人可能会争辩说名称描述不充分),但在像 mesh::~mesh()
这样的函数中完全没有必要。它使您的代码更难阅读(无论如何对我来说),因为行要长得多。
遵循描述性名称不充分的主题,通过调用索引数组“triangles
”,您无意中将此网格 class 限制为绘制三角形。对于构建三角形网格的专用构造函数来说,这可能是一个很好的变量名,但对于 class 成员来说就不是那么多了。如果您改用 indices
,就可以避免名称冲突以及使用 this->
.