通过统一缓冲区对象发送到 GLSL 的数据会泄漏到其他绘制调用中 (OpenGL 3.2)
Data sent to GLSL via Uniform Buffer Objects leaks into other draw calls (OpenGL 3.2)
我在OpenGL 3.2代码中遇到了一个奇怪的现象。我正在绘制一系列对象,每个对象都有一个 2D(颜色)纹理和一些相当标准的材质设置(漫反射/镜面反射颜色等),我想通过统一的缓冲区将材质设置发送到我的片段着色器。相应统一块的 GLSL 声明如下所示:
layout(std140) uniform MaterialBlock {
vec4 diffuseColor, specularColor;
float shininess, ambient, emission;
} material;
这就是我的渲染周期在伪代码中的样子:
glUseProgram(objectShaderId);
for each object {
// Set material
glBindBuffer(GL_UNIFORM_BUFFER, materialBufferId);
MaterialBlockPtr = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
<set object's material values via MaterialBlockPtr>
glUnmapBuffer(GL_UNIFORM_BUFFER);
// Set texture
glBindTexture(GL_TEXTURE_2D, textureId);
// Draw
glBindVertexArray(object.vertexArrayId);
glDrawElements(GL_TRIANGLES, object.faceCount, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
只要 a) 屏幕上只有一个对象,或者 b) 使用此着色器的所有对象共享相同的材质设置,或者 c) 其他对象使用不同的着色器,这一切都足够好。
一旦两个对象使用相同的着色器,但具有不同的材质设置(例如,一个具有蓝色,一个具有绿色漫反射颜色),并且它们都在框架中,它们就会开始疯狂闪烁 - 每个对象在自己的材质设置和另一个对象的材质设置之间切换似乎是随机的。显然,某些绘图发生在上一个调用的材料值仍在统一缓冲区中的情况下,但为什么呢?我是否错过了关于统一缓冲液的基本知识?对 glDraw* 的调用是否会以某种方式重叠我向缓冲区写入的数据,或者缓冲区的内容会影响调用 glDraw* 后屏幕上的内容?
郑重声明,我正在 GeForce GT650M 上的 OS X 10.7.5 上开发它。
好的,
我很确定这有什么问题:
layout(std140) uniform MaterialBlock {
vec4 diffuseColor, specularColor;
float shininess, ambient, emission;
} material
我非常确定材料环境和发射本身就是颜色也应该声明为 vec4 数组,我怀疑在您的绘图代码中您有类似的东西
//this is just an example and assumption
float material_ambient[4];
float material_emmission[4];
//to setup material ambient and emmissive colour
material_ambient = {1.0, 1.0, 1.0, 1.0};
material_emmision = {1.0, 1.0, 1.0, 1.0};
glUniform4f(material_ambient_id, material_ambient[0], material_ambient[1], material_ambient[2], material_ambient[3]);
glUniform4f(material_emissive_id, material_emissive[0], material_emissive[1], material_emissive[2], material_emissive[3]);
这里非常明显的问题是,您将尝试发送 4 个元素数组来设置着色器中的浮点变量......希望这有帮助
相关文章:
- 什么时候调用组成单元对象的析构函数
- 绘制的 OpenGL 点消失,绘制调用和交换缓冲区问题
- 如何在调用函数时将对象绘制到 sfml 窗口上
- 调用 sf::矩形形状绘制函数
- OpenCV c++ 断言失败调用绘制轮廓
- 未调用QQuickPaintedItem的绘制方法
- 如何调用OnEraseBkgnd()在另一个函数中重新绘制窗口?(MFC)
- DirectX 11:绘制调用金额
- 在 win32 中调用WM_PAINT之间保留绘制的工作区
- c++ Glut 显示需要调用我的绘制函数,但我无法传递任何参数
- "QGraphicsView"滚动后不调用"绘制"方法
- 调用Qpainter的方法绘制以刷新图像和更改颜色
- OpenGL 批处理:为什么我的绘制调用超出了数组缓冲区边界
- 通过统一缓冲区对象发送到 GLSL 的数据会泄漏到其他绘制调用中 (OpenGL 3.2)
- 开放框架:绘制函数被多次调用
- QGraphicsScene一直在调用QGraphicsItem绘制事件
- Qt的子类QStyledItemDelegate绘制方法永远不会被调用
- openGL绘制调用之后会发生什么
- 圆函数:一次调用绘制多个圆
- 是否有可能在绘制其他Qt组件后强制Qt调用paintEvent ?