【问题标题】:Rendering primitives through shader on ATI doesn't show通过 ATI 上的着色器渲染图元不显示
【发布时间】:2014-04-23 17:07:26
【问题描述】:

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

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

在这种情况下,我可以绘制 VBO 对象,佛像,当我禁用着色器时,我可以在立即模式下绘制。但是当我尝试使用即时模式将三角形放在“3d”空间中时,它不会只在 ATI 上渲染。

ATI 渲染 http://s23.postimg.org/xcgjxl2h7/ATI.png

英伟达渲染 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;
}

顶点着色器

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

片段着色器

#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 作为三角形的 z 坐标。那正是在视图体积的边界上。如果某些东西正好在边界上,则不确定是否定义了剪裁行为。作为一个实验,你可以尝试像 -0.99 这样的 z 坐标吗?
  • 我更改了坐标,但没有变化,仍然显示在 nvidia 而不是 ATI。我禁用了背面剔除,所以它们仍然出现
  • 我想我有一个更可行的理论。在您的着色器中,您使用的是通用顶点属性。但是您的代码使用glVertex3f 作为红色三角形,它设置了一个预定义的属性。而且我根本看不到它设置颜色。为了使这一切完全干净,您需要获取/设置着色器程序的属性位置(例如,在链接之前将 s_vPosition 的位置设置为 0 并将 s_vColor 的位置设置为 1,使用 glBindAttribLocation)。然后在绘制代码中,使用glVertexAttrib3f(1, ...)设置颜色,使用glVertexAttrib3f(0, ...)绘制顶点。
  • 哦,好吧,安东打字速度更快。 :) 这个问题听起来很熟悉,不是吗?

标签: c++ opengl nvidia ati


【解决方案1】:

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

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

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

底线是您不应该像现在这样使用固定功能的顶点属性。我建议要么使用显式的通用属性并在着色器中绑定属性位置,要么只使用gl_Vertexgl_Color 等而不是通用属性。

【讨论】:

  • 所以,如果我理解的话,我在“vec4 s_vPosition”中的着色器中使用 VBO,因为我传入了缓冲区中的位置。但是在立即模式下,着色器没有正确获取顶点信息,因为它们没有显式传入?
  • @user3565590:这实际上取决于您如何设置顶点指针。您可能正在使用glVertexAttribPointer (...)glVertex3f (...) 与顶点着色器中的 gl_Vertex 相关联,但也可以别名为通用顶点属性 0。这里真正的大问题是,即使实现尊重这个别名,实现也可以按照他们想要的任何顺序在顶点着色器中分配通用顶点属性。您需要使用 glBindAttribLocation (...) 并确保使用 glVertexAttrib3f (0, ...) 而不是 glVertex3f (...) 以便携方式执行此操作。
  • 另外澄清一下,VBO 正在使用 'glVertexAttribPointer(positionID, 3, GL_FLOAT, GL_FALSE, 0, 0);' 'positionID' 指向 's_vPosition' 以将位置发送到着色器,如果我更改着色器以从边界正确获取顶点信息,我是否需要某种布尔值用于 VBO ->'gl_Position = mPmVmMs_vPosition;' vs 边界 ->'gl_Position = mPmVmMfl_Vertex;'?
  • 不,如果您查询了positionID,这就是您所需要的。不要在即时模式代码中写glVertex3f (...),而是将其替换为glVertexAttrib3f (positionID, ...)。现在,关于立即模式的奇怪之处在于,它只会在您向通用属性 0 发送内容时创建一个顶点。立即模式是一件可怕的事情,如果您可以重构代码以完全避免它,那么说实话,这是您最好的选择。同样,不要使用glColor3f (...),而是使用glVertexAttrib3f (colorID, ...) 之类的东西。
  • 哦,好的,所以 'glVertexAttrib3f (0, ...)' 0 是指着色器中的属性 0,它链接到变量 'gl_Vertex'。但是使用 'glVertex3f (...)' 并不能保证去任何地方?
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
相关资源
最近更新 更多