LWJGL BlockWorld

No.

Your Chunk Rendermethod should look like this:


public void render(???){
    // Create a new ChunkRenderer
    ChunkRenderer renderer = new ChunkRenderer();
    
    // FOR every_block_in_chunk DO render_block
      for(int x = 0; x < var1; x++){
         int gx = chunk.chunkTotalPosX + x;
         for(int z = 0; z < var2; z++){
            int gz = chunk.chunkTotalPosZ + z;
            for(int y = 0; y < var3; y++){
                int gy = chunk.chunkTotalPosY + Y;
                
                // Translate to the Blocks global Position
                renderer.setBlockTranslation(gx,gy,gz);
                
                // Then Render the Block using the renderer
                //When you render a vertex using the renderer, it will be translated by the global block position
            }
         }
      }
}

You must NOT translate anything!
All translations are done by the ChunkRenderer
This would just terminate the sense behind using a ChunkRenderer.

For Example:


public void render(Chunk chunk){
    // Create a new ChunkRenderer
    ChunkRenderer renderer = new ChunkRenderer();
    
    // FOR every_block_in_chunk DO render_block
      for(int x = 0; x < var1; x++){
         int gx = chunk.chunkTotalPosX + x;
         for(int z = 0; z < var2; z++){
            int gz = chunk.chunkTotalPosZ + z;
            for(int y = 0; y < var3; y++){
                int gy = chunk.chunkTotalPosY + Y;
                
                // Translate to the Blocks global Position
                renderer.setBlockTranslation(gx,gy,gz);
                
                // Then Render the Block using the renderer
                //When you render a vertex using the renderer, it will be translated by the global block position
                int blockID = chunk.getBlock(x,y,z);
                
                renderer.renderBlock();
            }
         }
      }
}

The Block render Method would look like this (only for top surfaces):


public void renderBlock(){
    
    // This would just draw the topside of the block
    // Notice how the vertex coordinates are local for the block
    drawVertex3d(0,1,0);
    drawVertex3d(1,1,0);
    drawVertex3d(1,1,1);
    drawVertex3d(0,1,1);
}

Important:
This can be optimized even more.
But that’s for you to find out!

  • Longor1996

Please don’t tell me you are using immediate mode.

PLEASE!

PLEASE!!!

PLEASE!!!

Whats the problem with doing it the way I did it? If I don’t use

glTranslatef()

then isn’t it ok? And another question, what is

chunkTotalPosX

Is that the total amount of chunks or the total amount of blocks in the x axis? Sorry, I’m a little confused right now :confused: I thought up some code last night where I pretty much draw cubes like this(pseudo code):

public Chunk(int var1, int var2, int var3){
Block block;

int offset = 0;
for(int x = 0; x < var1; x++){
//do all the for loops
block = new Block(offset, offset, offset);
offSet += 16;
}
}

Then the block:

