Shine

•March 22, 2009 • 1 Comment

Ok it’s been a while since I updated this, it’s also been a while since I’ve made any notable progress on this terrain rendering stuff.  I decided to scrap the chunking idea all together, as my VBO performance is more than adequate at the moment. Instead I started working on making it look better. It’s evident from the screenshots in my last post that the terrain doesn’t look that good, and you can’t really tell that it’s bumpy if it weren’t for the changes in colour.  I needed to improve this. To that end, I have added a couple of things to the terrain.

Normals

If my terrain is ever going to look better, I need normals. That is, vectors perpendicular to my terrain. Ok so it’s slightly more involved than that, but not much. If I haven’t detailed it already, my terrain generating system works like this:

Stage 1 – generating the vertices:

  1. Load an image (heightmap) into the engine using DevIL.
  2. Read the pixel data and generate an intensity based on the RGB values
  3. Create a vertex at each point (pixel * a scale value) using the intensity to calculate the height (Y axis)
  4. Calculate the colour for each point using the intensity (scaling up from blue to green)

Stage 2 – indexing the vertices and generating face normals:

  1. Create an index array using the vertices generated from the image (creating quads)
  2. For each quad generated, calculate the normal by getting the cross product of two of the edges of the quad and normalising it
  3. Add this to the array of face normals

Stage 3 – vertex normals and VBO:

  1. Read the 4 face normals for the faces around the current vertex
  2. Add the normalised sum of these 4 normals to the normal array – this is the normal for this vertex
  3. When the processing is complete, put the vertices, normals, and colours into the VBO

Well there it is, my terrain now has normals. The only problem is, there is no way to currently show them off nicely. This is where the next major addition to the render made an appearance.

Shaders

I added a class that encapsulates the creation and compilation of a GLSL shader program based on a number of text files containing shader code. This one is still under construction – needless to say, it does what I need it to do for now, which is to load and use a shader.  I also wrote a very basic shader to simulate a light, and using the normals from my terrain I calculate an intensity for each vertex (the dot product of the light direction and the vertex normal) and use it to scale the colour of the vertex. The result is quite nice, as you can see below…

normal-shader

The height in this image is a lot more obvious compared to drawing without normals and lighting.

VBO

•March 8, 2009 • Leave a Comment

Well I finally got around to changing my terrain renderer so it uses VBOs to store the land data. As promised here are some pictures –

Before – not using VBO, but “chunking” and frustum culling
terrain1

Notice the 160 FPS.

After – using an indexed VBO, but with no frustum culling yet
vbo1

VBO gives me an extra 80FPS when looking at the same spot. However, I’m still not happy with this. I think it will perform better if I still split the terrain up into smaller chunks, even just divided into four chunks, the performance will improve even more. I can use the same frustum culling technique as I did previously to decide which VBO objects to draw (it occurs to me now that if the camera is looking at the intersection of all four chunks, the FPS will still be 240, so maybe I should use 16 chunks instead..), hopefully 16 “is this box in the frustum” checks will be less expensive than drawing the whole VBO. I will find out soon!

Another thought is that so far this VBO contains only vertices and colours – eventually it’s going to contain vertices, normals, and tex coords, so that’s extra time needed to render (as I noticed a significant drop in performance when I went from vertices only to vertices and colours, I assume the same will happen with three sets of data). Hopefully my chunking mechanism will account for that… what’s the VBO limit in OpenGL? I better google that one…

Shiny Things

•March 3, 2009 • Leave a Comment

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!

Underwear

•March 3, 2009 • Leave a Comment

That’s right – Underwear.  I should point out now, if not obvious by this blog’s sub-title, that I’m using C++ as my language – that said… Underwear!  The underwear of a games engine is what I have to dress it with first. All the nasty bits that eventually make things easier to do. Things like Vector and Matrix classes, Frustum and Plane classes, Texture classes, and so on. But first – where is all this going to be used? The application class, of course!

I’m all for object oriented programming (OOP from now on, if I even have to say it again), and with that in mind I designed a class that allowed me not only to simplify window creation, but also to provide a class for me to copy and paste into any other application I was going to develop that required an OpenGL window. My window class acts as a base class, encapsulating all the Windows API calls to create a window and the OpenGL calls to initialise a context. It also handles input in a relatively simple way so far, but that’s not currently a huge concern. Key areas of the class (context creation, updating, drawing, etc) each call virtual functions that I implement in the class I derive from the base window class. Doing it like this makes it so much easier to read the important code, and gives me a warm fuzzy feeling inside.

So, I had my OpenGL window – but nothing in it. Here’s where the rest of the underwear had to be implemented.

