0

前段时间,我拿起一本 OpenGL SuperBible 第五版的副本,在从学校回来的时候习惯了 1.0 的方式之后,慢慢而痛苦地开始自学 OpenGL 3.3 的方式。让事情变得更具挑战性,我主要是一名 .NET 开发人员,所以我在 Mono 中使用 OpenTK OpenGL 包装器工作。在我的笔记本电脑上,我编写了一个程序,让用户使用几个着色器在简单的风景中走动,这些着色器实现了每个顶点的着色、照明和纹理映射。在我在桌面上运行相同的程序之前,一切都运行良好。

灾难!什么都不会渲染!我已经将我的程序削减到相机位于原点附近的点,指向原点,并渲染一个正方形(从技术上讲,一个三角形扇形)。四边形在我的笔记本电脑上完美呈现,着色、照明、纹理等等,但桌面呈现一个小的扭曲的非方形四边形,颜色不正确,不受灯光影响,也没有纹理。

我怀疑显卡有问题,因为无论我启动到 Ubuntu 10.10 还是 Win XP,我都会得到相同的结果。我确实发现,如果我将顶点着色器缩减为仅输出位置数据,将片段着色器缩减为仅输出纯色(白色),则四边形渲染正确。但是,一旦我开始传入颜色数据(无论我是否在片段着色器中使用它),顶点着色器的输出就会再次失真。着色器紧随其后。我留下了预先存在的代码,但注释掉了,这样你就可以知道我在做什么。我是 glsl 的菜鸟,所以代码可能会好很多。

我的笔记本电脑是旧的 lenovo T61p,带有 Centrino (Core 2) Duo 和运行 Ubuntu 10.10 的 nVidia Quadro 显卡 我的台式机有 i7 和 Saphire 双启动到 Ubuntu 10.10 的 Radeon HD 4850 x2(单卡,双 GPU)和视窗XP。XP 和 Ubuntu 都会出现此问题。

任何人都可以看到我遗漏的错误吗?我的 HD 4850x2 有什么“特别”之处?

string vertexShaderSource = @"
#version 330

precision highp float;

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
//uniform mat4 normal_matrix;
//uniform mat4 cmv_matrix;  //Camera modelview.  Light sources are transformed by this matrix.
//uniform vec3 ambient_color;
//uniform vec3 diffuse_color;
//uniform vec3 diffuse_direction;

in vec4 in_position;
in vec4 in_color;
//in vec3 in_normal;
//in vec3 in_tex_coords;

out vec4 varyingColor;
//out vec3 varyingTexCoords; 

void main(void)
{
  //Get surface normal in eye coordinates
  //vec4 vEyeNormal = normal_matrix * vec4(in_normal, 0);

  //Get vertex position in eye coordinates
  //vec4 vPosition4 = modelview_matrix * vec4(in_position, 0);
  //vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

  //Get vector to light source in eye coordinates
  //vec3 lightVecNormalized = normalize(diffuse_direction);
  //vec3 vLightDir = normalize((cmv_matrix * vec4(lightVecNormalized, 0)).xyz);

  //Dot product gives us diffuse intensity
  //float diff = max(0.0, dot(vEyeNormal.xyz, vLightDir.xyz));

  //Multiply intensity by diffuse color, force alpha to 1.0
  //varyingColor.xyz = in_color * diff * diffuse_color.xyz;
  varyingColor = in_color;

  //varyingTexCoords = in_tex_coords;
  gl_Position = projection_matrix * modelview_matrix * in_position;
}";

        string fragmentShaderSource = @"
#version 330
//#extension GL_EXT_gpu_shader4 : enable

precision highp float;

//uniform sampler2DArray colorMap;

//in vec4 varyingColor;
//in vec3 varyingTexCoords;

out vec4 out_frag_color;

void main(void)
{
  out_frag_color = vec4(1,1,1,1);
  //out_frag_color = varyingColor;
  //out_frag_color = vec4(varyingColor, 1) * texture(colorMap, varyingTexCoords.st);
  //out_frag_color = vec4(varyingColor, 1) * texture(colorMap, vec3(varyingTexCoords.st, 0));
  //out_frag_color = vec4(varyingColor, 1) * texture2DArray(colorMap, varyingTexCoords);
}";

请注意,在此代码中,颜色数据被接受但并未实际使用。无论片段着色器是否使用可变颜色,几何体的输出都是相同的(错误的)。只有当我注释掉该行时varyingColor = in_color;,几何输出才会正确。最初着色器采用 vec3 输入,我只在故障排除时将它们修改为采用 vec4。

4

1 回答 1

1

事实证明,nVidia 驱动程序按照它们在着色器中列出的顺序留下输入,而 AMD 驱动程序则按字母顺序对它们进行排序。我应该使用 GetAttribLocation 来获取位置。

于 2011-01-21T07:16:32.783 回答