我有一个包含未分配的指针_vertices
的基类,我想从派生类的构造函数中填充它:
class GameRenderable {
bool _indexed;
int _vertSize;
int _idxSize;
unsigned int VAO, VBO, EBO;
unsigned int _texture0;
protected:
float *_vertices;
unsigned int *_indices;
public:
GameRenderable(GameRenderableMode grm);
~GameRenderable();
void Render();
protected:
void SetupBuffer(int, int);
};
void GameRenderable::SetupBuffer(int vs, int is) {
_indexed = false;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vs, _vertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
_idxSize = is;
_vertSize = vs;
}
void GameRenderable::Render() {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _texture0);
glBindVertexArray(VAO);
glm::mat4 model = glm::mat4(1.0f);
GetShader()->setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, _vertSize);
}
派生类:
class Cube : public GameRenderable {
public:
Cube();
~Cube();
};
Cube::Cube():GameRenderable(GameRenderableMode::_3D) {
/* Cube ASCII
E--------F A -0.5f, 0.5f, -0.5f
/| /| B 0.5f, 0.5f, -0.5f
A--------B | C -0.5f, -0.5f, -0.5f
| | | | D 0.5f, -0.5f, -0.5f
| G------|-H E -0.5f, 0.5f, 0.5f
|/ |/ F 0.5f, 0.5f, 0.5f
C--------D G -0.5f, -0.5f, 0.5f
H 0.5f, -0.5f, 0.5f
*/
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
_vertices = new float[sizeof(vertices)];
memcpy_s(_vertices, sizeof(vertices), vertices, sizeof(float));
SetupBuffer(36, 0);
SetupTexture("container.jpg");
}
Cube::~Cube() {
}
当我调用SetupBuffer()
时,传递给openGL的数组总是只有1个元素,并且没有绘制任何内容。如果我将SetupBuffer()
的代码直接放在构造函数中,它将起作用。
答案 0 :(得分:1)
sizeof( type )
运算符以 bytes 为单位返回大小,例如代码:
std::cout << sizeof(float) << std::endl;
将打印输出:4
因此在以下行:
_vertices = new float[sizeof(vertices)];
您正在分配存储数组vertices
所需的数据量的4倍。应该是这样的:
_vertices = new float[sizeof(vertices) / sizeof(float)];
//this is more ugly but could also be:
_vertices = (float*)(new char[sizeof(vertices)]);
//that works since an ascii 'char' is 1 byte
来自MSDN的功能memcpy_s
:
参数
dest
新缓冲区。
destSize
目标缓冲区的大小,对于memcpy_s为以字节为单位,对于wmemcpy_s为宽字符(wchar_t)。
src
要复制的缓冲区。
count
要复制的字符个数。
因此呼叫应类似于:
memcpy_s(_vertices, sizeof(vertices), vertices, sizeof(vertices));
//although, I would just use the regular 'memcpy':
memcpy(_vertices, vertices, sizeof(vertices));
您的SetupBuffer
函数采用直接输入到vs
中的参数glBufferData
,但是glBufferData也采用字节大小:
size
指定缓冲区对象的新数据存储区的大小(以字节为单位)。
,因此输入值36
是不够的。您想找到一种传递sizeof(vertices)
值的方法,尽管由于您知道每个顶点的跨度(5个浮点数),所以您可以将调用更改为:
glBufferData(GL_ARRAY_BUFFER, vs * 5 * sizeof(float), _vertices, GL_STATIC_DRAW);
正如前面提到的许多评论一样,您也可以使用std::vector
类来简化一些代码,但是我认为,解决代码中的误解非常重要你已经写了。
我相当确定上述内容可以解决您的问题。但是,只是要确保构造函数:
Cube::Cube() : GameRenderable(GameRenderableMode::_3D) {
不会覆盖GameRenderable
构造函数,将首先调用GameRenderable
构造函数(使用参数_3D
),因此请确保GameRenderable
构造函数中的代码不会不要破坏任何东西(我看不到)。