Skip to main content
gamedev.net
🔒 Locked

RenderAble?

Started by McZ Nov 24, 2003 at 12:55 PM 10 replies 1.8k views
Original Post
McZ
McZ
I have created some classes for my engine cMoveAble - everything that I need to move an object in 3D-Space cRenderAble - everything that my RenderSystem need to render an object cEntity - an object in my scenegraph at the moment my renderable class is inherited from my moveable class and my Entity class is inherited from my renderable class my cWorld class has the SceneGraph and search through it for visible objects (as cEntity) the cEntity has an Update Function to update the RenderAble-class for the renderer (needs update every frame if it is an animated mesh) and then sends them to my RenderSystem (as a cRenderAble) then the rendersystem render the RenderAble item in it''s own way becouse the RenderAble class has it''s own VertexBuffer for the current mesh that is supposed to be processed.. the problem is that I can''t create a Static/non-moveable but still it should be a RenderAble object in my system or a MoveAble object but not a RenderAble how do can I sort this kind of problem?
jamessharpe
jamessharpe
The system is fine, it''s just you''re thinking of the concepts wrongly. Think of the moveable class as just providing the model matrix for rendering, by moving an object all you are essentially doing is transforming it by a matrix.

Now even static objects will have a position and orientation, so you can think of your moveable class as an interface to be able to position(and in only some cases move) the renderable object.

The other way to do it is not use inheritance for the renderable object. Have Entity derive directly from Moveable and then provide a method that returns a renderable object, filled with the appropriate data. This will enable you to create a moveable object which is not renderable.

James
davidino79
davidino79
ohh..I saw you have read the ogre source engine.... :-)

a little question for you...where you put the data structure for the rigid moving objects?

bye Davide
McZ
McZ
jamessharpe: if you say it is fine then I keep it this way


quote:
Original post by davidino79
ohh..I saw you have read the ogre source engine.... :-)

a little question for you...where you put the data structure for the rigid moving objects?

bye Davide


well... I have stolen some ideas from that engine although I changed them so that they would fit my own engine.

Data structure?! well.. the cMoveAble class is an Abstract class so you have to derive a new class from it to use it, at the moment my cRenderAble class derives from it and in that class I have a cVertexBuffer for vertex,normal,texcoord storage and a cMaterial class with material properties for the mesh current to be render at the current frame ( if it is an animated mesh it will be updated every frame ) and then my cRenderAble class is also an abstract class wich I have to derive anoter class that providing me with the data of the mesh and a function to fill the VertexBuffer...


class cMoveAble {
cMatrix Matrix;

public:
// functions to move the object

void Translate(void);
void Rotate(...);
...

cMatrix *GetMatrix(void); // return a pointer to the current matrix for this object, used in the RenderSystem to position the object in the world.

};

class cRenderAble : public cMoveAble {

cVertexBuffer *VertexBuffer; // VertexBuffer for vertexdata and so


cMaterial *Material; // The material to use for the above VB.


public:

// the RenderSystem calls this functions to render the mesh by setting the material and render the VertexBuffer

cVertexBuffer *GetVB(); // get a pointer to the VB

cMaterial *GetMaterial(); // get a pointer to the material

};

cEntity : public cRenderAble {

cMesh *Mesh; // This is a mesh loaded from disk, could be anything and stored in it''s own specefic way, but it must have a function to fill the VertexBuffer with the data to be sent to the render system for the current frame.


public:

void Update(void); // do some pre-render updates, like fill the VertexBuffer with new data for this frame ( if the mesh is animated, else it is done once )


};



then in my world class I go through the SceneGraph and send the visible objects to my RenderSystem Queue, the render system think they are of the class cRenderAble.

and my rendersystem then loops through the queue and set''s the material for the VertexBuffer and then sends the VB through the pipeline for rendering.

my engine is going to support for both Direct3D and OpenGL as a plugin-dll file, but so far I only have OpenGL running. the Direct3D version is at an early version, it can create a rendering context and render a singel triangle with the color blue, no texture and no lights no mather what I send to the queue. Not finished yet I will finish the OpenGL RenderSystem for my engine first.
Moagly
Moagly
Personally i think it would be better to have the dynamic object inherited from a static object, if you think about it a dynamic object has everything that a static object has, size, position, collision radius etc. but not vice versa the specialised class is the dynamic object, not the static object e.g.


