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.
Hi Oskar,
thanks for the tutorials and videos. They are really helpful, but I have a question.
How can we use the texture as a background and not by mapping it to specific points, but to make it repeatable until it fills the whole window?
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);
}
}
}
Texture coordinates need to be between 0 and 1.
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 meHow different is rendering textures when not using immediate mode?
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.
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);
Hi, try enabling alpha functionality:
glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
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)
I fixed it
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)
Have you tried the code from episode 5 on my source code repository? https://github.com/OskarVeerhoek/YouTube-tutorials/tree/master/src/
hrd to follow plz ad source at end. thx
where is wood.png?
Right here: https://github.com/OskarVeerhoek/YouTube-tutorials/raw/master/res/images/wood.png
Hi. Can you please upload the textures from the video??
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!!!
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:)
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.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?…
You are welcome. Sorry, I do not have my videos on another online database. In which country do you live? I do not wish to violate its law.
HI, good job btw, i love the tutorials.
I have a problem now, the slik-util.jar link is broken.
I mended the link. It works now.
I like how to say you ‘deal’ with exceptions.
“They need to be caught and dealt with.”
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"));
}
}
So you can see what I mean http://img268.imageshack.us/img268/1728/problemts.png .
haha, fixed it. needed to do 0.9f for the texture coodinates
my image is sort of cut up. like, there is the texture, then a line under it, and a line beside it.
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?
Essays like this are so important to brnoneaidg people’s horizons.
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.
That sounds an awful lot like bad texture coordinates. Try and print them to the console and see what you come up with.
Haha, I had NO texture coordinates. That’s what probably did it!
In your figure, you have the top-left coordinate of the square wrong. It should be (0, 0).
Thanks for pointing out.
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?
Please send your source code and image file to support@thecodinguniverse.com
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?
you have to use glEnable(GL_TEXTURE_2D);