Cool effects with "render to texture" :)

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Cool effects with "render to texture" :)

Post by Kencho »

Here are a couple of samples I did this morning:
Motion blur

Code: Select all

#include "Ogre.h"

#include "ExampleApplication.h"

AnimationState* mAnimState;

// Event handler 
class CameraTrackListener: public ExampleFrameListener
{
protected:
public:
    CameraTrackListener(RenderWindow* win, Camera* cam)
        : ExampleFrameListener(win, cam)
    {
    }

    bool frameStarted(const FrameEvent& evt)
    {

        mAnimState->addTime(evt.timeSinceLastFrame);

        // Call default
        return ExampleFrameListener::frameStarted(evt);
        

    }
};

class CameraTrackApplication : public ExampleApplication
{
public:
    CameraTrackApplication() {
    

    
    }

    ~CameraTrackApplication() {  }

protected:
    #define RTTSIZE 1024

    SceneNode* mFountainNode;

    // Just override the mandatory create scene method
    void createScene(void)
    {
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));

        // Create a skydome
        mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

        // Create a light
        Light* l = mSceneMgr->createLight("MainLight");
        // Accept default settings: point light, white diffuse, just set position
        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
        //  other objects, but I don't
        l->setPosition(20,80,50);

        Entity *ent;

        // Define a floor plane mesh
        Plane p;
        p.normal = Vector3::UNIT_Y;
        p.d = 200;
        MeshManager::getSingleton().createPlane("FloorPlane",p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z);

        // Create an entity (the floor)
        ent = mSceneMgr->createEntity("floor", "FloorPlane");
        ent->setMaterialName("Examples/RustySteel");
        // Attach to child of root node, better for culling (otherwise bounds are the combination of the 2)
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

        // Add a head, give it it's own node
        SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
        ent = mSceneMgr->createEntity("head", "ogrehead.mesh");
        headNode->attachObject(ent);

        // Make sure the camera track this node
        mCamera->setAutoTracking(true, headNode);

        // Create the camera node & attach camera
        SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
        camNode->attachObject(mCamera);

        // set up spline animation of node
        Animation* anim = mSceneMgr->createAnimation("CameraTrack", 10);
        // Spline it for nice curves
        anim->setInterpolationMode(Animation::IM_SPLINE);
        // Create a track to animate the camera's node
        AnimationTrack* track = anim->createTrack(0, camNode);
        // Setup keyframes
        KeyFrame* key = track->createKeyFrame(0); // startposition
        key = track->createKeyFrame(2.5);
        key->setTranslate(Vector3(500,500,-1000));
        key = track->createKeyFrame(5);
        key->setTranslate(Vector3(-1500,1000,-600));
        key = track->createKeyFrame(7.5);
        key->setTranslate(Vector3(0,-100,0));
        key = track->createKeyFrame(10);
        key->setTranslate(Vector3(0,0,0));
        // Create a new animation state to track this
        mAnimState = mSceneMgr->createAnimationState("CameraTrack");
        mAnimState->setEnabled(true);

        // Put in a bit of fog for the hell of it
        mSceneMgr->setFog(FOG_EXP, ColourValue::White, 0.0002);

        // Motion blur stuff :)
        RenderTexture *motionBlurTexture = mRoot->getRenderSystem ()->createRenderTexture ("MotionBlurTexture", RTTSIZE, RTTSIZE);
        motionBlurTexture->addViewport (mCamera);
        //motionBlurTexture->getViewport (0)->setOverlaysEnabled (false);
        Material *motionBlurMaterial = mSceneMgr->createMaterial ("MotionBlurMaterial");
        TextureUnitState *tUnit = motionBlurMaterial->getTechnique (0)->getPass (0)->createTextureUnitState ();
        tUnit->setTextureName ("MotionBlurTexture");
        tUnit->setAlphaOperation (LBX_BLEND_MANUAL, LBS_MANUAL, LBS_CURRENT, 0.8, 1, 1);
        motionBlurMaterial->setSceneBlending (SBT_TRANSPARENT_ALPHA);
        motionBlurMaterial->setDepthCheckEnabled (false);
        motionBlurMaterial->setDepthWriteEnabled (false);

        Overlay *motionBlurOverlay = mSceneMgr->createOverlay ("MotionBlurOverlay", 10);
        GuiElement *motionBlurPanel = GuiManager::getSingleton ().createGuiElement ("Panel", "MotionBlurPanel", false);
        motionBlurPanel->setMaterialName ("MotionBlurMaterial");
        motionBlurOverlay->add2D ((GuiContainer *)motionBlurPanel);
        motionBlurOverlay->show ();
        // End of motion blur :(
    }

    // Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new CameraTrackListener(mWindow, mCamera);
        mRoot->addFrameListener(mFrameListener);

    }


};



#if OGRE_PLATFORM == PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    CameraTrackApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif
    }


    return 0;
}
Depth of field (blurring when not focused)

Code: Select all

#include "Ogre.h"

#include "ExampleApplication.h"

AnimationState* mAnimState;

// Event handler 
class CameraTrackListener: public ExampleFrameListener
{
protected:
public:
    CameraTrackListener(RenderWindow* win, Camera* cam)
        : ExampleFrameListener(win, cam)
    {
    }

    bool frameStarted(const FrameEvent& evt)
    {

        mAnimState->addTime(evt.timeSinceLastFrame);

        // Call default
        return ExampleFrameListener::frameStarted(evt);
        

    }
};

class PlaneMover : public ControllerValue<Real>
{
protected:	
  SceneNode* mNode;
 	Real mHeight;
  Real mBaseHeight;
public:
  PlaneMover (SceneNode *node) {
    mNode = node;
    mBaseHeight = mNode->getPosition ().y;
  }
  virtual Real getValue (void) const {
    return mHeight;
  }
  virtual void setValue (Real value) {
    mHeight = value;
    mNode->setPosition (mNode->getPosition ().x, mBaseHeight + mHeight, mNode->getPosition ().z);
  }
};

class CameraTrackApplication : public ExampleApplication
{
public:
    CameraTrackApplication() {
    }

    ~CameraTrackApplication() {  }

protected:
    #define RTTSIZE 512
    #define JITTERRADIUS 4
    #define NUMJITTERS 3
    #define NUMRAZORS 30
    #define SQUADRONSIZE 2000

