I thought this would be a good place to post this question.

LWJGL doesn’t have a built in texture loader so what is the best thing to use to load textures.

I tried the slick-util but it gave me an error. If it is possible to load images without any added libraries that would be awesome.

this is the error that the slick util gave me:

WARN:class org.newdawn.slick.opengl.PNGImageData failed to read the data
java.lang.UnsupportedOperationException: Unsupported format for this image

Thanks in advance!!

Ned

EDIT:

I sorted that problem however if somebody could tell me how to use a part of an image so i can make a sprite sheet, that would be awesome

Thanks in advance !!

Tags: ,


12 Responses to “What should i use to load images in lwjgl?”

  1. GMan1337 says:

    Im not much experiensed wiht Java Light wight game librari :( sorry man. all i haerd is that its a game set of jars for easy game development :d here ill give you a link to some videos to help you out :) best of luck!

    first link by Oaskar:
    http://www.youtube.com/watch?v=naE3nbreSUo

    second link by TheBennybox:
    http://www.youtube.com/watch?v=9l1nBRrtzjA

    Hope you get some help!

  2. FyberOptic says:

    I’ve used slick-util quite a bit with LWJGL and never had that particular problem. Perhaps it’s not able to interpret something added by the program you’re making the PNGs in. Try opening and saving them again in another program, just to help rule that out.

    PNG files are not overly complicated, they’re basically broken into chunks of various types, so creating something to parse them yourself is not very complicated. But you would have to have code to decompress the image data, which I believe uses the “deflate” algorithm used in ZIP files.

    I honestly think you’re better off figuring out why slick-util is failing before going to all that trouble.

  3. Nnnnneeeedddd says:

    Ok thanks guys. I worked out that the image had to be a power of two. Also if somebody could tell me how to use only a part of an image with slick-util so i could make a sprite sheet that would be amazing.

    Ned

  4. FyberOptic says:

    Ah okay cool, glad you got it sorted.

    There’s a couple of different ways you could do it. First would be to break the image up in code and create separate textures that way. It wouldn’t be too bad if you plan to split it up into evenly-sized pieces. But keep in mind that switching textures during rendering can end up being costly if you do it a whole lot, so this might not be the best route depending on what you’re doing.

    The other way is to use UV coordinates for each vertex when drawing your geometry, to specify where in the image to draw from. You just need to do a little bit of math, since a UV coordinate goes from 0.0 to 1.0, regardless of your texture size.

  5. This may help, I’ve written a simple method to convert ARGB BufferedImages to flipped RGBA ByteBuffers that can be used with openGL: http://pastebin.com/acUfTMmG . The BufferedImage class has a great method called getSubImage that will help you with extracting from sprite sheets.
    Javadoc here: http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html

  6. djdduty says:

    I use http://codepad.org/BfkRvloU for png loading, don’t really have any small references on usage, but it should be simple to figure out. As far as using only a portion of an image, this is done using texture coordinates. Tex coords and unit length though, meaning that 1.0, 1.0 all the way bottom right, basically think of this as percentage where 1.0 is 100%, 0.5 as 50% etc. if you image is 64×64, then 0.5, 0.5 is 32,32. So if you have a sprite sheet that is 1 row tall, and like 5 columns, the first image is 0.0,1.0 on the upper left to 0.2, 1.0 on the bottom right(as needed to form a rectangle), each image after that is just an additional 0.2 to the X component of both of those.

  7. jedilemons says:

    I always just load it through a BufferedImage and put the pixel information into a ByteBuffer by doing

    int[] pixels = img.getRGB(0, 0, w, h, null, 0, w);

    and then doing a loop to put the RGBA into the ByteBuffer in the correct order. Then I create the opengl texture like normal and put the bytebuffer into it for the last argument to glTexImage2D.

    e.g. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytes);

    For sprite sheets I bind the entire sheet texture and then use magic (math) in the uv coords to bind the area you want:

    float u0 = xSpriteIndex / (float) spriteWidth;
    float u1 = u0 + (float) (1 / spriteWidth);
    float v0 = ySpriteIndex / (float) spriteHeight;
    float v1 = v0 + (float) (1 / spriteHeight);

    Use those for the texCoords. The reason it’s 1/x is because 1.0f would be the entire sheet in lwjgl, so you do 1 divided by the size of the sprite to get the smaller area.

    I hope I’ve explained this correctly haha. But I find doing this instead of using another library is better for me.

    • jedilemons says:

      Also if you’re unsure about creating the texture and using it correctly there’s tons of stuff online for lwjgl and straight OpenGL.

  8. marccspro says:

    Here is my way of loading textures in lwjgl:

    public void render() {
    Texture.blocks.bind();
    // Render your stuff in here
    Texture.blocks.unbind();
    }

    //——- TEXTURE CODE STARTS HERE ———–
    public class Texture {

    public static int LINEAR_FILTER = GL_LINEAR;
    public static int NEAREST_FILTER = GL_NEAREST;

    public static Texture blanc = new Texture();

    /*
    *
    * ——— Create a new static Texture here ———-
    *
    */
    public static Texture blocks = new Texture(“res/blocks.png”, Texture.NEAREST_FILTER);

    int width, height;
    int id;

    public Texture() {
    int w = width = 1;
    int h = height = 1;

    int[] pixels = new int[w * h];
    Arrays.fill(pixels, 0xffffff);

    ByteBuffer buffer = BufferUtils.createByteBuffer(w * h * 4);

    for (int y = 0; y < h; y++) {
    for (int x = 0; x > 16) & 0xFF));
    buffer.put((byte) ((pixel >> 8) & 0xFF));
    buffer.put((byte) ((pixel) & 0xFF));
    buffer.put((byte) ((pixel >> 24) & 0xFF));
    }
    }

    buffer.flip();

    id = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, id);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    }

    public Texture(String path, int filter) {
    BufferedImage image = null;
    try {
    image = ImageIO.read(new File(path));
    } catch (IOException e) {
    e.printStackTrace();
    }

    int w = width = image.getWidth();
    int h = height = image.getHeight();

    int[] pixels = new int[w * h];
    image.getRGB(0, 0, w, h, pixels, 0, w);

    ByteBuffer buffer = BufferUtils.createByteBuffer(w * h * 4);

    for (int y = 0; y < h; y++) {
    for (int x = 0; x > 16) & 0xFF));
    buffer.put((byte) ((pixel >> 8) & 0xFF));
    buffer.put((byte) ((pixel) & 0xFF));
    buffer.put((byte) ((pixel >> 24) & 0xFF));
    }
    }

    buffer.flip();

    id = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, id);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    }

    public Texture(String path, int xo, int yo, int size, int filter) {
    BufferedImage image = null;
    try {
    image = ImageIO.read(new File(path));
    } catch (IOException e) {
    e.printStackTrace();
    }

    int xx = xo * size;
    int yy = yo * size;
    int w = width = size;
    int h = height = size;

    int[] pixels = new int[w * h];
    image.getRGB(xx, yy, w, h, pixels, 0, w);

    ByteBuffer buffer = BufferUtils.createByteBuffer(w * h * 4);

    for (int y = 0; y < h; y++) {
    for (int x = 0; x > 16) & 0xFF));
    buffer.put((byte) ((pixel >> 8) & 0xFF));
    buffer.put((byte) ((pixel) & 0xFF));
    buffer.put((byte) ((pixel >> 24) & 0xFF));
    }
    }

    buffer.flip();

    id = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, id);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    }

    public int getWidth() {
    return width;
    }

    public int getHeight() {
    return height;
    }

    public void bind() {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, id);
    }

    public void unbind() {
    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);
    glColor4f(1, 1, 1, 1);
    }
    }

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]