问题
I am trying to make a simple game in Java.
I want to know how I can read a PNG file and use it in the game using only the OpenGL library.
Can anyone provide any code that could accomplish this?
回答1:
You can't load a texture directly using a single API call. You can however load a BufferedImage through ImageIO, and then convert it to an OpenGL texture. Example source code can be found here TextureLoader
回答2:
You can't load images only using OpenGL.
You should always keep in mind that OpenGL is a graphics API, nothing more: Not a game framework, not something that would do IO operations for you, etc.
You provide the data and OpenGL does the heavy lifting.
To answer your question: I personally use TWL's PNGDecoder for my projects. It's fast, simple and easy to use. The official LWJGL wiki has an article about it, check it out.
Here's a quick example on how to use it:
try(BufferedInputStream is = new BufferedInputStream(new FileInputStream(filePath))){
//Create the PNGDecoder object and decode the texture to a buffer
PNGDecoder decoder = new PNGDecoder(is);
int width = decoder.getWidth(), height = decoder.getHeight();
ByteBuffer pixelData = BufferUtils.createByteBuffer(4*width*height);
decoder.decode(pixelData, 4*width, Format.RGBA);
pixelData.flip();
//Generate and bind the texture
int id = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
//Upload the buffer's content to the VRAM
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixelData);
//Apply filters
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
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);
}catch(IOException e){
e.printStackTrace();
}
Later on when you want to use the texture just do GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
before you're rendering. I highly suggest to use some kind of data structure to store your textures for reusing them (you should only upload a texture once to the VRAM and use it multiple times later when you need it using it's ID). Personally I use my own Texture
class and a TextureBank
class with a static HashMap<String, Texture>
where the key is the name of the texture and the value is the appropiate Texture
object, to store the textures.
回答3:
If you only want to use openGL with some Java code and no extra library, this is actually possible.
You can find the documentation of the whole png format here: PNG Specifiaction
If you omit CRC and use the Inflater of Java, you only have to decode the chunks of the file and apply the filters of the image in reverse order.
But writing loaders by yourself often is a tricky thing. I actually wrote a png-loader but it does only support rgb and rgba images. You can find the code of my loader here: file
来源:https://stackoverflow.com/questions/21399242/load-a-png-file-with-pure-opengl