Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (496)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Huge lag in voxel engine using lwjgl  (Read 3631 times)
0 Members and 1 Guest are viewing this topic.
Offline Akinesis

Senior Newbie


Exp: 3 years



« Posted 2014-04-05 22:47:26 »

everyone ! First of all, please excuse my english, i'm just a poor frenche programer who's fighting for a project maybe a little to big for him. Cheesy

So, let me explain : I start developing a voxel engine using lwjgl. To do so, i implemented several class such as chunk, chunkManger (which of course manage all the chunks in the game) and of course cubes. There's a lot more but this is the basics.

To draw my cubes i use VBO (Vertex buffer Object), the chunk have the main vbo an i update it for every cube i have to draw at each frame of the game. As you can think, it's result of massive lags for nothing more than 400 cubes to draw. I've of course enable face-culling and i have a function that make sure to render only the visible cubes.

So me question is if anybody have the patience and the kindness to look at my sources (https://github.com/Akinesis/DinoSurvive/) and tell me what i do wrong (though i already have an idea why).

Well thank you for reading me and maybe thank you for helping me.

P.S: I'm not sure to be in the right section so sorry if i'm not.

What doesn't kill you, give you XP.
Offline HeroesGraveDev

JGO Kernel


Medals: 252
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #1 - Posted 2014-04-05 23:42:08 »

Put all the cubes in one VBO instead of one VBO per cube

Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #2 - Posted 2014-04-06 03:11:32 »

I figured it was the solution but if i do so, i could i be able to map the associate texture to the cube. I still need to draw the texture (wich difere for a cube to an other) .

Or maybe ther's somthing i'ved miss about VBOs ?

What doesn't kill you, give you XP.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Drenius
« Reply #3 - Posted 2014-04-06 03:13:17 »

You will need to work with spritesheets, but other that that...
Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #4 - Posted 2014-04-06 03:33:07 »

I'll looking for it, it seems interesting. But I already a-handle texturing with a unique png file. For now here what it's look like :



(i draw the texture myself so it's not very nice ...)

What i do when i draw is this :
-Put the coordinates of the cube in the vbo
-Take the coordinate of the associate texture in a second vbo
-draw the cube
-Back to step 1 with another cube.

But if i use a single vbo per chunk (aka a big array of float) how can i say which cube i want to draw (or i am drawing) at a particular moment to load the good coordinates ?

What doesn't kill you, give you XP.
Offline Drenius
« Reply #5 - Posted 2014-04-06 03:37:33 »

You can not really access data in a VBO after you passed it. Thats the point. You send everything one-way as a big packet to the GPU to avoid traffic.
Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #6 - Posted 2014-04-06 03:45:02 »

So if i want performance but being able to draw each cube with is specific texture i have to make a vbo per potential texture ?

That seems litle bit hardore does'nt it ? What if i have (i a bright future) 100+ type of cubes ? It's mean each chunk will have 100 different vbo ?

It will always be less than 4096 but ...

What doesn't kill you, give you XP.
Offline HeroesGraveDev

JGO Kernel


Medals: 252
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #7 - Posted 2014-04-06 03:46:51 »

Use spritesheets. Then you can have 1 vbo for the whole chunk.

Offline Drenius
« Reply #8 - Posted 2014-04-06 03:47:52 »

You give every vertex in you VBO a texture coord on your spritesheet.
Everything in the VBO, but you need to pass the texture coordinates.
Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #9 - Posted 2014-04-08 14:21:22 »

Hi guys, first of all, thanks for your advices. With them i managed to do much better but i'm stuck again and maybe you could help (i could make a new post but the problem is related to the first one so ...).

Anyway ! I put all my cubes coordinate into one and only vbo (on the chunk) and to bind each cube with the specific location of the texture, i stored the coordinate into the same vbo (the same float buffer on the vbo). For as much as i understand, i must "intervaled" my vbo rendering passing in argument many things so i will work. But right know all i have i my display and nothing in it. My cube wont render anymore.

So if someone could try to explain me how all of this work (i can show you the function i'm using), it would be verry nice.

Thanks.

What doesn't kill you, give you XP.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Drenius
« Reply #10 - Posted 2014-04-08 17:37:54 »

Well, showing what you have would probably be the best for now...
Offline Mike

JGO Wizard


Medals: 76
Projects: 1
Exp: 6 years


Java guru wanabee


« Reply #11 - Posted 2014-04-08 18:57:46 »

For as much as i understand, i must "intervaled" my vbo rendering passing in argument many things so i will work.

Every time someone talks about VBO's I have to post this post as it explains more or less anything in a simple way:
http://www.java-gaming.org/topics/introduction-to-vertex-arrays-and-vertex-buffer-objects-opengl/24272/view.html

It's almost the same for textures and colors, so it should give you a good beginning.

Mike

My current game, Minecraft meets Farmville and goes online Smiley
State of Fortune | Discussion thread @ JGO
Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #12 - Posted 2014-04-09 15:24:16 »

@Mike : Yup i've already find this (really helpful) post but i must have messed up something by trying to reproduce it.

I'll put there my generating and rendering methods and if you want to watch the full project, chek the "problem" branch on the github link (https://github.com/Akinesis/DinoSurvive/tree/problem)

The chunk class (handling the vbo):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
//call befor the rendering loop
public void genVBO(){
      vboVertexHandleChunk = GL15.glGenBuffers();
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboVertexHandleChunk);
      GL15.glBufferData(GL15.GL_ARRAY_BUFFER, interleavedBuffer, GL15.GL_STATIC_DRAW);

      // -- Now we can split our interleaved data over 2 attribute lists
     // First up is our positional information in list 0
     GL20.glVertexAttribPointer(0, positionFloatCount, GL11.GL_FLOAT, false,
            vertexFloatSizeInBytes, 0);

      // Second is our texture information in list 1, for this we also need the offset
     int byteOffset = floatByteSize * 2;
      GL20.glVertexAttribPointer(1, positionFloatCount, GL11.GL_FLOAT, false, vertexFloatSizeInBytes, byteOffset);

      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
      GL30.glBindVertexArray(0);

   }

//put each cube int the Buffer
//the two genCUbe method return an array of float (the coordinates of the cube and the texture's one)
public void genCubes(TextureManager texMan){
      interleavedBuffer = BufferUtils.createFloatBuffer(renderCubes.size()*3*2*36);
      for(Cube3dVbo cube : renderCubes){
         interleavedBuffer.put(cube.genCubes());
         interleavedBuffer.put(texMan.genText(cube.getType(), cube.getTextX(), cube.getTextY()));
      }
      interleavedBuffer.flip();
   }

//a monkey with a keyboard would have done something better than this.
//this is the method called in the rendering loop
public void draw(TextureManager texMan){
      //texMan.bindBuffer();
     GL13.glActiveTexture(GL13.GL_TEXTURE0);
      GL11.glBindTexture(GL11.GL_TEXTURE_2D, texMan.getTextVBO());
     
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboVertexHandleChunk);
     
      glDrawArrays(GL_TRIANGLES, 0, 36*renderCubes.size());
      GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
   }


The textureManager class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
//the constructor, also, i do not know what i am doing here, at least for half of the code
public TextureManager() {
      tWidth = 0;
      tHeight = 0;
      try {
         // Open the PNG file as an InputStream
        InputStream in = new FileInputStream("res/text.png");
         // Link the PNG decoder to this stream
        PNGDecoder decoder = new PNGDecoder(in);
         
         // Get the width and height of the texture
        tWidth = decoder.getWidth();
         tHeight = decoder.getHeight();
         // Decode the PNG file in a ByteBuffer
        buf = ByteBuffer.allocateDirect(
               4 * decoder.getWidth() * decoder.getHeight());
         decoder.decode(buf, decoder.getWidth() * 4, Format.RGBA);
         buf.flip();
         in.close();
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }

      textureData = BufferUtils.createFloatBuffer(36 * 2);
      //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     
      textVBO = GL11.glGenTextures();
      GL13.glActiveTexture(GL13.GL_TEXTURE0);
      GL11.glBindTexture(GL11.GL_TEXTURE_2D, textVBO);

      // All RGB bytes are aligned to each other and each component is 1 byte
     GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
     
      // Upload the texture data and generate mip maps (for scaling)
     GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tWidth, tHeight, 0,
      GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf);
      GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);

      // Setup the ST coordinate system
     GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
      GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
     
      GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,
            GL11.GL_NEAREST);
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
            GL11.GL_LINEAR_MIPMAP_LINEAR);
   }


