由于某种原因,OpenGL VAO 指向地址 0
OpenGL VAO is pointing to address 0 for some reason
我的 VAO 绑定不正确(至少我认为是这样)。
所以,我正在做的是我有一个 class 从一些原始数据创建 vbo 和 vao,在本例中是指向浮点数组的指针。
RawModel* Loader::loadToVao(float* positions, int sizeOfPositions) {
unsigned int vaoID = this->createVao();
this->storeDataInAttributeList(vaoID, positions, sizeOfPositions);
this->unbindVao();
return new RawModel(vaoID, sizeOfPositions / 3);
}
unsigned int Loader::createVao() {
unsigned int vaoID;
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);
unsigned int copyOfVaoID = vaoID;
vaos.push_back(copyOfVaoID);
return vaoID;
}
void Loader::storeDataInAttributeList(unsigned int attributeNumber, float* data, int dataSize) {
unsigned int vboID;
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, dataSize * sizeof(float), data, GL_STATIC_DRAW);
glVertexAttribPointer(attributeNumber, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
unsigned int copyOfVboID = vboID;
vbos.push_back(copyOfVboID);
}
void Loader::unbindVao() {
glBindVertexArray(0);
}
RawModel 只是一个 class,它应该接受浮点数组并创建一个 vbo 和一个 vao。我正在使用的向量 vbos
和 vaos
只是用来跟踪所有 ID,这样我就可以在使用完所有数据后删除它们。
我有 90% 的信心这一切都可以正常工作。但是,当我去尝试 运行 一些可以绘制它的代码时,OpenGL 正在退出,因为它试图从地址 0x0000000 读取并且它不喜欢那样。我将在此之前从代码创建的原始模型传递到渲染器中的函数中,如下所示:
void Renderer::render(RawModel* model) {
glBindVertexArray(model->getVaoID());
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, model->getVertexCount());
glDisableVertexAttribArray(0);
glBindVertexArray(0);
}
我已检查以确保创建 vao 时和尝试检索 vao 时 VaoID 相同。其实是一样的
我不知道如何读取当前存储在任何 OpenGL 当前绑定为顶点属性数组的地址,因此我无法测试它是否指向顶点数据。不过,我很确定它出于某种原因指向地址 0。
编辑:
原来不是硬编码的 0 有问题。它消除了 Visual Studio 和 OpenGL 给我的错误,但实际错误在其他地方。我意识到我在上面的一些代码中将 vaoID
作为 attributeNumber
传递,而我应该传递一个硬编码的 0。我在这里编辑了我的代码:
RawModel* Loader::loadToVao(float* positions, int sizeOfPositions) {
unsigned int vaoID = this->createVao();
this->storeDataInAttributeList(0, positions, sizeOfPositions);
this->unbindVao();
return new RawModel(vaoID, sizeOfPositions / 3);
}
我将 this->storeDataInAttributeList(vaoID, positions, sizeOfPositions);
行更改为您在上面看到的内容,并带有一个硬编码的 0。因此,事实证明我什至没有将数组绑定到 vbo 中的正确位置。但是,更改后它工作正常。
您应该将顶点属性索引与 glVertexAttribPointer
、glEnableVertexAttribArray
和 glDisableVertexAttribArray
一起使用,但您得到的是:
- 与
glVertexAttribPointer
一起使用的 VAO id
- 硬编码
0
与 glEnableVertexAttribArray
和 glDisableVertexAttribArray
一起使用(这不一定是错误,但如果您确定该值)
如果您不确定索引值(例如,如果您没有在着色器中指定布局),那么您可以通过 glGetAttribLocation
调用获取它:
// The code assumes `program` is created with glCreateProgram
// and `position` is the attribute name in your vertex shader
const auto index = glGetAttribLocation(program, "position");
然后就可以使用index
上面提到的调用了。
我的 VAO 绑定不正确(至少我认为是这样)。
所以,我正在做的是我有一个 class 从一些原始数据创建 vbo 和 vao,在本例中是指向浮点数组的指针。
RawModel* Loader::loadToVao(float* positions, int sizeOfPositions) {
unsigned int vaoID = this->createVao();
this->storeDataInAttributeList(vaoID, positions, sizeOfPositions);
this->unbindVao();
return new RawModel(vaoID, sizeOfPositions / 3);
}
unsigned int Loader::createVao() {
unsigned int vaoID;
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);
unsigned int copyOfVaoID = vaoID;
vaos.push_back(copyOfVaoID);
return vaoID;
}
void Loader::storeDataInAttributeList(unsigned int attributeNumber, float* data, int dataSize) {
unsigned int vboID;
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, dataSize * sizeof(float), data, GL_STATIC_DRAW);
glVertexAttribPointer(attributeNumber, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
unsigned int copyOfVboID = vboID;
vbos.push_back(copyOfVboID);
}
void Loader::unbindVao() {
glBindVertexArray(0);
}
RawModel 只是一个 class,它应该接受浮点数组并创建一个 vbo 和一个 vao。我正在使用的向量 vbos
和 vaos
只是用来跟踪所有 ID,这样我就可以在使用完所有数据后删除它们。
我有 90% 的信心这一切都可以正常工作。但是,当我去尝试 运行 一些可以绘制它的代码时,OpenGL 正在退出,因为它试图从地址 0x0000000 读取并且它不喜欢那样。我将在此之前从代码创建的原始模型传递到渲染器中的函数中,如下所示:
void Renderer::render(RawModel* model) {
glBindVertexArray(model->getVaoID());
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, model->getVertexCount());
glDisableVertexAttribArray(0);
glBindVertexArray(0);
}
我已检查以确保创建 vao 时和尝试检索 vao 时 VaoID 相同。其实是一样的
我不知道如何读取当前存储在任何 OpenGL 当前绑定为顶点属性数组的地址,因此我无法测试它是否指向顶点数据。不过,我很确定它出于某种原因指向地址 0。
编辑:
原来不是硬编码的 0 有问题。它消除了 Visual Studio 和 OpenGL 给我的错误,但实际错误在其他地方。我意识到我在上面的一些代码中将 vaoID
作为 attributeNumber
传递,而我应该传递一个硬编码的 0。我在这里编辑了我的代码:
RawModel* Loader::loadToVao(float* positions, int sizeOfPositions) {
unsigned int vaoID = this->createVao();
this->storeDataInAttributeList(0, positions, sizeOfPositions);
this->unbindVao();
return new RawModel(vaoID, sizeOfPositions / 3);
}
我将 this->storeDataInAttributeList(vaoID, positions, sizeOfPositions);
行更改为您在上面看到的内容,并带有一个硬编码的 0。因此,事实证明我什至没有将数组绑定到 vbo 中的正确位置。但是,更改后它工作正常。
您应该将顶点属性索引与 glVertexAttribPointer
、glEnableVertexAttribArray
和 glDisableVertexAttribArray
一起使用,但您得到的是:
- 与
glVertexAttribPointer
一起使用的 VAO id
- 硬编码
0
与glEnableVertexAttribArray
和glDisableVertexAttribArray
一起使用(这不一定是错误,但如果您确定该值)
如果您不确定索引值(例如,如果您没有在着色器中指定布局),那么您可以通过 glGetAttribLocation
调用获取它:
// The code assumes `program` is created with glCreateProgram
// and `position` is the attribute name in your vertex shader
const auto index = glGetAttribLocation(program, "position");
然后就可以使用index
上面提到的调用了。