2012-02-06 5 views
6

균일 버퍼를 사용하려고하지만 예상대로 작동하지 않습니다. 나는 두 개의 균일 한 버퍼를 가지고 있는데, 하나는 조명이고 다른 하나는 물적이다. 문제는 색상이 카메라가 움직일 때마다 변경된다는 것입니다. 정상적인 제복을 사용할 때이 문제는 존재하지 않았습니다. 무슨 뜻인지 보여주는 그림은 다음과 같습니다 : When using uniform bufferswhen using normal uniforms!OpenGL 균일 버퍼?

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

편집 : 내가 바로 모든 일을하지만, 여기에 내가 균일 버퍼를 만드는 방법은 한 확실하지 않다

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

: 저는 여기를 채우는 방법

이 내 조각 쉐이더입니다 버퍼 :

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

디버깅을 위해 무엇을 했습니까? 셰이더에 어떤 값을 출력했는지 (단순히 셰이더 셰이더 출력으로 쓰는 것만으로) 시도해 봤나? 적어도 색상은 예상대로 나오지 않는 값을 볼 수 있어야합니다. –

+0

또한 버퍼에 값을 채우는 데 사용하는 코드는 어디에 있습니까? –

+0

@Gigi : Cat 12.1에서 이걸 보지 못했습니다. 그것은 나를 위해 잘 작동하는 것, 그리고 내 조각 쉐이더에서 2 블록을 사용합니다. 또한 이것에 버그 보고서를 제출 했습니까? –

답변

2

동일한 문제가 있지만 AMD (NVIDIA 제외)에서만 발생합니다. 재미있는 점은 뷰 매트릭스를 변경할 때만 문제가 발생했기 때문입니다.

뷰 매트릭스의 변경에 따라 반복적 인 문제가 있었기 때문에 근본 원인 (힘든 시행 착오)을 추적 할 수있었습니다. 애플리케이션에서 뷰를 변경할 때 필요한 부분에 따라 동적으로 OpenGL 리소스를 할당하고 해제합니다. 이 과정에서 버퍼 0에 대한 glDeleteBuffers() 호출이 있습니다. 버퍼 0에 대해 glDeleteBuffers를 호출하지 않도록 조건문을 사용하면 문제가 사라집니다.

설명서에 따르면 버퍼 0은 자동으로 glDeleteBuffers에 의해 무시됩니다. 내 생각 엔 AMD 드라이버에 버그가 있다는 것입니다.

1

glMapBuffer/glUnmapBuffer을 사용하여 버퍼를 업데이트하십시오.