    SceneNode* mFountainNode;
    unsigned int i;

    // Just override the mandatory create scene method
    void createScene(void)
    {
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));

        // Create a skydome
        mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

        // Create a light
        Light* l = mSceneMgr->createLight("MainLight");
        // Accept default settings: point light, white diffuse, just set position
        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
        //  other objects, but I don't
        l->setPosition(20,80,50);
        l->setDirection (-100, -60, -30);
        l->setType (Light::LT_DIRECTIONAL);

        Entity *ent;

        // Define a floor plane mesh
        Plane p;
        p.normal = Vector3::UNIT_Y;
        p.d = 200;
        MeshManager::getSingleton().createPlane("FloorPlane",p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z);

        // Create an entity (the floor)
        ent = mSceneMgr->createEntity("floor", "FloorPlane");
        ent->setMaterialName("Examples/RustySteel");
        // Attach to child of root node, better for culling (otherwise bounds are the combination of the 2)
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

        // Add a head, give it it's own node
        SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3 (0, 0, -500));
        ent = mSceneMgr->createEntity("head", "razor.mesh");
        headNode->attachObject(ent);
        SceneNode *node;
        PlaneMover *mover;
        WaveformControllerFunction *moverFunction;
        Controller<Real> *controller;
        ControllerManager *mControllerManager = &ControllerManager::getSingleton ();
        for (i = 0; i < NUMRAZORS; i++) {
          ent = mSceneMgr->createEntity("razor" + StringConverter::toString (i), "razor.mesh");
          node = headNode->createChildSceneNode (Vector3 (Math::RangeRandom (-SQUADRONSIZE / 2.0, SQUADRONSIZE / 2.0), Math::RangeRandom (2 * SQUADRONSIZE / 3.0, 0), Math::RangeRandom (0, -SQUADRONSIZE)));
          node->attachObject(ent);
          mover = new PlaneMover (node);
          moverFunction = new WaveformControllerFunction (WFT_SINE, 0, Math::RangeRandom (0.01, 0.2), 0, 10);
          controller = mControllerManager->createController (mControllerManager->getFrameTimeSource (), mover, moverFunction);
        }

        // Make sure the camera track this node
        mCamera->setAutoTracking(true, headNode);

        // Create jittered cameras
        Camera *jitterCamera[NUMJITTERS];
        for (i = 0; i < NUMJITTERS; i++) {
          jitterCamera[i] = mSceneMgr->createCamera ("JitteredCamera" + StringConverter::toString (i));
          jitterCamera[i]->setPosition (mCamera->getDerivedPosition ());
          jitterCamera[i]->setAutoTracking (true, headNode);
        }

        mWindow->setPriority (100);

        // Create the camera node & attach camera
        SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
        camNode->attachObject(mCamera);

        SceneNode *jitterNode;
        for (i = 0; i < NUMJITTERS; i++) {
          jitterNode = camNode->createChildSceneNode ();
          Real angle = 2.0 * Math::PI * ((Real )i / (Real )NUMJITTERS);
          jitterNode->setPosition (Vector3 (Math::Cos (angle), Math::Sin (angle), 0.0) * (Real )JITTERRADIUS);
          jitterNode->attachObject (jitterCamera[i]);
          LogManager::getSingleton ().logMessage ("Jittered camera created at: " + StringConverter::toString (jitterNode->getPosition ()));
        }

        // set up spline animation of node
        Animation* anim = mSceneMgr->createAnimation("CameraTrack", 50);
        // Spline it for nice curves
        anim->setInterpolationMode(Animation::IM_SPLINE);
        // Create a track to animate the camera's node
        AnimationTrack* track = anim->createTrack(0, camNode);
        // Setup keyframes
        KeyFrame* key = track->createKeyFrame(0); // startposition
        key = track->createKeyFrame(12.5);
        key->setTranslate(Vector3(250,250,1000));
        key = track->createKeyFrame(25);
        key->setTranslate(Vector3(-1000,100,600));
        key = track->createKeyFrame(37.5);
        key->setTranslate(Vector3(0,-250,100));
        key = track->createKeyFrame(50);
        key->setTranslate(Vector3(0,0,0));
        // Create a new animation state to track this
        mAnimState = mSceneMgr->createAnimationState("CameraTrack");
        mAnimState->setEnabled(true);

        // Put in a bit of fog for the hell of it
        mSceneMgr->setFog(FOG_EXP, ColourValue::White, 0.0002);

        // Depth of field stuff :)
        RenderTexture *jitterTexture[NUMJITTERS];
        for (i = 0; i < NUMJITTERS; i++) {
          jitterTexture[i] = mRoot->getRenderSystem ()->createRenderTexture ("JitterTexture" + StringConverter::toString (i), RTTSIZE, RTTSIZE);
          jitterTexture[i]->addViewport (jitterCamera[i]);
          jitterTexture[i]->getViewport (0)->setOverlaysEnabled (false);
        }
        Material *depthOfFieldMaterial = mSceneMgr->createMaterial ("DepthOfFieldMaterial");
        TextureUnitState *tUnit;
        for (i = 0; i < NUMJITTERS; i++) {
          tUnit = depthOfFieldMaterial->getTechnique (0)->getPass (0)->createTextureUnitState ();
          tUnit->setTextureName ("JitterTexture" + StringConverter::toString (i));
          tUnit->setAlphaOperation (LBX_BLEND_MANUAL, LBS_MANUAL, LBS_CURRENT, 1.0 / (float )(NUMJITTERS+1), 1, 1);
          tUnit->setColourOperation (LBO_ALPHA_BLEND);
        }
        depthOfFieldMaterial->setSceneBlending (SBT_TRANSPARENT_ALPHA);
        depthOfFieldMaterial->setDepthCheckEnabled (false);
        depthOfFieldMaterial->setDepthWriteEnabled (false);

        Overlay *depthOfFieldOverlay = mSceneMgr->createOverlay ("DepthOfFieldOverlay", 10);
        GuiElement *depthOfFieldPanel = GuiManager::getSingleton ().createGuiElement ("Panel", "DepthOfFieldPanel", false);
        depthOfFieldPanel->setMaterialName ("DepthOfFieldMaterial");
        depthOfFieldOverlay->add2D ((GuiContainer *)depthOfFieldPanel);
        depthOfFieldOverlay->show ();
        // End of depth of field :(
    }

    void createCamera (void) {
        // Create the camera
        mCamera = mSceneMgr->createCamera("PlayerCam");

        mCamera->setPosition(Vector3(0,0,0));
    }

    // Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new CameraTrackListener(mWindow, mCamera);
        mRoot->addFrameListener(mFrameListener);

    }


};



