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

Posted

技术标签:

【中文标题】使用 OpenGL 渲染时 CPU 和 GPU 之间的数据丢失【英文标题】:Loss of data between the CPU and GPU when rendering with OpenGL 【发布时间】:2016-06-11 10:30:42 【问题描述】:

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

渲染器代码包括为渲染实体设置顶点数组和顶点缓冲区对象,并创建 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 上的着色器?老实说,我很难过。不知道为什么制服设置方式上的这种细微差别会导致渲染效果如此不同。

有人能解释一下吗?

【问题讨论】:

应该没什么区别。在第二个示例中,您如何以及何时初始化作为 loc 传入的值?在 glUseProgram 之后? 您是否正确设置了 VertexAttribPointers ?我还会在着色器类的成员前面加上 m_*** 之类的前缀,这样你就不会在调用中感到困惑 :) @samgak 我在将位置传递给函数之前找到了位置。是的,在 glUseProgram() 之后。 @HannesHauptmann 是的,我确实正确设置了它们。我知道这是因为对象正在屏幕上渲染,纹理也是如此。只是我在渲染场景上方的第一种方法并没有被我的着色器完全着色。立方体只会在摄像机和光源的正前方被点亮和着色,而一切都是黑色的。当我切换到第二个实现时,它起作用了。 【参考方案1】:

嗯,根据docs,函数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);

// struct vec3  float arr[3]; ;
glUseProgram(this->program);
glUniform3fv(glGetUniformLocation(this->program, name), 1, &data.arr[0]);

当然取决于您的 vec3 实施。

【讨论】:

另外,您可以选择使用预取的统一位置,而不是像您一样在每次更新时查询它们。 vec3 是 glm 库的一部分。我用了 glUniform3f;并将参数提供为glUniform3f(loc, vector.x, vector.y, vector.z); 好的。那么,在这两种情况下,你是在glUniformXXX 之前调用glUseProgram 吗? 预取的统一位置是什么意思,我该怎么做?是在游戏循环之前通过获取位置来完成的吗? 是的,在这两种情况下,我都会在 glUniform 之前调用 glUseProgram()。

以上是关于使用 OpenGL 渲染时 CPU 和 GPU 之间的数据丢失的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 图片从文件渲染到屏幕的过程

opengl 渲染方式在屏 离屏 CPU

CUDA与OpenGL互操作

如何使用 GPU 高效地渲染和处理视频流?

OpenGL核心技术之GPU编程

将渲染设备从 Sandy Bridge GPU 更改为主 GPU