我花了相当一段时间学习openGL的固定管线,最近开始学习可编程管线。我知道我的painter和shader类不是问题,因为它们可以与固定管线的东西一起工作。我似乎无法让glDrawArrays正常工作。
我不确定我的错误是在如何设置顶点缓冲对象、我的着色器还是其他地方。我也调试了我的代码,并在display函数中设置了断点,它似乎永远无法通过glDrawArrays()(即它在glDrawArrays处触发断点,但在之后没有任何断点被触发,不知道为什么)。
输出的只是一个白屏,什么都没有。
这是我的代码:
float vertices[] = { 0.75, 0.75, 0.0, 1.0,
0.75, -0.75, 0.0, 1.0,
-0.75, -0.75, 0.0, 1.0 };
GLuint vertexBufferObject;
GLuint positionLocation;
GLuint vaoObject;
void initVertexBuffer(GLuint& vertexBufferObject, float* vertexData, unsigned int size, GLenum GL_DRAW_TYPE)
{
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, size, vertexData, GL_DRAW_TYPE);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void main(int argc, char* argv[])
{
painter.initEngine(argc, argv, 500, 500, 0, 0, "2D3D");
painter.initGlutFuncs(display, resize, Input::MouseButtonClick, Input::MouseDrag, keyboard);
defaultShader.init("default.vert", "default.frag");
defaultShader.link();
initVertexBuffer(vertexBufferObject, vertices, sizeof(vertices), GL_STATIC_DRAW);
glGenVertexArrays(1, &vaoObject);
glBindVertexArray(vaoObject);
positionLocation = glGetAttribLocation(defaultShader.id(), "position");
painter.startMainLoop();
}
void display()
{
painter.clearDisplay();
defaultShader.bind();
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
std::cout << Framework::glErrorCheck() << std::endl;
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(positionLocation);
glBindBuffer(GL_ARRAY_BUFFER, 0);
defaultShader.unbind();
painter.flushAndSwapBuffers();
}
顶点着色器:
#version 140
in vec4 position;
void main()
{
gl_Position = position;
}
片元着色器:
#version 140
out vec4 outColor;
void main()
{
outColor = vec4(1.0, 0.0, 1.0, 1.0);
}
编辑:代码已经更新,采纳了Joey Dewd、keltar和genpfault的建议。 现在我不再卡在glDrawArrays这里了,也就是说不再出现白屏,但是出现了黑屏。这让我觉得我的缓冲区可能仍然没有正确设置。或者,我可能还缺少其他用于顶点数组缓冲区初始化(vaoObject)的东西?
glDrawArrays
或glDrawElements
等调用之前设置VAO。 - Joey Dewd1. 绑定VAO对象。2. 绑定缓冲区并设置其数据和VertexAttribPointers。
VAO存储了所有绑定到它的VAO的缓冲区命令。这意味着,一旦你绑定了VAO,任何后续的VBO/EBO和指针调用都将被存储,因此下次需要绘制时,你只需要调用glBindVertexArray(VAO)
即可。尝试先绑定VAO,然后再进行后续的缓冲区和属性指针调用。 - Joey Dewd