#if OGRE_PLATFORM == PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    CameraTrackApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif
    }


    return 0;
}
They're (heavily) based on the "camera track" sample.

I know this thread is floody, and the samples (specially the DOF one) are slow... :cry:

I'm working on a coooool stereo 3D effect (red-blue glasses) :D

All of this apart of researching about shadows (don't worry, Sinbad :D)
Image
jeckil
Gnoblar
Posts: 9
Joined: Mon Feb 09, 2004 6:32 am
Location: Mexico City

Thank You!

Post by jeckil »

Hey dude thanks!. I was working at making these effects as well, looks like you beat me to them, thank you!

Many Regards
jeckil
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Post by jacmoe »

Kencho Rocks ! :D
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

I'm glad you like it guys 8)
I'm still having problems with stereo view (seems that I can't change colour to the materials I render to!!)
Image
_bad_camel

Post by _bad_camel »

Which version of Ogre did you do this with, CVS crashes quite badly?
jeckil
Gnoblar
Posts: 9
Joined: Mon Feb 09, 2004 6:32 am
Location: Mexico City

OpenGL compatibility

Post by jeckil »

for a strange reason the moment I change renderers from D3D9 to opengl the sample code doesnt work :O. On the motion blur sample I reduced the texture size to 512 and it fits almost completely on a 640x480 screen. how would i fit it on the screen?

On the depth of field sample I have no clue :(
help!?

many regards
jeckil
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

Well, I updated CVS for shadow support, so this should be the lates, I guess. Anyways, I did the same demo for version 0.11.0 (or maybe 12....) the one that added render to texture support...

About depth, I think any that handles blending... so 16, 24 or 32 should work...

About the opengl/dx problem... I guess it's because of the render to texture support (I know OpenGL can do it, as I did a couple of demos with these effects some time ago, but maybe this feature hasn't been added in the opengl plugin...)
Image
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

Well, I updated CVS for shadow support, so this should be the lates, I guess. Anyways, I did the same demo for version 0.11.0 (or maybe 12....) the one that added render to texture support...

About depth, I think any that handles blending... so 16, 24 or 32 should work...

About the opengl/dx problem... I guess it's because of the render to texture support (I know OpenGL can do it, as I did a couple of demos with these effects some time ago, but maybe this feature hasn't been added in the opengl plugin...)

About the size of the texture... well, you should just make some calculations about the size you'll need for textures at first (think that Depth of field with 1024 x 1024 and 4 jitters are 4096 x 4096 x 4 bytes!!!). Then, if you want the maximum resolution, then use the lowest of the greater power of two you want to use. For example, for 640x480 this would be 1024x512
Image
jeckil
Gnoblar
Posts: 9
Joined: Mon Feb 09, 2004 6:32 am
Location: Mexico City

Great!

Post by jeckil »

Thanks for the texture info Kencho, ill look be looking at the texture sizes soon. The bluring must look real neat with shadows on, cant wait for 0.14 to be final :D
User avatar
temas
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 390
Joined: Sun Oct 06, 2002 11:19 pm
Location: The Woodlands, TX

Post by temas »

post screenshots for those of us that are busy burying our heads in the engine ;)
User avatar
Borundin
Platinum Sponsor
Platinum Sponsor
Posts: 243
Joined: Fri Oct 03, 2003 5:57 am
Location: Sweden
x 2

Post by Borundin »

Yes, some screenshots please! Just to show the effects..
Image : Image
jeckil
Gnoblar
Posts: 9
Joined: Mon Feb 09, 2004 6:32 am
Location: Mexico City

my screenshot

Post by jeckil »

ok this is on a dualie 800 mac: running at about 30 fps: warning some have anomalies (TI4600)



I played around a bit with some samples just to see what would happen
Image

water demo
Image

People looking for fade outs Take note:I noticed that if you switch the screen to a black (say for example when you turn off the cubemap on the water demo), because of the motion blur you get a very smooth fade effect on the mac, can someone confirm on the pc?? it should work the same I gather...

Many thanks to kencho for the motion blur code :).

P.S. Depth of field is not shown cuz it cant get it to work on the mac :cry:
Last edited by jeckil on Thu Jul 08, 2004 5:12 am, edited 1 time in total.
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

Here goes some screens of the DOF effect (blurring unfocused objects):
Image
Image


About the blurring effect with motion blur, I have an explanation. This effect is based on render feedback, which means that then new image will be a combination of the actual image, and the previous one. If you don't clear the viewport background, then the viewport ALSO keeps the previous image, so you have a combination of the previous image, and... the previous image too! This should result in having a static image, but because of the texture resolution (the one you render to), the motion blur image becomes blurry, so it blurs slooooooowly.... ;)
(sorry for the speech, but it's needed to explain this :))
Image
User avatar
Antiarc
Greenskin
Posts: 120
Joined: Thu Jan 23, 2003 8:40 am

Post by Antiarc »

Very, very slick.

Keep this up and Sinbad's gonna be drowning in eye candy soon!
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

Thanks a lot for your support and feedback. I'm glad this is useful for you guys :D I hope to improve performace a little, at least :cry:
Image
supersuper
Greenskin
Posts: 114
Joined: Wed Feb 11, 2004 5:41 pm
Location: England!

Post by supersuper »

Kencho,

lovely demos u've posted! well done.

just one question, i think it's with the depth of field demo (just incase u wondering, i'm using DX9), if I use the arrow key to move forward, i can see the overlay of the plane (the one in focus) coming towards me. Dunno if you've seen it?

And is it possible to do all these effects without using the overlay? if so how? (should i be posting a new thread on the other forum)? :?
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

I didn't notice that, but you're right. Maybe the problem is that the main camera wasn't disabled (it's a "free pass", so I decided to leave it that way...).Anyways, these are examples of how it can be done.

