显示时,LWJGL纹理会颠倒翻转

我按照教程阅读图片并从中创建纹理,然而,它在渲染时显示为颠倒翻转。 图像是两个的力量。

主要课程

public class Main { public static void main(String args[]) throws IOException{ Main quadExample = new Main(); quadExample.start(); } public void start() throws IOException { try { Display.setDisplayMode(new DisplayMode(1280,720)); Display.create(); } catch (LWJGLException e) { e.printStackTrace(); System.exit(0); } // init OpenGL GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); GL11.glOrtho(0, 1280, 0, 720, -1, 1); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glClearColor(0, 1, 0, 0); GL11.glEnable(GL11.GL_TEXTURE_2D); BufferedImage image = TextureLoader.loadImage("C:\\test.png"); final int textureID = TextureLoader.loadTexture(image); while (!Display.isCloseRequested()) { GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID); GL11.glBegin(GL11.GL_QUADS); GL11.glTexCoord2f(0, 0); GL11.glVertex2f(0, 0); GL11.glTexCoord2f(1, 0); GL11.glVertex2f(256, 0); GL11.glTexCoord2f(1, 1); GL11.glVertex2f(256, 256); GL11.glTexCoord2f(0, 1); GL11.glVertex2f(0, 256); GL11.glEnd(); Display.update(); } Display.destroy(); } 

}

纹理加载器

 public class TextureLoader { private static final int BYTES_PER_PIXEL = 4; public static int loadTexture(BufferedImage image) { int[] pixels = new int[image.getWidth() * image.getHeight()]; image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); for (int y = 0; y < image.getHeight(); y++) { for (int x = 0; x > 16) & 0xFF)); buffer.put((byte) ((pixel >> 8) & 0xFF)); buffer.put((byte) (pixel & 0xFF)); buffer.put((byte) ((pixel >> 24) & 0xFF)); } } buffer.flip(); int textureID = glGenTextures(); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); return textureID; } public static BufferedImage loadImage(String location) { try { return ImageIO.read(new File(location)); } catch (IOException e) { System.out.println(Errors.IOException); e.printStackTrace(); } return null; } 

代码有什么问题,还是我必须在创建纹理之前翻转图像?

大多数图像格式从上到下存储数据。 除非您在加载图像时重新调整数据,否则这也是读取图像后内存中的序列。

从加载的图像创建OpenGL纹理时,除非您明确更改顺序,否则将保留此内存顺序。 所以纹理内存中的顺序仍然是从上到下。

OpenGL实际上没有图像/纹理方向。 但是当你使用纹理坐标时,它们按照存储在内存中的顺序来处理纹理。 这意味着对于t坐标的两个极值:

  • t = 0.0对应于存储器中图像的开始,这是图像的上边缘。
  • t = 1.0对应于内存中图像的结尾,即图像的下边缘。

现在,看看你的绘制调用:

 GL11.glTexCoord2f(0, 0); GL11.glVertex2f(0, 0); GL11.glTexCoord2f(1, 0); GL11.glVertex2f(256, 0); GL11.glTexCoord2f(1, 1); GL11.glVertex2f(256, 256); GL11.glTexCoord2f(0, 1); GL11.glVertex2f(0, 256); 

在默认的OpenGL坐标系中,y坐标从下到上。 所以前两个顶点是四边形的底部顶点(因为它们具有较小的y坐标),其余两个顶点是顶部的两个顶点。

由于前两个顶点(位于四边形的底部)使用t = 0.0,而t = 0.0对应于图像的顶部,因此图像的顶部位于四边形的底部。 反之亦然,对于后两个顶点使用t = 1.0,它们位于四边形的顶部,而t = 1.0对应于图像的底部。 因此,您的图像显示为颠倒。

到目前为止,解决此问题的最简单方法是更改​​纹理坐标。 对于底部两个顶点使用t = 1.0,对于顶部两个顶点使用t = 0.0,并且图像方向现在与屏幕上四边形的方向匹配:

 GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex2f(0.0f, 0.0f); GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex2f(256.0f, 0.0f); GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex2f(256.0f, 256.0f); GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex2f(0.0f, 256.0f); 

另一种选择是在读取图像时翻转图像,例如通过更改for循环的顺序:

 for (int y = 0; y < image.getHeight(); y++) { 

至:

 for (int y = image.getHeight() - 1; y >= 0; y--) { 

但是在内存中以自上而下的顺序存储图像是很常见的,如果您使用系统库/框架来读取它们,则通常无法控制它。 因此,使用纹理坐标在期望的方向上渲染它们是一种经常使用的方法,并且恕我直言地改变了数据。