纹理无法正确拉伸。为什么会发生这种情况?

4

我正在使用LWJGL和Slick框架来加载纹理到我的OpenGL应用程序。

我正在使用这张图片:日本国旗,用于纹理

以下是导入和使用纹理的代码:

    flagTexture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("japan.png"));

......

    flagTexture.bind();

    GL11.glColor3f(1.0f, 1.0f, 1.0f);
    GL11.glPushMatrix();

    GL11.glTranslatef(0.0f, 0.0f, -10.0f);

    GL11.glBegin(GL11.GL_QUADS);
    GL11.glTexCoord2f(0.0f, 0.0f);
    GL11.glVertex2f(0.0f, 0.0f);
    GL11.glTexCoord2f(1.0f, 0.0f);
    GL11.glVertex2f(2.5f, 0.0f);
    GL11.glTexCoord2f(1.0f, 1.0f);
    GL11.glVertex2f(2.5f, 2.5f);
    GL11.glTexCoord2f(0.0f, 1.0f);
    GL11.glVertex2f(0.0f, 2.5f);
    GL11.glEnd();

    GL11.glPopMatrix();

但最终结果是这样的: 纹理没有延伸到顶点参数 我没有使用任何特殊设置,如GL_REPEAT之类的东西。发生了什么?如何使纹理填充给定的顶点?
3个回答

9
看起来纹理被填充到了最接近2的幂的大小。这里有两个解决方案:
  1. 将纹理拉伸到最接近2的幂的大小。
  2. 计算您的纹理尺寸与最接近2的幂之间的差异,并将纹理坐标从1.0f更改为textureWidth/nearestPowerOfTwoWidthtextureHeight/nearestPowerOfTwoHeight
也可能有一些特定于LWJGL的方法可以允许非2的幂纹理,请进行研究。

哇,解决方案1有效了!非常感谢,我一直在为此苦苦挣扎。您能解释一下为什么这个解决方案有效,而原来的宽度和高度不行吗?是OpenGL的问题吗?谢谢。 - JulenissensHjelper
1
OpenGL自2.0版本起支持非二次幂纹理,这是LWJGL的特点。根据我所了解的,LWJGL仍然将纹理填充到最近的二次幂(可能是为了支持旧硬件)。通过您上传的图像,您的600x400像素的图像变成了1024x512的纹理。OpenGL纹理坐标在x和y轴上都缩放为0-1。一个纹理坐标(1, 1)表示(大约)像素(1024, 512)。您想要的是像素(600, 400),但按照0-1比例尺度进行缩放,因此将其缩小到该比例尺度:(600/1024,400/512)。 - Robert Rouhani

1
如果您需要支持非二次幂纹理,可以修改加载方法。如果您使用Slick2D,则除了实现自己的纹理类之外,没有其他方法可以做到这一点(您可以在此处获取一些示例:Texture.javaTextureLoader.java)。
TextureLoader类包含一个“get2Fold”方法,用于计算比纹理宽度/高度大的下一个二次幂。因此,如果您想使用非二次幂大小的纹理,只需更改此方法以简单地返回fold;(=输入),以便程序“认为”下一个二次幂是图像的大小,在许多情况下它并不是,但如果硬件支持它(大多数都支持),这不应该是问题。更“抽象”的方法是更改此行:
GL11.glTexImage2D(target,0,dstPixelFormat,get2Fold(bufferedImage.getWidth()),get2Fold(bufferedImage.getHeight()),0,srcPixelFormat,GL11.GL_UNSIGNED_BYTE,textureBuffer);
这里,第4个参数=纹理的宽度,第5个参数=纹理的高度。如果将它们设置为IMAGE的宽度/高度,它将起作用。由于此方法基本上与之前的方法相同,因此两者存在相同的问题。如前所述,这将减慢图像处理速度,并且可能不受支持。

0
希望这个链接能对你有所帮助。

http://www.lwjgl.org/wiki/index.php?title=Slick-Util_Library_-_Part_1_-_Loading_Images_for_LWJGL

看起来这和你在这里做的很相似。

GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0,0);
GL11.glVertex2f(100,100);
GL11.glTexCoord2f(1,0);
GL11.glVertex2f(100+texture.getTextureWidth(),100);
GL11.glTexCoord2f(1,1);
GL11.glVertex2f(100+texture.getTextureWidth(),100+texture.getTextureHeight());
GL11.glTexCoord2f(0,1);
GL11.glVertex2f(100,100+texture.getTextureHeight());
GL11.glEnd();

1
这仍然会产生相同的问题,这是纹理坐标的问题,而不是顶点的问题。 - Robert Rouhani

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