About why I use overlays... well, what I want is to render the whole screen into a polygon that covers the whole screen also, so the best way is to use overlays. Anyways, the trick is using the render to texture feature, so you can use on tv screens, or anything else in your scenes, so it's ok. You and your imagination set the limits! :D
Image
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

Ok. I've solved some (serious) bugs, and added new features to the depth of field demo. Here is the code:

Code: Select all

#include "Ogre.h"

#include "ExampleApplication.h"

AnimationState* mAnimState;

#define RTTSIZE 512
#define JITTERRADIUS 4
#define NUMJITTERS 3
#define NUMRAZORS 30
#define SQUADRONSIZE 2000
#define FOCUSSPEED 12.0
#define MINFOCUS 100
#define MAXFOCUS 2000000l

// Event handler 
class CameraTrackListener: public ExampleFrameListener
{
protected:
  SceneNode **mPlane;
  SceneNode *mCameraTarget;
  unsigned int mCurrentPlane;
  SceneManager *mSceneMgr;
  bool mPaused;
  Overlay *mDebugOverlay;
  Vector3 mTarget;
public:
    CameraTrackListener(RenderWindow* win, Camera* cam, SceneNode **planes, SceneManager *sceneMgr, SceneNode *cameraTarget, Overlay *debugOverlay)
        : ExampleFrameListener(win, cam)
    {
      mPlane = planes;
      mCurrentPlane = 0;
      mSceneMgr = sceneMgr;
      mPaused = false;
      mCameraTarget = cameraTarget;
      mTimeUntilNextToggle = 0;
      mDebugOverlay = debugOverlay;
      mTarget = Vector3 (0, 0, 0);
    }

    bool frameStarted(const FrameEvent& evt)
    {
      if (ExampleFrameListener::frameStarted(evt)) {

        if (!mPaused) {
          mAnimState->addTime(evt.timeSinceLastFrame);
        }

        if (mInputDevice->isKeyDown (KC_V) && mTimeUntilNextToggle <= 0) {
          if (mDebugOverlay->isVisible ())
            mDebugOverlay->hide ();
          else
            mDebugOverlay->show ();

          mTimeUntilNextToggle = 0.5;
        }
        if (mInputDevice->isKeyDown (KC_PAUSE) && mTimeUntilNextToggle <= 0) {
          mPaused = !mPaused;

          mTimeUntilNextToggle = 0.3;
        }

        if (mInputDevice->isKeyDown (KC_TAB) && mTimeUntilNextToggle <= 0) {
          if (mInputDevice->isKeyDown (KC_LSHIFT) || mInputDevice->isKeyDown (KC_RSHIFT)) {
            mCurrentPlane = (mCurrentPlane - 1 + (NUMRAZORS + 1)) % (NUMRAZORS + 1);
          }
          else {
            mCurrentPlane = (mCurrentPlane + 1) % (NUMRAZORS + 1);
          }

          mTarget = mPlane[mCurrentPlane]->_getDerivedPosition ();

          mTimeUntilNextToggle = 0.2;
        }

        // Manual focusing adjust (cooool!!)
        if (mInputDevice->isKeyDown (KC_SUBTRACT)) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
/*
          targetingVector.normalise ();
          mTarget = mTarget - (targetingVector * 10);
*/
          mTarget = mCamera->getDerivedPosition () + targetingVector * 0.95;
        }
        if (mInputDevice->isKeyDown (KC_ADD)) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
/*
          targetingVector.normalise ();
          mTarget = mTarget + (targetingVector * 10);
*/
          mTarget = mCamera->getDerivedPosition () + targetingVector * 1.05;
        }
        // Limit focusing - both far and close
        if ((mCamera->getDerivedPosition () - mTarget).length () < JITTERRADIUS * MINFOCUS) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
          targetingVector.normalise ();
          mTarget = mCamera->getDerivedPosition () + targetingVector * JITTERRADIUS * MINFOCUS;
        }
        if ((mCamera->getDerivedPosition () - mTarget).length () > JITTERRADIUS * MAXFOCUS) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
          targetingVector.normalise ();
          mTarget = mCamera->getDerivedPosition () + targetingVector * JITTERRADIUS * MAXFOCUS;
        }

        // Try to focus the object
        mCameraTarget->setPosition (mCameraTarget->_getDerivedPosition () + (mTarget - mCameraTarget->_getDerivedPosition ()) / FOCUSSPEED);

        mWindow->setDebugText ("Selected razor: " + StringConverter::toString (mCurrentPlane + 1) + " out of " + StringConverter::toString (NUMRAZORS + 1) + " :: " + 
                               "Target distance: " + StringConverter::toString ((mTarget - mCamera->getDerivedPosition ()).length ()));
        // Call default
        return true;
      }
      return false;

    }
};

class PlaneMover : public ControllerValue<Real>
{
protected:	
  SceneNode* mNode;
 	Real mHeight;
  Real mBaseHeight;
public:
  PlaneMover (SceneNode *node) {
    mNode = node;
    mBaseHeight = mNode->getPosition ().y;
  }
  virtual Real getValue (void) const {
    return mHeight;
  }
  virtual void setValue (Real value) {
    mHeight = value;
    mNode->setPosition (mNode->getPosition ().x, mBaseHeight + mHeight, mNode->getPosition ().z);
  }
};

class CameraTrackApplication : public ExampleApplication
{
public:
    CameraTrackApplication() {
    }

    ~CameraTrackApplication() {  }

protected:
    SceneNode* mFountainNode;
    SceneNode *mCameraTarget;
    unsigned int i;
    SceneNode *mPlane[NUMRAZORS+1];
    Overlay *mDebugOverlay;

