Cube Hello World in 3D

In the last couple of chapters we've already made heavy use of the concept of model space. It's the space in which we define our models; it's completely unrelated to our world space. We use the convention of constructing all objects around the model space's origin so that an object's center coincides with that origin. Such a model can then be reused for rendering multiple objects at different locations and with different orientations in world space, just as in the massive BobTest example in Chapter 7.

The first thing we need to figure out for our cube are its corner points. Figure 10-10 shows a cube with a side length of 1 unit (e.g., 1 meter). I also exploded the cube a little so you can see the separate sides made up of two triangles each. In reality, the sides would all meet at the edges and corner points, of course.

Figure 10-10. A cube and its corner points

A cube has six sides, and each side is made up of two triangles. The two triangles of each side share two vertices. For the front side of the cube, the vertices at (-0.5,0.5,0.5) and (0.5,-0.5,0.5) are shared. We only need four vertices per side; for the complete cube, that's 6 x 4 = 24 vertices in total. However, we need to specify 36 indices, not just 24. That's because we have 6 x 2 triangles, each using 3 out of our 24 vertices. We can create a mesh for this cube using vertex indexing, as follows:

short[] indices = { 0, 1, 3, 1, 2, 3, 4, 5, 7, 5, 6, 7, 8, 9, 11, 9, 10, 11, 12, 13, 15, 13, 14, 15, 16, 17, 19, 17, 18, 19, 20, 21, 23, 21, 22, 23,

Vertices3 cube = new Vertices3(glGraphics, 24, 36, false, false); cube.setVertices(vertices, 0, vertices.length); cube.setIndices(indices, 0, indices.length);

We're only specifying vertex positions in this code. We start with the front side and its bottom-left vertex at (-0.5,-0.5,0.5). Then we specify the next three vertices of that side, going counterclockwise. The next side is the right side of the cube, followed by the back side, the left side, the top side, and the bottom side, all following the same pattern. Compare the vertex definitions with Figure 10-10.

Next we define the indices. We have a total of 36 indices—each line in the preceding code defines two triangles made up of three vertices each. The indices (0, 1, 3, 1, 2, 3) define the front side of the cube, the next three indices define the left side, and so on. Compare these indices with the vertices given in the preceding code, as well as with Figure 10-10 again.

Once we have all our vertices and indices defined, we can store them in a Vertices3 instance for rendering, which we do in the last couple of lines of this snippet.

What about texture coordinates? Easy, just add them to the vertex definitions. Let's say we have a 128x128 texture containing the image of one side of a crate. We want each side of the cube to be textured with this image. Figure 10-11 shows how we can do this.

Figure 10-11. Texture coordinates for each of the vertices of the front, left, and top sides (this is the same for the other sides as well)

Figure 10-11. Texture coordinates for each of the vertices of the front, left, and top sides (this is the same for the other sides as well)

Adding texture coordinates to the front side of our cube would then look like this in code:

Of course, we also need to tell the Vertices3 instance that it contains texture coordinates as well:

Vertices3 cube = new Vertices3(glGraphics, 24, 36, false, true);

All that's left is loading the texture itself, enabling texture mapping with glEnable(), and binding the texture with Texture.bind(). Let's write an example.

0 0

Post a comment