So, up to this point, we’ve created a fairly unattractive room composed of small one-cubic-meter boxes. Pretty cool huh? Well, I think we can make it more interesting. See, the sheer scale of this room (50m by 50m by 25m) is quite difficult to grasp with each side of each cube being a plain, solid color. That is when we reach into our special bag of tricks to find textures!
Textures are nice little (or not-so little) graphics we can paste on our 3D geometries. They provide flavor to our environment, drawing in all colors of the spectrum and rendering with our geometries to create an attractive end-product to output to our user. Well, attractiveness is well on the horizon, because textures in this case are merely to give us a grid with which we can base our location upon.
The first step, as always, is to figure out what exactly we need within the context of our project. With this project, every texture will be 16×16 pixels, exactly the same size as textures found in Minecraft. This format actually allows us to do some pretty neat things. First of all, we will store all of the textures in a 256×256 sprite sheet. With each texture filling up 16×16 pixels of space, that means we will be able to fit 16 columns of textures, as well as 16 rows. 16 by 16 would be 256, which also happens to be the same number of unique ID values our cubes are able to have based on the “char” data type! Mind blown.
Our next step is to write a simple algorithm to apply a 16×16 portion of the sprite sheet to each face of a cube based on its ID value. With that implemented, our scene suddenly looks a little more interesting.

There we go. Now we can have a better idea of how large our room really is! Just for fun, let’s change the ID values of each wall to a different number, and draw a few more sprites onto our sheet. This is what we get as a result:

Well, at the very least, we now know that our scene doesn’t look too bad with some added variation. This is not a permanent change, but it’s nice to get a taste of how it may look in the future when we have fancy things like lighting in place.
Now, we come to some problems I did not expect. First of all, see what looks to be smudges of white in the distance? It’s most noticeable where the floor is viewed from an extreme angle. After some testing, I realized that this effect is the result of adjacent textures on the sprite sheet bleeding into the texture on the face of the cubes. I might fix this issue later, but given that my rooms will most definitely not be this large or this simple in the future, it’s not on my top priority list.
Yet another issue I encountered was this:

Guess what, this issue is also a result of bleeding textures! The blue and white lines visible between the squares is a small portion of an adjacent sprite, so this problem was fixed simply by stretching the texture out on each cube face slightly, cutting off a small amount of each edge to prevent bleeding. Here is the outcome:

Hold on, that’s not quite right. See, though we ended up with a neat plaid pattern, this is not exactly what we were looking for. What happened is that I put a negative number where it should have been positive, and I actually increased our bleeding problem. Whoops. When I change it to a positive, this is what we get:

That is what we are looking for. All of the bleeding is finally gone!
Now you may be wondering why I showed you my mistakes, rather than just skipping ahead to where everything is perfect and pretty (relatively). The reason is because I want to show you that programming is not the idea of putting numbers together to magically create a functioning program. Programming is a meticulous process of trial and error, even for the professionals to a certain degree. This is not to say that every program is intensely complex to understand, as they do vary greatly in complexity. However, it is to say that writing a program is so open-ended to the point where the computer takes everything the programmer writes absolutely literally, and if there is a bug in the program, it is usually the fault of the programmer, not the computer. I like to show you my entire process, including my mistakes, because I believe that is an essential part of what programming is all about. Learning from my own mistakes is what I do 50% of the time while programming. 49% of the time I’m banging my head on the keyboard over a small, mysteriously dysfunctional portion of code, and the other 1% of the time I’m making progress.
That’s it for textures for now. So far we’ve developed a stable framework on which we can develop more game! In Part 4, we get to take a look at making this game playable. This is a large and exciting next step which includes camera movement, character movement, and collision detection/reaction!