    // Just override the mandatory create scene method
    void createScene(void)
    {
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));

        // Create a skydome
        mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

        // Create a light
        Light* l = mSceneMgr->createLight("MainLight");
        // Accept default settings: point light, white diffuse, just set position
        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
        //  other objects, but I don't
        l->setPosition(20,80,50);
        l->setDirection (-100, -60, -30);
        l->setType (Light::LT_DIRECTIONAL);

        Entity *ent;

        // Define a floor plane mesh
        Plane p;
        p.normal = Vector3::UNIT_Y;
        p.d = 200;
        MeshManager::getSingleton().createPlane("FloorPlane",p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z);

        // Create an entity (the floor)
        ent = mSceneMgr->createEntity("floor", "FloorPlane");
        ent->setMaterialName("Examples/RustySteel");
        // Attach to child of root node, better for culling (otherwise bounds are the combination of the 2)
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

        // Create the camera target
        mCameraTarget = mSceneMgr->getRootSceneNode ()->createChildSceneNode ("CameraTarget");

        createPlanes ();

        // Make sure the camera track this node
        mCamera->setAutoTracking(true, mCameraTarget);

        mWindow->setPriority (100);

        // Create the camera node & attach camera
        SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
        camNode->attachObject(mCamera);

        // set up spline animation of node
        Animation* anim = mSceneMgr->createAnimation("CameraTrack", 120);
        // Spline it for nice curves
        anim->setInterpolationMode(Animation::IM_SPLINE);
        // Create a track to animate the camera's node
        AnimationTrack* track = anim->createTrack(0, camNode);
        // Setup keyframes
        KeyFrame* key;
        for (i = 0; i < 12; i++) {
          key = track->createKeyFrame(i * 10);
          key->setTranslate(Vector3(Math::RangeRandom (-SQUADRONSIZE, SQUADRONSIZE),Math::RangeRandom (0, SQUADRONSIZE),Math::RangeRandom (-2 * SQUADRONSIZE, SQUADRONSIZE)));
        }
        key = track->createKeyFrame(120);
        key->setTranslate(track->getKeyFrame (0)->getTranslate ());
        // Create a new animation state to track this
        mAnimState = mSceneMgr->createAnimationState("CameraTrack");
        mAnimState->setEnabled(true);

        // Put in a bit of fog for the hell of it
        mSceneMgr->setFog(FOG_EXP, ColourValue::White, 0.0002);

        // Depth of field stuff :)
        depthOfField (camNode);
    }

    void createCamera (void) {
        // Create the camera
        mCamera = mSceneMgr->createCamera("PlayerCam");

        mCamera->setPosition(Vector3(0,0,0));
    }

    // Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new CameraTrackListener(mWindow, mCamera, mPlane, mSceneMgr, mCameraTarget, mDebugOverlay);
        mRoot->addFrameListener(mFrameListener);
    }

  protected:
    void createPlanes (void) {
        Entity *ent;
        // Add a head, give it it's own node
        SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3 (0, 0, -500));
        ent = mSceneMgr->createEntity("head", "razor.mesh");
        headNode->attachObject(ent);
        mPlane[0] = headNode;
        SceneNode *node;
        PlaneMover *mover;
        WaveformControllerFunction *moverFunction;
        Controller<Real> *controller;
        ControllerManager *mControllerManager = &ControllerManager::getSingleton ();
        for (i = 0; i < NUMRAZORS; i++) {
          ent = mSceneMgr->createEntity("razor" + StringConverter::toString (i), "razor.mesh");
          // Uncomment ONE of these depending on the method you want to create the squadron
          node = headNode->createChildSceneNode (Vector3 (Math::RangeRandom (-SQUADRONSIZE / 2.0, SQUADRONSIZE / 2.0), Math::RangeRandom (2 * SQUADRONSIZE / 3.0, 0), Math::RangeRandom (0, -SQUADRONSIZE)));
//          node = headNode->createChildSceneNode (Vector3 (0, 0, (int )(i + 1) * -200));

          node->attachObject(ent);
          mPlane[i+1] = node;
          mover = new PlaneMover (node);
          moverFunction = new WaveformControllerFunction (WFT_SINE, 0, Math::RangeRandom (0.01, 0.2), 0, 10);
          controller = mControllerManager->createController (mControllerManager->getFrameTimeSource (), mover, moverFunction);
        }
    }

    void depthOfField (SceneNode *camNode) {
        // Create jittered cameras
        Camera *jitterCamera[NUMJITTERS];
        for (i = 0; i < NUMJITTERS; i++) {
          jitterCamera[i] = mSceneMgr->createCamera ("JitteredCamera" + StringConverter::toString (i));
          jitterCamera[i]->setPosition (mCamera->getDerivedPosition ());
          jitterCamera[i]->setAutoTracking (true, mCameraTarget);
        }

        SceneNode *jitterNode;
        for (i = 0; i < NUMJITTERS; i++) {
          jitterNode = camNode->createChildSceneNode ();
          Real angle = (Real )i * (2.0 * Math::PI / (Real )NUMJITTERS);
          jitterNode->attachObject (jitterCamera[i]);
          jitterNode->setPosition (Vector3 (Math::Cos (angle) * (Real )JITTERRADIUS, Math::Sin (angle) * (Real )JITTERRADIUS, 0.0));
          LogManager::getSingleton ().logMessage ("Jittered camera created at: " + StringConverter::toString (jitterNode->getPosition ()));
        }

        // Depth of field stuff :)
        RenderTexture *jitterTexture[NUMJITTERS];
        for (i = 0; i < NUMJITTERS; i++) {
          jitterTexture[i] = mRoot->getRenderSystem ()->createRenderTexture ("JitterTexture" + StringConverter::toString (i), RTTSIZE, RTTSIZE);
          jitterTexture[i]->removeAllViewports ();
          jitterTexture[i]->addViewport (jitterCamera[i], i)->setOverlaysEnabled (false);
          //jitterTexture[i]->getViewport (0)->setOverlaysEnabled (false);
        }
        Material *depthOfFieldMaterial;
        TextureUnitState *tUnit;
        for (i = 0; i < NUMJITTERS; i++) {
          depthOfFieldMaterial = mSceneMgr->createMaterial ("DepthOfFieldMaterial" + StringConverter::toString (i));
          tUnit = depthOfFieldMaterial->getTechnique (0)->getPass (0)->createTextureUnitState ();
          tUnit->setTextureName ("JitterTexture" + StringConverter::toString (i));
          tUnit->setAlphaOperation (LBX_BLEND_CURRENT_ALPHA, LBS_MANUAL, LBS_CURRENT, 1.0 / (float )(NUMJITTERS), 1.0 - 1.0 / (float )(NUMJITTERS), 1.0 / (float )(NUMJITTERS));
          depthOfFieldMaterial->setSceneBlending (SBT_TRANSPARENT_ALPHA);
          depthOfFieldMaterial->setDepthCheckEnabled (false);
          depthOfFieldMaterial->setDepthWriteEnabled (false);
        }

        Overlay *depthOfFieldOverlay = mSceneMgr->createOverlay ("DepthOfFieldOverlay", 10);
        for (i = 0; i < NUMJITTERS; i++) {
          GuiElement *depthOfFieldPanel = GuiManager::getSingleton ().createGuiElement ("Panel", "DepthOfFieldPanel" + StringConverter::toString (i), false);
          depthOfFieldPanel->setMaterialName ("DepthOfFieldMaterial" + StringConverter::toString (i));
          depthOfFieldOverlay->add2D ((GuiContainer *)depthOfFieldPanel);
        }
        depthOfFieldOverlay->show ();
        // End of depth of field :(

        // Debugging overlay
        mDebugOverlay = mSceneMgr->createOverlay ("DebugOverlay", 20);
        for (i = 0; i < NUMJITTERS; i++) {
          GuiElement *depthOfFieldPanel = GuiManager::getSingleton ().createGuiElement ("Panel", "DepthOfFieldDebugPanel" + StringConverter::toString (i), false);
          depthOfFieldPanel->setDimensions (1.0 / (int )NUMJITTERS, 1.0 / (int )NUMJITTERS);
          depthOfFieldPanel->setPosition (1.0 - 1.0 / (int )NUMJITTERS, i * 1.0 / (int )NUMJITTERS);
          depthOfFieldPanel->setMaterialName ("DepthOfFieldMaterial" + StringConverter::toString (i));
          mDebugOverlay->add2D ((GuiContainer *)depthOfFieldPanel);
        }
        // End of debugging overlay
    }
};