Here, i think you got everything. If you not hate me after seeing what i'm doing here and still wanna help, thank you. Otherwise thank you for at least reading me.

What doesn't kill you, give you XP.
Offline Mike

JGO Wizard


Medals: 76
Projects: 1
Exp: 6 years


Java guru wanabee


« Reply #13 - Posted 2014-04-09 15:40:07 »

That code looks messy Smiley The first thing that pops out is that you first draw all vertrices and then all textures for each cube, instead of splitting them up in triangles. Why don't you try to first get a single triangle on the screen and then add another one and then expand that to all the cubes? I think that will be a lot easier for you.

Mike

My current game, Minecraft meets Farmville and goes online Smiley
State of Fortune | Discussion thread @ JGO
Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #14 - Posted 2014-04-09 17:07:50 »

That a good advice but the thing is ... I don't understand all of what i am doing.

So yeah i really need help sorry. I just tryed random thinks based on what i could find on textured vbo and intervaling but it's not all clear to me.

I don't heaven see how am i drawing all the cube then the textured and not a triangle at a time.

Sorry and thanks for the answer.

What doesn't kill you, give you XP.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 798
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #15 - Posted 2014-04-10 10:58:52 »

1  
2  
GL20.glVertexAttribPointer(0, positionFloatCount, GL11.GL_FLOAT, false, vertexFloatSizeInBytes, 0);
GL20.glVertexAttribPointer(1, positionFloatCount, GL11.GL_FLOAT, false, vertexFloatSizeInBytes, byteOffset);


