LWJGL 纹理 - glTexImage2D 有时会崩溃

LWJGL Texturing - glTexImage2D sometimes crashes

我正在为我的游戏引擎制作纹理 class。现在我有这个简单的代码来创建二维纹理并向其加载图像。

public class Texture {
    private int id;
    
    private Texture(int id) {
        this.id = id;
    }
    
    public static Texture createColorTexture() {
        int id = GL11.glGenTextures();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); 
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        return new Texture(id); 
    }
    
    public void loadImage(String file) {
        bind();
        String path = "res/textures/" + file;
        int width = 0, height = 0;
        int[] pixels = null;
        try {
            BufferedImage image = ImageIO.read(new FileInputStream(path));
            width = image.getWidth();
            height = image.getHeight();
            pixels = new int[width * height];
            image.getRGB(0, 0, width, height, pixels, 0, width);
        } catch (IOException e) {
            e.printStackTrace();
        }
        ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 4);
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int pixel = pixels[y * width + x];
                buffer.put((byte) ((pixel >> 16) & 0xFF)); 
                buffer.put((byte) ((pixel >> 8) & 0xFF));      
                buffer.put((byte) (pixel & 0xFF));              
                buffer.put((byte) ((pixel >> 24) & 0xFF));  
            }
        }
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, 
                GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
        unbind();
    }
    
    public int getId() {
        return id;
    }
    
    public void bind() {
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
    }
    
    public void unbind() {
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
    }
}

问题是,当我将图像加载到纹理时,它有时可以工作,但有时会崩溃。这是怎么回事?

我使用 Eclipse,当它崩溃时,我得到一个名为“hs_err_pid”的文件,后跟一个数字。

这是一个包含很多内容的长文件,但该文件中有一些值得注意的内容,为了便于阅读,我已将其缩短。

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.lwjgl.opengl.GL11C.nglTexImage2D(IIIIIIIIJ)V+0
j  org.lwjgl.opengl.GL11C.glTexImage2D(IIIIIIIILjava/nio/ByteBuffer;)V+17
j  org.lwjgl.opengl.GL11.glTexImage2D(IIIIIIIILjava/nio/ByteBuffer;)V+14

...
RIP=0x00007ffedadee30e nvoglv64.dll
RAX=0x0000018ad74522c0 points into unknown readable memory: 0x0000000000000000 | 00 00 00 00 00 00 00 00
RBX=0x0000018ad74522c0 points into unknown readable memory: 0x0000000000000000 | 00 00 00 00 00 00 00 00
RCX=0x0000000000019010 is an unknown value
RDX=0x0000000000661d50 is an unknown value
(and so on)

...

Event: 0.266 Thread 0x0000018aaba20670 Exception <a 'sun/nio/fs/WindowsException'{0x00000006204f6f38}> (0x00000006204f6f38) 
thrown [e:\jenkins\tmp\workspace\build\src\src\hotspot\share\prims\jni.cpp, line 516]
Event: 0.271 Thread 0x0000018aaba20670 Exception <a 'java/lang/NoSuchMethodError'{0x000000062052c3f8}: 'java.lang.Object java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(java.lang.Object)'> (0x000000062052c3f8) 
thrown [e:\jenkins\tmp\workspace\build\src\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.310 Thread 0x0000018aaba20670 Exception <a 'sun/nio/fs/WindowsException'{0x0000000620637ef0}> (0x0000000620637ef0) 
thrown [e:\jenkins\tmp\workspace\build\src\src\hotspot\share\prims\jni.cpp, line 516]
Event: 0.573 Thread 0x0000018aaba20670 Exception <a 'java/lang/ClassNotFoundException'{0x00000006201aa080}: sun/awt/resources/spi/awtProvider> (0x00000006201aa080) 
thrown [e:\jenkins\tmp\workspace\build\src\src\hotspot\share\classfile\systemDictionary.cpp, line 256]
Event: 0.611 Thread 0x0000018aaba20670 Exception <a 'java/lang/NoSuchMethodError'{0x00000006202a53c0}: 'java.lang.Object java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(java.lang.Object, int, int, int, int)'> (0x00000006202a53c0) 
thrown [e:\jenkins\tmp\workspace\build\src\src\hotspot\share\interpreter\linkResolver.cpp, line 766]

发生了什么事?为什么有时可以,有时会崩溃?

这是因为glTexImage2D从缓冲区的位置读取像素。你必须翻转缓冲区。

GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, 
        GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer.flip() /* note here */);