#if OGRE_PLATFORM == PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    CameraTrackApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif
    }


    return 0;
}
Notice that now I use one material instead of one layer per jittered camera, so also one PanelGuiElement each, too. About the blending mode take a look at the changes done in tUint->setAlphaOperation (...)
Some screenshots:
Image
Image
Image
Now, it features some keyboard commands:
- Pause key to pause/unpause the flying camera
- Tab/Shift+tab to target different planes/razors
- V to enable/disable a debug overlay (shows the rendering of each jittered camera separately)

Now it looks A LOT better :D
But there is still the glitch with skydomes (and I suppose skyboxes and skyplanes too... :?) I'll study this soon ;)
Enjoy!

EDIT: Now it handles also manual focusing with NumPad add/substract :)
Image
User avatar
japito
Halfling
Posts: 77
Joined: Mon Apr 26, 2004 11:01 pm
Location: In your MBR ... (sometimes in spain)

Post by japito »

This code causes lots of errors for me :(
ummmm emmmm estoooo.....
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179

Post by jacmoe »

japito wrote:This code causes lots of errors for me :(
Of course it does:
Posted: Tue Mar 30, 2004 5:32 pm
:)
This is nearly one year ago - so you have to rewrite it for Ogre 1.0.1 :wink:
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
User avatar
Emmeran
Goblin
Posts: 272
Joined: Wed Jun 02, 2004 11:47 am
Location: Erlangen

Post by Emmeran »

i did that so at least it works a bit

Code: Select all

#include "Ogre.h"

#include "ExampleApplication.h"

AnimationState* mAnimState;

#define RTTSIZE 512
#define JITTERRADIUS 4
#define NUMJITTERS 3
#define NUMRAZORS 30
#define SQUADRONSIZE 2000
#define FOCUSSPEED 12.0
#define MINFOCUS 100
#define MAXFOCUS 2000000l

// Event handler
class CameraTrackListener: public ExampleFrameListener
{
protected:
  SceneNode **mPlane;
  SceneNode *mCameraTarget;
  unsigned int mCurrentPlane;
  SceneManager *mSceneMgr;
  bool mPaused;
  Overlay *mDebugOverlay;
  Vector3 mTarget;
public:
    CameraTrackListener(RenderWindow* win, Camera* cam, SceneNode **planes, SceneManager *sceneMgr, SceneNode *cameraTarget, Overlay *debugOverlay)
        : ExampleFrameListener(win, cam)
    {
      mPlane = planes;
      mCurrentPlane = 0;
      mSceneMgr = sceneMgr;
      mPaused = false;
      mCameraTarget = cameraTarget;
      mTimeUntilNextToggle = 0;
      mDebugOverlay = debugOverlay;
      mTarget = Vector3 (0, 0, 0);
    }

    bool frameStarted(const FrameEvent& evt)
    {
      if (ExampleFrameListener::frameStarted(evt)) {

        if (!mPaused) {
          mAnimState->addTime(evt.timeSinceLastFrame);
        }

        if (mInputDevice->isKeyDown (KC_V) && mTimeUntilNextToggle <= 0) {
          if (mDebugOverlay->isVisible ())
            mDebugOverlay->hide ();
          else
            mDebugOverlay->show ();

          mTimeUntilNextToggle = 0.5;
        }
        if (mInputDevice->isKeyDown (KC_PAUSE) && mTimeUntilNextToggle <= 0) {
          mPaused = !mPaused;

          mTimeUntilNextToggle = 0.3;
        }

        if (mInputDevice->isKeyDown (KC_TAB) && mTimeUntilNextToggle <= 0) {
          if (mInputDevice->isKeyDown (KC_LSHIFT) || mInputDevice->isKeyDown (KC_RSHIFT)) {
            mCurrentPlane = (mCurrentPlane - 1 + (NUMRAZORS + 1)) % (NUMRAZORS + 1);
          }
          else {
            mCurrentPlane = (mCurrentPlane + 1) % (NUMRAZORS + 1);
          }

          mTarget = mPlane[mCurrentPlane]->_getDerivedPosition ();

          mTimeUntilNextToggle = 0.2;
        }

        // Manual focusing adjust (cooool!!)
        if (mInputDevice->isKeyDown (KC_SUBTRACT)) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
/*
          targetingVector.normalise ();
          mTarget = mTarget - (targetingVector * 10);
*/
          mTarget = mCamera->getDerivedPosition () + targetingVector * 0.95;
        }
        if (mInputDevice->isKeyDown (KC_ADD)) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
/*
          targetingVector.normalise ();
          mTarget = mTarget + (targetingVector * 10);
*/
          mTarget = mCamera->getDerivedPosition () + targetingVector * 1.05;
        }
        // Limit focusing - both far and close
        if ((mCamera->getDerivedPosition () - mTarget).length () < JITTERRADIUS * MINFOCUS) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
          targetingVector.normalise ();
          mTarget = mCamera->getDerivedPosition () + targetingVector * JITTERRADIUS * MINFOCUS;
        }
        if ((mCamera->getDerivedPosition () - mTarget).length () > JITTERRADIUS * MAXFOCUS) {
          Vector3 targetingVector = mTarget - mCamera->getDerivedPosition ();
          targetingVector.normalise ();
          mTarget = mCamera->getDerivedPosition () + targetingVector * JITTERRADIUS * MAXFOCUS;
        }

        // Try to focus the object
        mCameraTarget->setPosition (mCameraTarget->_getDerivedPosition () + (mTarget - mCameraTarget->_getDerivedPosition ()) / FOCUSSPEED);

        mWindow->setDebugText ("Selected razor: " + StringConverter::toString (mCurrentPlane + 1) + " out of " + StringConverter::toString (NUMRAZORS + 1) + " :: " +
                               "Target distance: " + StringConverter::toString ((mTarget - mCamera->getDerivedPosition ()).length ()));
        // Call default
        return true;
      }
      return false;

    }
};

