5
\$\begingroup\$

I'm making a voxel rendering engine. My "chunks" are 32 * 32 * 256 blocks and I can render a 16 * 16 square of them (which corresponds to Minecraft's maximal render distance). I'm using VBOs holding XYZ float positions and UV float coordinates. I use one VBO per chunk.

VBOs are alloacted with:

GL44.glBufferStorage(GL15.GL_ARRAY_BUFFER,
            BufferUtils.createFloatBuffer(32 * 32 * 256 * 6 * 6 * 5),
            GL30.GL_MAP_WRITE_BIT | GL44.GL_MAP_PERSISTENT_BIT);

I map them once at creation:

GL30.glMapBufferRange(GL15.GL_ARRAY_BUFFER,
            0,
            32 * 32 * 256 * 6 * 6 * 5 * 4,
            GL30.GL_MAP_WRITE_BIT | GL30.GL_MAP_UNSYNCHRONIZED_BIT | GL44.GL_MAP_PERSISTENT_BIT, null);

Then I can write directly into the buffer and make changes visible to the GPU with:

GL42.glMemoryBarrier(GL44.GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);

This works, except I get about 20 FPS, while Minecraft gets 300 without frustum culling. The CPU is clearly not the bottleneck, as I have 1M FPS when the window is minimized.

Am I doing something wrong or are VBOs slower than Minecraft's Display Lists? How can I speed this up?

System specs: i7 4770 & GTX 770 OC

\$\endgroup\$
7
  • \$\begingroup\$ why did you assume that Minecraft's use Display Lists? \$\endgroup\$
    – concept3d
    Commented Mar 18, 2014 at 22:05
  • \$\begingroup\$ I took a look at the source code. \$\endgroup\$
    – Toun
    Commented Mar 18, 2014 at 22:23
  • 2
    \$\begingroup\$ I suspect it is the GL_MAP_PERSISTENT_BIT that is destroying your performance. On an unrelated note, I hope you have fallbacks for when those GL4 features are unavailable, otherwise a large number of computers will choke and die with your engine, including about 95% of laptops by my estimation. \$\endgroup\$
    – bcrist
    Commented Mar 19, 2014 at 2:48
  • \$\begingroup\$ I tried without persistent mapping and I got no performance increase. Also, my game would be very resource demanding so I assume players will have very recent graphics cards, or at least OpenGL 4.4 capable. \$\endgroup\$
    – Toun
    Commented Mar 19, 2014 at 11:09
  • \$\begingroup\$ @Toun - AMD don't support GL4.4 at all - you can't make that assumption. \$\endgroup\$ Commented Mar 19, 2014 at 21:16

2 Answers 2

4
\$\begingroup\$

If you don't do any optimization you are rendering up to ~half a billion vertices, you can:

Remove faces/vertices where blocks touch, and don't issue draw calls for chunks that lay outside of the FOV.

Beyond that you can do more advanced vismap approaches, and merge faces when possible.

If you still think there is something wrong, i suggest you edit your post with some more code, rather then just the buffer initializations.

\$\endgroup\$
1
  • \$\begingroup\$ Ok I'll edit my post. \$\endgroup\$
    – Toun
    Commented Mar 20, 2014 at 6:50
0
\$\begingroup\$

I finally implemented a display list version and now I get nearly 3000 constant FPS, which is excellent I think. I didn't change the number of vertices nor the number of chunks (I already did a face selection when tesselating the chunks).

Like @bcrist said, the persistant mapping may have killed the performance.

Display lists are also far more easier to use than VBO's, as I don't even need to manually allocate memory, and they don't require the latest unsupported OpenGL versions.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .