Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将数据传递到顶点着色器不起作用?_C++_Opengl_Framebuffer_Vertex Shader - Fatal编程技术网

C++ 将数据传递到顶点着色器不起作用?

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

OpenGL到底是如何工作的,仍然是一个很大的谜。今天我从帧缓冲区开始。在帧缓冲区中,我希望将数据传递到顶点着色器。以下代码是其中的一部分:

初始化

(...) // 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
请求着色器程序绘制一些东西。谢谢你的认识!