我正在重构一个以前使用opengl 1.1的物理模拟器,现在我正在将其设置为使用VBO和GLSL着色器。目前,模拟中的粒子都是从VBO中绘制的,其中物理边界是使用opengl即时模式绘制的。(我知道即时模式不是最终解决方案,但升级它是为了下一次)
问题:经过测试,我发现在ATI卡上没有绘制边界。我建立了一个简单的测试项目来了解发生了什么,我看到了与我的主要项目相同的结果:
在这种情况下,我可以绘制VBO对象Buddha,当我禁用着色器时,我可以在即时模式下绘制。但当我尝试使用即时模式将三角形放在"3d"空间时,它不会仅在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
相关着色器:顶点阴影边缘
#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;
}
NVIDIA以在顶点属性方面做一些不应该做的事情而闻名。在这种情况下,您正在利用顶点属性别名,这实际上违反了GLSL规范。
如果要使用固定函数顶点属性,请不要按照现有方式编写着色器。使用glVertexAttrib* (0, ....)
或使用gl_Vertex
而不是通用顶点属性(例如s_vPosition
)。
即使顶点属性0通常别名为gl_Vertex
,您也依赖于未定义的行为将in s_vPosition
分配给属性槽0\strong>。根本无法保证会发生这种情况。s_vColor
可以分配给0,特别是因为一些GLSL实现会在自动分配位置之前按字母顺序重新排列属性变量。
底线是,你不应该像现在这样使用固定函数的顶点属性。我建议使用显式通用属性并绑定着色器中的属性位置,或者简单地使用gl_Vertex
、gl_Color
等来代替通用属性。