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

Revision 692, 16.4 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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