Some reading of various articles and tutorials finally got me to kick my ass into gear and attempt to fully comprehend vector and matrix math. I don’t claim to be anything close to an expert, but I now know enough to get me by. It turned out not to be as hard as it seemed the last time I tried looking at it. With the help of this new found knowledge, I came up with a Vector class and a Matrix class, each with some basic functions like normalising and identity and other small things. All the more complex things (which even still aren’t that complex anymore) went in a Math namespace, if anything to keep things a bit neater. This consists of a collection of functions like Dot, Cross (for vectors), and Transform, which transforms a vector by a matrix. Then there are some other functions like Translate, Rotate, etc, that give me matrices containing information from whatever function I called (translation matrix, rotation matrix, etc). I also cobbled together a frustum class based on things I learned here, and a plane class to be used with it. To use a fancy sounding term, I did this in order to implement “clip space frustum culling”, which I will get around to describing a bit later on. So, that’s the math out the way, for now. I will have to revisit it many times I fear, as I find out about other things I need to implement before something else will work. For now though, it will do.

Something else I should mention is my texture cache. Eventually there will be model cache too, using a similar system, but for now, it’s just textures. My texture class is probably as simple as they come. It uses DevIL (aka OpenIL), which is a very nice image library that loads a LOT of formats. I also like it because of its OpenGL-like interface. Anyway, all my texture class does is take an image file, loads it with DevIL, and uploads it to a texture unit on the graphics card. It also allows for optional retention of the raw image data in system memory (currently so I can use the intensity of pixels in a greyscale image to generate my terrain heightmap). The texture cache performs the calls to load images, and stores instances of the texture class in its own map (std::map). If a call is made to load an image file that is already in the map, it simply returns the pointer to the instance that is already loaded. Otherwise it creates one first and adds it to the map. I also wrote a few helper functions to draw basic shapes on the screen, but that’s hardly spectacular, so I’ll spare some torture by skipping that bit.

That just about covers the privates (with Underwear… get it?), so next I can finally talk about the feature list for the application shell.

Step one

•March 3, 2009 • Leave a Comment

Ok, so the “Step” system isn’t going to stick in this case. But the first question is always the same – what shall I make?

Originally, in my naivety, I thought “great, I’ll build an engine framework!”. I can say for sure that was the biggest mistake. I saw an article posted in this thread on Gamedev.net and just seeing the title caused some alarm bells to ring. Why am I writing a framework I have no use for? That’s when I came up with a basic idea for a game. Very basic.  I think the closest this comes to an idea for a game is the word “idea”. I am focusing on a sort of RTS style gameplay, maybe Turn Based instead of Real Time, I am still undecided. Not good I know, but my philosophy is, start working on something and it will come together. Otherwise I find myself planning out endless combinations of things that never get implemented. I want a basic shell to be able to build on. Something with networking too.

My target is to have a shell with the following features:

  • User controlled camera looking into a 3D world
  • Complex and efficiently rendered and textured terrain generated by heightmaps
  • The ability to place objects (3D models) on the terrain with the mouse
  • A networking system that can replicate said object placement between all connected peers in real time
  • A GUI to provide the user with the tools to select and place objects
  • A basic chat system

I think thats a reasonable feature list for an RTS “shell”. If anything it’s proof of my ability to write such an application, and it gives me something to do at the weekends.

I think I’m going to try and give my posts more interesting names from now on, so next I will go through my bullet points, identifying what I have done so far, and how I plan to do the rest.

The beginning

•March 3, 2009 • Leave a Comment

I do a lot of programming. It’s my job, so I tend to sit at a desk from 9am until around 5pm writing something or other. The company I work for is called Virtalis, and mostly works on advanced visualisation software and other R&D projects. I’ve only been working in the software industry for about 9 months, since I graduated from university with a First Class Degree in Video Games. I felt it was about time for me to start getting down and dirty with my own projects using skills I have learnt from my time in the industry so far. Admittedly it’s not the “games industry”, but Virtalis is pretty close in my mind – if not much cooler (we have some awesome toys).

Anyway, enough about me, on to the interesting stuff!

Blog?

•March 2, 2009 • Leave a Comment

Ok, so I’ve decided to become one of those randoms that keeps a blog. This isn’t a blog for me to spout off about the cats I don’t have, or how much I hate something, but rather for me to document my journey through my lame excuse for a game (or is it just a tech demo?) as I program it. I don’t really expect anyone to read it apart from myself, so hey, who cares what you think!

I guess I’ll have to start by documenting what I’ve done so far… but not today, I need to go to bed – I have work in the morning.