Got two considerable things done today.
The first thing is fixing up and finalizing the chunk mesh building system. I created a diagram to help explain this:
NOTE: "tiles" are actually cubes/voxels, probably should have referred to them as such

.
EDIT: Each dotted face represents a visible tile/voxel face.
This process essentially results in the mesh becoming the shell of the chunk. In the prototype I made for The Ascender, chunk building was done within each chunk, whereas in this version it's being handled in the world class. The reason for the switch is because beforehand invisible chunks and chunk borders were still being drawn because the system was not aware of adjacent chunks obsuring them. Now, only the visible tile/voxel faces of the visible chunks are being drawn.
I've heard of people using subdivision methods when constructing chunk meshes to cut down the amount of vertices, which is something I may consider doing later on, but for now, this works, so I'm not going to break it.
I'm much prouder of the second thing I accomplished today:

Basic directional lighting!
I know for you experienced OpenGL/GLSL programmers, this isn't much. But that's not what matters to me. What matters is the extremely annoying bug I ran into that took me hours to fix.
When building meshes, I store each piece of data into a std::vector, which is basically a dynamic array which you can add/remove data to. Right now I have three vectors for each VBO (which is like an attribute applied to each vertex of a mesh (ex. position of each vertex, color of each vertex, texture coordinates)), one for positions, one for texture coordinates, and one for normals. Case and point: I was storing the data for the normals into the position vector

. That took me 2.5 hours to figure out. Oh well.
Up next: Texture altasing (different textures for different block types).