OpenGL纹理质量问题

时间:2010-12-05 13:23:59

标签: opengl

不久前,我将我的C#程序转换为使用OpenGL,发现它在家里的计算机上运行得非常好(并且速度更快)。但是,我有2个问题。首先,我用来从图形卡中释放纹理的代码没有字,它在运行时给了我一个内存访问冲突异常。其次,大多数图形不能在我的任何其他机器上运行。

偶然地,我设法将一些图形转换为8位PNG(所有其他的都是32位),这些在其他机器上运行良好。认识到这一点,我试图在加载图像时调节质量。我的尝试失败了(这是一段时间以前,我认为他们主要涉及尝试格式化位图,然后使用GDI将纹理绘制到其上,创建较低质量的版本)。在.NET中有什么方法可以采用位图并很好地改变质量?有关的代码如下。我记得它主要是基于我过去在Stack Overflow上发现的一些,但它不太适合我的需求。 'img'作为.NET图像,'d'是整数维度,我用它来确保图像是方形的。

uint[] output = new uint[1];

Bitmap bMap = new Bitmap(img, new Size(d, d));

System.Drawing.Imaging.BitmapData bMapData;
Rectangle rect = new Rectangle(0, 0, bMap.Width, bMap.Height);

bMapData = bMap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bMap.PixelFormat);

gl.glGenTextures(1, output);
gl.glBindTexture(gl.GL_TEXTURE_2D, output[0]);
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST);

gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST);
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP);
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP);
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1);
if (use16bitTextureLimit)
 gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA_FLOAT16_ATI, bMap.Width, bMap.Height, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, bMapData.Scan0);
else
 gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, bMap.Width, bMap.Height, 0, gl.GL_BGRA, gl.GL_UNSIGNED_BYTE, bMapData.Scan0);

bMap.UnlockBits(bMapData);
bMap.Dispose();

return output;

'use16bitTextureLimit'是一个bool,我更希望显示的代码会将质量降低到16位,但我没有发现任何差异。这可能是有效的,显卡仍然不喜欢它。我无法找到任何使用8位PNgs的方法。 这是一个函数,它返回uint数组(作为纹理地址)以供渲染时使用。错误的纹理处理只涉及:gl.glDeleteTextures(1, imgsGL[i]);其中imgGL是一个单元数组的数组。

如上所述,渲染在某些计算机上很好,并且纹理删除导致所有系统上的运行时错误(除了我的上网本,我无法创建纹理,但我认为这可能与质量问题有关)。

如果任何人都能提供任何相关信息,那就太棒了。我花了很多天在这个程序上,并且真的希望与不太好的显卡更加兼容。

1 个答案:

答案 0 :(得分:0)

如果调用glTexImage2D导致缓冲区溢出,通常会遇到您遇到的访问冲突类型。仔细检查与解包有关的所有glPixelStore参数是否正确设置格式参数(第二个)与您提供的数据的类型和大小相匹配。我非常了解这种bg,这是我经常做的第一次检查,每当我遇到它时。

对于没有显示的纹理:你有没有检查过,纹理的尺寸实际上是两个的幂?在C中使用宏来测试2的幂可以写成这样的(这个归结为测试,那个只有一个整数位被设置)

#define ISPOW2(x) ( x && !( (x) & ((x) - 1) ) )

然而,纹理图像是方形的并不是必需的。常见的误解,但你真的必须确保每个维度是2的幂.16×128的图像非常好。

将内部格式更改为GL_RGBA_FLOAT16_ATI甚至可能会提高质量,但人们无法确定,因为GL_RGBA可能强制要求驾驶员认为合适的任何内容。这也是供应商特定的格式,所以我无视它的使用。有各种ARB格式,也有半浮点格式(FLOAT16_ATI是)。