通过ATI上的着色器渲染基元不会显示

时间:2014-04-23 17:07:26

标签: c++ opengl nvidia ati

我正在重构以前使用过opengl 1.1的物理模拟器现在我将它设置为使用VBO和GLSL着色器。目前,模拟中的粒子都是从VBO中抽取的,其中物理边界是用opengl立即模式绘制的。 (我知道立即模式不是最终解决方案,而是另一次升级)

问题: 经过测试,我发现在ATI卡上没有绘制边界。我设置了一个简单的测试项目来弄清楚发生了什么,我看到了与我的主项目相同的结果:

在这种情况下,我可以绘制VBO对象,佛像,当我禁用着色器时,我可以立即绘制。但是当我尝试使用立即模式将三角形放在“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电话

相关着色器: 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 个答案:

答案 0 :(得分:1)

NVIDIA因处理顶点属性而不应该做的事情而闻名。在这种情况下,您正在利用顶点属性别名,这实际上违反了GLSL规范。

如果您要使用固定功能顶点属性,请不要按照您的方式编写着色器。使用glVertexAttrib* (0, ....)或使用gl_Vertex代替通用顶点属性(例如s_vPosition)。

尽管顶点属性 0 通常是gl_Vertex的别名,但您依靠未定义的行为将in s_vPosition分配给属性插槽 0 。根本无法保证会发生这种情况。 s_vColor可以分配给 0 ,特别是因为一些GLSL实现会在自动为其分配位置之前按字母顺序重新排列属性变量。

底线是你不应该像你一样使用固定功能顶点属性。我建议使用显式通用属性并在着色器中绑定属性位置,或者只使用gl_Vertexgl_Color等代替通用属性。