Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 


Submitted by Steve Streeting, posted on October 01, 2001




Image Description, by Steve Streeting



This image is from OGRE (Object Oriented Rendering Engine), which is a scene-oriented rendering engine written in C++ designed to make it easier and more intuitive for developers to produce games and demos utilising 3D hardware. The class library exposes a number of useful objects allowing you to create and manipulate a 3D environment, and render it to your specifications, whilst removing the unnecessary complexities of the underlying system libraries like Direct3D and OpenGL.

This image may not be too spectacular, but the idea is to show how easy it is to apply effects using the engine. This 2-layer, environment mapped, additive blended model is achieved using only 3 lines of code, starting with a simple base metal texture as loaded from the model:


mat->addTextureLayer("spheremap.png");
mat->getTextureLayer(1)->addEffect(Material::TextureLayer::ET_TEXCOORD_EFFECT,
                                   Material::TextureLayer::TTCE_ENVIRONMENT_MAP);
mat->getTextureLayer(1)->setColourOperation(BO_ADD);

This adds a second environment mapped texture layer, blends it over the static blue metal texture and OGRE handles the most efficient use of texture units, minimised render state changes and everything else for you.

There is still plenty to do to the engine but it is designed to be platform, API and genre independent, but with specific optimisations for the task at hand implemented underneath the surface based on the API or hints given by the application user (e.g. asking to start an indoor-based scene silently uses a BSP/portal oriented version of scene management).

The engine is still under development, so don't tell me it's missing stuff, I know. However it's structure and design make it extremely effective, and once all the features are in place I think it will have a lot more versatility than engines designed around a single API or rendering approach.

Take a look at the site at http://ogre.sourceforge.net, CVS is being constantly updated, Quake3 and particle support is currently under development.


[prev]
Image of the Day Gallery
www.flipcode.com

[next]

 
Message Center / Reader Comments: ( To Participate in the Discussion, Join the Community )
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
Daan Nusman

October 01, 2001, 10:31 AM

Dig! I've been working with scene-oriented stuff too. Three lines to implement a blending mode: very cool! But what if the 3D card doesn't handle this kind of blending?

I like the torus knot too: my fave test object :)

I think it will be very difficult to keep it as generic as you describe, but I wish you the best of luck anyhow :-)

Daan.

 
bwalmisley

October 01, 2001, 10:34 AM

I would like to know how OGRE handles the fallback cases. If it can handle them elegantly I would REALLY REALLY like to see the material/texture handling stuff seperated out into a seperate library. (So us peeps with an existing engine can use OGREs smart stuff)

Benedict

 
Rasmus Christian Kaae

October 01, 2001, 10:53 AM

I use the following way to do much the same :

first i have a material class :

// kaae@daimi.au.dk
#pragma once

#include "textureimage.h"

class Material
{
protected:
enum
{
RENDER_TEXTUREMAP,
RENDER_ENVMAP,
RENDER_WIRE,
RENDER_PARTICLE,
RENDER_FLAT,
RENDER_TRANSPARENT,
RENDER_TRANSPARENT_ADDITIV,
RENDER_ALPHA_MASK,
RENDER_SEE_THROUGH,
CULL_FRONT,
CULL_BACK,
CULL_NONE
};

char RenderTexturemap;
char RenderEnvmap;
char RenderWire;
char RenderParticle;
char RenderFlat;
char RenderTransparent;
char RenderTransparentAdditiv;
char RenderAlphaMask;
char RenderSeeThrough;
char CullFront, CullBack, CullNone;

float *SolidColor; // rgba
float *WireColor;

float ParticleSize;

TextureImage *Texture;
TextureImage *Envmap;

public:
Material();

void Enable(int what); // enable one of the RENDER_? features
void Disable(int what); // disable - - - - -

void SetSolidColor(float r, float g, float b, float a); // set the solid color for this material

void SetWireColor(float r, float g, float b, float a);

void SetTexture(TextureImage *texture); // set texture
void SetEnvmap(TextureImage *envmap); // set envmap


void SetParticleSize(float s);

friend class Object;
};





secondly i (ofcourse) have my object class :

// kaae@daimi.au.dk
#pragma once

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "vector.h"
#include "material.h"
#include "texturecoord.h"


