geometry3dprojective-geometry

Creating a Cube-based 3-Dimensional Game


I am trying to create a 3-dimensional game that is based entirely off of cubes of the exact same size. I wanted to learn how to make my own 3-dimensional game using only 2-dimensional game libraries. Currently, the way I am doing is that I have an array storing the locations of all the centers of each cube in the game. Then, when drawing a single cube, I figure out which 3 sides of the cube I need to draw (since you don't need to draw all 3 sides of the cube). Then, knowing the 3-dimensional points of all the corners of the cube, I project those points onto a 2 dimensional space using the camera position, camera angle, and the point I am projecting.

Now my real question is: Now that I can draw a single cube, how do I draw multiple cubes, considering that cubes need to be drawn in a certain order (i.e. the cubes that are further away need to be drawn first so that the cubes that are closer to us appear on top of the cubes far away from us)? How do I determine which cubes to draw first given the list of cube centers and their sizes, and the camera position/angle?


Solution

  • its quite a few years when I learned 3D graphics ...

    All of the sites I used are gone now (as usual on the WEB but there are tons of new ones). I am OpenGL user so I recommend to use that. Many of mine students liked NEHE tutorials so look here. Also look at 4x4 transform matrices (homogenous coordinates).

    Z-Buffer is automatic in OpenGL just create context with Z-Buffer (all tutorials use it) and call glEnable(GL_DEPTH_TEST);

    Face culling (skip the other side of object) is done by glEnable(GL_CULL_FACE); and drawing faces in the same polygon winding (CW or CCW)

    Here few related questions:

    And some good sites to look at (strongly recommend):

    Sorry for that list of links but I think they are relevant and copy their stuff here would be too much. Now back to your question how to render more cubes. I see few options (in OpenGL):

    1. every cube has its own transform matrix

      Representing its position and orientation in space then just before rendering each cube change GL_MODELVIEW matrix and draw cube (with the same code for each). If you have too much objects/cubes it will consume big chunk of memory (+16 floats per cube).

    2. every cube is aligned to each other

      in this case you need to know just the 3D position (+3 floats per cube) so just do something like this:

      glMatrixMode(GL_MODELVIEW);    // this store original matrix
      glPushMatrix();
      glTranslatef(x[i],y[i],z[i]); // position of i-th cube
      // here render cube (like glBegin(GL_QUADS); ... or use glDraw... )
      glMatrixMode(GL_MODELVIEW);    // this restore original matrix
      glPopMatrix();
      
    3. use of shaders

      in modern shader pipeline you can use geometry shader to emit cube on receiving point but this is too much for OpenGL beginner. But in this case you would draw just points and the shader will convert them to cubes on GPU which is much faster ...

    4. use VBO or VAO

      • VAO is vertex array object (list of VBO's)
      • VBO is vertex buffer object


      VBO is basically an array of parameters copied to GPU as one chunk and not by individual calls like glVertex,glColor,glNormal... which is much much faster. This allows you to create model of your space (all cubes) and draw it at once with enough speed unless you hit the GPU/CPU/MEM speed limits

      VAO similarly groups more VBOs together so you need to bind just single VAO per object instead of one VBO for each one parameter further reducing the API calls number needed for rendering.