OpenGL Унифицированные буферы? - PullRequest
7 голосов
/ 06 февраля 2012

Я пытаюсь использовать одинаковые буферы, но это не работает, как предполагалось. У меня есть два одинаковых буфера, один для освещения, а другой для материала. Проблема в том, что цвета не такие, какими они должны быть, и они меняются каждый раз, когда я перемещаю камеру. Эта проблема не существовала, когда я использовал обычную форму. Вот изображения, чтобы показать, что я имею в виду: При использовании унифицированных буферов и при использовании обычных униформ !

Это мой фрагментный шейдер:

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

Ответы [ 2 ]

2 голосов
/ 18 ноября 2014

Попробуйте обновить буфер, используя glMapBuffer / glUnmapBuffer.

2 голосов
/ 24 июля 2012

У меня была такая же проблема, но только с AMD (не NVIDIA).Самое смешное, что проблема возникала только при смене матрицы вида.

Поскольку у меня была повторяемая проблема в зависимости от изменения матрицы вида, я смог отследить основную причину (выполнение трудных проб и ошибок).).При изменении представления в моем приложении я динамически распределяю и освобождаю некоторые ресурсы OpenGL в зависимости от того, что необходимо.В этом процессе происходит вызов glDeleteBuffers () для буфера 0. Если я использую условный оператор, чтобы не вызывать glDeleteBuffers для буфера 0, то проблема исчезнет.

Согласно документации, буфер 0 glDeleteBuffers будет молча игнорироваться.Я предполагаю, что в драйверах AMD есть ошибка.

...