class Object
{
protected:
int displaylist;


Vector *normals;
Vector *vertices;
TextureCoord *mapping;
unsigned long numVertices;

unsigned long *faces;
unsigned long numFaces;
Vector *faceNormals;

Material *material;

Vector pivot;
Vector rotation;
Vector translate;


struct _bbox
{
Vector min, max;
} BoundingBox;

struct _bsphere
{
Vector center;
float radius;
} BoundingSphere;


Vector scale;

char name[255];
public:

Object();
Object(unsigned long nverts, unsigned long nfaces);

~Object();


void Clone(Object *o); // copy another object


void Allocate(unsigned long nverts, unsigned long nfaces);

void CalcPivot(); // finds the center of this object

void SetPivot(Vector pivot); // sets - - - - -
void SetRotation(Vector rotation); // sets the rotation
void SetRotation(float rx, float ry, float rz); // - - -

void SetScale(Vector scale); // scaling
void SetScale(float sx, float sy, float sz);
void SetScale(float s);

void SetTranslation(Vector trans); // set translation point
void SetTranslation(float x, float y, float z); // - - -


void SetMaterial(Material *mat); // set the material
void virtual Paint(); // paint!

void SetName(char *name); // set this object's name
char NameEquals(char *name); // ask if this object's name is the same as input


void CalculateBoundingSphere(); // sphere ;-)

void PaintBoundingBox();
void CalculateBoundingBox();

void CalculateFaceNormals();
void CalculateNormals();

private:
void UploadVertices();

void virtual PaintTexture();
void virtual PaintEnvmap();
void virtual PaintTextureEnvmap();
void virtual PaintParticle();
void virtual PaintFlat();
void virtual PaintWire();

void EnableCulling();
void DisableCulling();

void EnableTransparency();
void DisableTransparency();

void EnableRotation();
void DisableRotation();

void EnableScaling();
void DisableScaling();

void EnableTranslation();
void DisableTranslation();

void EnableAlphaMask();
void DisableAlphaMask();

void EnableSeeThrough();
void DisableSeeThrough();
};





My object::paint() looks like this :

void Object::Paint()
{
if (material==NULL) return;

EnableCulling();
EnableTranslation();
EnableRotation();
EnableScaling();


if (material->RenderSeeThrough) EnableSeeThrough();

if (material->RenderAlphaMask) EnableAlphaMask();

if (material->RenderTransparent || material->RenderTransparentAdditiv) EnableTransparency();

if (material->RenderWire) PaintWire();

if (material->RenderFlat) PaintFlat();

if (material->RenderTexturemap && material->RenderEnvmap) PaintTextureEnvmap();
else
{
if (material->RenderEnvmap) PaintEnvmap();
if (material->RenderTexturemap) PaintTexture();
}

if (material->RenderParticle) PaintParticle();

if (material->RenderTransparent || material->RenderTransparentAdditiv) DisableTransparency();

if (material->RenderAlphaMask) DisableAlphaMask();

if (material->RenderSeeThrough) DisableSeeThrough();

DisableScaling();
DisableRotation();
DisableTranslation();
DisableCulling();
}




And finally a little code snippet for using it :

...
Object *object = ObjectGenerator::Pyramid(Vector(0.0f,0.0f,0.0f), 50.0);
Material *material = new Material;
material->Enable(Material::RENDER_TEXTUREMAP);
material->Enable(Material::RENDER_ENVMAP);
material->Enable(Material::CULL_NONE);
material->Enable(Material::RENDER_TRANSPARENT);
material->SetTexture(TextureImage::DetectAndLoad("data/texture.jpg"));
material->SetTexture(TextureImage::DetectAndLoad("data/env.jpg"));
object->SetMaterial(material);
object->CalculateNormals();
...
while (1)
{
...
object->Paint();
...
}




i like it (sorry for the long post).

 
MdREV

October 01, 2001, 10:56 AM

Very nice... Don't be discouraged by the misbelief, C++ is the ideal tool for platform independance and optimisation if you make proper use of OO (And from your code sample it looks as though you have). I was tinkering with the idea of doing a C++ raytracing wrapper where you implemented the objects as derived classes, using a very similar ideology as you have adopted.

