LWJGL Textures

By the end of this tutorial you will have learned how to load and display textures.

A quick note

For this tutorial the classes provided by the “slick_util” jar-file will be used.

Loading the LWJGL textures

Firstly, an instance of Texture is created. It is not possible to invoke the constructor of the Texture class, so to initialize the instance, write the following code.

TextureLoader.getTexture(String, InputStream);

This method may throw two exceptions, both of which need to be caught and dealt with.

Texture texture;
try {
	texture = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/image.png")));
        // Replace PNG with your file extension
} catch (FileNotFoundException e) {
	e.printStackTrace();
	Display.destroy();
	System.exit(1);
} catch (IOException e) {
	e.printStackTrace();
	Display.destroy();
	System.exit(1);
}

Drawing the textures

In the upper-left you can see the texture data. Note: “0,1” should be “0,0”. In the bottom-right you can see the shape that uses the texture data.

OpenGL knows where to find its texture data through texture coordinates. Texture coordinates are coordinates ranging from 0.0 to 1.0 ( (0,0) being upper-left; (1,1) being bottom-left ). They represent a point on the texture. Specify a texture coordinate using the following code.

glTexCoord2f(float, float);

In order for OpenGL to know which texture it wants to extract the data from, the texture needs to be bound. Just like with colours, it uses a global state; only one texture can be bound at a time. The binding of textures works with the following method.

glBindTexture(GL_TEXTURE_2D, texture_id);

You can retrieve your texture id from the texture object by calling.

texture.getTextureID();

Similarly, you can unbind a texture from OpenGL when you no longer need to draw with it.

glBindTexture(GL_TEXTURE_2D, 0);

This is how one would draw a textured rectangle on-screen.

glBegin(GL_TRIANGLES);
 
glTexCoord2f(1, 0);
glVertex2i(450, 10);
glTexCoord2f(0, 0);
glVertex2i(10, 10);
glTexCoord2f(0, 1);
glVertex2i(10, 450);
 
glTexCoord2f(0, 1);
glVertex2i(10, 450);
glTexCoord2f(1, 1);
glVertex2i(450, 450);
glTexCoord2f(1, 0);
glVertex2i(450, 10);
 
glEnd();

Releasing the LWJGL textures

Lastly, the texture needs to be destroyed when it’s no longer needed.

texture.release();

Conclusion

That concludes this tutorial. Should you have any questions or remarks I would love to see them in the comments section below.

