java LWJGL 纹理和字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10801016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LWJGL Textures and Strings
提问by Michael Malura
Is it possible to load PNG Textures and draw Strings in LWJGL
WITHOUT using the Slick Framework?
是否可以在LWJGL
不使用 Slick 框架的情况下加载 PNG 纹理并绘制字符串?
Everytime I google "how to load png images in lwjgl"I get answers like this -> "hey just use the textureloader from the slick framework".
Same for "how to draw strings in lwjgl"-> "just use the TTFFont Class from the slick framework"
每次我用谷歌搜索“如何在 lwjgl 中加载 png 图像”时,我都会得到这样的答案-> “嘿,只需使用光滑框架中的纹理加载器”。
与“如何在 lwjgl 中绘制字符串”相同-> “只需使用光滑框架中的 TTFFont 类”
But I don't want to use this half-way-crossframework design. Because I don't think that this is the best way.
但是我不想用这种半途而废的跨框架设计。因为我不认为这是最好的方法。
Are there any Libraries or Extensions for LWJGL
that are only made for Textures or Strings?
是否有任何LWJGL
仅用于纹理或字符串的库或扩展?
回答by Flafla2
Basically, you take a BufferedImage
, use getRGB()to get the RGB of each pixel, take that data and put it into a ByteBuffer(the data type used to input image data to OpenGL), set some texture data, and create the GL_TEXTURE_2D
.
基本上,您获取一个BufferedImage
,使用getRGB()获取每个像素的 RGB,获取该数据并将其放入ByteBuffer(用于将图像数据输入到 OpenGL 的数据类型),设置一些纹理数据,然后创建GL_TEXTURE_2D
.
This code by Krythicdoes it:
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL12;
import static org.lwjgl.opengl.GL11.*;
public class TextureLoader {
private static final int BYTES_PER_PIXEL = 4;//3 for RGB, 4 for RGBA
public static int loadTexture(BufferedImage image){
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4 for RGBA, 3 for RGB
for(int y = 0; y < image.getHeight(); y++){
for(int x = 0; x < image.getWidth(); x++){
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
buffer.put((byte) (pixel & 0xFF)); // Blue component
buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA
}
}
buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS
// You now have a ByteBuffer filled with the color data of each pixel.
// Now just create a texture ID and bind it. Then you can load it using
// whatever OpenGL method you want, for example:
int textureID = glGenTextures(); //Generate texture ID
glBindTexture(GL_TEXTURE_2D, textureID); //Bind texture ID
//Setup wrap mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
//Setup texture scaling filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Send texel data to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
//Return the texture ID so we can bind it later again
return textureID;
}
public static BufferedImage loadImage(String loc)
{
try {
return ImageIO.read(MainClass.class.getResource(loc));
} catch (IOException e) {
//Error Handling Here
}
return null;
}
}
To use this code, do something like this:
要使用此代码,请执行以下操作:
BufferedImage image = TextureLoader.loadImage("/res/test.png");//The path is inside the jar file
int textureID = TextureLoader.loadTexture(image);
You can either save the textureID as a final
variable(if the texture never changes), or unload the texture after each render using GL11.glDeleteTextures(textureID);
您可以将 textureID 保存为final
变量(如果纹理永远不会改变),或者在每次渲染后使用GL11.glDeleteTextures(textureID);
To do text, just create a BufferedImage
manually, and use createGraphics()to get a graphics2D()instance for the image. Then, use drawString()
to draw onto the BufferedImage
, load it into the TextureLoader
, render it onscreen, and unload the texture using the method above.
要处理文本,只需BufferedImage
手动创建一个,然后使用createGraphics()获取图像的 graphics2D()实例。然后,使用drawString()
绘制到 上,将其BufferedImage
加载到 中TextureLoader
,将其渲染到屏幕上,然后使用上述方法卸载纹理。
回答by aTom
LWJGL now includes STB bindings, which is the preferred way of loading images and fonts, without having to use Slick or even AWT.
LWJGL 现在包括 STB 绑定,这是加载图像和字体的首选方式,无需使用 Slick 甚至 AWT。
To load a PNG :
加载 PNG 文件:
import static org.lwjgl.opengl.GL11.GL_REPEAT;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_RGBA;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
import static org.lwjgl.opengl.GL11.GL_UNPACK_ALIGNMENT;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glGenTextures;
import static org.lwjgl.opengl.GL11.glPixelStorei;
import static org.lwjgl.opengl.GL11.glTexImage2D;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL30.glGenerateMipmap;
import static org.lwjgl.stb.STBImage.stbi_load_from_memory;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.demo.util.IOUtils.ioResourceToByteBuffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.system.MemoryStack;
public class Texture{
private int width;
private int height;
private int id;
public Texture(String imagePath) {
ByteBuffer imageData = ioResourceToByteBuffer(imagePath, 1024);
try (MemoryStack stack = stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer components = stack.mallocInt(1);
// Decode texture image into a byte buffer
ByteBuffer decodedImage = stbi_load_from_memory(imageData, w, h, components, 4);
this.width = w.get();
this.height = h.get();
// Create a new OpenGL texture
this.id = glGenTextures();
// Bind the texture
glBindTexture(GL_TEXTURE_2D, this.id);
// Tell OpenGL how to unpack the RGBA bytes. Each component is 1 byte size
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Upload the texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, decodedImage);
// Generate Mip Map
glGenerateMipmap(GL_TEXTURE_2D);
}
}
}
More complete examples for image loading, and text printing can be found in LWJGL source code :
更完整的图片加载和文本打印示例可以在 LWJGL 源代码中找到: