2012-02-06 19 views
6

Estoy tratando de usar tampones uniformes pero no funciona como se supone. Tengo dos buffers uniformes, uno es iluminación y el otro es material. El problema es que los colores no son lo que se supone que deben ser y cambian cada vez que muevo la cámara. Este problema no existía cuando usaba uniformes normales. Aquí hay fotos para mostrar lo que quiero decir: When using uniform buffers y when using normal uniforms!OpenGL Uniform buffers?

Esta es mi fragmento de sombreado:

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

No estoy seguro de que he hecho todo bien, pero es cómo creo los buffers uniformes aquí:

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: He aquí cómo llenar el tampones:

// 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

¿Qué ha hecho para depurar esto? ¿Has intentado imprimir qué valores obtienes en el sombreador (simplemente escribiéndolos como salida del sombreador de fragmentos)? Al menos con los colores, debería poder ver qué valores no están saliendo como espera. –

+0

Además, ¿dónde está el código que usa para llenar esos almacenamientos intermedios con valores? –

+0

@Gigi: No he visto esto en los Cat 12.1. Parece funcionar bien para mí, y uso 2 bloques en mi sombreador de fragmentos. Además, ¿ha archivado informes de fallas sobre esto? –

Respuesta

2

que tenían el mismo problema, pero sólo con AMD (no NVIDIA). Lo curioso fue que el problema solo ocurrió al cambiar la matriz de vista.

Como tenía un problema repetible según el cambio de la matriz de vista, pude rastrear hasta la causa raíz (haciendo arduas pruebas y errores). Al cambiar la vista en mi aplicación, asigno y libero algunos recursos de OpenGL dinámicamente dependiendo de lo que se necesita. En este proceso, hay una llamada a glDeleteBuffers() para el buffer 0. Si uso un enunciado condicional para no llamar a glDeleteBuffers para el buffer 0, entonces el problema desaparece.

De acuerdo con la documentación, el buffer 0 será ignorado silenciosamente por glDeleteBuffers. Supongo que hay un error en los controladores de AMD.

1

Intente actualizar el búfer usando glMapBuffer/glUnmapBuffer.