-------------------
| STATIC OBJECT |
-------------------
| Position:CVector|
| CollRadis:float |
|-----------------|
| void render() |
| void update() |
| etc. etc. |
-------------------
|
|
\|/
---------------------------
| DYNAMIC OBJECT |
---------------------------
| Acceleration : CVector |
| Velocity : CVector |
| etc. |
---------------------------
| void integrate(float dt)|
| void applyForce( |
| etc. etc. |
---------------------------

Just a thought, but i think this is the better way of doing it!


jamessharpe
jamessharpe
That''s the kind of structure I would go for. As I said earlier the base class just provides a matrix for the rendering stage.
How this matrix is generated can be dependent upon the derived class. Another way would be to hold a pointer to a kinematics/dynamics struct. If this pointer is null, then it is static, if it is not then the object uses these atributes via the physics code to update the matrix returned from the base class. This isn''t the only way to do it, but once the ideas are there you can play around with it and see which method integrates into your code neatest. Don''t necessarily redesign everything just because of the suggestions we have made here.

James
davidino79
davidino79
I personally think that the difference beetwen a static model and a dinamic model is simply an "object" (ie bone) that can move it,so I''m thinking to move an model only if it has one bone attached that can move it.
Obviusly the only means to apply a fisic entity (like a force) to an object is to apply them to bone!

bye Davide
McZ
McZ
I don''t really know how to implement the bone force thing becouse I can''t understand it yet..

but the static and dynamic object will be based on the same one and use an Update() function that updates the VertexBuffer in that function it check''s if there is any data that is needed for an animated mesh if there is it will update the VB as needed for the mesh else it just skip that.
Vich
Vich
I would apply the vector class different: why don't you just use a templatized class, so you can apply any kind of vector:

CVector3D<int> a;
CVector3D<float> a;
CVector3D<double> a;


This way, you can use any kind of coordinate system



"My basic needs in life are food, love and a C++ compiler"
[Project AlterNova] [Novanet]


[edited by - Vich on November 27, 2003 4:33:05 AM]
[www.LifeIsDigital.net - My open source projects and articles.
snk_kid
snk_kid
quote:
Original post by McZ
jamessharpe: if you say it is fine then I keep it this way


quote:
Original post by davidino79
ohh..I saw you have read the ogre source engine.... :-)

a little question for you...where you put the data structure for the rigid moving objects?

bye Davide


quote:

well... I have stolen some ideas from that engine although I changed them so that they would fit my own engine.

Data structure?! well.. the cMoveAble class is an Abstract class so you have to derive a new class from it to use it, at the moment my cRenderAble class derives from it and in that class I have a cVertexBuffer for vertex,normal,texcoord storage and a cMaterial class with material properties for the mesh current to be render at the current frame ( if it is an animated mesh it will be updated every frame ) and then my cRenderAble class is also an abstract class wich I have to derive anoter class that providing me with the data of the mesh and a function to fill the VertexBuffer...


class cMoveAble {
cMatrix Matrix;

public:
// functions to move the object

void Translate(void);
void Rotate(...);
...

cMatrix *GetMatrix(void); // return a pointer to the current matrix for this object, used in the RenderSystem to position the object in the world.

};

class cRenderAble : public cMoveAble {

cVertexBuffer *VertexBuffer; // VertexBuffer for vertexdata and so


cMaterial *Material; // The material to use for the above VB.


public:

// the RenderSystem calls this functions to render the mesh by setting the material and render the VertexBuffer

cVertexBuffer *GetVB(); // get a pointer to the VB

cMaterial *GetMaterial(); // get a pointer to the material

};

cEntity : public cRenderAble {

cMesh *Mesh; // This is a mesh loaded from disk, could be anything and stored in it's own specefic way, but it must have a function to fill the VertexBuffer with the data to be sent to the render system for the current frame.


public:

void Update(void); // do some pre-render updates, like fill the VertexBuffer with new data for this frame ( if the mesh is animated, else it is done once )


};



then in my world class I go through the SceneGraph and send the visible objects to my RenderSystem Queue, the render system think they are of the class cRenderAble.

and my rendersystem then loops through the queue and set's the material for the VertexBuffer and then sends the VB through the pipeline for rendering.

my engine is going to support for both Direct3D and OpenGL as a plugin-dll file, but so far I only have OpenGL running. the Direct3D version is at an early version, it can create a rendering context and render a singel triangle with the color blue, no texture and no lights no mather what I send to the queue. Not finished yet I will finish the OpenGL RenderSystem for my engine first.



I think multiple type inheritance would be far better and cleaner. Moveable and Rendable sounds more like interface types so in C++ i would make those classes pure abstract types and have an implementing abstract class for code reuse so taking your code and rearranging a couple of things and adding one more class i would do something like this:



//Interface Type: IMoveable

class IMoveable {
public:
virtual void Translate(void) = 0;
virtual void Rotate(...) = 0;
....
virtual ~Moveable() { };
};

//Interface Type: IRenderable

class IRenderable {
public:
virtual void render() = 0; //or draw

virtual ~Renderable() { };
};

//Abstract implementing class for code reuse

class AbstractModel : public virtual IRenderable, public virtual IMoveable {
public:
//Methods implemented from Moveable

virtual void Translate(void);
virtual void Rotate(...);
....

//Methods implemented from Renderable

virtual void render(); //or draw


//New Methods for the Model

virtual cVertexBuffer *GetVB();
virtual cMaterial *GetMaterial();
virtual cMatrix *GetMatrix();
virtual void update(long elapsedTime);

virtual ~Model() {
delete VertexBuffer;
delete Material;
delete Mesh;
}

protected:
cVertexBuffer *VertexBuffer;
cMaterial *Material;
cMesh *Mesh;
};

//Contrete type can re - use or override Mode Methods

class Entity : public AbstractModel {
// do something here i guess ;-)

};


That seems much more cleaner and more extensiable but its just my personnal opinion.

[edited by - snk_kid on December 1, 2003 4:06:32 AM]
jamessharpe
jamessharpe
The thing is though that a renderable object has to have a position by it''s very nature - it needs a matrix to set where it is relative to the rest of the world. There is no point in making movable an abstract base class and implementing the methods in the derived class, since the methods of movement will always be the same - why would you want to implement different ways of translating or rotating an object? That would just be messy.

With your method, the renderer would have to take AbstractModel as its primitive. What about things that are renderable like text or GUI elements - these aren''t exactly abstract models now are they? Okay you could have seperate methods for these cases, but that''s hardly a unified interface which is what we are ultimately aiming for.

By the way in your implementation you make some of the methods virtual that don''t need to be e.g. GetMaterial doesn''t need to be it just needs to return a pointer to the protected material pointer. Then derived classes set up the material through the pointer.

Of course I''m not saying that your method is totally wrong, its just you have missed some slight properties of the data you are dealing with that could be small stumbling blocks in the design later on.

James

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.