Archived

This topic is now archived and is closed to further replies.

kspansel

C++ OpenGL Game Engine

Recommended Posts

I''m looking to create a set of generic classes for an opengl game engine. However, I''m stuck on the design of the engine. I can divide the engine into different sections: Input Graphics Audio Physics ... But what kinda of classes should I create in each section? And how should I allow classes use each other? Let''s say I create a class to render my scene and I have a camera class to handle the view information. Now I need a class to handle input so i create an input class. How do I move my camera or interact with the scene? Should my camera control the input class? I would like to create fairly extensible toolkit but I''m not understanding how each section fits/interacts together to form the game engine. Hopefully someone out there can understand the non-sense I just typed. Thanks, Kory

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
First, I would strongly suggest starting with a less ambitious project than writing a game engine. Do you really need a game engine? How about just writing a game? After writing a couple games (should you get so far), it becomes a lot easier to figure out how to abstract out and refactor the common parts.

Game engine design is not easy. If you really want to get into it, study open source game engines such as OGRE and Crystal Space.

Share this post


Link to post
Share on other sites
Did anyone know''s a homepage where you can learn how an engine is build up, and how to programm the engine? All the basic stuff to build a little engine, nothing fantastic.

Share this post


Link to post
Share on other sites
I agree with the AP, once you''ve made a few (simple) games it gets easier to understand how such a "game engine" should be constructed. And when you do get to that point make your *own* design, don''t add stuff because Carmack happens to use it....

On a more constructive note: use common sense...

Share this post


Link to post
Share on other sites
an easy way to find useful things to add is to take a few games you like, and look at the step by step prosesses they(probably) use. then compare the lists of prosesses and find mutual common opperations (which will turn out to be important in most games).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I got a book about game programming in 24 our,
it gives easy example''s for a game engine u should try it

Share this post


Link to post
Share on other sites
http://www.gamedev.net/reference/list.asp?categoryid=45#115

That should give u a head start; only problem is that he doesnt finish the game. Once your finished with it i suggust u go through the quake, quake 2, and wolfenstien code.

Share this post


Link to post
Share on other sites
Game engines are specific to the type of game, for example, FPS will have 3d map input as well as deep newtonian physics and collision detection, while strategy games will have heighmaps and, since they can just use the coordinates of the heightmap, the collision detection needs only be nominal.

Anyway, if you don''t already know how to program one, don''t program one! Do a few smaller projects and understanding will come!

Share this post


Link to post
Share on other sites
[caution]

I started a reply then got carried away here. So I go on about all sorts of random stuff. So my inital point may be completely lost by the end. So I guess reading more than once might be a good idea

[/caution]

the idea behind classes is to break code down into small manageable, and in perticular, reusable chunks.

doing:

quote:

Input
Graphics
Audio
Physics



doesn't really apply to those rules.
And in my opinion there should not be a 'physics section' to any engine. There should definitly be an object management system with space partitioing and the like, which lends itself quite easily to individual objects doing 'physics'. Object management is by far one of the most important components in any engine, and this covers far more than just if something is on screen or not.

There should be a rendering sub-system, thats a given, but it ideally should not be one giant class. The core can be (say, the code that actually does the rendering) but there should be very few, highly generic methods in there that do everything (eg, setup multitexturing, lighting, and draw a batch of tris). Then you can make helper classes that sit on top of this and use it, eg, vertex array objects, immediate-mode objects, which all act like you would expect but just access the generic methods.

Input is a realitivly small part of an engine. A generic base class that can be extended is all you really would need. The overall game logic object should create input objects as it sees fit (eg, a CMouse object, or whatnot).

Sound is harder. Depending how you do it, it can be very tricky to get right. But it will all boil down to a central sound engine and sound objects.

Overall, if you find you are making 'manager' objects, you need to re-think your design. A good example is I've seen people in the past planning to make things like particles managers, etc. All things should simply boil down to individual classes. (eg, Textures, particle shooters, lights, and whatnot). Most of these things need very little, if any 'managment' - all textures need is a hash table of all loaded textures, so you don't reload duplicates, and you can kill them all before the window gets killed. This can be static inside the Texture object, easy..... All you need for every game entity is just a list, and maybe a hash table for the named ones (ideally though you want space partitioning though).. Cameras arn't really objects, they are just matrices, so 'setCamera' can just take in a matrix, you could then later make a 'supercamera' class if you ever needed it.. etc.

Try not to overcomplicate things, and especially try not to bind yourself to anything, make things very simple to start with, with very simple, and highly generic and adaptable basic methods. No locking yourself down to this or that. And leave open the door for adding variations on each method you make (eg, the code that sets up textures/multi-texturing, you might want to later make a version that does shaders too).

Eg, all a renderer needs to do is:

set camera from a matrix and scene lighting
setup textures for rendering
setup object lights
render triangles from an array (with index), with a matrix
clear the screen and swap buffers

two most important:

store a group of triangles, their material, etc, for rendering
render all stored data to the screen

You can do _a_lot_ with those 7 methods. It's very flexible, and very powerful, and can be extended very easily. It's the basic structure I use.
For example;
say, you want to be able to render without writing to the depth buffer, but these things should be rendered after everything else is rendered (otherwise you get depth errors) - well, it's easy, just modify the method that renders all stored data so that it renders solid things first, then stuff that doesn't write depth. Done. The objects that make the render calls need not know.

yeah.

