OpenGL如何真正起作用,仍然是个大谜。今天我开始使用Framebuffers。在我的帧缓冲区中,我想将数据传递给我的顶点着色器。以下代码是其中的一部分:
初始化
(...) // Compile and link shaderProgram
(...) // Compile and link lightingShaderProgram
glGenFramebuffers(1, &frameBuffer);
(...) // Setting up the map and objects VAO's
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
return false;
}
glGenVertexArrays(1, &VAORectLighting);
glBindVertexArray(VAORectLighting);
glGenBuffers(1, &VBOQuadLighting);
glBindBuffer(GL_ARRAY_BUFFER, VBOQuadLighting);
GLfloat test[] = {0.5f, 0.5f};
glBufferData(GL_ARRAY_BUFFER, sizeof(test), test, GL_DYNAMIC_DRAW);
// For the last two arguments, 2*sizeof(GLfloat), (GLvoid*)0 give the same result
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0);
glUseProgram(lightingShaderProgram);
glUniform1i(glGetUniformLocation(lightingShaderProgram, "texFramebuffer"), 0);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glGenTextures(1, &frameBufferTexture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, frameBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, viewportWidth, viewportHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTexture, 0);
渲染循环
(...)
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glUseProgram(shaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
(...) // Using subDataBuffer to update the scene
glBindVertexArray(m->VAOMap);
glDrawArrays(GL_POINTS, 0, m->mapDrawIndex);
glBindVertexArray(m->VAOObjects);
glDrawArrays(GL_POINTS, 0, m->objectsDrawIndex);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(lightingShaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAORectLighting);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, frameBufferTexture);
glDrawArrays(GL_POINTS, 0, 6);
glBindVertexArray(0);
glfwSwapBuffers(window);
(...)
顶点着色器源
#version 330 core
layout (location = 0 in vec2 lightpos;
out VSO
{
vec4 vLight;
} outputs;
void main()
{
outputs.vLight = vec4(lightpos.x, lightpos.y, 0.5, 0.5);
}
其余的不相关。一切正常,如果我在Vertex着色器的源代码中填写lightpos.x和lightpos.y的自定义值,我会看到正确的结果。
然而,不的作用是:使用(lightpos.x == 0 ? 0.5 : -0.5)
我可以调试lightpos
的值,结果是两个值都为零。但是灯光肯定应该是0.5
和0.5
!
经过大量调试(试错)后,我发现了一些非常奇怪的东西。以下代码为lightpos.xy
返回两个零。
GLfloat test[] = {0.5f, 0.5f};
但是,以下代码会为0.3
返回0.2
,lightpos.xy
:
GLfloat test[] = {0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.3f, 0.2f};
如果我向test
添加更多值:
GLfloat test[] = {0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.3f, 0.2f, 0.5f, 0.5f, 0.5f, 0.5f, ...};
无论我做什么,顶点着色器接收的值将始终是test
的第10和第11个索引。
我现在的问题显然是,为什么?!我错过了什么?
我怀疑如下(但我不知道这意味着什么,以及如何处理这个问题):
当非零缓冲区对象绑定到GL_ARRAY_BUFFER目标时,顶点数组指针参数将被解释为以基本机器单位测量的缓冲区对象内的偏移量。
来源:OpenGL.org docs: glBindBuffer
此外,VAORectLighting
的值为3
,而VBOQuadLighting
的值为7
,这加起来为10
。但我仍然不知道这是如何运作的。