Keep up the good work, I'm sick of API's continually using 'C' or lazy, memory leaking, non-OO C++...

 
L.e.Denninger

October 01, 2001, 10:58 AM

I like the name, especially the way you abbreviate Object Orienter Rendering Engine (OORE) to OGRE :-)

 
Steve Streeting

October 01, 2001, 11:31 AM

If the card doesn't support the blending at all, you get the top-most texture layer. Otherwise if the card supports blending but for a subset of modes only, I believe the underlying API gives you the nearest available (I may be wrong here - I only have cards which support all or nowt!)

Keeping it generic is very tough, I'm doing my best but I bet people will find ways where it doesn't work. I'm interested to hear about these cases so I can factor it in to a later version.

Torus knots are just sweet for environment map effects, lots of sweeping normals. ;)

 
Steve Streeting

October 01, 2001, 11:36 AM

OGRE falls back nicely on cards with less than required numbers of texture units by just building up as many layers as there are units for each pass, terminating when it runs out of layers.

As I mentioned in my reply to the above post, lack of any blending modes on the card will result in the topmost layer being displayed (it just multi-passes from lowest to highest texture), I haven't implemented any smart software modes.

 
=[Scarab]=

October 01, 2001, 11:38 AM

LeD, at the site you can read that OGRE stands for Object-Oriented Graphics Rendering Engine so he obviously made a typo in his IOTD post. :)

Anyway, I like the image, and I like it even more that it takes only 3 lines!

 
Steve Streeting

October 01, 2001, 11:40 AM

You forgot 'Graphics' hence the 'G'. I pretended Object-oriented is one word if you use a hyphen, cos no-one knows what an OOGRE is. ;)

 
Steve Streeting

October 01, 2001, 11:57 AM

Oops, ok *I* forgot the 'Graphics' part in my original post. My bad. ;)

 
spikeD

October 01, 2001, 01:53 PM

I implemented materials using quake3-style textfile shaders. I also developed a MAX plug-in that automatically generates shader code and binds surfaces to materials. At loading time the shaders are interpreted and the layers are collapsed or removed matching graphics card capabilities. Clearly everything is done in a object oriented and platform independent way.
Obviously the coder can use C++ functions to add layers and set blending operations, but it's a little more complicated than the 3-lines method you describe. :-)

spikeD

 
dEViNiTY

October 01, 2001, 03:31 PM

not too spectacular image you say?
pah
i've always liked torus knots
don't forget the stencilbuffer shadow casting
i'm addicted to it

keep it up

Emil

 
masterpoi

October 01, 2001, 03:38 PM

What does the BSP-here variable do?

 
Octopussy

October 01, 2001, 05:02 PM

What kind of game do you plan to do with your library ?

 
elikez

October 01, 2001, 07:26 PM

Is it just me or did someone just posted the whole windows source code in the middle of this thread :(

Looks great, anyhow. I'd be happy to use it.

 
BigBen

October 01, 2001, 08:41 PM

WOW! IMPRESSIVE !!!
ITS REALLY AMAZING !!!

 
Prince

October 01, 2001, 10:57 PM

nt

 
Lion V

October 02, 2001, 02:36 AM

*sigh*

Thats intense.

 
Steve Streeting

October 02, 2001, 04:41 AM

I know you're referring to the code posted in the message rather than mine, but I think you'll find it's short for BoundingSphere rather han being BSP related.

BTW the classes starting with 'Bsp' in the OgreEngineIndoor module are work-in-progress implementations of BSP-based rendering, data being loaded from Quake3 files.

 
Steve Streeting

October 02, 2001, 04:44 AM

I'm hoping other people will use it to make their own games/demos and feed back their experiences to me - I don't think I'll have time to develop the library and build a game with it as well. I'll obviously be producing test beds which will have game-like features just to test that my ideas work, but a full game is probably out of the question in the short term.

I hope to find time to build a demo with it later on though.

 
Tammo Hinrichs

October 02, 2001, 06:43 AM

And all that you do with it are CUBES... coool :)

kb
http://kebby.org

 
Rasmus Christian Kaae

October 03, 2001, 07:28 AM

and hairballs for tp2001 ;-)

 
This thread contains 22 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.