Ever since seeing the Voxel Cataclysm demo that was done a while back, the idea of a 3d display mode for the game has lurked in the back of my mind.
Recently, I saw some discussion about how a 3d version of CDDA would be prohibitively difficult. This, given certain assumptions like the need for labor intensive 3d assets, is a fairly reasonable claim.
As a side project both for fun and a way to improve my programming skills, I have over the years been making various iterations of custom OpenGL graphics engines. Some of these have basic game engine components on top, but my focus was primarily on the rendering side. I discovered pretty quickly while trying to develop basic competency in Blender/3dsMax that I HATE 3d modeling. Though some free pre-made models are available online, I found it was much easier to work with and create custom assets in 2d. Then, for 2d assets in a 3d world, I would employ a simple technique called ‘billboarding’ ( flat textured rectangular surfaces that always orient towards the camera so you can’t perceive their flatness ).
I started asking myself, is this really that hard? We now have some very good 2d assets for this game so perhaps one of the major perceived hurdles is already cleared. Here’s a quick rundown of some of the details I’ve brainstormed on making something like this work.
In short, this is actually easier than I originally thought. I’m not super familiar with SDL, but discovered that opening an OpenGL context from within SDL is supported:
Using OpenGL With SDL
This means that the input, event handling and sound could remain largely the same.
Rendering sub-system hook
Shaders are king in 3d graphics and need to be passed a fair bit of data in order to make the magic happen. A large element of this whole setup would be exposing all of the variables required by the shaders via an interface layer. The primary object in the rendering system would be a single orbital camera, centered on the player position with basic mouse rotation and zoom functionality. So, on the input side of things at the very least the mouse input would need to be made available.
As far as world data, the main thing required would be the current state of viewable tiles that would otherwise be displayed in normal SDL mode at maximum zoom out level. There may be additional details that would be needed in order to get objects like walls, vehicles and some terrain to render in a pleasing way.
Rendering details/Asset management
All the tiles would need to be handled in a manner quite similar to the current SDL asset management. OpenGL texture objects would be created and associated with the appropriate game objects. A pre-processing stage would also be required for nice looking smooth zoom levels on all the textures through mip-map generation.
( As a side note, everything up to this point could be used to simply make a nicer looking 2d map display taking advantage of opengl anisotropic filtering and mip-maps to have smoother textures and a continuous zoom level )
For actually creating a passable 3d illusion, most objects would only need a basic spherical billboard transform. Terrain tiles would be mapped to a plane and just given perspective projection transformation. This would mean looking essentially the same as a 2d map from directly above with no z-axis rotation. As tilt is applied the terrain would shift in 3d perspective. A depth test based on the position of the camera would determine the rendering order so things overlap appropriately.
…and that is what I’ve got so far.
Most of this is stuff I’ve worked out in my own code before. The hardest part of this from my perspective is getting a good interface up without being too invasive and not breaking any existing code. I’d love to hear any thoughts people have on that aspect particularly. I’ve looked at the SDL parts of the code a bit, but I’m probably missing a few aspects.
ANYWAY, long post I know, but this is something I’m interested in trying out seriously when I have the time. Figured that I’d toss this out there in the meantime.