OpenGL 3 和 Radeon HD 4850x2
不久前,我拿起一本《OpenGL SuperBible》第五版,在从学校开始习惯了 1.0 方式之后,开始慢慢地、痛苦地开始以 3.3 方式自学 OpenGL。让事情变得更具挑战性的是,我主要是一名 .NET 开发人员,因此我在 Mono 中使用 OpenTK OpenGL 包装器进行工作。在我的笔记本电脑上,我编写了一个程序,让用户使用几个实现每个顶点着色、照明和纹理映射的着色器在简单的景观中行走。一切都运行得很好,直到我在桌面上运行相同的程序。
灾难!什么都不会渲染!我已经将程序缩减到相机位于原点附近的点,指向原点,并渲染一个正方形(从技术上讲,是一个三角形扇形)。该四边形在我的笔记本电脑上完美渲染,包括着色、照明、纹理等,但桌面渲染了一个小的扭曲的非方形四边形,其颜色不正确,不受灯光影响,也没有纹理。
我怀疑显卡有问题,因为无论我启动Ubuntu 10.10还是Win XP,都会得到相同的结果。我确实发现,如果我将顶点着色器削减为仅输出位置数据,并将片段着色器削减为仅输出纯色(白色),则四边形将正确渲染。但是,当我开始传递颜色数据(无论我是否在片段着色器中使用它)时,顶点着色器的输出再次失真。着色器紧随其后。我保留了预先存在的代码,但对其进行了注释,以便您可以了解我想要做什么。我是 glsl 的菜鸟,所以代码可能会更好。
我的笔记本电脑是旧的 lenovo T61p,配备 Centrino (Core 2) Duo 和 nVidia Quadro 显卡,运行 Ubuntu 10.10 我的桌面有一个 i7,带有 Radeon HD 4850 x2(单卡,双 GPU),从 Saphire 双启动到 Ubuntu 10.10 和 Windows 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);
}";
请注意,在此代码中,颜色数据被接受但并未实际使用。无论片段着色器是否使用不同颜色,几何体都会输出相同(错误)的结果。仅当我注释掉 variingColor = in_color;
行时,几何图形才能正确输出。最初着色器接受 vec3 输入,我只是在故障排除时将它们修改为接受 vec4。
A while ago, I picked up a copy of the OpenGL SuperBible fifth edition and slowly and painfully started teaching myself OpenGL the 3.3 way, after having been used to the 1.0 way from school way back when. Making things more challenging, I am primarily a .NET developer, so I was working in Mono with the OpenTK OpenGL wrapper. On my laptop, I put together a program that let the user walk around a simple landscape using a couple shaders that implemented per-vertex coloring and lighting and texture mapping. Everything was working brilliantly until I ran the same program on my desktop.
Disaster! Nothing would render! I have chopped my program down to the point where the camera sits near the origin, pointing at the origin, and renders a square (technically, a triangle fan). The quad renders perfectly on my laptop, coloring, lighting, texturing and all, but the desktop renders a small distorted non-square quadrilateral that is colored incorrectly, not affected by the lights, and not textured.
I suspect the graphics card is at fault, because I get the same result whether I am booted into Ubuntu 10.10 or Win XP. I did find that if I pare the vertex shader down to ONLY outputting the positional data and the fragment shader to ONLY outputting a solid color (white) the quad renders correctly. But as SOON as I start passing in color data (whether or not I use it in the fragment shader) the output from the vertex shader is distorted again. The shaders follow. I left the pre-existing code in, but commented out so you can get an idea what I was trying to do. I'm a noob at glsl so the code could probably be a lot better.
My laptop is an old lenovo T61p with a Centrino (Core 2) Duo and an nVidia Quadro graphics card running Ubuntu 10.10
My desktop has an i7 with a Radeon HD 4850 x2 (single card, dual GPU) from Saphire dual booting into Ubuntu 10.10 and Windows XP. The problem occurs in both XP and Ubuntu.
Can anyone see something wrong that I am missing? What is "special" about my 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);
}";
Note that in this code the color data is accepted but not actually used. The geometry is outputted the same (wrong) whether the fragment shader uses varyingColor or not. Only if I comment out the line varyingColor = in_color;
does the geometry output correctly. Originally the shaders took in vec3 inputs, I only modified them to take vec4s while troubleshooting.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,nVidia 驱动程序按照着色器中列出的顺序保留输入,而 AMD 驱动程序则按字母顺序对它们进行排序。我应该使用 GetAttribLocation 来获取位置。
It turns out nVidia drivers leave inputs in the order they are listed in he shaders, while AMD drivers sort them alphabetically. I should have used GetAttribLocation to get the locations.