interleaved VBO and textures (Solved)

Heeeelllo everyone ! I come to you a second time to talk you about how lost i am in lwjgl. The thing is that i try to implement a voxel base engine. To do so i create a lot of class and methodes that are working … correctly but i ran into a major issue when starting to work with VBO. I’ve manage to make a “beautiful” and make it all working smooth but my framerate where to low because i where createing a VBO for each single cubes i’ve draw.

Here is a link of my previous post on the same project http://www.java-gaming.org/topics/huge-lag-in-voxel-engine-using-lwjgl/32692/view.html

So now i’ve understund that i needed to make just one VBO per chunk so the drawing part would be smoother. For what i’ve see i must use the interleaving technic to render all of this but it’s not realy clear to me. I have a few questions about it :
*Do i need shader to manage to render my chunk while interleaving ?
*If yes or no … how do i do.

At this point i’m so much lost if good samaritan could help me and answer my questions “i would be sooo happy”.

Thank you i advance at least for reading this.

Doing one VBO per cube will be an overkill. It’s like feeding a little child with hot chilly sauce. Since every cube will have same dimensions, just create a single VBO for the cube. Then translate to the positions of the cubes and render that VBO with the texture it needs bound. That can solve your problem.

hi ! I understund what you meant but doing so the whole VBO (aka: the chunk) will have the same texture, what i want is i different texture information vor each cube separatly.

I’m going to give you an example to help you understand what @SHC is trying to get across. Imagine that you have a Stripey Yellow block at position A, a Dotted Green block at position B and a Checkered Black and White block at position C. Here is the order your rendering should take.

  • Bind VBO (and IBO if you’re using it)

  • Bind Stripey Yellow Texture.

  • Translate to Position A.

  • Draw VBO.

  • Bind Dotted Green Texture.

  • Translate to Position B.

  • Draw VBO.

  • Bind Checkered Black and White Texture.

  • Translate to Position C.

  • Draw VBO.

  • Unbind VBO.

So you use the same VBO, which is bound the whole time during your rendering, but you change the texture and transformation matrix in between drawing. One set of geometric data, infinite number of cubes.

NB: Looking at your first post, I think you’ve misunderstood what interleaving is. The technique we’re talking about here is called “instancing.” Which involves having one set of data which you draw several times. “Interleaving” is where you store all of the information about an object (position, normal, texture-coords etc) in the same VBO. If you are unsure about these things I recommend reading up on them once more just to get it clear in your head.

It is in fact little bit more clear for me. Don’t worry about my old post it whase in the time i didn’t understand very well those concepts.

But how did i “translate” to an other position in my texture vbo ?

For now all i have is a big png file with the different texture for the cube and i interleaved my big one O’ chunk vbo like so : CCCTTCCCTTCCCTT where C is the cube coordinates and T the texture coordinate.

Thank you for your responses.

Voxel engines does not draw cubes! You work with xyz(example 8x8x8) chunks and make one vbo per chunk. This vbo only contain the visible faces and can be transformed already to world space. You also need to put all textures that chunk use to single texture atlas/array.

The way you translate depends on how you’re doing things, but using VBOs doesn’t change anything. You can translate things exactly the way you were before. I expect you are using the fixed function pipeline (ie not shaders) so glTranslatef().

As a side note. Trust me when i say you will have to learn about shaders eventually and once you have you will find most things a lot easier. Better sooner rather than later.

Ok, thanks for the advices. I’ll start looking into it, but first i would like to make it work in order to continue on other features.

I Wrote a small thing that should draw a single triangle with an texture on it but all i have is an empty black window. Can anybody see what i am doing wrong and (maybe) if this is even worst than i did before ?

public class Triangles {

	private Texture texture;
	private FloatBuffer textureData;
	private Vector3f position, rotation;
	private int vboVertexHandleChunk;
	private FloatBuffer interleavedBuffer;
	private int floatByteSize = 4;
	private int positionFloatCount = 3;
	private int floatsPerVertex = positionFloatCount*2;
	private int texId;

	public Triangles(){
		this.initDisplay();
		this.openGL();
		position = new Vector3f(0f, 0, 0);
		rotation = new Vector3f(0, 0, 0);
	}

	public static void main(String[] args) {
		Triangles test = new Triangles();
		test.openImage();

		test.renderLoop();

	}

	private void openGL(){
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(50, 800/600, 0.01f, 20);
		glMatrixMode(GL_MODELVIEW);	
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_CULL_FACE);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glLoadIdentity();

	}

	public void initDisplay(){
		try{
			Display.setResizable(true);
			Display.setDisplayMode(new DisplayMode((int)800, (int)600));
			Display.setTitle("Dino Survive");
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			Display.destroy();
			System.exit(1);
		}

		Mouse.setGrabbed(false);
	}

	private void renderLoop(){
		genCubes();
		
		while(!Display.isCloseRequested()){
		
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			glLoadIdentity();
			
			useView();
			input();
			drawCube();
			 
			Display.sync(60);
			Display.update();
		}

		Display.destroy();
	}

	private void openImage(){
		try {
			texture = TextureLoader.getTexture("PNG",
					ResourceLoader.getResourceAsStream("../DinoSurvive/res/text.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}

		textureData = BufferUtils.createFloatBuffer(3 * 2);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	}

	private void useView(){
		glRotatef(rotation.x, 1, 0, 0);
		glRotatef(rotation.y, 0, 1, 0);
		glRotatef(rotation.z, 0, 0, 1);
		glTranslatef(position.x, position.y, position.z);
		System.out.println(position);
	}
	
	private void genCubes(){
		vboVertexHandleChunk = GL15.glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandleChunk);
		
		interleavedBuffer = BufferUtils.createFloatBuffer(3*2+3*3);
		interleavedBuffer.put(new float[]{
				0, 0, 3, 0.03125f+0, 0.03125f+0,
				-1, 0, 3, 0.03125f+0, 0+0,
				-1, -1, 3, 0+0, 0.03125f+0});
		interleavedBuffer.flip();
		
		glBufferData(GL_ARRAY_BUFFER, interleavedBuffer, GL_STATIC_DRAW);
	}
	
	private void drawCube(){
		
		glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandleChunk);
		//glEnableClientState(GL_VERTEX_ARRAY);
		glVertexPointer(3, GL_FLOAT, 5*4, 0L);
		glClientActiveTexture(GL_TEXTURE0);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glTexCoordPointer(2, GL_FLOAT, 5*4, 3*4 );
		glDrawArrays(GL_TRIANGLES, 0, 6);
		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	}

}

