2017-02-19 216 views
1

我正在使用lwjgl處理OpenGL中的項目。我很難爲窗口加載一個圖標,因爲它需要一個GLFWImage緩衝區。後在網上淘的很長一段時間,這是我有:GLFW窗口圖標

try { 
      BufferedImage originalImage = 
        ImageIO.read(new File("favicon.png")); 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      ImageIO.write(originalImage, "png", baos); 
      baos.flush(); 
      byte[] imageInByte = baos.toByteArray(); 
      ByteBuffer buF = ByteBuffer.wrap(imageInByte); 
      GLFWImage.Buffer b = new GLFWImage.Buffer(buF); 
      glfwSetWindowIcon(window, b); 
     } catch (IOException io){ 
      System.out.println("Could not load window icon!"); 
      System.out.println(io.toString()); 
     } 

Java運行時崩潰,像這樣的輸出:

# A fatal error has been detected by the Java Runtime Environment: 
# The crash happened outside the Java Virtual Machine in native code. 
# See problematic frame for where to report the bug. 

我一直沒能找到一種方法來做這不會給這種錯誤。官方的glfw文檔說要使用LWJGL中似乎不存在的方法。如果您有任何這方面的經驗,那麼將我指向正確的方向甚至會有所幫助。

在此先感謝。

+0

我有這個相同的問題;但是,我發現了一些有趣的事情:如果在b = new Buffer行之前添加buF.flip(),它將防止崩潰,但無法更改圖標。此外,我只能使用緩衝區而不是GLFWImage.Buffer,但這可能與IDE相關。 –

回答

0

這種解決方案很笨拙;然而,它適用於我! :) 它基於lwjgl events演示中的代碼,但要使用我必須實施演示IOUtil。用於設置圖標的代碼是這樣的:

ByteBuffer icon16; 
ByteBuffer icon32; 
try { 
    icon16 = IOUtil.ioResourceToByteBuffer("src/hexsweeper/hex16.png", 2048); 
    icon32 = IOUtil.ioResourceToByteBuffer("src/hexsweeper/hex32.png", 4096); 
} catch (Exception e) { 
    throw new RuntimeException(e); 
} 


IntBuffer w = memAllocInt(1); 
IntBuffer h = memAllocInt(1); 
IntBuffer comp = memAllocInt(1); 

try (GLFWImage.Buffer icons = GLFWImage.malloc(2)) { 
    ByteBuffer pixels16 = stbi_load_from_memory(icon16, w, h, comp, 4); 
    icons 
     .position(0) 
     .width(w.get(0)) 
     .height(h.get(0)) 
     .pixels(pixels16); 

    ByteBuffer pixels32 = stbi_load_from_memory(icon32, w, h, comp, 4); 
    icons 
     .position(1) 
     .width(w.get(0)) 
     .height(h.get(0)) 
     .pixels(pixels32); 

    icons.position(0); 
    glfwSetWindowIcon(window, icons); 

    stbi_image_free(pixels32); 
    stbi_image_free(pixels16); 
} 

進口如下:

import java.nio.ByteBuffer; 
import java.nio.IntBuffer; 

import org.lwjgl.glfw.GLFWImage; 

import static org.lwjgl.stb.STBImage.*; 
import static org.lwjgl.system.MemoryUtil.*; 

而在另一個文件(名爲IOUtil)我把下面的代碼:

import org.lwjgl.BufferUtils; 

import java.io.IOException; 
import java.io.InputStream; 
import java.nio.ByteBuffer; 
import java.nio.channels.Channels; 
import java.nio.channels.ReadableByteChannel; 
import java.nio.channels.SeekableByteChannel; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 

import static org.lwjgl.BufferUtils.*; 

public final class IOUtil { 

private IOUtil() { 
} 

private static ByteBuffer resizeBuffer(ByteBuffer buffer, int newCapacity) { 
    ByteBuffer newBuffer = BufferUtils.createByteBuffer(newCapacity); 
    buffer.flip(); 
    newBuffer.put(buffer); 
    return newBuffer; 
} 

/** 
* Reads the specified resource and returns the raw data as a ByteBuffer. 
* 
* @param resource the resource to read 
* @param bufferSize the initial buffer size 
* 
* @return the resource data 
* 
* @throws IOException if an IO error occurs 
*/ 
public static ByteBuffer ioResourceToByteBuffer(String resource, int bufferSize) throws IOException { 
    ByteBuffer buffer; 

    Path path = Paths.get(resource); 
    if (Files.isReadable(path)) { 
     try (SeekableByteChannel fc = Files.newByteChannel(path)) { 
      buffer = BufferUtils.createByteBuffer((int)fc.size() + 1); 
      while (fc.read(buffer) != -1) ; 
     } 
    } else { 
     try (
      InputStream source = IOUtil.class.getClassLoader().getResourceAsStream(resource); 
      ReadableByteChannel rbc = Channels.newChannel(source) 
     ) { 
      buffer = createByteBuffer(bufferSize); 

      while (true) { 
       int bytes = rbc.read(buffer); 
       if (bytes == -1) 
        break; 
       if (buffer.remaining() == 0) 
        buffer = resizeBuffer(buffer, buffer.capacity() * 2); 
      } 
     } 
    } 

    buffer.flip(); 
    return buffer; 
} 

} 

用你的窗口代替"src/hexsweeper/hex16.png",然而你得到你的文件,window,你應該設置。這對我有用,希望它適用於其他人!

注:我沒有寫這段代碼的大部分內容。它是由奇妙有益的lwjgl貢獻者apostolos,Spasi和kappaOne製作的。