source: OGRE/trunk/ogrenew/Samples/Shadows/src/Shadows.cpp @ 657

Revision 657, 16.8 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10You may use this sample code for anything you like, it is not covered by the
11LGPL like the rest of the engine.
12-----------------------------------------------------------------------------
13*/
14
15/**
16    \file
17        Shadows.cpp
18    \brief
19        Shows a few ways to use Ogre's shadowing techniques
20*/
21
22#include "ExampleApplication.h"
23
24/*
25#include "OgreNoMemoryMacros.h"
26#include <ode/odecpp.h>
27#include <ode/odecpp_collision.h>
28#include "OgreMemoryMacros.h"
29*/
30
31/*
32#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
33#include "OgreNoMemoryMacros.h"
34#include <crtdbg.h>
35#endi*/
36
37Entity* mAthene;
38AnimationState* mAnimState = 0;
39Entity* pPlaneEnt;
40Light* mLight;
41Light* mSunLight;
42SceneNode* mLightNode = 0;
43AnimationState* mLightAnimationState = 0;
44ColourValue mMinLightColour(0.3, 0.0, 0);
45ColourValue mMaxLightColour(0.5, 0.3, 0.1);
46Real mMinFlareSize = 40;
47Real mMaxFlareSize = 80;
48
49#define NUM_ATHENE_MATERIALS 2
50String mAtheneMaterials[NUM_ATHENE_MATERIALS] =
51{
52    "Examples/Athene/NormalMapped",
53    "Examples/Athene/Basic"
54};
55#define NUM_SHADOW_TECH 4
56String mShadowTechDescriptions[NUM_SHADOW_TECH] =
57{
58    "Stencil Shadows (Additive)",
59    "Stencil Shadows (Modulative)",
60    "Texture Shadows (Modulative)",
61    "None"
62};
63ShadowTechnique mShadowTech[NUM_SHADOW_TECH] =
64{
65    SHADOWTYPE_STENCIL_ADDITIVE,
66    SHADOWTYPE_STENCIL_MODULATIVE,
67    SHADOWTYPE_TEXTURE_MODULATIVE,
68    SHADOWTYPE_NONE
69};
70
71
72int mCurrentAtheneMaterial;
73int mCurrentShadowTechnique = 0;
74
75OverlayElement* mShadowTechniqueInfo;
76OverlayElement* mMaterialInfo;
77OverlayElement* mInfo;
78
79
80/** This class 'wibbles' the light and billboard */
81class LightWibbler : public ControllerValue<Real>
82{
83protected:
84    Light* mLight;
85    Billboard* mBillboard;
86    ColourValue mColourRange;
87    ColourValue mMinColour;
88    Real mMinSize;
89    Real mSizeRange;
90    Real intensity;
91public:
92    LightWibbler(Light* light, Billboard* billboard, const ColourValue& minColour,
93        const ColourValue& maxColour, Real minSize, Real maxSize)
94    {
95        mLight = light;
96        mBillboard = billboard;
97        mMinColour = minColour;
98        mColourRange.r = maxColour.r - minColour.r;
99        mColourRange.g = maxColour.g - minColour.g;
100        mColourRange.b = maxColour.b - minColour.b;
101        mMinSize = minSize;
102        mSizeRange = maxSize - minSize;
103    }
104
105    virtual Real  getValue (void) const
106    {
107        return intensity;
108    }
109
110    virtual void  setValue (Real value)
111    {
112        intensity = value;
113
114        ColourValue newColour;
115
116        // Attenuate the brightness of the light
117        newColour.r = mMinColour.r + (mColourRange.r * intensity);
118        newColour.g = mMinColour.g + (mColourRange.g * intensity);
119        newColour.b = mMinColour.b + (mColourRange.b * intensity);
120
121        mLight->setDiffuseColour(newColour);
122        mBillboard->setColour(newColour);
123        // set billboard size
124        Real newSize = mMinSize + (intensity * mSizeRange);
125        mBillboard->setDimensions(newSize, newSize);
126
127    }
128};
129
130Real timeDelay = 0;
131#define KEY_PRESSED(_key,_timeDelay, _macro) \
132{ \
133    if (mInputDevice->isKeyDown(_key) && timeDelay <= 0) \
134{ \
135    timeDelay = _timeDelay; \
136    _macro ; \
137} \
138}
139
140class ShadowsListener : public ExampleFrameListener
141{
142protected:
143    SceneManager* mSceneMgr;
144public:
145    ShadowsListener(RenderWindow* win, Camera* cam, SceneManager* sm)
146        : ExampleFrameListener(win, cam), mSceneMgr(sm)
147    {
148    }
149
150
151    void changeShadowTechnique()
152    {
153        mCurrentShadowTechnique = ++mCurrentShadowTechnique % NUM_SHADOW_TECH;
154        mShadowTechniqueInfo->setCaption("Current: " + mShadowTechDescriptions[mCurrentShadowTechnique]);
155
156        mSceneMgr->setShadowTechnique(mShadowTech[mCurrentShadowTechnique]);
157        Vector3 dir;
158        switch (mShadowTech[mCurrentShadowTechnique])
159        {
160        case SHADOWTYPE_STENCIL_ADDITIVE:
161            // Fixed light, dim
162            mSunLight->setCastShadows(true);
163
164            // Point light, movable, reddish
165            mLight->setType(Light::LT_POINT);
166            mLight->setCastShadows(true);
167            mLight->setDiffuseColour(mMinLightColour);
168            mLight->setSpecularColour(1, 1, 1);
169            mLight->setAttenuation(8000,1,0.0005,0);
170
171            break;
172        case SHADOWTYPE_STENCIL_MODULATIVE:
173            // Multiple lights cause obvious silhouette edges in modulative mode
174            // So turn off shadows on the direct light
175            // Fixed light, dim
176            mSunLight->setCastShadows(false);
177
178            // Point light, movable, reddish
179            mLight->setType(Light::LT_POINT);
180            mLight->setCastShadows(true);
181            mLight->setDiffuseColour(mMinLightColour);
182            mLight->setSpecularColour(1, 1, 1);
183            mLight->setAttenuation(8000,1,0.0005,0);
184            break;
185        case SHADOWTYPE_TEXTURE_MODULATIVE:
186            // Change fixed point light to spotlight
187            // Fixed light, dim
188            mSunLight->setCastShadows(true);
189
190            // Change moving light to spotlight
191            // Point light, movable, reddish
192            mLight->setType(Light::LT_SPOTLIGHT);
193            mLight->setDirection(Vector3::NEGATIVE_UNIT_Z);
194            mLight->setCastShadows(true);
195            mLight->setDiffuseColour(mMinLightColour);
196            mLight->setSpecularColour(1, 1, 1);
197            mLight->setAttenuation(8000,1,0.0005,0);
198            mLight->setSpotlightRange(Degree(80),Degree(90));
199            break;
200        default:
201            break;
202        };
203
204
205
206    }
207
208    void changeAtheneMaterial()
209    {
210        mCurrentAtheneMaterial = ++mCurrentAtheneMaterial % NUM_ATHENE_MATERIALS;
211        mMaterialInfo->setCaption("Current: " + mAtheneMaterials[mCurrentAtheneMaterial]);
212        mAthene->setMaterialName(mAtheneMaterials[mCurrentAtheneMaterial]);
213    }
214
215    bool frameEnded(const FrameEvent& evt)
216    {
217        if (timeDelay >= 0)
218            timeDelay -= evt.timeSinceLastFrame;
219
220        if (mAnimState)
221            mAnimState->addTime(evt.timeSinceLastFrame);
222
223        KEY_PRESSED(KC_O, 1, changeShadowTechnique());
224        KEY_PRESSED(KC_M, 0.5, changeAtheneMaterial());
225
226        return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
227    }
228
229   
230
231
232};
233
234class ShadowsApplication : public ExampleApplication
235{
236public:
237    ShadowsApplication() {
238
239
240    }
241
242    ~ShadowsApplication()
243    {
244    }
245protected:
246
247    void chooseSceneManager(void)
248    {
249        mSceneMgr = mRoot->getSceneManager( ST_GENERIC );
250    }
251
252
253    void generalSceneSetup()
254    {
255        // do this first so we generate edge lists
256        mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
257        // Set the default Athene material
258        // We'll default it to the normal map for ps_2_0 capable hardware
259        // everyone else will default to the basic
260        if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") ||
261            GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1"))
262        {
263            mCurrentAtheneMaterial = 0;
264        }
265        else
266        {
267            mCurrentAtheneMaterial = 1;
268        }
269
270        // Set ambient light off
271        mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.0));
272
273        // Fixed light, dim
274        mSunLight = mSceneMgr->createLight("SunLight");
275        mSunLight->setType(Light::LT_SPOTLIGHT);
276        mSunLight->setPosition(1000,1250,500);
277        mSunLight->setSpotlightRange(Degree(30), Degree(50));
278        Vector3 dir;
279        dir = -mSunLight->getPosition();
280        dir.normalise();
281        mSunLight->setDirection(dir);
282        mSunLight->setDiffuseColour(0.35, 0.35, 0.38);
283        mSunLight->setSpecularColour(0.9, 0.9, 1);
284
285        // Point light, movable, reddish
286        mLight = mSceneMgr->createLight("Light2");
287        mLight->setDiffuseColour(mMinLightColour);
288        mLight->setSpecularColour(1, 1, 1);
289        mLight->setAttenuation(8000,1,0.0005,0);
290
291        // Create light node
292        mLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(
293            "MovingLightNode");
294        mLightNode->attachObject(mLight);
295        // create billboard set
296        BillboardSet* bbs = mSceneMgr->createBillboardSet("lightbbs", 1);
297        bbs->setMaterialName("Examples/Flare");
298        Billboard* bb = bbs->createBillboard(0,0,0,mMinLightColour);
299        // attach
300        mLightNode->attachObject(bbs);
301
302        // create controller, after this is will get updated on its own
303        ControllerFunctionRealPtr func = ControllerFunctionRealPtr(
304            new WaveformControllerFunction(Ogre::WFT_SINE, 0.75, 0.5));
305        ControllerManager& contMgr = ControllerManager::getSingleton();
306        ControllerValueRealPtr val = ControllerValueRealPtr(
307            new LightWibbler(mLight, bb, mMinLightColour, mMaxLightColour,
308            mMinFlareSize, mMaxFlareSize));
309        Controller<Real>* controller = contMgr.createController(
310            contMgr.getFrameTimeSource(), val, func);
311
312        //mLight->setPosition(Vector3(300,250,-300));
313        mLightNode->setPosition(Vector3(300,250,-300));
314
315
316        // Create a track for the light
317        Animation* anim = mSceneMgr->createAnimation("LightTrack", 20);
318        // Spline it for nice curves
319        anim->setInterpolationMode(Animation::IM_SPLINE);
320        // Create a track to animate the camera's node
321        AnimationTrack* track = anim->createTrack(0, mLightNode);
322        // Setup keyframes
323        KeyFrame* key = track->createKeyFrame(0); // A startposition
324        key->setTranslate(Vector3(300,250,-300));
325        key = track->createKeyFrame(2);//B
326        key->setTranslate(Vector3(150,300,-250));
327        key = track->createKeyFrame(4);//C
328        key->setTranslate(Vector3(-150,350,-100));
329        key = track->createKeyFrame(6);//D
330        key->setTranslate(Vector3(-400,200,-200));
331        key = track->createKeyFrame(8);//E
332        key->setTranslate(Vector3(-200,200,-400));
333        key = track->createKeyFrame(10);//F
334        key->setTranslate(Vector3(-100,150,-200));
335        key = track->createKeyFrame(12);//G
336        key->setTranslate(Vector3(-100,75,180));
337        key = track->createKeyFrame(14);//H
338        key->setTranslate(Vector3(0,250,300));
339        key = track->createKeyFrame(16);//I
340        key->setTranslate(Vector3(100,350,100));
341        key = track->createKeyFrame(18);//J
342        key->setTranslate(Vector3(250,300,0));
343        key = track->createKeyFrame(20);//K == A
344        key->setTranslate(Vector3(300,250,-300));
345        // Create a new animation state to track this
346        mAnimState = mSceneMgr->createAnimationState("LightTrack");
347        mAnimState->setEnabled(true);
348        // Make light node look at origin, this is for when we
349        // change the moving light to a spotlight
350        mLightNode->setAutoTracking(true, mSceneMgr->getRootSceneNode());
351
352        // Prepare athene mesh for normalmapping
353        MeshPtr pAthene = MeshManager::getSingleton().load("athene.mesh",
354            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
355        unsigned short src, dest;
356        if (!pAthene->suggestTangentVectorBuildParams(src, dest))
357        {
358            pAthene->buildTangentVectors(src, dest);
359        }
360
361        SceneNode* node;
362        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
363        mAthene = mSceneMgr->createEntity( "athene", "athene.mesh" );
364        //mAnimState = pEnt->getAnimationState("Walk");
365        //mAnimState->setEnabled(true);
366        mAthene->setMaterialName(mAtheneMaterials[mCurrentAtheneMaterial]);
367        node->attachObject( mAthene );
368        node->translate(0,-20, 0);
369        node->yaw(Degree(90));
370
371        Entity* pEnt;
372
373        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
374        pEnt = mSceneMgr->createEntity( "col1", "column.mesh" );
375        //mAnimState = pEnt->getAnimationState("Walk");
376        //mAnimState->setEnabled(true);
377        pEnt->setMaterialName("Examples/Rockwall");
378        node->attachObject( pEnt );
379        node->translate(200,0, -200);
380
381        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
382        pEnt = mSceneMgr->createEntity( "col2", "column.mesh" );
383        //mAnimState = pEnt->getAnimationState("Walk");
384        //mAnimState->setEnabled(true);
385        pEnt->setMaterialName("Examples/Rockwall");
386        node->attachObject( pEnt );
387        node->translate(200,0, 200);
388
389        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
390        pEnt = mSceneMgr->createEntity( "col3", "column.mesh" );
391        //mAnimState = pEnt->getAnimationState("Walk");
392        //mAnimState->setEnabled(true);
393        pEnt->setMaterialName("Examples/Rockwall");
394        node->attachObject( pEnt );
395        node->translate(-200,0, -200);
396
397        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
398        pEnt = mSceneMgr->createEntity( "col4", "column.mesh" );
399        //mAnimState = pEnt->getAnimationState("Walk");
400        //mAnimState->setEnabled(true);
401        pEnt->setMaterialName("Examples/Rockwall");
402        node->attachObject( pEnt );
403        node->translate(-200,0, 200);
404        // Skybox
405        mSceneMgr->setSkyBox(true, "Examples/StormySkyBox");
406
407        // Floor plane
408        Plane plane;
409        plane.normal = Vector3::UNIT_Y;
410        plane.d = 100;
411        MeshManager::getSingleton().createPlane("Myplane",
412            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
413            1500,1500,20,20,true,1,5,5,Vector3::UNIT_Z);
414        Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
415        pPlaneEnt->setMaterialName("Examples/Rockwall");
416        pPlaneEnt->setCastShadows(false);
417        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
418
419        // show overlay
420        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/ShadowsOverlay");   
421        mShadowTechniqueInfo = OverlayManager::getSingleton().getOverlayElement("Example/Shadows/ShadowTechniqueInfo");
422        mMaterialInfo = OverlayManager::getSingleton().getOverlayElement("Example/Shadows/MaterialInfo");
423        mInfo = OverlayManager::getSingleton().getOverlayElement("Example/Shadows/Info");
424
425        mShadowTechniqueInfo->setCaption("Current: " + mShadowTechDescriptions[mCurrentShadowTechnique]);
426        mMaterialInfo->setCaption("Current: " + mAtheneMaterials[mCurrentAtheneMaterial]);
427        pOver->show();
428
429                if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_HWRENDER_TO_TEXTURE))
430        {
431            // In D3D, use a 1024x1024 shadow texture
432            mSceneMgr->setShadowTextureSettings(1024, 2);
433        }
434        else
435        {
436            // Use 512x512 texture in GL since we can't go higher than the window res
437            mSceneMgr->setShadowTextureSettings(512, 2);
438        }
439        mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
440
441        // incase infinite far distance is not supported
442        mCamera->setFarClipDistance(100000);
443
444        //mSceneMgr->setShowDebugShadows(true);
445
446
447    }
448
449
450    // Just override the mandatory create scene method
451    void createScene(void)
452    {
453        // set up general scene (this defaults to additive stencils)
454        generalSceneSetup();
455    }
456    // Create new frame listener
457    void createFrameListener(void)
458    {
459        mFrameListener= new ShadowsListener(mWindow, mCamera, mSceneMgr);
460        mFrameListener->showDebugOverlay(true);
461        mRoot->addFrameListener(mFrameListener);
462
463    }
464
465
466public:
467    void go(void)
468    {
469        if (!setup())
470            return;
471
472        mRoot->startRendering();
473    }
474
475
476};
477
478
479
480#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
481#define WIN32_LEAN_AND_MEAN
482#include "windows.h"
483#endif
484
485#ifdef __cplusplus
486extern "C" {
487#endif
488
489#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
490INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
491#else
492int main(int argc, char *argv[])
493#endif
494{
495    // Create application object
496    ShadowsApplication app;
497
498    SET_TERM_HANDLER;
499   
500    try {
501        app.go();
502    } catch( Ogre::Exception& e ) {
503#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
504        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
505#else
506        std::cerr << "An exception has occured: " <<
507            e.getFullDescription().c_str() << std::endl;
508#endif
509    }
510
511    return 0;
512}
513
514#ifdef __cplusplus
515}
516#endif
Note: See TracBrowser for help on using the repository browser.