C++ 使用OpenGL渲染时CPU和GPU之间的数据丢失

C++ 使用OpenGL渲染时CPU和GPU之间的数据丢失,c++,opengl,glsl,shader,C++,Opengl,Glsl,Shader,我一直在为一个基本的渲染应用程序编写一些代码 渲染器代码包括为渲染实体设置顶点阵列和顶点缓冲区对象,并创建3个纹理单元,分别用作漫反射、镜面反射和发射组件。我为着色器编写了一个包装器类,用于创建和设置制服 void Shader::SetVec3Uniform(const GLchar * name, vec3 data) { glUniform3f(glGetUniformLocation(this->program, name), data); } 当我使用上述函数设置制服时

我一直在为一个基本的渲染应用程序编写一些代码

渲染器代码包括为渲染实体设置顶点阵列和顶点缓冲区对象,并创建3个纹理单元,分别用作漫反射、镜面反射和发射组件。我为着色器编写了一个包装器类,用于创建和设置制服

void Shader::SetVec3Uniform(const GLchar * name, vec3 data)
{
    glUniform3f(glGetUniformLocation(this->program, name), data);
}
当我使用上述函数设置制服时,它不会以预期的结果进行渲染。但是,当我在设置制服之前找到位置时,它会正确渲染。我使用下面的函数来设置它

void Shader::SetVec3Uniform(GLint loc, vec3 data)
{
    glUniform3f(loc, data.x, data.y, data.z);
}
所以我的问题是,数据是否丢失,数据是否没有及时到达GPU上的着色器?我真的被难倒了。不知道为什么制服设置方式上的细微差异会导致其渲染上的差异

有人能解释一下吗?

好吧,根据,函数
glUniform3f
的原型是:

void glUniform3f(GLint location,
                 GLfloat v0,
                 GLfloat v1,
                 GLfloat v2);
对于函数
glUniform3fv
,它是:

void glUniform3fv(GLint location,
                  GLsizei count,
                  const GLfloat *value);
如何定义
vec3
?如果您有以下内容,该程序可能会起作用:

// struct vec3 { float x; float y; float z; };
glUseProgram(this->program);
glUniform3f(glGetUniformLocation(this->program, name), data.x, data.y, data.z);

当然,这取决于您的
vec3
实现。

根据,函数
glUniform3f
的原型是:

void glUniform3f(GLint location,
                 GLfloat v0,
                 GLfloat v1,
                 GLfloat v2);
对于函数
glUniform3fv
,它是:

void glUniform3fv(GLint location,
                  GLsizei count,
                  const GLfloat *value);
如何定义
vec3
?如果您有以下内容,该程序可能会起作用:

// struct vec3 { float x; float y; float z; };
glUseProgram(this->program);
glUniform3f(glGetUniformLocation(this->program, name), data.x, data.y, data.z);



当然,这取决于您的
vec3
实现。

这不会有任何区别。如何以及何时初始化第二个示例中作为loc传递的值?glUseProgram之后?您是否正确设置了VertexAttribute指针?我还会在着色器类的成员前面加上类似于m_***的前缀,这样您就不会在调用中感到困惑:)@samgak我会在将其传递给函数之前找到位置。是的,在glUseProgram()之后。@HannesHauptmann是的,我确实正确设置了它们。我知道这一点,因为对象正在屏幕上渲染,纹理也是如此。只是在我第一次接近上面的场景时,被渲染的场景并没有被我的着色器完全着色。立方体只有在相机和光源的正前方才被照亮和着色,而所有的东西都是黑色的。当我切换到第二个实现时,它工作了。它应该不会有任何区别。如何以及何时初始化第二个示例中作为loc传递的值?glUseProgram之后?您是否正确设置了VertexAttribute指针?我还会在着色器类的成员前面加上类似于m_***的前缀,这样您就不会在调用中感到困惑:)@samgak我会在将其传递给函数之前找到位置。是的,在glUseProgram()之后。@HannesHauptmann是的,我确实正确设置了它们。我知道这一点,因为对象正在屏幕上渲染,纹理也是如此。只是在我第一次接近上面的场景时,被渲染的场景并没有被我的着色器完全着色。立方体只有在相机和光源的正前方才被照亮和着色,而所有的东西都是黑色的。当我切换到第二个实现时,它成功了。此外,您可以选择使用预取的统一位置,而不是像您那样在每次更新时查询它们。vec3是glm库的一部分。我用glUniform3f;并提供参数为,
glUniform3f(loc,vector.x,vector.y,vector.z)确定。那么,在这两种情况下,您是在
glUniformXXX
之前调用
glUseProgram
吗?您所说的预取统一位置是什么意思?我该怎么做?是否在游戏循环之前获取位置?是的,在这两种情况下,我都在glUniform之前调用glUseProgram()。此外,您可以选择使用预先获取的统一位置,而不是像您一样在每次更新时查询它们。vec3是glm库的一部分。我用glUniform3f;并提供参数为,
glUniform3f(loc,vector.x,vector.y,vector.z)确定。那么,在这两种情况下,您是在
glUniformXXX
之前调用
glUseProgram
吗?您所说的预取统一位置是什么意思?我该怎么做?它是通过在游戏循环之前获取位置来完成的吗?是的,在这两种情况下,我都在glUniform之前调用glUseProgram()。