У меня странное поведение с одинаковыми буферами в моем хобби движке OpenGL4.1.
В Windows все работает нормально (как на графических процессорах Intel, так и на видеокартах Nvidia), но на моем MacBook (также на Intel) это не работает.
Итак, чтобы объяснить, что происходит в OSX: если я жестко закодирую все свои переменные Uniform Buffer в фактическом фрагментном коде шейдера, тогда я смогу отрендериться отлично, но если я верну их обратно в переменные - я ничего не получу.
Я посмотрел на состояние OpenGL с помощью apitrace, и все значения переменных идеальны, поэтому я немного смущен тем, что здесь происходит.
Я надеюсь, что это просто ошибка кода, а не какая-то основная проблема с драйверами.
Ниже приведен фрагмент кода шейдера, где, если я жестко закодирую все переменные DirectionLight, все будет работать нормально.
#version 410
struct DirectionalLightData
{
vec4 Colour;
vec3 Direction;
float Intensity;
};
layout(std140) uniform ObjectBuffer
{
mat4 Model;
};
layout(std140) uniform FrameBuffer
{
mat4 Projection;
mat4 View;
DirectionalLightData DirectionalLight;
vec3 ViewPos;
};
uniform sampler2D PositionMap;
uniform sampler2D NormalMap;
uniform sampler2D AlbedoSpecMap;
layout(location = 0) in vec2 TexCoord;
out vec4 FinalColour;
float CalcDiffuseContribution(vec3 lightDir, vec3 normal)
{
return max(dot(normal, -lightDir), 0.0f);
}
float CalcSpecularContribution(vec3 lightDir, vec3 viewDir, vec3 normal, float specularExponent)
{
vec3 reflectDir = reflect(lightDir, normal);
vec3 halfwayDir = normalize(lightDir + viewDir);
return pow(max(dot(normal, halfwayDir), 0.0f), specularExponent);
}
float CalcDirectionLightFactor(vec3 viewDir, vec3 lightDir, vec3 normal)
{
float diffuseFactor = CalcDiffuseContribution(lightDir, normal);
float specularFactor = CalcSpecularContribution(normal, viewDir, normal, 1.0f);
return diffuseFactor * specularFactor;
}
void main()
{
vec3 position = texture(PositionMap, TexCoord).rgb;
vec3 normal = texture(NormalMap, TexCoord).rgb;
vec3 albedo = texture(AlbedoSpecMap, TexCoord).rgb;
vec3 viewDir = normalize(ViewPos - position);
float directionLightFactor = CalcDirectionLightFactor(viewDir, DirectionalLight.Direction, normal) * DirectionalLight.Intensity;
FinalColour.rgb = albedo * directionLightFactor * DirectionalLight.Colour.rgb;
FinalColour.a = 1.0f * DirectionalLight.Colour.a;
}
Вот порядок, в котором я обновляю и связываю UBO (я извлек их из apitrace, так как здесь слишком много кода, чтобы скопировать вставку):
glGetActiveUniformBlockName(5, 0, 255, NULL, FrameBuffer);
glGetUniformBlockIndex(5, FrameBuffer) = 0;
glGetActiveUniformBlockName(5, 1, 255, NULL, ObjectBuffer);
glGetUniformBlockIndex(5, ObjectBuffer) = 1;
glBindBuffer(GL_UNIFORM_BUFFER, 1);
glMapBufferRange(GL_UNIFORM_BUFFER, 0, 172,GL_MAP_WRITE_BIT);
memcpy(0x10b9f8000, [binary data, size = 172 bytes], 172);
glUnmapBuffer(GL_UNIFORM_BUFFER);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, 2);
glBindBufferBase(GL_UNIFORM_BUFFER, 1, 1);
glBindBuffer(GL_UNIFORM_BUFFER, 2);
glMapBufferRange(GL_UNIFORM_BUFFER, 0, 64, GL_MAP_WRITE_BIT);
memcpy(0x10b9f9000, [binary data, size = 64 bytes], 64);
glUnmapBuffer(GL_UNIFORM_BUFFER);
glUniformBlockBinding(5, 1, 0);
glUniformBlockBinding(5, 0, 1);
glDrawArrays(GL_TRIANGLES, 0, 6);
Обратите внимание, что UBO FrameBuffer имеет идентификатор 1, а UBO ObjectBuffer имеет идентификатор 2