前段时间,我拿起一本 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。