I remove some of the method to make the code a little less longer.
One again, thank you for reading and caring !

I noticed three problems, but nothing with your use of VBOs or interleaving so you’re getting better.

  1. You make your texture, but then you don’t bind it when you draw the triangle. Also you should bind it before changing any texture parameters. The getTexture() method probably leaves the texture bound but you can’t garuntee that and should always do it yourself. Also you make a FloatBuffer in that method which you then don’t do anything with.

  2. You did enable the GL_VERTEX_ARRAY but you have commented out that code. This is why I think you’re getting black screen. You are using vertex arrays so you do need them enabled.

  3. When you call glDrawArrays() you specify it to draw 6 vertices when you only need 3 and have only given 3.

Hello, to be honest i’m no sure of what to do with my texture buffer. I had commented out the GL_VERTEX_ARRAY because of a bug but i whase due to another problème. so i change a little bit but still don’t have any result. Maybe the triangle i drawn but the camera is not in front of it but i’m 90% sure it’s not this.

private void drawCube(){
		texture.bind();
		glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandleChunk);
		glEnableClientState(GL_VERTEX_ARRAY);
		glVertexPointer(3, GL_FLOAT, 5*4, 0L);
		glClientActiveTexture(GL_TEXTURE0);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getTextureID());
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glTexCoordPointer(2, GL_FLOAT, 5*4, 3*4 );
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	}

P.S: Thank you for your help / time quew8, if i manage to make this work with your help, i’ll name my firstborn after you :slight_smile:

So firstly, you are absolutely right - the triangle is behind the camera. I go the triangle rendering by changing the z coordinates to “-3” instead of “+3.” The reason for this is going to sound a little idiotic but I will try to explain it. In OpenGL, by default, the positive z direction is coming out of the screen towards you, which means that going into the screen (which is the forward direction of the camera) is actually the negative z.

The reason for this. You don’t need to know but it might be interesting
The reason for this is that OpenGL uses a right handed coordinate system. Imagine your hand is 3 coordinate axis. Your thumb is the x axis, your first finger (index finger) is the y axis and your second finger (middle finger). (I gave both names of fingers not to patronize you but because I know that the French have a different system for naming fingers. I don’t know enough to name them but I know it is different). So in OpenGL, the origin is the bottom left corner of the screen with the y axis going up and the x axis to the right. So take your right hand and put it at the bottom left corner with your thumb pointing to the right and your first finger pointing up. You will notice that your middle finger is pointing towards you. If you were using DirectX, it is a left handed coordinate system and with your left hand, the middle finger would be pointing into the screen.
Reason over. You can start reading again.

If I had done a proper job of reading through your code to begin with I would have noticed this and saved you the trouble. So probably not a good idea to name your first born after me - firstly he might be bullied a little (Quew8 is a weird name) and secondly he’d probably grow up to be the kind of person who does half-arsed jobs like me.

In the interest of completeness, I did notice two more things about your new render method.

-You are now binding the texture twice. Once with Slick’s Texture class’s bind() method and once with the direct OpenGL glBindTexture() method. There is no reason to.

-(This one is just an FYI so you don’t have to bother reading this either) I notice you using the glClientActiveTexture() function. Now I didn’t actually know how this differed from glActiveTexture() so I looked it up and thought I would share my findings.

OpenGL works with “texture units.” You can have a different texture bound to each texture unit which allows rendering different textures at the same time. What glActiveTexture() does is to change the current texture unit. I.e it changes which texture unit glBindTexture() binds the texture to. By default it is “GL_TEXTURE0.”

Now here is the bit I didn’t know. Each texture unit can also have it’s own texture coordinate pointer, so two different textures don’t have to share the same texture coordinates. So what glClientActiveTexture() does is to define which texture unit subsequent calls to glEnableClientState(GL_TEXTURE_COORD_ARRAY) and glTexCoordPointer() affect. Which is neat. Superfluous if you are using the programmable pipeline but still neat.

Hope I’ve helped.

I feel so bad right now. I thought i could be this so i’d implemented a method to move the camera around … But forget to disable face-culling. I am soooo sorry.

I already read some things about the left-handed and right-handed system and i should have figure this out. Anyway, thank you a lot for your help, if you want i’ll keep you aware my progress on the game :wink:

P.S: Of course it’s working, i wouldn’t say this if it wont ^^

Don’t worry about it. I made far worse mistakes when I was learning OpenGL and a black screen is the hardest to debug. And yeah I wouldn’t mind hearing how you get on.

Hello there ! Just a little message to show how it is working nice now. I manage to use the interleaving thing with the 2D too (not that complicated but thought …). Thanks again for the help, sorry for the looooong time re-up of this post and i hope i will soon post a message in the project section of this forum.

http://image.noelshack.com/fichiers/2014/33/1407941096-dine1.png

That’s looking very pretty. It’s nice to know that I am actually helping projects along.