OpenGL统一缓冲区?

OpenGL统一缓冲区?

问题描述:

我试图使用统一的缓冲区,但它不工作。我有两个统一的缓冲区,一个是光照,另一个是材质。问题在于颜色不是它们应该是的,每次移动相机时它们都会发生变化。当我使用正常制服时,这个问题不存在。这里的图片来展示我的意思:When using uniform bufferswhen using normal uniformsOpenGL统一缓冲区?

这是我的片段着色器:

#version 400 // Fragment Shader 
uniform layout(std140); 

in vec3 EyePosition; 
in vec3 EyeNormal; 
in vec2 TexCoord; 

out vec4 FragColor; 

uniform sampler2D Texture; 

uniform LightBlock 
{ 
    vec4 Position; 
    vec4 Intensity; 
} Light; 

uniform MaterialBlock 
{ 
    vec4 Ambient; 
    vec4 Diffuse; 
} Material; 

vec4 PointLight(in int i, in vec3 ECPosition, in vec3 ECNormal) 
{ 
    vec3 n = normalize(ECNormal); 
    vec3 s = normalize(Light.Position.xyz - ECPosition); 

    return Light.Intensity * (Material.Ambient + Material.Diffuse * max(dot(s, n), 0.0)); 
} 

void main() 
{ 
    FragColor = texture(Texture, TexCoord); 
    FragColor *= PointLight(0, EyePosition, EyeNormal); 
} 

我不知道我所做的一切都是正确的,但在这里就是我如何建立统一的缓冲区:

glGenBuffers(1, &light_buffer); 
glGenBuffers(1, &material_buffer); 

glBindBuffer(GL_UNIFORM_BUFFER, light_buffer); 
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightBlock), nullptr, GL_DYNAMIC_DRAW); 

glBindBuffer(GL_UNIFORM_BUFFER, material_buffer); 
glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialBlock), nullptr, GL_DYNAMIC_DRAW); 

GLuint program = Shaders.GetProgram(); 

light_index = glGetUniformBlockIndex(program, "LightBlock"); 
material_index = glGetUniformBlockIndex(program, "MaterialBlock"); 

glUniformBlockBinding(program, light_index, 0); 
glUniformBlockBinding(program, material_index, 1); 

glBindBufferBase(GL_UNIFORM_BUFFER, 0, light_buffer); 
glBindBufferBase(GL_UNIFORM_BUFFER, 1, material_buffer); 

编辑:这就是我如何填写缓冲区:

// Global structures 
struct LightBlock 
{ 
    Vector4 Position; // Vector4 is a vector class I made 
    Vector4 Intensity; 
}; 

struct MaterialBlock 
{ 
    Vector4 Ambient; 
    Vector4 Diffuse; 
}; 

// This is called for every object rendered 
LightBlock Light; 
Light.Position = Vector3(0.0f, 5.0f, 5.0f) * Camera.GetCameraMatrix(); 
Light.Intensity = Vector4(1.0f); 

glBindBuffer(GL_UNIFORM_BUFFER, light_buffer); 
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightBlock), &Light); 

MaterialBlock Material; 
Material.Diffuse = Vector4(1.0f); 
Material.Ambient = Material.Diffuse * Vector4(0.3f); 

glBindBuffer(GL_UNIFORM_BUFFER, material_buffer); 
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(MaterialBlock), &Material); 
+0

你做了什么来调试呢?你有没有尝试打印出你在着色器中获得的值(通过简单地将它们写为片段着色器输出)?至少在颜色方面,你应该能够看到哪些值不会像你期望的那样出现。 – 2012-02-06 03:29:58

+0

另外,您用来使用值填充这些缓冲区的代码在哪里? – 2012-02-06 03:30:10

+0

@Gigi:我没有在Cat 12.1上看到过这个。它似乎对我来说工作得很好,我在片段着色器中使用了2个块。另外,你是否提交过这方面的错误报告? – 2012-02-06 03:36:49

我有同样的问题,但只与AMD(不NVIDIA)。有趣的是,这个问题只发生在改变视图矩阵时。

由于我有一个可重复的问题取决于视图矩阵的变化,我能够追溯到根本原因(做了艰难的尝试和错误)。在我的应用程序中更改视图时,根据需要动态分配和释放一些OpenGL资源。在这个过程中,为缓冲区0调用glDeleteBuffers()。如果我使用条件语句以避免为缓冲区0调用glDeleteBuffers,则问题消失。

根据文档,缓冲区0将被glDeleteBuffers默默忽略。我的猜测是AMD驱动程序中存在一个错误。

尝试使用glMapBuffer/glUnmapBuffer更新缓冲区。