Now its time to talk about my feature list (finally). It’s not that shiny though, at least, not yet… I’ll just dive straight into this one. I will ninja-edit in some screenshots when I have somewhere to upload them.
* User controlled camera looking into a 3D world
This is one of the things I have already done. It’s not quite finished, but basically it’s a perspective projection transformed in the modelview matrix by using gluLookAt. I will get around to controlling it with a matrix but for now gluLookAt provides adequate functionality for me. Currently the camera is controlled by the mouse, right click and drag rotates it around the Y axis (making it look left and right), and left click and drag moves it around. There is no provision for tilting or rolling, since the view angle is always going to be fixed facing down (like most RTS games, I guess). This gives me a nice window on my world, which is still empty.
* Complex and efficiently rendered and textured terrain generated by heightmaps
This is the part I’m working on at the moment. I started by drawing some points representing every pixel in the image. This was fine for a 50×50 image, but fell down when I used a 300×300 one. This was even worse when I rendered the vertices as triangles or quads. The first solution I came up with, which is where I’m at now, was to use frustum culling to skip the drawing of anything that wasn’t visible to my camera. I created a frustum with my frustum class, using the current projection view matrix (I pulled the projection matrix and modelview matrix from OpenGL, and mutliplied them together), with which the frustum class calculated the six planes of the frustum. I then passed the points constituting the bounds of each “square” on my map to a function in my frustum class which decides if the box I pass it (created by the two points in 3D space) is inside or outside the frustum, in part or whole. This stopped the application from completely dying, however I was only getting 10FPS. Time for some more creative thinking. I split the whole map into blocks of approx 50×50 points, creating “groups” of vertices. I then culled these whole areas if they weren’t in viewable range, which magically cut down on the number of “BoxInFrustum” tests I had to do, my FPS is now around 350 minimum. Being a perfectionist, this still isn’t good enough for me, so the next thing I’m going to try is using Vertex Buffer Objects (VBOs) to pre-compile the map geometry (much like the depreicated Display Lists), perhaps in the same chunks as the culling currently uses, and draw them using the VBO. Hopefully that will drastically boost the performance. I can use the VBO to store texture coordinates too, which is handy.
* The ability to place objects (3D models) on the terrain with the mouse
This is one of the next things I will do after handling the terrain rendering. I haven’t decided what format of model to use, but whatever it is, I will probably end up writing a class to load the data into a format that my app can understand. I might start with something simple like *obj files, and then move on to supporting COLLADA, which will most likely lead me to use FCollada to parse the models (since I already know my way around that API). There will be a model cache just like the texture cache to prevent multiple copies of the model existing in memory.
* A networking system that can replicate said object placement between all connected peers in real time
This will be my favourite part, probably. I really enjoy networking related programming over anything else, I don’t know why. I’ll start simple and use a client-server architecture where one instance of the application acts as the server, and others connect to it. When objects are created in the world, they are sent to the server, which recreates the action locally and sends it to all other client also, so they can do the same. I will probably start with TCP and maybe move over to UDP if it’s required and if I can be bothered implementing the sort of verification that TCP applies to its packets (ACKs and stuff).
* A GUI to provide the user with the tools to select and place objects
I have started a GUI system – it is designed to be a class that “tacks on” to other classes when required (namely, an application class). I use multiple inheritence to implement it into my application class, simply by deriving from Gui as well as Window. This then gives me access to functions such as GUIAdd, which lets me create an object of whatever type I specify (there is a base GUI object used here, which is used in other objects like GUIText, GUIButton, etc). I have direct control over when the GUI is drawn by calling GUIDraw somewhere in my application draw function. It can also receive input if I want it to, by calling its input functions from my applications input functions. Currently it supports a tree-type structure of frames containing other elements such as buttons and text display. It will also let the user drag the frames around the screen (if the frame flag for move is set). It’s not finished, but it’s not at the top of the list.
* A basic chat system
This is just going to send strings to the server which will echo them to everyone. Not much else to say. It will use the same networking system as the replication stuff, and display the text on each clients screen somewhere. Can’t get more basic than that.
For all the features here (the ones I havent’ done yet, anyway), I will document them in more detail as I do them. For now this is mostly just a rough idea of how I plan to do them – all of which are subject to change. I think from now on it will be easier for me to add bits and pieces here and there, in smaller sections on this blog, so I don’t end up with loads of posts as long as this one!
Posted in Ramblings