FloatBuffer verticeData;
public Block(int xOffSet, int zOffSet, int yOffSet){
//vbo stuff
verticeData.put(x, z, y, 
                     x + offSet, z, y
                    //do rest of faces 
}

That might not format very well… but anyway, that was just some of pseudo code. Is that bad? All I do is draw vertices and add 16(the blocksize) to some vertices to achieve the 3D effect. So when I need to get to draw the vertex of the bottom front face, I just do something like this:

(x + offSet, z, y)

offSet is then increased by 16 to be able to access the other vertices. Is that bad?

It doesnt matter what the Renderer implementation does.
Im using Display Lists in Puzzlez Project, because VBO just never work for me.
If you wan’t to use VBO’s, the same Code can be used with just a few modifications.
In Puzzlez Project, im using a Abstract Renderer Class that does all the Chunk Rendering.

Example:


public interface IChunkTessellator{
    public abstract void drawVertex(float x,float y,float z);
    public abstract void drawVertex(float x,float y,float z,float u,float v);
}

Then i just make an implementation:


public class ChunkTessellator_DisplayList {
    public void drawVertex(float x,float y,float z){
        GL11.glVertex3f(tx+x,ty+y,tz+z);
    }
    public abstract void drawVertex(float x,float y,float z,float u,float v){
        GL11.glTexCoord2f(u,v);
        drawVertex(x,y,z);
    }
}

I could also just make an implementation that uses VBO’s to render Chunks.

Fun Fact:
My whole Render System is so abstract, i could just use it with directX!
Is that enough explanation?

(Small Edit here: I would never replace my core-renderer with directX, that would be way too much work for me, but i could do it if i was insane!)

chunkTotalPosX/Y/Z is the Total Position of the Chunk in the Worldspace.
That means that the “TotalPos” is just the chunk coordinates multiplied by the chunksize.

The problem with glTranslate is:
It is just a big waste of memory and calculation time!
If you use glTranslate, the Graphicscard has to calculate a lot more, because every block is a single mesh.
If you send the blocks already translated to the Graphicscard, the Graphicscard can render the chunk as a single big mesh wich is much faster.

I too, tryed to draw blocks with glTranlste first, then realised it is insaneley slow with big amounts of blocks.
Just think of this:
How many blocks are on the screen in Minecraft?
A thousand? A ten-thousand? No, it goes into the millions!

If you would use a glTranslate for every single block,
this would simply not be possible anymore.

Enough explanation why using glTranslate for every single block is the worst possible idea?

  • Longor1996

It kind of does matter whether you use immediate mode or display lists/VBOs/VAOs. :cranky:

Those points are true, but your solution of immediate mode is even worse.

I think that if you are going to help, help people go forwards, not backwards.
If you actually are using VBOs, use VBOs in the example. Otherwise it’s misleading.

Anyway:

@OP: I recommend using VBOs.
Here’s the most bare-bones implementation I could find from my old code.
Note that it renders tiles, not voxels. It can be adapted quite easily for 3D though.


	public void createBuffer()
	{
		FloatBuffer buf = BufferStorage.getBuffer(tiles.size() * 6 * 8); // 6 = vertices; 8 = floats per vertex
		vc = 0;
		
		for(Entry<Vector2Int, Tile> tile : tiles.entrySet()) // Tiles are stored in a HashMap
		{
			int x = tile.getKey().x + chunkpos.x*CHUNKSIZE;
			int y = tile.getKey().y + chunkpos.y*CHUNKSIZE; // tile position + (chunkpos*chunksize)
			
			float[] color = {1, 1, 1, 1};
			
			float[][] vertices = new float[][]{{x, y+1}, {x+1, y+1}, {x, y}, {x+1, y}};
			float[][] texCoords = tile.getValue().getTexCoords();
			buf.put(vertices[0]).put(texCoords[0]).put(color);
			buf.put(vertices[1]).put(texCoords[1]).put(color);
			buf.put(vertices[2]).put(texCoords[2]).put(color);
			buf.put(vertices[3]).put(texCoords[3]).put(color);
			buf.put(vertices[2]).put(texCoords[2]).put(color);
			buf.put(vertices[1]).put(texCoords[1]).put(color);
			vc += 6;
		}
		
		buf.flip();
		
		glBindBuffer(GL_ARRAY_BUFFER, buffer);
		glBufferData(GL_ARRAY_BUFFER, buf, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		outdatedBuffer = false;
		BufferStorage.addBuffer(buf);
	}

	public void render()
	{
		if(outdatedBuffer)
			createBuffer();
		
		glBindBuffer(GL_ARRAY_BUFFER, buffer);
		
		glVertexPointer(2, GL_FLOAT, 8*4, 0L);
		glTexCoordPointer(2, GL_FLOAT, 8*4, 2*4L);
		glColorPointer(4, GL_FLOAT, 8*4, 4*4L);
		
		glDrawArrays(GL_TRIANGLES, 0, vc);
		
		glBindBuffer(GL_ARRAY_BUFFER, 0);
	}

Oh, I know

glTranslatef()

is terrible! I’m trying to convert all my code over to offsets, just like in my pseudo code. That’s why I’m confused, you keep talking about glTranslatef(), but it wasn’t anywhere in my code! I was just wondering if increasing offSet like this:

offSet += 16

and then drawing like this:

(x + offSet, z + offSet, y)

(which would draw the bottom left corner of the back face of the cube). I don’t see how that is bad, but you keep saying it is!

And i don’t care about that.
The OP can use whatever method he wants to draw his vertices.
If it is IntermdiateMode, DisplayLists or VBO’s, that’s his decision.
I use DisplayLists, because VBO’s never work for me, and let that be my problem.

@OP
Woops, Sorry for the confusion!

Yes,I say that using glTrnslate per Block is bad.
No, im not saying that offsets are bad.

Actually, the Block Translation (The Offset of the Block in the world) is done by the ChunkRenderer per vertex.
Means that:
Every time you “draw” a vertice, the vertice will be drawen with an offset.
The “offset” is the global position of the block in the world.
From what i understand, your blocks have a size of 16, and your chunks are made up of 16x16x16 blocks, is that right?

So, what you have to do is:


FOR every_block_in_a_chunk DO {
    int x = blockXCoordinateInChunk + theChunkPositionMeasuredInBlocksX;
    int y = blockYCoordinateInChunk + theChunkPositionMeasuredInBlocksY;
    int z = blockZCoordinateInChunk + theChunkPositionMeasuredInBlocksZ;
    
    chunkRenderer.setTheBlockTranslation(x,y,z);
    chunkRenderer.doRenderTheBlockByUsingHisID(blockID);
}



// Chunk Renderer
int totalBlockPositionInWorldRenderSpaceX = 0;
int totalBlockPositionInWorldRenderSpaceY = 0;
int totalBlockPositionInWorldRenderSpaceZ = 0;

setTheBlockTranslation(int bposX,int bposY,int bposZ)
{
    // Because the Blocks are 16x16x16 Units Big, multiply the global block coordinates by 16 to get the global block render coordinates.
    totalBlockPositionInWorldRenderSpaceX = bposX * 16;
    totalBlockPositionInWorldRenderSpaceY = bposY * 16;
    totalBlockPositionInWorldRenderSpaceZ = bposZ * 16;
}

doRenderTheBlockUsingHisID(int blockID){
    
    // Draw the Top Surface of the Block
    // (Your blocks are 16 units big, right? So let's draw the top surface)
    this.drawVertex(0,16,0);
    this.drawVertex(16,16,0);
    this.drawVertex(16,16,16);
    this.drawVertex(0,16,16);
    
    // Draw all the other surfaces...
}

drawVertex(flaot blockvertex_x,float blockvertex_y,float blockvertex_z){
    // The Translation for the Block Vertices is done HERE.
    drawAVertex(
        totalBlockPositionInWorldRenderSpaceX + blockvertex_x;
        totalBlockPositionInWorldRenderSpaceY + blockvertex_y;
        totalBlockPositionInWorldRenderSpaceZ + blockvertex_z;
    );
}

I can’t really explain it very good, because my english is not the best.
Just ask as many questions as possible!
Im better in explaining stuff piece by piece than explaining everything at once.

  • Longor1996

PS: How you draw a vertice doesn’t matter and i really don’t care about that part.
Use VBO’s: They are faster, but more complicated to use.
Use DisplayLists: They are easier to use, but slower because of intermediate-mode.
Use Textures: I tried that once, it works too, but it is utterly complicated.

So I played around with offSets a little, but I ran into a few problems. First, I’m going to apologize for using immediate mode, I didn’t feel like using VBOs because this is just a little test. Second, here’s a picture of the cube:

Looks fine!
But then I enable

glEnable(GL_CULL_FACE)

I then cull the back face and the cube ends up looking like this:

Obviously, the faces are screwed up. I render out my faces like this:

public Cube(int offSet){

		glBegin(GL_QUADS);

		glColor3f(1, 0, 0);
		glVertex3f(0 + offSet, 0 + offSet, 0);
		glVertex3f(0, 0 + offSet, 0);
		glVertex3f(0, 0, 0);
		glVertex3f(0 + offSet, 0, 0);

		glColor3f(1, 0, 1);
		glVertex3f(0, 0 + offSet, 0 + offSet);
		glVertex3f(0 + offSet, 0 + offSet, 0 + offSet);
		glVertex3f(0 + offSet, 0, 0 + offSet);
		glVertex3f(0, 0, 0 + offSet);

		glColor3f(1, 1, 1);
		glVertex3f(0 + offSet, 0, 0);
		glVertex3f(0, 0, 0);
		glVertex3f(0, 0, 0 + offSet);
		glVertex3f(0 + offSet, 0, 0 + offSet);

		glColor3f(0, 0, 1);
		glVertex3f(0, 0 + offSet, 0);
		glVertex3f(0 + offSet, 0 + offSet, 0);
		glVertex3f(0 + offSet, 0 + offSet, 0 + offSet);
		glVertex3f(0, 0 + offSet, 0 + offSet);

		glColor3f(1, 1, 0);
		glVertex3f(0, 0 + offSet, 0);
		glVertex3f(0, 0 + offSet, 0 + offSet);
		glVertex3f(0, 0, 0 + offSet);
		glVertex3f(0, 0, 0);

		glColor3f(0, 2, 1);
		glVertex3f(0 + offSet, 0 + offSet, 0 + offSet);
		glVertex3f(0 + offSet, 0 + offSet, 0);
		glVertex3f(0 + offSet, 0, 0);
		glVertex3f(0 + offSet, 0, 0 + offSet);
		glEnd();

	}

Did I just render the faces backwards or something?

offSet

is set to 10.

Sorry not been updating much, had things to do.

Firstly Opi, Im using Immediate mode at the moment. I know its not the best but I’m learning too, and it a good way to learn some basics.
I think you must be drawing the vertices in the wrong order. You can specify which - back or front to cull. here is my intermediate cube, It does not have offsets for translation (yet)
but it has offsets for texture, to allow drawing of tiles.

size: is size of the texture ie= 0.25 of the width
h and voffsett are the offest sizes so maybe 0.5f and 0.25 to select which tile it is on the texture sheet.

	public void Render(int textureID,float Hoffset, float Voffset,float size){
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);//select texture
		
		//
		GL11.glBegin(GL11.GL_QUADS);
		
		// Front Face ..............................................................................................
		GL11.glNormal3f(0.0f, 0.0f, i); // Normal Pointing Towards Viewer
		
		//                  x ,   y
		GL11.glTexCoord2f(Hoffset, Voffset + size); GL11.glVertex3f(-i, -i, i); // Bottom Left Of The Texture and Quad
		
		GL11.glTexCoord2f(Hoffset + size, Voffset + size );	GL11.glVertex3f(i, -i, i); // Bottom Right Of The Texture and Quad
		
		GL11.glTexCoord2f(Hoffset + size,Voffset );GL11.glVertex3f(i, i, i); // Top Right Of The Texture and Quad
		
		GL11.glTexCoord2f(Hoffset, Voffset );	GL11.glVertex3f(-i, i, i); // Top Left Of The Texture and Quad
		
		
		
		
	
		// Back Face
		GL11.glNormal3f(0.0f, 0.0f, -i); // Normal Pointing Away From Viewer
		
		GL11.glTexCoord2f(Hoffset + size,  Voffset + size); GL11.glVertex3f(-i, -i, -i); // Bottom Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset + size, Voffset  ); GL11.glVertex3f(-i, i, -i); // Top Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset, Voffset  );	GL11.glVertex3f(i, i, -i); // Top Left Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset,  Voffset + size);	GL11.glVertex3f(i, -i, -i); // Bottom Left Of The Texture and Quad
		
	
		// Top Face
		
		
		GL11.glNormal3f(0.0f, i, 0.0f); // Normal Pointing Up
		
		GL11.glTexCoord2f(Hoffset, Voffset + size);	GL11.glVertex3f(-i, i, -i); // Top Left Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset, Voffset);GL11.glVertex3f(-i, i, i); // Bottom Left Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset + size, Voffset);	GL11.glVertex3f(i, i, i); // Bottom Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset + size, Voffset + size);GL11.glVertex3f(i, i, -i); // Top Right Of The Texture and Quad
		
		
		// Bottom Face
				
		GL11.glNormal3f(0.0f, -i, 0.0f); // Normal Pointing Down
		
		
		GL11.glTexCoord2f(Hoffset + size,Voffset + size); GL11.glVertex3f(-i, -i, -i); // Top Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset, Voffset + size);	GL11.glVertex3f(i, -i, -i); // Top Left Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset, Voffset);GL11.glVertex3f(i, -i, i); // Bottom Left Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset + size, Voffset);	GL11.glVertex3f(-i, -i, i); // Bottom Right Of The Texture and Quad
		
	
		// Right face
		
		GL11.glNormal3f(i, 0.0f, 0.0f); // Normal Pointing Right
		
		GL11.glTexCoord2f(Hoffset + size, Voffset + size);	GL11.glVertex3f(i, -i, -i); // Bottom Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset + size, Voffset);GL11.glVertex3f(i, i, -i); // Top Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset, Voffset);	GL11.glVertex3f(i, i, i); // Top Left Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset, Voffset + size);	GL11.glVertex3f(i, -i, i); // Bottom Left Of The Texture and Quad
		
		// Left Face
		
		
		GL11.glNormal3f(-i, 0.0f, 0.0f); // Normal Pointing Left
		
		GL11.glTexCoord2f(Hoffset,Voffset + size);	GL11.glVertex3f(-i, -i, -i); // Bottom Left Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset + size,Voffset + size);	GL11.glVertex3f(-i, -i, i); // Bottom Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset + size,Voffset);GL11.glVertex3f(-i, i, i); // Top Right Of The Texture and Quad
		GL11.glTexCoord2f(Hoffset, Voffset);	GL11.glVertex3f(-i, i, -i); // Top Left Of The Texture and Quad
		GL11.glEnd();
	}

My next move is to switch to VBO. Thank you everyone for all the code you have put on, when(if) i get it working ill pop that on. I am doing a lot a glTranslate atm, and im going to change that to 1 per chunk. Then see how that goes with VBO’s. Im happy to share stuff, but you have also to remember Im just having fun getting things to work, and learning, so the solutions I present may not be the best, but with all your discussions, input, sharing of solutions and problems hopefully we can all learn what we want.

Trying VBO’s

VBO one block at a time.
Thats not fast enough. Next test - to send 16*16 blocks to VBO at once, and see what difference is.

I also tried using offseting blocks insead of glTranslate for each block and there was no difference in framerate for 9 16^3 chunks.

Now Im getting confused with it all, but below is my code to draw a VBO textured cube

// create geometry buffer (both vertex and texture)
	FloatBuffer vcBuffer = BufferUtils.createFloatBuffer((6*18) + (6*12)); //18 ver + 12 text  6 faces
	
	//front face
	//triangle 1 bottom
	vcBuffer.put(-0.5f).put(-0.5f).put(+0.5f); // vertex
	vcBuffer.put(0).put(1); // texture 	
	vcBuffer.put(+0.5f).put(-0.5f).put(+0.5f); // v
	vcBuffer.put(1).put(1); // 	t
	vcBuffer.put(+0.5f).put(+0.5f).put(+0.5f); // v
	vcBuffer.put(1).put(0); // t
	
	//triangle 2  top
	vcBuffer.put(-0.5f).put(-0.5f).put(+0.5f); // v
	vcBuffer.put(0).put(1); // t	
	vcBuffer.put(+0.5f).put(+0.5f).put(+0.5f); // v
	vcBuffer.put(1).put(0); // t
	vcBuffer.put(-0.5f).put(+0.5f).put(+0.5f); // v
	vcBuffer.put(0).put(0); //t

	// right face
	// triangle 1 bottom
	vcBuffer.put(+0.5f).put(-0.5f).put(+0.5f); // v
	vcBuffer.put(0).put(1); //
	vcBuffer.put(+0.5f).put(-0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(1); //
	vcBuffer.put(+0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(0); //

	// triangle 2 top
	vcBuffer.put(+0.5f).put(-0.5f).put(+0.5f); // v
	vcBuffer.put(0).put(1); // c green
	vcBuffer.put(+0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(0); // c red
	vcBuffer.put(+0.5f).put(+0.5f).put(+0.5f); // v
	vcBuffer.put(0).put(0); // c blue

	//back face
	//triangle 1 bottom
	vcBuffer.put(+0.5f).put(-0.5f).put(-0.5f); // vertex
	vcBuffer.put(0).put(1); // texture 	
	vcBuffer.put(-0.5f).put(-0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(1); // 	
	vcBuffer.put(-0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(0); // 
	
	//triangle 2  top
	vcBuffer.put(+0.5f).put(-0.5f).put(-0.5f); // v
	vcBuffer.put(0).put(1); // c   green	
	vcBuffer.put(-0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(0); // c    red	
	vcBuffer.put(+0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(0).put(0); // c   blue

	//top face
	//triangle 1 bottom
	vcBuffer.put(-0.5f).put(+0.5f).put(+0.5f); // vertex
	vcBuffer.put(0).put(1); // texture 	
	vcBuffer.put(+0.5f).put(+0.5f).put(+0.5f); // v
	vcBuffer.put(1).put(1); // 	
	vcBuffer.put(+0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(0); // 
	
	//triangle 2  top
	vcBuffer.put(-0.5f).put(+0.5f).put(+0.5f); // v
	vcBuffer.put(0).put(1); // c   green	
	vcBuffer.put(+0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(1).put(0); // c    red	
	vcBuffer.put(-0.5f).put(+0.5f).put(-0.5f); // v
	vcBuffer.put(0).put(0); // c   blue
	
	// left face
		// triangle 1 bottom
		vcBuffer.put(-0.5f).put(-0.5f).put(-0.5f); // v
		vcBuffer.put(0).put(1); //
		vcBuffer.put(-0.5f).put(-0.5f).put(+0.5f); // v
		vcBuffer.put(1).put(1); //
		vcBuffer.put(-0.5f).put(+0.5f).put(+0.5f); // v
		vcBuffer.put(1).put(0); //

		// triangle 2 top
		vcBuffer.put(-0.5f).put(-0.5f).put(-0.5f); // v
		vcBuffer.put(0).put(1); // c green
		vcBuffer.put(-0.5f).put(+0.5f).put(+0.5f); // v
		vcBuffer.put(1).put(0); // c red
		vcBuffer.put(-0.5f).put(+0.5f).put(-0.5f); // v
		vcBuffer.put(0).put(0); // c blue
		
		//top face
		//triangle 1 bottom
		vcBuffer.put(+0.5f).put(-0.5f).put(-0.5f); // v
		vcBuffer.put(1).put(0); // 
		vcBuffer.put(+0.5f).put(-0.5f).put(+0.5f); // v
		vcBuffer.put(1).put(1); // 
		vcBuffer.put(-0.5f).put(-0.5f).put(+0.5f); // vertex
		vcBuffer.put(0).put(1); // texture 	
			
		
		
		//triangle 2  top
		vcBuffer.put(-0.5f).put(-0.5f).put(-0.5f); // v
		vcBuffer.put(0).put(0); // c   blue
		vcBuffer.put(+0.5f).put(-0.5f).put(-0.5f); // v
		vcBuffer.put(1).put(0); // c    red	
		vcBuffer.put(-0.5f).put(-0.5f).put(+0.5f); // v
		vcBuffer.put(0).put(1); // c   green	
		
		
		
	
	
	vcBuffer.flip();
	
	
	IntBuffer ib = BufferUtils.createIntBuffer(1);
	glGenBuffersARB(ib);
	
	
	int vcHandle = ib.get(0);
	
	glEnableClientState(GL_VERTEX_ARRAY);
	GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
	//glEnableClientState(GL_COLOR_ARRAY);
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, vcHandle);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, vcBuffer, GL_STATIC_DRAW_ARB);   
	
	// the 20 stride   =   3x4byte for the vertex and 2*4 bytes for colour    
	// Vpointer starts at 0  (0<<2)
	// the textures start at 3*4  = 3<<2
	glVertexPointer(3, GL_FLOAT, /* stride **/20, /* offset **/0 << 2); // float at index 0
	//glColorPointer(3, GL_FLOAT, /* stride **/(3 * 2) << 2, /* offset **/(3*1) << 2); // float at index 3
	GL11.glTexCoordPointer(2, GL_FLOAT, /* stride **/20, /* offset **/(3*1) << 2);
	//glDrawArrays(GL_TRIANGLES, 0, 6/* elements */);
	glTranslatef(1f, -7f, 0f);
	
	for (int n = 0; n<128; n++){
	//glDrawArrays(GL_TRIANGLES, 0, 6);
		
		for ( int  m = 0; m<128; m++){
			glTranslatef(0f, 0f, -1f);
	glDrawArrays(GL_TRIANGLES, 0, 42);
	//glDrawArrays(GL_TRIANGLES, 0, 6); //draw front only
	//glDrawArrays(GL_TRIANGLES, 6, 12); 
	//glDrawArrays(GL_TRIANGLES, 12, 18); 
		}
	glTranslatef(1f, 0f, +128f);
	}
	
	
	
	
	
	
	
	
	
	glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
	GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
	//glDisableClientState(GL_COLOR_ARRAY);  //glDisableClientState(GL_COLOR_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY); 
	
	// cleanup VBO handles
	ib.put(0, vcHandle);
	glDeleteBuffersARB(ib); 

I welcome any suggestions!

Im always forgetting to turn laptop on at the wall!

NOOOOOO!!!

You put ALL the cubes in ONE VBO. (Per chunk)

Thank you, that does improve things a lot

Next step: to precauculate the drawing of only the needed faces (ie not faces of adjacent cubes).

The tread has also been moved to a more suitable place, and Im going to have a good read at what everyone else is doing in this catagory - so thank you for all help.

Going to start working on making it work as a game again now…

this is where im at:

I can now remove hidden faces and cubes to boost this more. Then get it to work with my existing game.

Problems to solve:
how to draw different chunks (in this picture its the same chunk copied 16 times).
how to update a chunk.

Also water will have to be drawn seperatly on another VBO.

I have found all the threads in the cube world challanges helpful.

Rendering the above with 100 chunks (161616) I get 160 fps

Hi,
I’m doing a voxel engine also. How do you calculate your fps? Mine is always a steady 60fps - I’m using display lists and only rendering chunks. Blocks in chunks are only drawn if not obscured by neighbouring blocks.

Looking at putting in view frustum culling but guess I’d need some sort of octree so not to have to check every chunk…

I’ve got 22 chunks on of 161616 blocks, actual block count being rendered is 11604 and running at 60fps, I’m also drawing a skybox in immediate mode.

Cheers

Hi steg, yea I keep having a look how yours is going. I’ve not got all the features you have yet. I think ur FPS is 60 because you have vsync on. If you disable vsync it will then run as fast as it can. You can also the set the sync() to a specific frame rate. If you can’t get that working ill post my loop code for you. Will keep looking in on your project.

Just wondering, in your pictures I see you have text on the screen. Are you actually rendering that in the game? If so, could I ask where you learned how to do that? The best way I’ve heard to do it is to actually render quads on the screen with the letter as a texture. That seems very inefficient though!

In my videos I was rendering to the screen, I may be wrong but I belive bitmap font rendering is more efficiant then actually rendering true fonts. here is my font class. I can supply the graphic if you need it

public class BitmapFont {

	
	private static String chars = "" + //
			"ABCDEFGHIJKLMNOPQRSTUVWXYZ      " + //
			"0123456789.,!?'\"-+=/\\%()<>:;     ";

	public BitmapFont() {
		
	}
	
	

		
	
	

	public void drawString( String msg, int x, int y, int size) {
		
		
	
		// bind the font text so we can render quads with the characters
		// on
	//	GL11.glEnable(GL11.GL_TEXTURE_2D);
		//texture.bind();
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, 2);
		// turn blending on so characters are displayed above the
		// scene
		GL11.glEnable(GL11.GL_BLEND);
		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MAG_FILTER,GL11.GL_NEAREST);
		// cycle through each character drawing a quad to the screen
		// mapped to the right part of the texture
		GL11.glBegin(GL11.GL_QUADS);
		
		
		msg.toUpperCase();
		
		float Hoffsett = 0.0f;
		float Voffsett = 0.0f;
		float squaresize = 0.03125f;
		
		for (int i=0;i<msg.length();i++) {
			
			int ix = chars.indexOf(msg.charAt(i));
			if (ix >= 0) {
				
						
			Hoffsett = squaresize*ix;
			
			Voffsett = ((int)(ix/32))*squaresize;
			
			
			//start drawing
			GL11.glBegin(GL11.GL_QUADS);
			GL11.glTexCoord2f(0+Hoffsett,squaresize + Voffsett);
			GL11.glVertex2f(x+(i*size),y+size);
			
			
			GL11.glTexCoord2f(squaresize+Hoffsett,squaresize+Voffsett);
			GL11.glVertex2f(x+size+(i*size),y+size);
			
			
			GL11.glTexCoord2f(squaresize+Hoffsett,0+Voffsett);
			GL11.glVertex2f(x+size+(i*size),y);
			
			GL11.glTexCoord2f(0+Hoffsett,0+Voffsett);
			GL11.glVertex2f(x+(i*size),y);
			
	
			}
		}
		GL11.glEnd();
		
		// reset the blending
		GL11.glDisable(GL11.GL_BLEND);
	}
}

the render with somthing like Gamefont.drawString( “X:” + playerX , 10,10,16); // to render at 10,10 with 16 pixel size

you will need to switch to orthagrphic mode while rendering the bitmap font. but if ur making a GUI you may do that anyway.

Hi,

Removed the vsyncon but still showing 60fps?

PS - this is on my macbook pro which has intel HD 3000 video card, maybe this is the issue?

Cheers,
Steve

In your images the glyph spacing is proportional (e.g. the 'l’s takes less horizontal space than capital letters). How are you doing that? It’s not apparent in the code.