我正在重写基于opengl的gis /映射程序。除其他外,该程序允许您加载海图的栅格图像,将其固定为经度/纬度坐标,并在其上缩放和平移。
该程序的先前版本使用自定义切片系统,从本质上讲,它是手动创建原始图像的Mipmap,其形式为256x256像素瓦片,具有多种二次方缩放级别。使用简单的四点平均算法,从缩放级别n的四个图块构建缩放级别为n-1的图块。因此,它关闭了opengl mipmapping,而当需要在某个缩放级别绘制图表的某些部分时,它将使用最接近匹配缩放级别的图块(即,图块处于二次幂缩放状态)级别,但程序允许任意缩放级别),然后缩放图块以匹配实际的缩放级别。当然,它必须在各个级别管理所有这些图块的缓存。
在我看来,这种拼贴系统过于复杂。看来我应该能够让图形硬件为我完成所有这些映射工作。因此,在新程序中,当我读取图像时,我将其切成每个1024x1024像素的纹理。然后将每个纹理固定为其lon / lat坐标,然后在缩放和平移时让opengl处理其余纹理。
它可以工作,但问题是:我的结果比原始程序有点模糊,这对于该应用程序很重要,因为您希望能够尽早缩放显示图表上的文本。因此,在清晰度方面,似乎原始程序使用的简单的四点平均算法比opengl +我的GPU提供了更好的结果。
我知道有几个glTexParameter设置可以控制mipmap如何工作的某些方面。我尝试了GL_TEXTURE_MIN_FILTER的各种设置与GL_TEXTURE_MAX_LEVEL的各种组合(从0到10的任何地方)。当我将GL_TEXTURE_MAX_LEVEL设置为0(没有mipmaps)时,我当然会获得“清晰”的结果,但是它们太清晰了,因为像素只是在这里和那里掉落,因此在中间缩放时这些数字不可读。当我将GL_TEXTURE_MAX_LEVEL设置为较高的值时,将图像缩小得很远(例如,当整个图表都适合屏幕时)时,图像看起来会很好,但是当您放大到中间缩放时,您会注意到模糊,尤其是在观看时图表上的文字。 (即,如果不是针对文本,您可能会认为“哇,opengl在顺利缩放我的图像方面做得很好。”但是对于文本,您会认为“为什么这张图表不清晰?”)
我的理解是,基本上,您告诉opengl生成mipmap,然后在放大时选择要使用的适当的mipmap,并且在两个最接近的mipmap级别之间进行插值,并且使用最接近的像素或对附近的像素。但是,正如我说的那样,在图表的相同缩放级别(即文本较小但不小)的缩放级别(如等价于“ 7点”或“ 8磅”大小),作为以前的基于图块的版本。
我的结论是,opengl创建的mipmap比以前用均四点算法创建的程序更加模糊,并且没有选择正确的mipmap或LINEAR vs NEAREST就能获得我所需要的清晰度。
具体问题:
(1)与原始程序中的平均四点算法相比,opengl实际上制作的模糊mipmap是否正确?
(2)在我使用glTexParameter时,使用opengl制作的mipmap可能会产生更清晰的结果吗?
(3)是否可以通过某种方式使opengl首先制作更清晰的mipmap,例如通过使用“立方”过滤器或以其他方式控制mipmap的创建过程?或就此而言,似乎我可以使用相同的平均四点代码手动生成mipmap,并将其交给opengl。但是我不知道该怎么做...
最佳答案
(1)似乎不太可能;我希望它仅使用盒式过滤器,平均效果为四个点。可能是在不同的时间从一种纹理切换到一种高分辨率的纹理,例如它“选择与要纹理化的像素的大小最接近的mipmap”,因此将使用256x256的地图对383x383的区域进行纹理化,而它替换的手动系统可能始终从512x512缩小到目标尺寸为256x256或更少。
(2)不是我在基本GL中知道的,但是如果要切换到GLSL和可编程管线,则可以使用'bias'参数到texture2D,如果问题是在以下情况下使用的是较低分辨率的贴图:你不希望如此。类似地,GL_EXT_texture_lod_bias扩展名可以在固定管道中执行相同的操作。这是十年前的NVidia扩展,是所有可编程卡都可以做到的事情,因此您很有可能会拥有它。
(编辑:更详尽地阅读扩展,纹理偏差已迁移到1.4版的OpenGL核心规范中;显然我的手册页已经过时。检查1.4 spec,第279页,您可以提供GL_TEXTURE_LOD_BIAS)
(3)是的-如果禁用GL_GENERATE_MIPMAP,则可以使用glTexImage2D提供每个缩放级别所需的任何图像,这就是“ level”参数所指示的。因此,您可以根据需要提供完全不相关的Mip映射。
关于opengl - 如何使opengl mipmap更清晰?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5989332/