显示时,LWJGL纹理会颠倒翻转 [英] LWJGL Texture is flipped upside down when displayed

查看:164
本文介绍了显示时,LWJGL纹理会颠倒翻转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I followed a tutorial for reading a picture and creating a texture out of it, however, it shows up flipped upside down when rendered. The image is power of two.

主类

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 < image.getWidth(); x++) {
            int pixel = pixels[y * image.getWidth() + x];
            buffer.put((byte) ((pixel >> 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;
}

代码有问题或我必须先翻转图像创建纹理?

Is there something wrong with the code or do I have to flip the image before creating the texture?

推荐答案

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

Most image formats store the data top to bottom. Unless you reshuffle the data while loading the image, this is also the sequence in memory after reading the image.

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

When you create an OpenGL texture from the loaded image, this memory order is maintained unless you explicitly change the order. So the order in texture memory is still top to bottom.

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

OpenGL does not really have an image/texture orientation. But when you use texture coordinates, they address the texture in the order it's stored in memory. This means for the two extreme values of the t-coordinate:


  • t = 0.0对应于内存中图像的开头,即图像的上边缘。

  • t = 1.0对应于内存中图像的结尾,即图像的下边缘。

现在,查看您的绘制调用:

Now, looking at your draw calls:

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坐标),其余两个是顶部的两个顶点。

In the default OpenGL coordinate system, the y-coordinate goes bottom to top. So the first two vertices are the bottom vertices of the quad (since they have the smaller y-coordinate), the remaining two are the top two vertices.

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

Since you used t = 0.0 for the first two vertices, which are at the bottom of the quad, and t = 0.0 corresponds to the top of the image, the top of the image is at the bottom of the quad. Vice versa, you use t = 1.0 for the second two vertices, which are at the top of the quad, and t = 1.0 corresponds to the bottom of the image. Therefore, your image appears upside down.

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

By far the easiest way to fix this is to change the texture coordinates. Use t = 1.0 for the bottom two vertices, and t = 0.0 for the top two vertices, and the image orientation now matches the orientation of the quad on the screen:

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循环来自:

Another option is that you flip the image while reading it in, for example by changing the order of your for loop from:

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

to:

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

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

But it's very common to have images in top-down order in memory, and you often don't have control over it if you're using system libraries/frameworks for reading them. So using the texture coordinates to render them in the desired direction is a frequently used approach, and IMHO preferable over shuffling the data around.

这篇关于显示时,LWJGL纹理会颠倒翻转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