使用 Slick2D TextureLoader 加载 PNG 图像时 LWJGL 挂起
LWJGL hangs when loading PNG image using Slick2D TextureLoader
在 Mac OS X El Capitan,OpenGL 4.1 版中,我的 LWJGL 3.0 应用程序在调用 Slick2D 函数时挂起 TextureLoader.getTexture()
这是我试图用来加载纹理的代码。它与主循环在同一线程上 运行,并在 window 设置后调用。
FileInputStream file = new FileInputStream("src/AppIcon.png");
texture = TextureLoader.getTexture("PNG", file);
文件确实存在,我把贴图的代码注释掉后代码运行正常,就是这个方法
public int loadTexture(String filename){
Texture texture = null;
try{
FileInputStream file = new FileInputStream(filename + ".png");
//The app freezes here
texture = TextureLoader.getTexture("png", file);
//"LOADED" is never printed to the console.
System.out.println("LOADED");
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
return texture.getTextureID();
}
我尝试使用的纹理是 1024 x 1024 PNG 图像,
我也尝试过使用更小的 16 x 16 像素图像,
但我得到了相同的结果。
两个图像在物理上都没有问题,没有记录错误,控制台中最后打印的内容来自 Slick2D,说明
INFO:Use Java PNG Loader = true
这是 OS 特定的错误,还是我做错了什么?
我认为代码只有图像的路径,但尽管您在其后放置了文件类型 (.png),但它不知道文件类型,请尝试:
FileInputStream file = new FileInputStream(filename + ".png", PNG);
如果这不起作用,那可能是我弄乱了“”,所以如果您再次遇到错误,请试试这个(但它可能不会起作用)
FileInputStream file = new FileInputStream(filename + ".png", "PNG");
事实证明,Slick2D
与 OS X 上的 GLFW 不兼容。因此,我不得不使用 stb
binding, which is LWJGL 3.0's STBImage
、org.lwjgl.stb.STBImage
。
这是我使用的代码
public int loadTexture(String filename){
ByteBuffer imageBuffer;
try{
imageBuffer = readFile(filename);
}
catch (IOException e) {
throw new RuntimeException(e);
}
IntBuffer w = BufferUtils.createIntBuffer(1);
IntBuffer h = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer image = STBImage.stbi_load_from_memory(imageBuffer, w, h, comp, 0);
if(image == null){
throw new RuntimeException("Failed to load image: " + STBImage.stbi_failure_reason());
}
this.width = w.get(0);
this.height = h.get(0);
this.comp = comp.get(0);
if(this.comp == 3){
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, this.width, this.height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, image);
}
else{
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, this.width, this.height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, image);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
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.glEnable(GL11.GL_TEXTURE_2D);
return GL11.glGenTextures();
}
private ByteBuffer readFile(String resource) throws IOException{
File file = new File(resource);
FileInputStream fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
ByteBuffer buffer = BufferUtils.createByteBuffer((int) fc.size() + 1);
while(fc.read(buffer) != -1);
fis.close();
fc.close();
buffer.flip();
return buffer;
}
它按预期工作
在 Mac OS X El Capitan,OpenGL 4.1 版中,我的 LWJGL 3.0 应用程序在调用 Slick2D 函数时挂起 TextureLoader.getTexture()
这是我试图用来加载纹理的代码。它与主循环在同一线程上 运行,并在 window 设置后调用。
FileInputStream file = new FileInputStream("src/AppIcon.png");
texture = TextureLoader.getTexture("PNG", file);
文件确实存在,我把贴图的代码注释掉后代码运行正常,就是这个方法
public int loadTexture(String filename){
Texture texture = null;
try{
FileInputStream file = new FileInputStream(filename + ".png");
//The app freezes here
texture = TextureLoader.getTexture("png", file);
//"LOADED" is never printed to the console.
System.out.println("LOADED");
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
return texture.getTextureID();
}
我尝试使用的纹理是 1024 x 1024 PNG 图像,
我也尝试过使用更小的 16 x 16 像素图像,
但我得到了相同的结果。
两个图像在物理上都没有问题,没有记录错误,控制台中最后打印的内容来自 Slick2D,说明
INFO:Use Java PNG Loader = true
这是 OS 特定的错误,还是我做错了什么?
我认为代码只有图像的路径,但尽管您在其后放置了文件类型 (.png),但它不知道文件类型,请尝试:
FileInputStream file = new FileInputStream(filename + ".png", PNG);
如果这不起作用,那可能是我弄乱了“”,所以如果您再次遇到错误,请试试这个(但它可能不会起作用)
FileInputStream file = new FileInputStream(filename + ".png", "PNG");
事实证明,Slick2D
与 OS X 上的 GLFW 不兼容。因此,我不得不使用 stb
binding, which is LWJGL 3.0's STBImage
、org.lwjgl.stb.STBImage
。
这是我使用的代码
public int loadTexture(String filename){
ByteBuffer imageBuffer;
try{
imageBuffer = readFile(filename);
}
catch (IOException e) {
throw new RuntimeException(e);
}
IntBuffer w = BufferUtils.createIntBuffer(1);
IntBuffer h = BufferUtils.createIntBuffer(1);
IntBuffer comp = BufferUtils.createIntBuffer(1);
ByteBuffer image = STBImage.stbi_load_from_memory(imageBuffer, w, h, comp, 0);
if(image == null){
throw new RuntimeException("Failed to load image: " + STBImage.stbi_failure_reason());
}
this.width = w.get(0);
this.height = h.get(0);
this.comp = comp.get(0);
if(this.comp == 3){
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, this.width, this.height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, image);
}
else{
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, this.width, this.height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, image);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
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.glEnable(GL11.GL_TEXTURE_2D);
return GL11.glGenTextures();
}
private ByteBuffer readFile(String resource) throws IOException{
File file = new File(resource);
FileInputStream fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
ByteBuffer buffer = BufferUtils.createByteBuffer((int) fc.size() + 1);
while(fc.read(buffer) != -1);
fis.close();
fc.close();
buffer.flip();
return buffer;
}
它按预期工作