LWJGL Spritesheets not working...

I’ve been messing with LWJGL For a few weeks, And I’ve decided to make my first game, Which just so happens to be tilebased. I’ve gotten a decent amount of the work done, However Loading the tiles has been a bit of a challenge. I’ve made my own spritesheet class, that loads the correct amount of sprites based on the size of the sprites. I’m just stuck on the “Displaying” the sprite part. Please don’t link me to the Slick utils or anything; I want to see what can be done with LWJGL by itself.

Heres my Spritesheet class:


import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.nio.ByteBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

import test.Test;

public class Spritesheet
{

	protected BufferedImage spritesheetImages;
	
	protected int spriteSize;
	protected int texturesIndex;
	protected int textureID;
	
	public int[] textures;
	
	public Spritesheet(InputStream input, int size)
	{
		this.spritesheetImages = getImageFromStream(input);
		if (spritesheetImages.getWidth() % 2 == 0 & spritesheetImages.getHeight() % 2 == 0){
			System.out.println("Loaded a spritesheet that is a multiple of two. Continuing.");
			this.spriteSize = size;
			this.texturesIndex = ((spritesheetImages.getWidth() / spriteSize) * (spritesheetImages.getHeight() / spriteSize));//Returns the amount of possible images in the sheet.
			this.textureID = convertBufferedImageToID(spritesheetImages); //Gets ID of the spritesheet as a whole.
			this.textures = new int[texturesIndex]; //Creates an int index the size of the possible sprites in the image.
			this.loadAllPossibleImages();
		}else{
			System.err.println("Tried to load a spritesheet that is not a multiple of two!");
		}
	}
	
	public void loadAllPossibleImages()
	{
		int currentIndex = 0;
		/** Starts loading at the bottom left sprite. */
		for(int i = spriteSize; i < spritesheetImages.getHeight(); i += spriteSize)
		{
			for(int j = 0; j < spritesheetImages.getWidth(); j += spriteSize)
			{
				textures[currentIndex] = convertBufferedImageToID(spritesheetImages.getSubimage(j, i, spriteSize, spriteSize));
				System.out.println("Loaded sprite @ " + j + " & " + i + " & Width: " + spriteSize);
				currentIndex++;
			}
		}
		/** Ends loading at the top right sprite. */
	}
	
	public void drawSprite(float x, float y, int index)
	{
		GL11.glPushMatrix();
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, textures[index]);
		GL11.glTranslatef(x, y, 0);
		GL11.glTexCoord2f(0, 0);
		GL11.glVertex2f(0, 0);
		GL11.glTexCoord2f(1.0f, 0);
		GL11.glVertex2f(spriteSize, 0);
		GL11.glTexCoord2f(1.0f, 1.0f);
		GL11.glVertex2f(spriteSize, spriteSize);
		GL11.glTexCoord2f(0.0f, 1.0f);
		GL11.glVertex2f(0, spriteSize);
		GL11.glPopMatrix();
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, -1);
	}
	
	private int convertBufferedImageToID(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() * 4); //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));
	                buffer.put((byte) ((pixel >> 8) & 0xFF));
	                buffer.put((byte) (pixel & 0xFF));
	                buffer.put((byte) ((pixel >> 24) & 0xFF));
	            }
	        }
	        buffer.flip();
	        int textureID = GL11.glGenTextures();
			GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
	        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
	        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
	        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
	        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
	        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
	      return textureID;
	}
	
	private BufferedImage getImageFromStream(InputStream input)
	{
		try{
			return ImageIO.read(input);
		}catch(Exception ex){
			System.out.println("Unable to load spritesheet from stream.");
			return null;
		}
	}
}


Also, Heres the init of my OpenGL just in case theres anything wrong in there (Which I don’t think there is…)


	/**
	 * The default OpenGL Settings. Used if too lazy to make configs by him/her self.
	 */
	public void initDefaultGL()
	{   
		GL11.glEnable(GL11.GL_COLOR_MATERIAL);
        	GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
       		GL11.glClearColor(backgroundColors[0], backgroundColors[1], backgroundColors[2], backgroundColors[3]); // Black Background
        	GL11.glDisable(GL11.GL_DITHER); //Disable dither.
        	GL11.glDepthFunc(GL11.GL_LESS); // Depth function less or equal
        	GL11.glEnable(GL11.GL_NORMALIZE); // calculated normals when scaling
        	GL11.glEnable(GL11.GL_CULL_FACE); // prevent render of back surface   
        	GL11.glEnable(GL11.GL_BLEND); // Enabled blending
		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // selects blending method
        	GL11.glEnable(GL11.GL_ALPHA_TEST); // allows alpha channels or transperancy
        	GL11.glAlphaFunc(GL11.GL_GREATER, 0.1f); // sets alpha function
        	GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // High quality visuals
        	GL11.glHint(GL11.GL_POLYGON_SMOOTH_HINT, GL11.GL_NICEST); //  Really Nice Perspective Calculations
        	GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
		GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
        	GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
        	GL11.glLoadIdentity(); // Reset The Projection Matrix
        	GLU.gluPerspective(30, Display.getWidth()/(float)Display.getHeight(), 1f, 300f);  //Aspect Ratio Of The Window
        	GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
        	GL11.glDepthMask(true); // Enable Depth Mask
	}
	
	/**
	 * Sets the 2D Mode for loading 2D Objects on the screen.
	 */
    public static void set2DMode(float x, float width, float y, float height) {
    	//GL11.glDisable(GL11.GL_DEPTH_TEST);
    	GL11.glMatrixMode(GL11.GL_PROJECTION);                        // Select The Projection Matrix
        GL11.glPushMatrix();                                     // Store The Projection Matrix
        GL11.glLoadIdentity();                                   // Reset The Projection Matrix
        GL11.glOrtho(x, width, y, height, -1, 1);                          // Set Up An Ortho Screen
        GL11.glMatrixMode(GL11.GL_MODELVIEW);                         // Select The Modelview Matrix
        GL11.glPushMatrix();                                     // Store The Modelview Matrix
        GL11.glLoadIdentity();                                   // Reset The Modelview Matrix
    }

What’s the actual problem?

We can’t help unless you tell us what’s wrong.

Allow me to point you to my tutorial series which covers a lot of this and explains things in more detail. :slight_smile: It’s important that you understand texture coordinates in order to create a texture atlas – your current code is creating many unnecessary textures, instead of just one.

Display & Context Creation
Textures

Some suggestions:
[]Instead of using a separate OpenGL texture for each sprite in your atlas (which defeats the purpose of an atlas in the first place), you should load a single texture and draw separate regions of it with texture coordinates.
[
]Making a generic Texture class will minimize code duplication and keep things clean. Then you can implement sprite sheets with a TextureRegion class. This may seem like a lot of work so early on, but it will save you time in the long run.
[]Don’t call glBindTexture with “-1”
[
]Your initDefaultGL does some weird things… You should not enable things like polygon smoothing, alpha test, culling, normalize, depth, etc. unless you actually need it.
[*]Along that line, your problem is probably because you’ve enabled writing to the depth mask. Don’t call glDepthMask.