betajaen
29-11-2007 19:40:48
I've decided to divert the future of NxOgre every so slightly. I love Ogre to pieces, I really do. But I think it's time NxOgre should reign over other rendering and game engines, not only that I don't think NxOgre should say how things should be rendered.
Inheritable Actors was the big thing of 3rd generation of NxOgre, but I don't feel it's enough. Today we have instancing and render call optimisation which can't fit into the Inheritable actor model, and what happens if you don't want to use a Node. Or you do, but you want to use your own SceneNode wrapper? You can't. Then you have specific things like cloth, or wheels which you have no control over.
So I introduce "Renderables"; NodeRenderable, AnimatedRenderable, MeshRenderable, VoxelRenderable and SpriteRenderable, small neat abstract classes which anything that needs to be rendered uses one of those. The implementation of those aren't up to NxOgre. NxOgre just uses them an expects them to be complete.
Sounds good so far? How do we control these Renderables, and how do make sure the Renderable I want is the one that the Actor uses? We use RenderSystems. They don't have to be as grand as a complete wrapper to a rendering engine, they can just be a simple wrapper for your special node class. Infact they don't even have to render, NodeRenderable could just append the position of the Actor to disk, or better still to a network library!
You with me so far? No? http://www.nxogre.org/NxOgreUML1.jpg
Anyway. With these new wonderful wrapped classes to handle the render specific things, what happens to Ogre? Well by the time NxOgre 1.5 is around, I wish to be able to compile NxOgre without a single reference to a Ogre header file or library, not have it in the linker settings. But replace it with a DLL; just like DirectX and OpenGL RenderSystems are with Ogre. Just think you could have NxOgre working with Gamebyro, or a little closer to home with NeoAxis.
For clarification, I am not "dropping" Ogre. I'm merley moving it aside a little so other rendering and game engines can have a go too. Ogre will always be the number one rendering engine for me, and the default Rendering System for NxOgre.
For a proof of concept, and to show it is going forward. In 20 minutes, I wrote a simple and very quick SceneRenderer and NodeRenderable for Irrlicht; the unspellable, games engine which many people compare Ogre to.
If you don't believe me; scroll down.
Questions, Comments? Complaints can be handed to NULL. And before anyone asks; The original body constructor remains, and always works with the default rendering system.
Inheritable Actors was the big thing of 3rd generation of NxOgre, but I don't feel it's enough. Today we have instancing and render call optimisation which can't fit into the Inheritable actor model, and what happens if you don't want to use a Node. Or you do, but you want to use your own SceneNode wrapper? You can't. Then you have specific things like cloth, or wheels which you have no control over.
So I introduce "Renderables"; NodeRenderable, AnimatedRenderable, MeshRenderable, VoxelRenderable and SpriteRenderable, small neat abstract classes which anything that needs to be rendered uses one of those. The implementation of those aren't up to NxOgre. NxOgre just uses them an expects them to be complete.
Sounds good so far? How do we control these Renderables, and how do make sure the Renderable I want is the one that the Actor uses? We use RenderSystems. They don't have to be as grand as a complete wrapper to a rendering engine, they can just be a simple wrapper for your special node class. Infact they don't even have to render, NodeRenderable could just append the position of the Actor to disk, or better still to a network library!
You with me so far? No? http://www.nxogre.org/NxOgreUML1.jpg
Anyway. With these new wonderful wrapped classes to handle the render specific things, what happens to Ogre? Well by the time NxOgre 1.5 is around, I wish to be able to compile NxOgre without a single reference to a Ogre header file or library, not have it in the linker settings. But replace it with a DLL; just like DirectX and OpenGL RenderSystems are with Ogre. Just think you could have NxOgre working with Gamebyro, or a little closer to home with NeoAxis.
For clarification, I am not "dropping" Ogre. I'm merley moving it aside a little so other rendering and game engines can have a go too. Ogre will always be the number one rendering engine for me, and the default Rendering System for NxOgre.
For a proof of concept, and to show it is going forward. In 20 minutes, I wrote a simple and very quick SceneRenderer and NodeRenderable for Irrlicht; the unspellable, games engine which many people compare Ogre to.
If you don't believe me; scroll down.
#include "Cake2Frosting.h"
#include <math.h>
#include <irrlicht.h>
using namespace NxOgre;
using namespace Ogre;
using namespace std;
using namespace irr;
IrrlichtDevice *device;
video::IVideoDriver* driver;
scene::ISceneManager* scenemgr;
scene::ICameraSceneNode* cameranode;
class ISceneRenderer;
class INodeRenderable : public NodeRenderable {
public:
INodeRenderable(NodeRenderableParams params, SceneRenderer* renderer)
: NodeRenderable(params, renderer) {
mNode = scenemgr->addAnimatedMeshSceneNode(scenemgr->getMesh(params.GraphicsModel.c_str()));
if (params.GraphicsModelMaterial.size() >= 1)
{
mNode->setMaterialTexture(0, driver->getTexture(params.GraphicsModelMaterial.c_str()));
mNode->setMaterialFlag(video::EMF_LIGHTING, false);
}
if (params.GraphicsModelScale != NxVec3(1,1,1))
{
mNode->setScale(core::vector3df(params.GraphicsModelScale.x, params.GraphicsModelScale.y, params.GraphicsModelScale.z));
}
}
~INodeRenderable() {
}
void setPose(const NxOgre::Pose& p) {
mNode->setPosition(core::vector3df(p.v.x, p.v.y, p.v.z));
}
NxOgre::Pose getPose() const {
NxOgre::Pose p;
core::vector3df np = mNode->getPosition();
p.v.x = np.X;
p.v.y = np.Y;
p.v.z = np.Z;
core::vector3df nr = mNode->getRotation();
Ogre::Vector3 v(nr.X, nr.Y, nr.Z);
p.q = NxConvert<NxQuat, Ogre::Quaternion>(Ogre::Quaternion(&v));
return p;
}
void setMaterial(const NxString&) {}
NxString getMaterial() const {return "";}
void setScale(const Ogre::Vector3&) {}
void setScale(const NxVec3&) {}
Ogre::Vector3 getScale() const {return Vector3(0,0,0);}
NxVec3 getScaleAsNxVec3() const {return NxVec3(0,0,0);}
void setOffset(const NxOgre::Pose&) {}
NxOgre::Pose getOffset() const {return NxOgre::Pose();}
NxString getType() {return "Irrlicht-NodeRenderable";}
NxShortHashIdentifier getHashType() const {return 51418;}
protected:
scene::IAnimatedMeshSceneNode* mNode;
irr::scene::ISceneManager* mSceneMgr;
private:
};
class ISceneRenderer : public SceneRenderer {
friend class Scene;
public:
ISceneRenderer(Scene* s) : SceneRenderer(s) {
}
~ISceneRenderer() {
}
NodeRenderable* createNodeRenderable(NodeRenderableParams params) {
INodeRenderable* renderable = new INodeRenderable(params, this);
return renderable;
}
private:
};
class Sponge_Cake : public Cake {
public:
World* mWorld;
Scene* mScene;
void createPhysics() {
// start up the engine
device = createDevice(video::EDT_DIRECT3D8, core::dimension2d<s32>(640,480));
driver = device->getVideoDriver();
scenemgr = device->getSceneManager();
device->setWindowCaption(L"Cake2 Irrlicht Version Powered by NxOgre");
cameranode = scenemgr->addCameraSceneNode();
mWorld = new World("log: html");
mScene = mWorld->createScene("Main", mSceneMgr, "gravity: yes, floor: yes, controller: fixed, renderer: null");//, time-step-method: async");
mScene->setSceneRenderer(new ISceneRenderer(mScene));
for (int i=0;i < 16;i++)
Body* b = mScene->createBody("cube", new CubeShape(1), Vector3(0,5 + i,float(i) * 0.01f), "model: cube.1m.mesh, material: sphere.jpg", "mass: 10");
}
void destroyPhysics() {
// delete device
device->drop();
delete mWorld;
}
void onFrame(float deltaTime) {
cameranode->setPosition(core::vector3df(mCamera->getPosition().x, mCamera->getPosition().y, mCamera->getPosition().z));
cameranode->setTarget(core::vector3df(0,2,0));
mCamera->lookAt(0,2,0);
driver->beginScene(true, true, video::SColor(255,0,0,255));
scenemgr->drawAll();
driver->endScene();
if (mKeyboard->isKeyDown(mKeys[AC_OPTION_1]) && mTargetActor) {
Actor* a = mTargetActor;
unselectTargetActor();
mTargetActor = 0;
mScene->destroyActor(a->getName());
}
}
BakeMyCake();
};
Questions, Comments? Complaints can be handed to NULL. And before anyone asks; The original body constructor remains, and always works with the default rendering system.