Build the building blocks simple and solid and the rest of the code you build on top of it won't fall down or have to prop itself up. If either happens, bang, your engine is dead or will need a major re-write.


and lastly:

the entities in your game world (eg, particles, models, whatnot) should NEVER have to know about any other entity, or engine state, etc (unless of couse they can collide with them or such) - a simple example is that some people will do:

void myEffect::render(CRenderer * renderer)
{
if (renderer->isFogEnabled())
renderer->disableFog();

renderer->setTexture(myTexture);

renderer->renderTriangles(myTriangles);
}

This is EXTREMLY BAD!

a)
it checks on states set by other objects (fog) - and what if you add a feature, eg, enableShader() - you then need to go through every single object you have and add 'if shader, disable shader' to all of them... Not good. And once again think about render order, this way does NOT account for it at all.

better:


void myEffect::render(CRenderer * renderer)
{
CRenderBatch batch;

batch.fog=true;
batch.fogColour=renderer->getEnvirontmentFogColour()*0.5;

batch.texture[0]=myTexture;
batch.texture[1]=myOtherTexture;
batch.textureMode[0]=Additive;

batch.vertexShader=myVS;

batch.triangleData=myTris;

batch.indexData=myTrisIndex;

batch.renderType=Triangles;

renderer->addRenderBatchToRenderQueue(batch);
}


Imagine now how much this system can be extended and how much easier bug fixing will be in the long run, consider also since it's a class, it's constructor can set useful and meaningful defaults... Sure it's more difficult to use now and harder to code... but after 1 year development??

| - My project website - | - email me - |

[edited by - RipTorn on February 22, 2004 5:20:55 AM]

Share this post


Link to post
Share on other sites
Okay i have only made a couple of Space invader games in Pascal but here is the struct idea

Basicly im gona briefly explain how to create a particle engine say just for smoke,fire,water,and the other effects(but we will be using bitmaps for the effects)

struct sParticle {

int x,y,z;
int frame;//if we are using a bitmap that is composed of
// diffrent frames - for animation
bool active;
}

say a unit is hit and u wanna do the explosion it will be like this
Particle[l].x = unit.x;
y = unit.y
z=z;
frame = 0;
active = true;

And then withing the main game loop you will have two procedures
calcParticle(); // Guess what we do here
drawParticle() //mmm
{
if active
{
BindTexture,DrawCube(remember you texture co-ordinates;


Here is procedure to draw a Part of a bitmap say like divide it into 8*8 sqaures and then draw sqaure 1

void drawSprite(int _x,int _y,int _xx,int _yy,int _z,int _dx,int _dy,int frame)
{

float dx,dy,mx,my,cy,cx;

dx = float(_dx);
dy = float(_dy);
mx = 1.0f/dx;
my = 1.0f/dy;

cx = float(frame%int(dx))/dx;
cy = float(frame/int(dy))/dy;

glBegin(GL_QUADS); // GL QUAD Built in COunter-Clockwise from bottom Left
glTexCoord2f(cx,1-cy-my);
glVertex3f( _x ,_y ,_z); // Bottom Left
glTexCoord2f(mx+cx,1-cy-my);
glVertex3f( _xx ,_y ,_z); // Bottom Right
glTexCoord2f(mx+cx,1.0f-cy);
glVertex3f( _xx ,_yy ,_z); // Top Right
glTexCoord2f(cx,1.0f-cy);
glVertex3f( _x, _yy,_z); // Top Left
glEnd;
}
}
}


usage:drawSprite(Particle.x-10,Particle[i].y-10,Particle[i].x+10,Particle[i].y+10,Particle[i].z,8,8,int(Particle[i].frame));

Share this post


Link to post
Share on other sites
hmm, for an engine, you don''t want just generic names. What if you wanted to have another DrawSprite function for the fires or something, and not just for the particle engine? Operator overloading will only get you so far before your code becomes unreadable.

Better is to make classes full of just function. It may look a little weird having something like CCAMERA Camera; at the start of the page but you might want to look at it like having several different files, one of them called Camera, and the functions in Camera-> concern the Camera.

So with a particle engine say, you might have a class like this:

class CPARTICLE
{
public:
CPARTICLE();
void CalcPaticle();
void DrawPaticle();
~CPARTICLE();
private:
int x,y,z;
int frame;//if we are using a bitmap that is composed of

// diffrent frames - for animation

bool active;
}


and you might have another one for font:

class CFONT
{
public:
CFONT();
bool InitFont(char * FontName, int FontSize);
void Write(char * WhatToWrite);
void ChangeFont(char * FontName, int FontSize);
void DeInitFont();
~CFONT();
private:
char * FontName;
int FontSize;
}

CFONT Font;


This isn''t a direct example or anything, I just did it off the top of my head thinking what I''d put in a font class. Anyway, you get the idea - you might have another class for Rendering, OpenGL, DirectX, Vectors, Matrices, Quaternions, Networking, Timer, BSP Maps, Half Life Models, Quake 3 Models, Ogg Vorbis, Wav, OpenAL, shadow volumes, heightmaps, bump mapping, pixel shading, vertex shading, portals, and alot more. You can''t just "divide the engine into different sections" as the engine is a collection of classes intertwined to help make a game. And if you don''t know how to do each one of the things above, don''t even start making a full game engine! If you don''t know how to do the AI for a basic game, don''t even start making a full game engine.

If you do, though, go ahead!

Share this post


Link to post
Share on other sites