texture loading issue

Im having an issue where if I load 2 textures only the first texture is used in any situation , even if I use a seperate method it still shows only the first loaded texture.
here is my code.


public class Texture {
	public int id;

	public int width;

	public int height;

	private Texture(int id, int width, int height) {
		this.id = id;
		this.width = width;
		this.height = height;
	}
	public Texture(){
		
	}

	public Texture loadTexture(String name) {

		BufferedImage bimg = null;
		try {
			bimg = ImageIO.read(Texture.class.getClassLoader()
					.getResourceAsStream(name));
		} catch (IOException e) {
			
			e.printStackTrace();
			System.out.println("Texture loading failure! " + name);

		}

		int[] pixels = new int[bimg.getWidth() * bimg.getHeight()];
		bimg.getRGB(0, 0, bimg.getWidth(), bimg.getHeight(), pixels, 0,
				bimg.getWidth());

		ByteBuffer buffer = BufferUtils.createByteBuffer(bimg.getWidth()
				* bimg.getHeight() * 4);
		System.out.println(pixels[65]);
		for (int y = 0; y < bimg.getHeight(); y++) {
			for (int x = 0; x < bimg.getWidth(); x++) {
				if (pixels[y * bimg.getWidth() + x] != -65281) {
					int pixel = pixels[y * bimg.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));
				}
				else{
					buffer.put((byte)0);
					buffer.put((byte)0);
					buffer.put((byte)0);
					buffer.put((byte)0);
				}
			}
		}
		buffer.flip();
		int textureID = glGenTextures();
		glBindTexture(GL_TEXTURE_2D, textureID);
		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, bimg.getWidth(),
				bimg.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

		return new Texture(textureID, bimg.getWidth(), bimg.getHeight());
	}
}



public class spritesheet {
	private Texture tex,load;
	private float x,y,ex,ey,width,height;
	public spritesheet(String location){
		load = new Texture();
		tex = load.loadTexture(location);
		this.width = tex.width;
		this.height = tex.height;
	}
	public spritecomponent getcoords(int x, int y, int ex,int ey){
		spritecomponent temp= new spritecomponent();
		this.x = x/width;
		this.y = y/height;
		this.ex = ex/width;
		this.ey = ey/height;
		temp.set(this.x, this.y, this.ex, this.ey, tex);
		return temp;
	}
	public Texture gettexture(){
		return tex;
	}
}

You’ve to bind the other texture before using it. Add this method to the [icode]Texture[/icode] class and call it before drawing with that texture.


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

Hope this helps.

Where do you bind said textures? Also, these lines:


load = new Texture();
      tex = load.loadTexture(location);

Are highly suspicious. You create a new Texture… and then create a new Texture using that texture? That makes absolutely no sense. Since loadTexture() is the same across the board, make it static. Then you can do this:


tex = Texture.loadTexture()

That’s OO.

Also, please please please learn naming conventions. Uppercase your class names, and any words besides the first in your method names. Please.

It was referenced statically before so I thought it was that as an issue. I bind the textures in the actual object itsself so I am going to load all it in a different order.

Ok so when im trying to fix my code im a little bit stuck , when im binding my active texture what is the default as in when I dont want to bind a buffer anymore I refer to bindbuffer(GL_ARRAY_BUFFER,0) but what about for GL13.glActiveTexture(GL13.GL_TEXTURE0);?

You are actually loading only one texture.


load = new Texture();
tex = load.loadTexture(location);

because load is just an empty texture object with no valid id and others. Then you are using [icode]load[/icode] to load the texture. The method loads the texture into a new texture object. So you have only one texture available.

I load two textures ( two spritesheets)

Okay, let’s trace down what you did. First you’ve loaded the one texture of spritesheet 1. In the method [icode]loadTexture()[/icode] the first loaded texture is bound. Then you’ve loaded the one texture of spritesheet 2. Again [icode]loadTexture()[/icode] method gets called and this time, the second loaded texture is bound. Since you are having the texture of second spritesheet is bound, even if you draw using spritesheet 1, the second spritesheet gets shown.

Thats why you need to bind the texture you are trying to use to make sure that it is the texture that needs to be drawn. Hope this helps.

well currently for testing im using single VBOS per object , so I bind per texture. here is the code that I use to bind my texture.


//game init
GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, (int) width, 0, (int) height, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		verticalaspect = (float) (height / width);
		world = new World(this,128,128);//first spritesheet (the one drawn) is initialized in here
		icon = new GB(this);
		spritesheet iconsheet = new spritesheet("com/Core/graphics/texture/sprites/icon.png");//second spritesheet loaded and not shown for some reason
		
		icon.createobject(world.shape.square(200, iconsheet.getcoords(0, 0, 199, 149)), iconsheet.gettexture(),1);
		logger = new Logger(5000);
		logger.log("LOGGING STARTED OF SOLIS");
		//WORLD AND TILE SETUP
		world.t.addtile(new space(this),0);
		logger.log("Tiles added successfully");
		//FINILIZATION
		//world.setmap();
		logger.log("Game initialized succesfully");

//method within the graphics object
public void bindtexture(int texunit) {
		int loc = GL20.glGetUniformLocation(shader.programID, "tex");
		if (loc != -1) {
			GL20.glUniform1i(loc, texunit);
			
			if (texunit == 0) {
				GL13.glActiveTexture(GL13.GL_TEXTURE0);
			}
			else if (texunit == 1) {
				GL13.glActiveTexture(GL13.GL_TEXTURE1);
			}
			else if (texunit == 2) {
				GL13.glActiveTexture(GL13.GL_TEXTURE2);
			}
			else if (texunit == 3) {
				GL13.glActiveTexture(GL13.GL_TEXTURE3);
			}
			GL11.glBindTexture(GL11.GL_TEXTURE_2D, t.id);

		} else {
			System.err.println("WARNING: NO VARIABLE DETECTED WITHIN SHADER");
		}

	}

call once vbo is setup

I bind my icon texture to texunit 1 and everything else to texunit 0.

Textures doesn’t get bound to VBOs, they are completely different (unless you use a Texture Buffer Object), they bind to the global state.

so if I initizalise the bind externally then bind my other object it should work.

OpenGL is a state based machine. When you bind a texture, thats the active texture until you change it. So logically when drawing multiple objects, you will need to bind the texture corresponding to that object before drawing. Basically:

bind texture 1
draw object 1

bind texture 2
draw object 2

but what im doing is binding it to a texture unit then rendering it within the shader.

It doesn’t matter, OpenGL still is a state based machine whether you are using shaders or not. Binding a texture has to happen.

ok thanks , ill write that into my render method.

quick question , if I batch a group of objects and I pass in three attributes , verticies, texture, relative transformations. can I modify the transformations vbo using buffersubdata?