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

Revision 657, 12.3 KB checked in by mattausch, 19 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
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25/*
26-----------------------------------------------------------------------------
27Filename:    Fresnel.cpp
28Description: Fresnel reflections and refractions
29-----------------------------------------------------------------------------
30*/
31
32#include "ExampleApplication.h"
33
34// Hacky globals
35Camera* theCam;
36Entity* pPlaneEnt;
37std::vector<Entity*> aboveWaterEnts;
38std::vector<Entity*> belowWaterEnts;
39
40// Fish!
41#define NUM_FISH 30
42#define NUM_FISH_WAYPOINTS 10
43#define FISH_PATH_LENGTH 200
44AnimationState* fishAnimations[NUM_FISH];
45SimpleSpline fishSplines[NUM_FISH];
46Vector3 fishLastPosition[NUM_FISH];
47SceneNode* fishNodes[NUM_FISH];
48Real animTime = 0.0f;
49
50
51Plane reflectionPlane;
52
53
54class RefractionTextureListener : public RenderTargetListener
55{
56public:
57    void preRenderTargetUpdate(const RenderTargetEvent& evt)
58    {
59        // Hide plane and objects above the water
60        pPlaneEnt->setVisible(false);
61        std::vector<Entity*>::iterator i, iend;
62        iend = aboveWaterEnts.end();
63        for (i = aboveWaterEnts.begin(); i != iend; ++i)
64        {
65            (*i)->setVisible(false);
66        }
67
68    }
69    void postRenderTargetUpdate(const RenderTargetEvent& evt)
70    {
71        // Show plane and objects above the water
72        pPlaneEnt->setVisible(true);
73        std::vector<Entity*>::iterator i, iend;
74        iend = aboveWaterEnts.end();
75        for (i = aboveWaterEnts.begin(); i != iend; ++i)
76        {
77            (*i)->setVisible(true);
78        }
79    }
80
81};
82class ReflectionTextureListener : public RenderTargetListener
83{
84public:
85    void preRenderTargetUpdate(const RenderTargetEvent& evt)
86    {
87        // Hide plane and objects below the water
88        pPlaneEnt->setVisible(false);
89        std::vector<Entity*>::iterator i, iend;
90        iend = belowWaterEnts.end();
91        for (i = belowWaterEnts.begin(); i != iend; ++i)
92        {
93            (*i)->setVisible(false);
94        }
95        theCam->enableReflection(reflectionPlane);
96
97    }
98    void postRenderTargetUpdate(const RenderTargetEvent& evt)
99    {
100        // Show plane and objects below the water
101        pPlaneEnt->setVisible(true);
102        std::vector<Entity*>::iterator i, iend;
103        iend = belowWaterEnts.end();
104        for (i = belowWaterEnts.begin(); i != iend; ++i)
105        {
106            (*i)->setVisible(true);
107        }
108        theCam->disableReflection();
109    }
110
111};
112
113class FresnelFrameListener : public ExampleFrameListener
114{
115public:
116
117    FresnelFrameListener(RenderWindow* win, Camera* cam)
118        : ExampleFrameListener(win, cam, false, false)
119    {}
120    bool frameStarted(const FrameEvent &evt)
121    {
122        animTime += evt.timeSinceLastFrame;
123        while (animTime > FISH_PATH_LENGTH)
124            animTime -= FISH_PATH_LENGTH;
125
126        for (size_t fish = 0; fish < NUM_FISH; ++fish)
127        {
128            // Animate the fish
129            fishAnimations[fish]->addTime(evt.timeSinceLastFrame*2);
130            // Move the fish
131            Vector3 newPos = fishSplines[fish].interpolate(animTime / FISH_PATH_LENGTH);
132            fishNodes[fish]->setPosition(newPos);
133            // Work out the direction
134            Vector3 direction = fishLastPosition[fish] - newPos;
135            direction.normalise();
136                        // Test for opposite vectors
137                        Real d = 1.0f + Vector3::UNIT_X.dotProduct(direction);
138                        if (fabs(d) < 0.00001)
139                        {
140                                // Diametrically opposed vectors
141                                Quaternion orientation;
142                                orientation.FromAxes(Vector3::NEGATIVE_UNIT_X,
143                                        Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_Z);
144                                fishNodes[fish]->setOrientation(orientation);
145                        }
146                        else
147                        {
148                                fishNodes[fish]->setOrientation(
149                                        Vector3::UNIT_X.getRotationTo(direction));
150                        }
151            fishLastPosition[fish] = newPos;
152
153        }
154
155
156
157        return ExampleFrameListener::frameStarted(evt);
158    }
159
160};
161
162class FresnelApplication : public ExampleApplication
163{
164protected:
165    RefractionTextureListener mRefractionListener;
166    ReflectionTextureListener mReflectionListener;
167public:
168    FresnelApplication() {
169   
170   
171    }
172
173    ~FresnelApplication()
174    {
175    }
176protected:
177   
178
179
180    // Just override the mandatory create scene method
181    void createScene(void)
182    {
183
184        // Check prerequisites first
185                const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
186        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
187        {
188            OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs, so cannot "
189                "run this demo. Sorry!",
190                "Fresnel::createScene");
191        }
192        else
193        {
194            if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") &&
195                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") &&
196                                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4")
197                                )
198            {
199                OGRE_EXCEPT(1, "Your card does not support advanced fragment programs, "
200                    "so cannot run this demo. Sorry!",
201                "Fresnel::createScene");
202            }
203        }
204
205        theCam = mCamera;
206        theCam->setPosition(-100,20,700);
207        // Set ambient light
208        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
209
210        // Create a point light
211        Light* l = mSceneMgr->createLight("MainLight");
212        l->setType(Light::LT_DIRECTIONAL);
213        l->setDirection(-Vector3::UNIT_Y);
214
215        Entity* pEnt;
216
217       
218        RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
219               
220        {
221            Viewport *v = rttTex->addViewport( mCamera );
222            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
223            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
224            v->setOverlaysEnabled(false);
225            rttTex->addListener(&mRefractionListener);
226        }
227       
228               
229        rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
230        {
231            Viewport *v = rttTex->addViewport( mCamera );
232            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
233            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
234            v->setOverlaysEnabled(false);
235            rttTex->addListener(&mReflectionListener);
236        }
237       
238       
239        // Define a floor plane mesh
240        reflectionPlane.normal = Vector3::UNIT_Y;
241        reflectionPlane.d = 0;
242        MeshManager::getSingleton().createPlane("ReflectPlane",
243            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
244            reflectionPlane,
245            1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z);
246        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
247        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
248        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
249
250       
251        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
252
253        // My node to which all objects will be attached
254        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
255
256        // Above water entities - NB all meshes are static
257        pEnt = mSceneMgr->createEntity( "head1", "head1.mesh" );
258        myRootNode->attachObject(pEnt);
259        aboveWaterEnts.push_back(pEnt);
260        pEnt = mSceneMgr->createEntity( "Pillar1", "Pillar1.mesh" );
261        myRootNode->attachObject(pEnt);
262        aboveWaterEnts.push_back(pEnt);
263        pEnt = mSceneMgr->createEntity( "Pillar2", "Pillar2.mesh" );
264        myRootNode->attachObject(pEnt);
265        aboveWaterEnts.push_back(pEnt);
266        pEnt = mSceneMgr->createEntity( "Pillar3", "Pillar3.mesh" );
267        myRootNode->attachObject(pEnt);
268        aboveWaterEnts.push_back(pEnt);
269        pEnt = mSceneMgr->createEntity( "Pillar4", "Pillar4.mesh" );
270        myRootNode->attachObject(pEnt);
271        aboveWaterEnts.push_back(pEnt);
272        pEnt = mSceneMgr->createEntity( "UpperSurround", "UpperSurround.mesh" );
273        myRootNode->attachObject(pEnt);
274        aboveWaterEnts.push_back(pEnt);
275
276        // Now the below water ents
277        pEnt = mSceneMgr->createEntity( "LowerSurround", "LowerSurround.mesh" );
278        myRootNode->attachObject(pEnt);
279        belowWaterEnts.push_back(pEnt);
280        pEnt = mSceneMgr->createEntity( "PoolFloor", "PoolFloor.mesh" );
281        myRootNode->attachObject(pEnt);
282        belowWaterEnts.push_back(pEnt);
283
284        for (size_t fishNo = 0; fishNo < NUM_FISH; ++fishNo)
285        {
286            pEnt = mSceneMgr->createEntity("fish" + StringConverter::toString(fishNo), "fish.mesh");
287            fishNodes[fishNo] = myRootNode->createChildSceneNode();
288            fishAnimations[fishNo] = pEnt->getAnimationState("swim");
289            fishAnimations[fishNo]->setEnabled(true);
290            fishNodes[fishNo]->attachObject(pEnt);
291            belowWaterEnts.push_back(pEnt);
292
293
294            // Generate a random selection of points for the fish to swim to
295            fishSplines[fishNo].setAutoCalculate(false);
296            Vector3 lastPos;
297            for (size_t waypoint = 0; waypoint < NUM_FISH_WAYPOINTS; ++waypoint)
298            {
299                Vector3 pos = Vector3(
300                    Math::SymmetricRandom() * 700, -10, Math::SymmetricRandom() * 700);
301                if (waypoint > 0)
302                {
303                    // check this waypoint isn't too far, we don't want turbo-fish ;)
304                    // since the waypoints are achieved every 5 seconds, half the length
305                    // of the pond is ok
306                    while ((lastPos - pos).length() > 750)
307                    {
308                        pos = Vector3(
309                            Math::SymmetricRandom() * 700, -10, Math::SymmetricRandom() * 700);
310                    }
311                }
312                fishSplines[fishNo].addPoint(pos);
313                lastPos = pos;
314            }
315            // close the spline
316            fishSplines[fishNo].addPoint(fishSplines[fishNo].getPoint(0));
317            // recalc
318            fishSplines[fishNo].recalcTangents();
319
320
321        }
322
323
324
325
326    }
327
328    void createFrameListener(void)
329    {
330        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
331        mFrameListener->showDebugOverlay(true);
332        mRoot->addFrameListener(mFrameListener);
333    }
334
335};
336
337
338
339#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
340#define WIN32_LEAN_AND_MEAN
341#include "windows.h"
342#endif
343
344#ifdef __cplusplus
345extern "C" {
346#endif
347
348#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
349INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
350#else
351int main(int argc, char **argv)
352#endif
353{
354    // Create application object
355    FresnelApplication app;
356
357    try {
358        app.go();
359    } catch( Exception& e ) {
360#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
361        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
362#else
363        std::cerr << "An exception has occured: " << e.getFullDescription();
364#endif
365    }
366
367
368    return 0;
369}
370
371#ifdef __cplusplus
372}
373#endif
Note: See TracBrowser for help on using the repository browser.