What is this 'positionFloatCount' variable?

The 2nd parameter ('size') specifies how many components your vertex attribute has.
   3 for 3D vertex
   2 for 2D vertex
   2 for regular texcoords
   4 for RGBA colors
   etc, etc


Additionally, it seems your
int byteOffset = floatByteSize * 2;
is probably off, because presumably you start your interleaved geometry with the vertex position, which is 3D (you're rendering cubes), so the offset for the 2nd vertex attribute should be 3 floats, not 2 floats.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #16 - Posted 2014-04-10 13:21:56 »

Hi,

so 'positionFloatCount' is 3 which i change in 2 for the the call of glVertexAttribPointer. I also try several combination with the offset but i still have a clear screen with nothing drawn on it.

What doesn't kill you, give you XP.
Offline Mike

JGO Wizard


Medals: 76
Projects: 1
Exp: 6 years


Java guru wanabee


« Reply #17 - Posted 2014-04-10 14:42:15 »

Hi,

That is (also?) because you aren't adding vertex,vertex,vertex,texCoord,texCoord,vertex,vertex,vertex,texCoord,texCoord and so on.

You are adding first all vertices from each cube and then all texture coordinates, like this: vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,vertex,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord,texcoord

That's not going to work, which is why I suggested that you start with just drawing a single triangle and then work your way up from that Smiley

Mike

My current game, Minecraft meets Farmville and goes online Smiley
State of Fortune | Discussion thread @ JGO
Offline Akinesis

Senior Newbie


Exp: 3 years



« Reply #18 - Posted 2014-04-11 08:49:47 »

Hello,

so i try what you said to me, so i intervaled mes triangle like so : VVVTTVVVTTVVVTT ...
but nothing change. I'm sorry i do not test with only one but it would to longue to figure out to rearrange my code to make a single triangle.

Here what i did:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
public void genCubes(TextureManager texMan){
      interleavedBuffer = BufferUtils.createFloatBuffer(renderCubes.size()*3*2*36);
      float[] textArray, cubeArray;
      int i;

      for(Cube3dVbo cube : renderCubes){
         textArray = texMan.genText(cube.getType(), cube.getTextX(), cube.getTextY());
         cubeArray = cube.genCubes();
         int j = 0;
         
         for(i =0; i<108; i+=3){
            interleavedBuffer.put(cubeArray[i]);
            interleavedBuffer.put(cubeArray[i+1]);
            interleavedBuffer.put(cubeArray[i+2]);
           
            interleavedBuffer.put(textArray[j]);
            interleavedBuffer.put(textArray[j+1]);
            System.out.println(i +" " + j);
            j+=2;
         }
   
      }
      interleavedBuffer.flip();
   }

What doesn't kill you, give you XP.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 798
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #19 - Posted 2014-04-11 09:06:44 »

As it appears you can't figure it out while having it integrated in your game, do just like Mike said:
  • render 1 triangle
  • render 2 triangles
  • render 3 triangles
  • render 1 cube
  • render 2 cubes
  • integrate in your engine

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline lcass
« Reply #20 - Posted 2014-04-11 12:01:36 »

ok so what I would do for this is , store all data for the cubes in one big VBO. When you add to the VBO you also have to add your texture coordinates. They are added to the texture buffer in the same position. Im not sure that GL_TRIANGLE_STRIPS would work though.
Offline bogieman987
« Reply #21 - Posted 2014-05-28 16:26:38 »

Wouldn't instancing be a much better thing to do in this case?
Since all the geometry seems to have the same vertices. With only the texture and position being different.

Online theagentd
« Reply #22 - Posted 2014-05-28 18:30:08 »

Instanced cubes will always be slower than precomputed chunks with per-face culling.

Myomyomyo.
Offline trollwarrior1
« Reply #23 - Posted 2014-05-30 06:29:13 »

Create a level renderer class. When a cube is changed in your level, set flag 'update' in your renderer class to true. When it is time to render your level, call renderer.render() method. In render method, do something like this:
1  
2  
if(update) { updateVBO(); update=false; }
renderVBO();


This code will update the VBO when cubes are changed.

updateVBO() method should either make new buffer, or clear existing buffer and upload all the cubes you have in your level. You might also not want to put cubes that don't make contact with air blocks (empty blocks) into your buffer.
Pages: [1]
  ignore  |  Print  
 
 

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

BurntPizza (14 views)
2014-09-19 03:14:18

Dwinin (33 views)
2014-09-12 09:08:26

Norakomi (58 views)
2014-09-10 13:57:51

TehJavaDev (80 views)
2014-09-10 06:39:09

Tekkerue (40 views)
2014-09-09 02:24:56

mitcheeb (62 views)
2014-09-08 06:06:29

BurntPizza (46 views)
2014-09-07 01:13:42

Longarmx (33 views)
2014-09-07 01:12:14

Longarmx (37 views)
2014-09-07 01:11:22

Longarmx (36 views)
2014-09-07 01:10:19
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!