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 */);
我正在为我的游戏引擎制作纹理 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 */);