C++ 将数据传递到顶点着色器不起作用?
OpenGL到底是如何工作的,仍然是一个很大的谜。今天我从帧缓冲区开始。在帧缓冲区中,我希望将数据传递到顶点着色器。以下代码是其中的一部分: 初始化C++ 将数据传递到顶点着色器不起作用?,c++,opengl,framebuffer,vertex-shader,C++,Opengl,Framebuffer,Vertex Shader,OpenGL到底是如何工作的,仍然是一个很大的谜。今天我从帧缓冲区开始。在帧缓冲区中,我希望将数据传递到顶点着色器。以下代码是其中的一部分: 初始化 (...) // Compile and link shaderProgram (...) // Compile and link lightingShaderProgram glGenFramebuffers(1, &frameBuffer); (...) // Setting up the map and objects VAO's i
(...) // 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);
}
其余的都无关紧要。一切正常,如果我在顶点着色器的源代码中为lightpos.x和lightpos.y填充自定义值,我会看到正确的结果
然而,不起作用的是:使用(lightpos.x==0?0.5:-0.5)
我可以调试lightpos
的值,结果是两个值都是零。但是lightpos肯定应该是0.5
和0.5
经过广泛的调试(反复试验),我发现了一些非常奇怪的东西。以下代码为lightpos.xy
返回两个零
GLfloat test[] = {0.5f, 0.5f};
但是,对于lightpos.xy
,以下代码返回0.3
,0.2
:
GLfloat test[] = {0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.3f, 0.2f};
如果我向测试添加更多值
:
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, ...};
顶点着色器接收的值将始终是测试的第10和第11个索引,无论我做什么
我现在的问题显然是,为什么?!我错过了什么
我的怀疑如下(但我不知道这意味着什么,以及如何应对):
当非零缓冲区对象绑定到GL_数组_缓冲区目标时,顶点数组指针参数被解释为缓冲区对象内以基本机器单位测量的偏移量
资料来源:
此外,VAORECLIGHTING
的值为3
,VBOQuadLighting
的值为7
,总计为10
。但我还是不明白这是怎么回事。因为你在画6个顶点,每个顶点都有自己的lightpos值(因为它是一个顶点属性)?有趣的想法:)但这6个顶点是由我的几何体着色器使用GL_三角形条带发射的,所以我希望只发送一个顶点,对吗?(这加起来怎么会是10?)另外,请看我的编辑,也许这是一个线索。glDrawArrays(GL_点,0,6)代码>这将向几何体着色器提交6点基本体,但您只有两个灯光属性。几何体着色器实际发射的基本体数量与此调用无关。哇,谢谢!我只需将glDrawArrays(GL_点,0,6)
更改为glDrawArrays(GL_点,0,1)
,它就可以正常工作了。如果你给我一个答案,我会接受的。基本上,我对glDrawArrays
的理解是错误的,我认为缓冲区请求着色器程序绘制内容,而glDrawArrays
只是绘制(部分)结果。但实际上情况正好相反,glDrawArrays
请求着色器程序绘制一些东西。谢谢你的认识!