【发布时间】: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, ...)绘制顶点。 -
哦,好吧,安东打字速度更快。 :) 这个问题听起来很熟悉,不是吗?