OpenGL Mipmapping: OpenGL如何决定纹理的映射级别?

4
我在OpenGL中实现mipmapping时遇到了问题。我正在使用OpenFrameworks,并已修改ofTexture类以支持创建和渲染mipmaps。
以下代码是该类的原始纹理创建代码(稍作修改以提高清晰度):
  glEnable(texData.textureTarget);
      glBindTexture(texData.textureTarget, (GLuint)texData.textureID);
      glTexSubImage2D(texData.textureTarget, 0, 0, 0, w, h, texData.glType, texData.pixelType, data);
      glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glDisable(texData.textureTarget);

这是我带有mipmap支持的版本:

  glEnable(texData.textureTarget);
       glBindTexture(texData.textureTarget, (GLuint)texData.textureID);
       gluBuild2DMipmaps(texData.textureTarget, texData.glTypeInternal, w, h, texData.glType, texData.pixelType, data);
       glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
       glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glDisable(texData.textureTarget);

代码没有生成错误(gluBuild2DMipmaps返回“0”),纹理也能被渲染。然而,我没有看到任何区别。
我渲染的场景由z=0的“平面正方形瓦片”组成。基本上是一个2D场景。在绘制瓦片之前,我使用“glScale()”进行缩放来放大和缩小。当我缩小时,瓦片纹理的像素开始“跳动”,表明(据我所知)未经过滤的纹理查找。请参见:http://www.youtube.com/watch?v=b_As2Np3m8A 在25秒处。
我的问题是:由于我没有移动相机位置,只是对整个场景进行缩放,这是否意味着OpenGL不能决定适当的mipmap级别并使用完整的纹理大小(级别0)?
保罗
2个回答

3
Mipmapping不仅可以补偿场景比例,还可以补偿透视距离。顶点着色器输出(即使您没有使用自己的着色器,驱动程序仍将创建)指定每个顶点的屏幕空间坐标和这些顶点的纹理坐标。 GPU将根据将生成的片段的像素与纹素比率决定使用哪个mip级别。
在渲染瓦片时,您是否设置了GL_LINEAR_MIPMAP_LINEAR?这仅在渲染物体时才有影响,而不是在创建/加载纹理时。您的bracketing glEnable / glDisable调用也可能需要移动,具体取决于您实际传递的状态。

谢谢您的回复。我已经将glTexParamateri()调用移动到了gluBuild2DMipmaps()之前,甚至将它们添加到了绘制函数中。我也调用了glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST),但仍然看不到任何区别。至少,多亏了您,我现在明白OpenGL是如何决定mipmap级别的。 - Droozle
@Droozle:当你将glTexParameter移动到渲染代码中时,你是在glDraw*调用之前还是之后放置它?必须是在之前。当你调用像glTexParameter或glEnable这样的函数时,你正在设置gl驱动程序中的状态。驱动程序将记住这些状态,直到你将其设置为其他内容。大多数这些状态仅在您调用glDrawSomething的确切瞬间由驱动程序使用。 - Alan
谢谢回复。我知道OpenGL是一个状态机,我觉得我按照要求做了一切。在查看了至少20个不同的代码示例之后,我暂时放弃了。也许这与我的纹理具有Alpha通道有关,但到目前为止我没有什么运气。这很奇怪。 - Droozle

-2

谢谢,我尝试了MIN/MAX_LOD选项,但是没有效果。我注意到glTexSubImage2D()不支持mipmapping。我已经将其更改为glTexImage2D()调用,并遵循有关自动mipmap生成的建议。仍然没有成功,没有视觉差异,像素仍然闪烁。我的驱动程序支持OpenGL2.1,所以应该可以工作。我感到困惑,呵呵。 - Droozle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接