• 12
• 10
• 10
• 13
• 10

Use VBO for vertex+indices, not tex coords?

This topic is 2569 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi,

I'm writing a basic minecraft clone as my first project to prove to myself that I'm good enough at programming to try to write 3d games by myself, or in a small team. Right now I can render an area with 32,000 textured cubes with upwards of 1400 fps using VBO's and some decent culling.

I only store each vertex once, and use indices to reference these vertices. In minecraft, the entire terrain is all cubes, so every single poly (in this VBO at least), is a quad. Therefore, assuming your textures are symmetrical on u and v, you can use the same four texture coordinates for every single quad: (0,0),(0,1),(1,1),(1,0). Is there a way to tell the gpu to only use those four coords for every quad? Because that way, you're saving the storage for over 64,000 texture coordinates.

Something like
 glBindBuffer(GL_ARRAY_BUFFER, vbuffer); glBindTexture(GL_TEXTURE_2D, texture); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_INT, 0, 0); // Tell GPU to use those four texture coordinates for EVERY quad glDrawElements(GL_QUADS, indices.size(), GL_UNSIGNED_INT, &indices[0]); glDisableClientState(GL_VERTEX_ARRAY); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); 

Share on other sites
In general, no it's not possible.

One alternate thing you could try if you wanted to would be to replace your 'cube' with a single vertex, and then write a geometry shader that expands a vertex into 24 vertices that make up a cube (similar to how point sprites work), and then generate the texcoords in the geometry shader. But if you're just sending single vertices like that than you have to include the texcoords with each vertex.

These are a relatively new feature though, so it won't be backward compatible with older hardware.

Share on other sites
Dang. I know nothing about shaders, was hoping to avoid them as long as possible

How fast is that strategy performance wise?

Share on other sites
You can use the vertex shader to generate the texture coordinates from another set of data. E.g., seeing your world is a grid of cubes, you can implement a planar mapping from positions to texture coordinates.

You can also do stuff like only upload tex-coord indices (e.g. each vertex only has the tex coords of "0", "1", "2", or "3", and then the shader uses these values to look up an actual float2 from somewhere).

Share on other sites
Is there anyway to use separate indices without using shaders? In other words, could I use my current method to say "use these indices for the vertices, use these indices for the textures"?

Share on other sites
The geometry shader thing was just an idea, it may be faster but it may be over your head at the moment if you have no shader experience.

As this is your first game I would just send the texcoords. You don't know if thats going to be your limiting factor eventually anyway. You say you're saving 64,000 texcoords, which is just 512kb of memory. I wouldn't sweat it.

Hodgman:

I don't think that's going to work will it? Assuming that hes got cubes, say each cube is one unit on the side, than one 'world space position' is going to be shared by the corners of 8 different cubes. If I said 'tell me the texture coordinates of (0,0,0)', you wouldn't be able to without knowing which cube it was part of.

Share on other sites

Is there anyway to use separate indices without using shaders? In other words, could I use my current method to say "use these indices for the vertices, use these indices for the textures"?

No. It's not even possible with shaders. You only get one index per vertex.

Share on other sites
This is the most common question. No, a vertex that has 2 tex-coords will become 2 separate vertices. There could be some tricks but why do you want to do this anyway? Speed seems to not be a problem in your case. Even if you do a geometry shader or whatever method, its going to be equal to or slower. A geometry shader would for instance take extra power just to calculate what you already know (a cube with 6 faces). If your just trying to be tricky or to save a couple bytes of ram, then there is no point.

Share on other sites

As this is your first game I would just send the texcoords. You don't know if thats going to be your limiting factor eventually anyway. You say you're saving 64,000 texcoords, which is just 512kb of memory. I wouldn't sweat it.

My goal is to get up to a million cubes, which is 62mb of texcoords in that case, assuming 101x101x101 vertices, and two 32-bit integer texture coordinates per vertex. But regardless, that comes with another problem:

Say you've got exactly 8 vertices on a cube, I'm failing to find a set of texture coordinates such that each face has four valid texture coordinates. For example, you'll find some issues one the left/right/front/back faces of this cube, yet the top is fine.
 (0,1)---(1,1) / | (0,0) | |(1,0)---(0,0) |/ / (1,1)---(0,1) 

Share on other sites

My goal is to get up to a million cubes, which is 62mb of texcoords in that case, assuming 101x101x101 vertices, and two 32-bit integer texture coordinates per vertex.
There's almost never a reason to use 32-bit integer texture coordinates - especially not when you're only ever using arrangements of the values of 0 or 1.
It's very common to store tex-coords as shorts or bytes.
In your case you could pack both the x and y coords into a single byte per vertex -- but that would require shaders to unpack the two values from the one byte.
Without using shaders, you can still reduce these buffer sizes greatly by using 2 bytes for tex-coords.
You might even be able to get away with using bytes for position data too (with 1 metre resolution, gives +/-128 meters in model space).

Say you've got exactly 8 vertices on a cube, I'm failing to find a set of texture coordinates such that each face has four valid texture coordinates. For example, you'll find some issues one the left/right/front/back faces of this cube, yet the top is fine.[/quote]dpadam450 addressed this already -- "a vertex that has 2 tex-coords will become 2 separate vertices".
A cube has 8 vertices when only position is considered. If unique texture-coordinates are considered, then a cube has up to 24 vertices.

Hodgman:
I don't think that's going to work will it? Assuming that hes got cubes, say each cube is one unit on the side, than one 'world space position' is going to be shared by the corners of 8 different cubes. If I said 'tell me the texture coordinates of (0,0,0)', you wouldn't be able to without knowing which cube it was part of.
I'm relying on the hardware texture wrap functionality, where x=0, x=1, x=2, x=3, etc all map to the exact same column of texels.
Another part I skipped over is that a planar mapping only works for 2 faces of the cube -- 3 planar mappings would be required, and then you'd need to use the normal to select one of the 3 mappings.