Uniform OpenGL buffers?

I am trying to use unified buffers, but it does not work as intended. I have two identical buffers, one is light and the other is material. The problem is that the colors are not what they should be, and they change every time I move the camera. This problem did not exist when I used the regular form. Here are the photos to show what I mean: When using uniform buffers and when using regular uniforms !

This is my fragment shader:

#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); } 

I'm not sure I did everything right, but here is how I create uniform buffers:

 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); 

EDIT: Here, as I fill the buffers:

 // 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); 
+6
source share
2 answers

I had the same problem, but only with AMD (and not with NVIDIA). The funny thing is that the problem occurred only when the view matrix changed.

Since I had a repeatable problem, depending on the change in the presentation matrix, I was able to trace to the root cause (making a complex trial version and an error). When changing the view in my application, I allocate and free some OpenGL resources dynamically depending on what is needed. In this process, there is a call to glDeleteBuffers () for buffer 0. If I use a conditional statement so as not to call glDeleteBuffers for buffer 0, the problem will disappear.

According to the documentation, buffer 0 will be silently ignored by glDeleteBuffers . I assume there is an error in AMD drivers.

+2
source

Try updating the buffer using glMapBuffer / glUnmapBuffer .

+1
source

Source: https://habr.com/ru/post/907734/


All Articles