Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (808)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (872)
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  
  VBO order of operations  (Read 3875 times)
0 Members and 1 Guest are viewing this topic.
Offline QuicK

Junior Devvie

« Posted 2012-10-31 01:58:42 » like everybody else, I'm trying to create a "simple" voxel engine.

I'm trying to create a VBO that will draw the entire chunk of 16x16x16 cubes.

My questions are:

1) FloatBuffer vertexData = BufferUtils.createFloatBuffer(294912);
    Is the above code bad? it's got 16*16*16*72 slots available for the vertex buffer which means it can store every vertex of every cube.
    Should I be storing this many floats in the same buffer? (it's my understanding that VBO's are to Immediate mode as the GPU is to the CPU) which would mean that
    what I'm doing is correct.

2) what does glGenBuffers() actually do, and when should it be called?
    before the vertices are stored in the float buffer? while they're being stored? after they're stored? etc.

3) what actually happens to the FloatBuffer when it is flipped?
    should it only be flipped once (always)?

4) what does the following code do?
int vboVertexHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Any information on any of the above questions would be much appreciated!
*as always, any source code will be supplied upon request Smiley


Offline ra4king

JGO Kernel

Medals: 508
Projects: 3
Exp: 5 years

I'm the King!

« Reply #1 - Posted 2012-10-31 03:20:15 »

1) Yes. 1.2MB of data for the same cube? How about just a VBO that holds the data for 1 cube that you render with different offsets 16*16*16 times.

2) glGenBuffers generates an id for a named location to store data. This location's memory will be allocated with the call to glBufferData.

3) When a NIO Buffer is flipped, the limit is set to the position and the position is set to 0. This way, you can read all the data from the beginning to the limit.

int vboVertexHandle = glGenBuffers();                        //Generate ID
glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);              //Bind ID
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);   //Store the data in that allocated space
glBindBuffer(GL_ARRAY_BUFFER, 0);                            //Un-bind the ID

Offline theagentd
« Reply #2 - Posted 2012-10-31 03:31:39 »

1) That's no problem, but most of the buffer should be unused in the end. You need to cull (remove) faces that border to other solid blocks so only faces that can actually be visible are stored in VRAM. The size of vertexData should be enough to store even worse case scenarios, but the actual amount of data being uploaded should be pretty low per chunk in 99% of all cases.

2) glGenBuffers() creates a buffer ID used to refer to data stored on in VRAM on the GPU. You should create a vertex buffer per chunk.

3) Flipping sets the limit (Kind of like the size of an ArrayList. Note that size != capacity, the array length.) to the current position and resets the position to 0. Basically, you put data into the buffer with buffer.put() and when you're finished you flip. That way only the actual used part of the array is used thanks to the new limit. If you want to reuse the buffer later, just do a buffer.clear() which resets the limit to the capacity of the buffer.

4) That code uploads the vertexData buffer to VRAM and stores it there. First line creates a buffer handle. Second binds that buffer handle (they works like texture handles). Third line uploads the data in vertexData to the VBO. 4th line just unbinds the VBO.

How about just a VBO that holds the data for 1 cube that you render with different offsets 16*16*16 times.
No, you really need to batch the cubes together into chunks if you want to render more than a few thousand of them. You also really need to ignore faces that are inside walls/the floor/etc to reduce the number of vertices and triangles as much as possible.

View distance of 400m (1 cube = 1m^3) = Minecraft
With culling: 480 FPS, 150MB of VRAM used
Without: Instant out of VRAM crash

View distance of 100m:
With: 2200 FPS, 40MB of VRAM used
Without: Instant out of VRAM crash

View distance of 50m:
With: 2500 FPS, 30MB of VRAM used
Without: Instant out of VRAM crash

View distance of 25m:
With: 2500 FPS, 30MB of VRAM used
Without: 400 FPS, Crashes after loading around 5 16x16x16 chunks due to out of memory.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline QuicK

Junior Devvie

« Reply #3 - Posted 2012-10-31 03:44:34 »

Thanks for the replies guys! That really clears up some things that I didn't know about VBOs!

@ra4king the reason I'm now using FloatBuffer vertexData = BufferUtils.createFloatBuffer(294912); is because I had tried what you suggested prior to posting this, and couldn't get it to work.

I'll take what you guys said, and try to fix my chunk code! I'll update this post after I've attempted it! Smiley


Okay, so...I've tried many things to no avail.

Let me make sure I have things right in my mind. (Note: this is to create a VBO for 16x16x16 cubes)

1) create the chunk-specific FloatBuffer (vertexData) with enough space to hold all indices of all vertices (294912)
2) generate the ID for the buffer (glGenBuffers()) -- there should be only one of these right?
3) run through 3 nested loops (x, y, z) to create the indices
4) put the indices in vertexData
5) after the nested loops, flip vertexData
6) bind the ID generated in step 2, provide the VBO with the vertex data, and unbind the ID generated in step 2
7) after all of the above steps have been completed, run this every draw tick:
public void draw() {
      glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
      glVertexPointer(3, GL_FLOAT, 0, 0L);
      glBindBuffer(GL_ARRAY_BUFFER, vboColorHandle);
      glColorPointer(3, GL_FLOAT, 0, 0L);
      glTranslatef(curx, cury, curz);
      glDrawArrays(GL_QUADS, 0, 98304); //98304 derived from 4 vertices per face and 6 faces (4*6) * (16*16*16)
   } usual I feel extremely dumb because I found out my problem as I was writing this out.
M issue was in glDrawArrays()...I was only allowing enough indices for 1 cube.

I decided to go ahead and post this in case anybody else finds it useful Smiley thanks for the help guys! I still learned a good bit about VBOs from this Smiley
Pages: [1]
  ignore  |  Print  

Riven (847 views)
2019-09-04 15:33:17

hadezbladez (5795 views)
2018-11-16 13:46:03

hadezbladez (2603 views)
2018-11-16 13:41:33

hadezbladez (6211 views)
2018-11-16 13:35:35

hadezbladez (1499 views)
2018-11-16 13:32:03

EgonOlsen (4734 views)
2018-06-10 19:43:48

EgonOlsen (5793 views)
2018-06-10 19:43:44

EgonOlsen (3276 views)
2018-06-10 19:43:20

DesertCoockie (4175 views)
2018-05-13 18:23:11

nelsongames (5501 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08 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‑
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!