38 thoughts on “LWJGL Textures

  1. Anonymous

    I don’t know why but instead of showing the texture it shows a white square.
    here’s my source code:

    import org.lwjgl.LWJGLException;
    import org.lwjgl.opengl.Display;
    import org.lwjgl.opengl.DisplayMode;
    import org.newdawn.slick.opengl.Texture;
    import org.newdawn.slick.opengl.TextureLoader;

    import static org.lwjgl.opengl.GL11.*;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;

    public class opengl {

    public static Texture texture;

    public static void main(String[] args) {
    try {
    Display.setDisplayMode(new DisplayMode(900, 600));
    Display.setTitle(“OpenGL”);
    Display.create();

    try {
    texture = TextureLoader.getTexture(“PNG”, new FileInputStream(new File(“res/textures/test.png”)));
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    Display.destroy();
    System.exit(1);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    Display.destroy();
    System.exit(1);
    }

    while (!Display.isCloseRequested()) {
    Display.update();
    Display.sync(60);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); // resets any previous projection matrices
    glOrtho(0, 640, 480, 0, 1, -1);
    glMatrixMode(GL_MODELVIEW);

    glBegin(GL_TRIANGLES);
    glTexCoord2f(0, 64);
    glBindTexture(GL_TEXTURE_2D, 0);
    glEnable(GL_TEXTURE_2D);
    texture.getTextureID();

    glTexCoord2f(1, 0);
    glVertex2i(450, 10);
    glTexCoord2f(0, 0);
    glVertex2i(10, 10);
    glTexCoord2f(0, 1);
    glVertex2i(10, 450);

    glTexCoord2f(0, 1);
    glVertex2i(10, 450);
    glTexCoord2f(1, 1);
    glVertex2i(450, 450);
    glTexCoord2f(1, 0);
    glVertex2i(450, 10);

    glEnd();

    }
    texture.release();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    Display.destroy();
    System.out.println(“The game has been destroyed”);
    System.exit(0);

    } catch (LWJGLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    Display.destroy();
    System.exit(1);
    }
    }
    }

    Reply
  2. Elian

    You forgot to mention in that you need to add glEnable(GL_TEXTURE_2D); I am following the text tutorials and not the videos so this is a crucial fact for me

    Reply
  3. Steve

    Is there a quick and easy way to create a Texture object from an existing ByteBuffer? Specifically, I want to capture a screenshot and draw it from a texture during a screen transition.

    Reply
  4. Vogon

    I have a png texture loading but the transparent areas show as black please help!!


    try {
    texture = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/door.png")));
    // Replace PNG with your file extension
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    System.exit(1);
    }

    if (texture != null) {

    glBegin(GL_QUADS);
    texture.bind();
    {

    glTexCoord2f(1,1);
    glVertex2d(50, 16);
    glTexCoord2f(0,1);
    glVertex2d(50+32, 16);
    glTexCoord2f(0,0);
    glVertex2d(50+32, 16+32);
    glTexCoord2f(1,0);
    glVertex2d(50, 16+32);
    }
    texture.release();
    glEnd();

    }
    else {
    System.out.println("FATAL EXCEPTION: TEXTURE FAILED TO LOAD");
    System.exit(0);
    }
    glDisable(GL_TEXTURE_2D);

    Reply
  5. Anonymous

    I keep trying to do it but it won’t work. I get the error:

    Exception in thread "main" java.lang.UnsatisfiedLinkError: no lwjgl in java.library.path
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at org.lwjgl.Sys$1.run(Sys.java:73)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.lwjgl.Sys.doLoadLibrary(Sys.java:66)
    at org.lwjgl.Sys.loadLibrary(Sys.java:95)
    at org.lwjgl.Sys.(Sys.java:112)
    at org.lwjgl.opengl.Display.(Display.java:135)
    at org.lwjgldemo.Main.main(Main.java:16)

    Reply
  6. NoName

    Sat Nov 02 19:54:20 GMT 2013 WARN:class org.newdawn.slick.opengl.PNGImageData failed to read the data
    java.io.IOException: unsupported interlace method
    at org.newdawn.slick.opengl.PNGDecoder.readIHDR(PNGDecoder.java:606)
    at org.newdawn.slick.opengl.PNGDecoder.(PNGDecoder.java:116)
    at org.newdawn.slick.opengl.PNGImageData.loadImage(PNGImageData.java:81)
    at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:62)
    at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.java:43)
    at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:292)
    at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:254)
    at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:200)
    at org.newdawn.slick.opengl.TextureLoader.getTexture(TextureLoader.java:64)
    at org.newdawn.slick.opengl.TextureLoader.getTexture(TextureLoader.java:24)
    at otherClasses.TextTest.main(TextTest.java:32)

    or for some textures it just wont work (Diagonal lines randomly instead of a texture)

    Reply
  7. Dean

    Hi Oskar, I was wondering if this code is effective in a 3d environment,
    As in your lwjgl videos, you explain this for a 2D environment, but what if now I have a cube, how can I add textures to that?
    I tried doing this way but the textures just don’t show, I have modified your code from https://github.com/OskarVeerhoek/YouTube-tutorials/tree/master/src/episode_19

    I really wish you can answer me how to map textures to my own cubes, the cubes arejust quads.
    Thank you!!!

    Reply
  8. Leah

    hi
    first i wanna thank you so much because your lessons are my resource for my final project at university:)
    I have an odd problem. I put my texture pic in the folder src at the project workspace
    I did whatever you did in your video at youtube
    BUT when I run my code, the empty window appears for one second and it closed by itself!
    why? do you want me to send you my code?
    please answer quickly:) thanks:)

    Reply
    1. Oskar Veerhoek Post author

      Does the program throw an exception? Try putting System.out.println(texture.getID()); after the texture has been loaded. If the program prints out 0, then the texture was never properly loaded. If the program prints out a number > 0, then something else is wrong.

      Reply
      1. Anonymous

        it resolved. thank you:)
        I can’t reach youtube anymore because it has been filtered in my country and no anti filters can open it:(
        have you upload your videos on another data base? or can I download them anywhere?…

        Reply
  9. Philippe Desjardins

    HI, good job btw, i love the tutorials.

    I have a problem now, the slik-util.jar link is broken.

    Reply
  10. Kyle L

    Hi, and thanks for the great tutorials 😀 ! I’m having a slight problem with my code I was hoping you’d know what I did wrong. I did a slight variation of your program with three boxes that are just colored , and of course the textured box. Here’s my problem. The texture loads fine and displays on the box, but there is also a color overlay from one of the boxes that were rendered before. Here’s part of the code that i’m using:


    //render() method from Rect2D
    public void render()
    {
    GL11.glBegin(GL11.GL_QUADS);
    if(texture != null)
    {
    texture.bind();
    GL11.glTexCoord2f(0, 0);
    GL11.glVertex2f(x, y);
    GL11.glTexCoord2f(1, 0);
    GL11.glVertex2f(x + width, y);
    GL11.glTexCoord2f(1, 1);
    GL11.glVertex2f(x + width, y + height);
    GL11.glTexCoord2f(0, 1);
    GL11.glVertex2f(x, y + height);
    texture.release();
    }
    else if(color != null)
    {
    GL11.glColor3f(color.getRed(), color.getGreen(), color.getBlue());
    GL11.glVertex2f(x, y);
    GL11.glVertex2f(x + width, y);
    GL11.glVertex2f(x + width, y + height);
    GL11.glVertex2f(x, y + height);
    }
    GL11.glEnd();
    }


    //play() Method in Game Class
    public void play()
    {
    int x;
    int y;

    while(!Display.isCloseRequested() && isPlaying)
    {
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    Display.processMessages();
    Mouse.poll();
    x = Mouse.getX();
    y = Mouse.getY();

    for(gameObject obj : map1.map)
    {

    if(Mouse.isButtonDown(0) && obj.getModel().inBounds(x, y) && !isSelected)
    {
    isSelected = true;
    obj.getModel().isSelected = true;
    }
    else if(!Mouse.isButtonDown(0))
    {
    isSelected = false;
    obj.getModel().isSelected = false;
    }
    if(obj.getModel().isSelected)
    {
    obj.getModel().update(x - obj.getModel().width/2, y - obj.getModel().height/2);
    }
    obj.getModel().render();
    }
    Display.update();
    Display.sync(60);
    }
    }


    //Map1 class
    public class Map1 extends Map
    {
    public Map1()
    {
    //map is located in the abstract class Map
    map.add(new Rect2D(400,100,100,100,Color.green));
    map.add(new Rect2D(100,100,100,100,Color.red));
    map.add(new Rect2D(400,400,100,100,Color.blue));
    map.add(new Rect2D(100,400,100,100,"res/wood.png"));
    }
    }

    Reply
  11. Reid Yoder

    Oskar, your lesson was very helpful, but I have a question. My texture is only mapping to a portion of a quad. I used .getWidth() and .getHeight() on the texture out of curiosity, and the width is 0.66015625 and the height is 0.9453125. I don’t want those numbers. I want 1 and 1. In the glTexCoord2f’s, it even says (0,0), (0,1), (1,1), and (1,0). How can I get the width and height to 1 like they are supposed to be instead of these crazy floats?

    Reply
  12. John

    I’ve made textures work before but now for some reason it will only display 1 pixel of the texture (looks like the top-left) :(. I have no idea what’s wrong.

    Reply
  13. uday

    I don’t know why but the texture is displayed, but fragmented. I am out of words to describe what is happening- anybody else experience the same thing?

    Reply
  14. Matsuo

    Eh… Somehow i can’t display the texture, i put it right in the res folder and the Eclipse IDE says the texture was loaded, but it won’t show to me. Any idea?

    Reply

Leave a Reply to Elian Cancel reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>