【问题标题】:OpenGL Texture Quality IssuesOpenGL 纹理质量问题
【发布时间】:2010-12-05 13:23:59
【问题描述】:

不久前,我将我的一个 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' 是一个布尔值,我更希望显示的代码会将质量降低到 16 位,但我没有注意到任何区别。这可能是可行的,而显卡仍然不喜欢它。我找不到任何使用 8 位 PNg 的方法的迹象。 这是在一个函数中,它返回 uint 数组(作为纹理地址)以供渲染时使用。错误的纹理处理简单地涉及:gl.glDeleteTextures(1, imgsGL[i]);其中imgGL是一个单元数组的数组。

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

如果有人可以提供任何相关信息,那就太好了。我在程序上花了很多天,真的很想与不太好的显卡兼容。

【问题讨论】:

    标签: opengl


    【解决方案1】:

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

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

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

    不过,纹理图像不一定是方形的。常见的误解,但您实际上只需要确保每个维度都是 2 的幂。16×128 的图像非常好。

    将内部格式更改为 GL_RGBA_FLOAT16_ATI 甚至可能会提高质量,但不能确定,因为 GL_RGBA 可能会强制转换为驱动程序认为合适的任何内容。这也是供应商特定的格式,所以我忽略了它的使用。 ARB 格式有很多种,半浮点数也有(FLOAT16_ATI 就是)。

    【讨论】:

    • 是的,“d”维度也计算为 2 的幂。感谢您的帖子,我会尝试一下。我不是 OpenGL 方面的专家,但我有一个朋友之前检查过加载 - 我会给他你的建议,看看他这次能否帮助诊断问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2019-12-23
    • 1970-01-01
    • 2012-06-26
    • 2012-07-24
    相关资源
    最近更新 更多