[可能是长期更新文]
之前在文章中写过,由于仿照的是lazy foo比较老的教程,只能使用
PROFILE_COMPATIBILITY,才能把图画出来。
最近还是想用renderDoc抓帧,但是renderDoc只支持core profile里的抓帧。
所以看看我的代码哪里有过时的写法,保证使用
SDL_GL_CONTEXT_PROFILE_CORE
时也能正常渲染。
注意点
1.要手动创建VAO
不多上,上链接:https://stackoverflow.com/questions/30057286/how-to-use-vbos-without-vaos-with-opengl-core-profile
对我的代码来说,只要在创建VBO前添加一个创建VAO的代码,就行了。
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
这样我的代码符合Core profile了,在使用SDL_GL_CONTEXT_PROFILE_CORE的情况下也能正常渲染了。
VAO是记录了binding等一系列操作状态的东西,bindVAO时,可以省去一些不必要的Bind函数
2.使用VAO时,改变数据的bind不能省
看下面代码:
glBindVertexArray(vb_->vao_);
//---vb things
glBindBuffer(GL_ARRAY_BUFFER, vb_->bufferName_);
int inx = 0;
GLint stride = material_->CalculateStride();
for (auto& param: material_->vsAttributeParams_)
{
glEnableVertexAttribArray(param->paramLocation_);
glVertexAttribPointer(param->paramLocation_, param->num_, param->type_, param->normalized_, stride, material_->CalculateOffset(inx));
inx += 1;
}
//___vb things end
我一开始以为绑定了vao之后,就不用绑定VBO了,就像下面代码中不需要绑定IBO和清理一些状态:
//...上面已经bind了VAO
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib_->bufferName_);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, NULL);
//--- clear things
//for (auto& param : material_->vsAttributeParams_)
//{
// glDisableVertexAttribArray(param->paramLocation_);
//}
//core profile下0号无效,退出时bind 0防止污染其他VAO信息
glBindVertexArray(0);
结果出了问题,原来glVertexAttribPointer在不绑定VBO的情况下无法正常工作,必须在其之前帮定VBO。
而且之前之所以没有看出问题,是因为{glVertexAttribPointer;绑定VBO}写在了一个循环里,第一帧绘制错误,但第二帧因为之前已经绑定了所以不会出错...除非2个dc,才能看出问题。。。
其他
但是RenderDoc还是抓帧失败?(虽然这个软件也是容易出bug),shader抓不到,Input.Output抓不到
但是单打开Mesh Window能看到输入的顶点....
如果发现还有其他问题,以后更新吧