class PlaneMover : public ControllerValue<Real>
{
protected:   
  SceneNode* mNode;
    Real mHeight;
  Real mBaseHeight;
public:
  PlaneMover (SceneNode *node) {
    mNode = node;
    mBaseHeight = mNode->getPosition ().y;
  }
  virtual Real getValue (void) const {
    return mHeight;
  }
  virtual void setValue (Real value) {
    mHeight = value;
    mNode->setPosition (mNode->getPosition ().x, mBaseHeight + mHeight, mNode->getPosition ().z);
  }
};

class CameraTrackApplication : public ExampleApplication
{
public:
    CameraTrackApplication() {
    }

    ~CameraTrackApplication() {  }

protected:
    SceneNode* mFountainNode;
    SceneNode *mCameraTarget;
    unsigned int i;
    SceneNode *mPlane[NUMRAZORS+1];
    Overlay *mDebugOverlay;

    // Just override the mandatory create scene method
    void createScene(void)
    {
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));

        // Create a skydome
        mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

        // Create a light
        Light* l = mSceneMgr->createLight("MainLight");
        // Accept default settings: point light, white diffuse, just set position
        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
        //  other objects, but I don't
        l->setPosition(20,80,50);
        l->setDirection (-100, -60, -30);
        l->setType (Light::LT_DIRECTIONAL);

        Entity *ent;

        // Define a floor plane mesh
        Plane p;
        p.normal = Vector3::UNIT_Y;
        p.d = 200;
        MeshManager::getSingleton().createPlane("FloorPlane","Main",p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z);

        // Create an entity (the floor)
        ent = mSceneMgr->createEntity("floor", "FloorPlane");
        ent->setMaterialName("Examples/RustySteel");
        // Attach to child of root node, better for culling (otherwise bounds are the combination of the 2)
        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

        // Create the camera target
        mCameraTarget = mSceneMgr->getRootSceneNode ()->createChildSceneNode ("CameraTarget");

        createPlanes ();

        // Make sure the camera track this node
        mCamera->setAutoTracking(true, mCameraTarget);

        mWindow->setPriority (100);

        // Create the camera node & attach camera
        SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
        camNode->attachObject(mCamera);

        // set up spline animation of node
        Animation* anim = mSceneMgr->createAnimation("CameraTrack", 120);
        // Spline it for nice curves
        anim->setInterpolationMode(Animation::IM_SPLINE);
        // Create a track to animate the camera's node
        AnimationTrack* track = anim->createTrack(0, camNode);
        // Setup keyframes
        KeyFrame* key;
        for (i = 0; i < 12; i++) {
          key = track->createKeyFrame(i * 10);
          key->setTranslate(Vector3(Math::RangeRandom (-SQUADRONSIZE, SQUADRONSIZE),Math::RangeRandom (0, SQUADRONSIZE),Math::RangeRandom (-2 * SQUADRONSIZE, SQUADRONSIZE)));
        }
        key = track->createKeyFrame(120);
        key->setTranslate(track->getKeyFrame (0)->getTranslate ());
        // Create a new animation state to track this
        mAnimState = mSceneMgr->createAnimationState("CameraTrack");
        mAnimState->setEnabled(true);

        // Put in a bit of fog for the hell of it
        mSceneMgr->setFog(FOG_EXP, ColourValue::White, 0.0002);

        // Depth of field stuff :)
        depthOfField (camNode);
    }

    void createCamera (void) {
        // Create the camera
        mCamera = mSceneMgr->createCamera("PlayerCam");

        mCamera->setPosition(Vector3(0,0,0));
    }

    // Create new frame listener
    void createFrameListener(void)
    {
        mFrameListener= new CameraTrackListener(mWindow, mCamera, mPlane, mSceneMgr, mCameraTarget, mDebugOverlay);
        mRoot->addFrameListener(mFrameListener);
    }

  protected:
    void createPlanes (void) {
        Entity *ent;
        // Add a head, give it it's own node
        SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3 (0, 0, -500));
        ent = mSceneMgr->createEntity("head", "razor.mesh");
        headNode->attachObject(ent);
        mPlane[0] = headNode;
        SceneNode *node;
        PlaneMover *mover;
        WaveformControllerFunction *moverFunction;
        Controller<Real> *controller;
        ControllerManager *mControllerManager = &ControllerManager::getSingleton ();
        for (i = 0; i < NUMRAZORS; i++) {
          ent = mSceneMgr->createEntity("razor" + StringConverter::toString (i), "razor.mesh");
          // Uncomment ONE of these depending on the method you want to create the squadron
          node = headNode->createChildSceneNode (Vector3 (Math::RangeRandom (-SQUADRONSIZE / 2.0, SQUADRONSIZE / 2.0), Math::RangeRandom (2 * SQUADRONSIZE / 3.0, 0), Math::RangeRandom (0, -SQUADRONSIZE)));
//          node = headNode->createChildSceneNode (Vector3 (0, 0, (int )(i + 1) * -200));

          node->attachObject(ent);
          mPlane[i+1] = node;
          mover = new PlaneMover (node);
          moverFunction = new WaveformControllerFunction (WFT_SINE, 0, Math::RangeRandom (0.01, 0.2), 0, 10);
          controller = mControllerManager->createController (mControllerManager->getFrameTimeSource (), (ControllerValueRealPtr)mover, (ControllerFunctionRealPtr)moverFunction);
        }
    }

    void depthOfField (SceneNode *camNode) {
        // Create jittered cameras
        Camera *jitterCamera[NUMJITTERS];
        for (i = 0; i < NUMJITTERS; i++) {
          jitterCamera[i] = mSceneMgr->createCamera ("JitteredCamera" + StringConverter::toString (i));
          jitterCamera[i]->setPosition (mCamera->getDerivedPosition ());
          jitterCamera[i]->setAutoTracking (true, mCameraTarget);
        }

        SceneNode *jitterNode;
        for (i = 0; i < NUMJITTERS; i++) {
          jitterNode = camNode->createChildSceneNode ();
          Real angle = (Real )i * (2.0 * Math::PI / (Real )NUMJITTERS);
          jitterNode->attachObject (jitterCamera[i]);
          jitterNode->setPosition (Vector3 (Math::Cos (angle) * (Real )JITTERRADIUS, Math::Sin (angle) * (Real )JITTERRADIUS, 0.0));
          LogManager::getSingleton ().logMessage ("Jittered camera created at: " + StringConverter::toString (jitterNode->getPosition ()));
        }

        // Depth of field stuff :)
        RenderTexture *jitterTexture[NUMJITTERS];
        for (i = 0; i < NUMJITTERS; i++) {
          jitterTexture[i] = mRoot->getRenderSystem ()->createRenderTexture ("JitterTexture" + StringConverter::toString (i), RTTSIZE, RTTSIZE);
          jitterTexture[i]->removeAllViewports ();
          jitterTexture[i]->addViewport (jitterCamera[i], i)->setOverlaysEnabled (false);
          //jitterTexture[i]->getViewport (0)->setOverlaysEnabled (false);
        }
        Material *depthOfFieldMaterial;
        TextureUnitState *tUnit;
		MaterialPtr tmp;
        for (i = 0; i < NUMJITTERS; i++) {
			tmp = (MaterialPtr)MaterialManager::getSingleton().create("DepthOfFieldMaterial" + StringConverter::toString (i), "Main");
			depthOfFieldMaterial = &(*tmp);
//          depthOfFieldMaterial = mSceneMgr->createMaterial ("DepthOfFieldMaterial" + StringConverter::toString (i));
          tUnit = depthOfFieldMaterial->getTechnique (0)->getPass (0)->createTextureUnitState ();
          tUnit->setTextureName ("JitterTexture" + StringConverter::toString (i));
          tUnit->setAlphaOperation (LBX_BLEND_CURRENT_ALPHA, LBS_MANUAL, LBS_CURRENT, 1.0 / (float )(NUMJITTERS), 1.0 - 1.0 / (float )(NUMJITTERS), 1.0 / (float )(NUMJITTERS));
          depthOfFieldMaterial->setSceneBlending (SBT_TRANSPARENT_ALPHA);
          depthOfFieldMaterial->setDepthCheckEnabled (false);
          depthOfFieldMaterial->setDepthWriteEnabled (false);
        }

        //Overlay *depthOfFieldOverlay = mSceneMgr->createOverlay ("DepthOfFieldOverlay", 10);
        Overlay *depthOfFieldOverlay = OverlayManager::getSingleton().create ("DepthOfFieldOverlay");
        for (i = 0; i < NUMJITTERS; i++) {
          OverlayElement *depthOfFieldPanel = OverlayManager::getSingleton ().createOverlayElement ("Panel", "DepthOfFieldPanel" + StringConverter::toString (i), false);
          depthOfFieldPanel->setMaterialName ("DepthOfFieldMaterial" + StringConverter::toString (i));
          depthOfFieldOverlay->add2D ((OverlayContainer *)depthOfFieldPanel);
        }
        depthOfFieldOverlay->show ();
        // End of depth of field :(

        // Debugging overlay
        mDebugOverlay = OverlayManager::getSingleton().create("DebugOverlay");
        for (i = 0; i < NUMJITTERS; i++) {
          OverlayElement *depthOfFieldPanel = OverlayManager::getSingleton ().createOverlayElement ("Panel", "DepthOfFieldDebugPanel" + StringConverter::toString (i), false);
          depthOfFieldPanel->setDimensions (1.0 / (int )NUMJITTERS, 1.0 / (int )NUMJITTERS);
          depthOfFieldPanel->setPosition (1.0 - 1.0 / (int )NUMJITTERS, i * 1.0 / (int )NUMJITTERS);
          depthOfFieldPanel->setMaterialName ("DepthOfFieldMaterial" + StringConverter::toString (i));
          mDebugOverlay->add2D ((OverlayContainer *)depthOfFieldPanel);
        }
        // End of debugging overlay
   }
};



#include "windows.h"
int main(int argc, char **argv)
{
    // Create application object
    CameraTrackApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif
    }


    return 0;
} 
User avatar
BenO
Goblin
Posts: 241
Joined: Mon Apr 18, 2005 5:03 pm

Post by BenO »

may we have working screenshot plz ? :D
User avatar
Sion
Gnoblar
Posts: 9
Joined: Thu May 05, 2005 11:55 am
Location: Aarhus, Denmark

Post by Sion »

First of all, nice work Kencho and Emmeran!
BenO wrote:may we have working screenshot plz ? :D
Here's one.
Image

The field of depth blurring is quite subtle, but I've modified the range of focus so here almost all the razors are blurred. Click for a bigger picture.
Last edited by Sion on Thu May 12, 2005 8:58 pm, edited 1 time in total.
Anders Nissen
My Blog
Korbi
Halfling
Posts: 59
Joined: Sun Aug 15, 2004 4:26 pm

Post by Korbi »

That yet looks nice, where is it from?
User avatar
Sputnick
Greenskin
Posts: 110
Joined: Wed Sep 08, 2004 11:49 pm
Location: Lausanne, Switzerland

Post by Sputnick »

Works fine for me with Emmeran's code.
Thanks,

- Sput