Рендеринг примитивов через шейдер на ATI не показывает

Я занимаюсь рефакторингом симулятора физики, который ранее использовал opengl 1.1. Теперь я настраиваю его для использования шейдеров VBO и GLSL. В настоящее время все частицы в моделировании взяты из VBO, где физические границы нарисованы в непосредственном режиме opengl. (Я знаю, что немедленный режим не является конечным решением, но его обновление в другой раз)

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

В этом случае я могу нарисовать объект VBO, Будду, и когда я отключаю шейдеры, я могу рисовать в непосредственном режиме. Но когда я пытаюсь использовать немедленный режим, чтобы поместить треугольники в «трехмерное» пространство, он не рендерится только на ATI.

Рендеринг ATI
http://s23.postimg.org/xcgjxl2h7/ATI.png

Рендеринг nvidia
http://s23.postimg.org/qaimbdyvf/NVIDIA.png

Итак, белый треугольник — это когда я использую

glUseProgram(0);
glBegin(GL_TRIANGLES);
glVertex3f(-0.9, 1, -1.0);
glVertex3f(-0.9, -1, -1.0);
glVertex3f(-0.2, 1, -1.0);
glEnd();

Красный треугольник

glUseProgram(shaderProgramPrimID);
glBegin(GL_TRIANGLES);
glVertex3f(0.9, 1, -1.0);
glVertex3f(0.9, -1, -1.0);
glVertex3f(0.2, 1, -1.0);
glEnd();

И Будда glDrawElements вызов

Соответствующие шейдеры:
VertexShaderPrim

#version 130

in vec4 s_vPosition;
in vec4 s_vColor;
out vec4 color;

void main () {
color = s_vColor;
gl_Position = s_vPosition;
}

FragmentShaderPrim

#version 130

in vec4 color;
out vec4 fColor;

void main () {
fColor = color;
}

VertexShader

#version 130

in vec4 s_vPosition;
in vec4 s_vNormal;

uniform mat4 mM;
uniform mat4 mV;
uniform mat4 mP;
uniform mat4 mRotations;

uniform vec4 vLight;

out vec3 fN;
out vec3 fL;

out vec3 fE;

void main () {
fN = (mRotations*s_vNormal).xyz;
fL = (vLight).xyz;
fE = (mV*mM*s_vPosition).xyz;
gl_Position = mP*mV*mM*s_vPosition;
}

FragmentShader

#version 130

in vec3 fN;
in vec3 fL;
in vec3 fE;

out vec4 fColor;

void main () {
vec3 N = normalize(fN);
vec3 L = normalize(fL);

vec3 E = normalize(-fE);
vec3 H = normalize(L + E);

float diffuse_intensity = max(dot(N, L), 0.0);
vec4 diffuse_final = diffuse_intensity*vec4(0.1, 0.1, 0.1, 1.0);

float spec_intensity = pow(max(dot(N, H), 0.0), 30);
vec4 spec_final = spec_intensity*vec4(0.9, 0.1, 0.1, 1.0);

fColor = diffuse_final + spec_final;
}

-1

Решение

NVIDIA известна своими действиями, которые она не должна выполнять в отношении атрибутов вершин. В этом случае вы используете псевдоним атрибута вершины, который фактически нарушает спецификацию GLSL.

Если вы собираетесь использовать атрибуты вершин с фиксированными функциями, не пишите свой шейдер так, как вы. Либо использовать glVertexAttrib* (0, ....) или использовать gl_Vertex вместо общего атрибута вершины (например, s_vPosition).

Хотя атрибут вершины 0 как правило, псевдонимы gl_Vertex, вы полагаетесь на неопределенное поведение, чтобы назначить in s_vPosition приписать слот 0. Просто нет гарантии, что это произойдет. s_vColor может быть назначен 0, особенно потому, что некоторые реализации GLSL перегруппируют ваши атрибутные переменные в алфавитном порядке перед автоматическим назначением их местоположений.

Суть в том, что вы не должны использовать атрибуты вершин с фиксированной функцией такими, какие вы есть. Я бы предложил либо использовать явные общие атрибуты и привязать расположение атрибутов в вашем шейдере, либо просто использовать gl_Vertex, gl_Colorи т. д. вместо общих атрибутов.

1

Другие решения


По вопросам рекламы [email protected]