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

Revision 692, 12.9 KB checked in by mattausch, 19 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
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#include "OgreHardwarePixelBuffer.h"
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        TexturePtr mTexture = TextureManager::getSingleton().createManual( "Refraction",
218                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
219                        512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
220        //RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
221        RenderTarget *rttTex = mTexture->getBuffer()->getRenderTarget();
222               
223        {
224            Viewport *v = rttTex->addViewport( mCamera );
225            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
226            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
227            v->setOverlaysEnabled(false);
228            rttTex->addListener(&mRefractionListener);
229        }
230       
231                mTexture = TextureManager::getSingleton().createManual( "Reflection",
232                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
233                        512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
234        //rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
235        rttTex = mTexture->getBuffer()->getRenderTarget();
236        {
237            Viewport *v = rttTex->addViewport( mCamera );
238            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
239            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
240            v->setOverlaysEnabled(false);
241            rttTex->addListener(&mReflectionListener);
242        }
243       
244       
245        // Define a floor plane mesh
246        reflectionPlane.normal = Vector3::UNIT_Y;
247        reflectionPlane.d = 0;
248        MeshManager::getSingleton().createPlane("ReflectPlane",
249            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
250            reflectionPlane,
251            1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z);
252        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
253        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
254        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
255
256       
257        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
258
259        // My node to which all objects will be attached
260        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
261
262        // Above water entities - NB all meshes are static
263        pEnt = mSceneMgr->createEntity( "head1", "head1.mesh" );
264        myRootNode->attachObject(pEnt);
265        aboveWaterEnts.push_back(pEnt);
266        pEnt = mSceneMgr->createEntity( "Pillar1", "Pillar1.mesh" );
267        myRootNode->attachObject(pEnt);
268        aboveWaterEnts.push_back(pEnt);
269        pEnt = mSceneMgr->createEntity( "Pillar2", "Pillar2.mesh" );
270        myRootNode->attachObject(pEnt);
271        aboveWaterEnts.push_back(pEnt);
272        pEnt = mSceneMgr->createEntity( "Pillar3", "Pillar3.mesh" );
273        myRootNode->attachObject(pEnt);
274        aboveWaterEnts.push_back(pEnt);
275        pEnt = mSceneMgr->createEntity( "Pillar4", "Pillar4.mesh" );
276        myRootNode->attachObject(pEnt);
277        aboveWaterEnts.push_back(pEnt);
278        pEnt = mSceneMgr->createEntity( "UpperSurround", "UpperSurround.mesh" );
279        myRootNode->attachObject(pEnt);
280        aboveWaterEnts.push_back(pEnt);
281
282        // Now the below water ents
283        pEnt = mSceneMgr->createEntity( "LowerSurround", "LowerSurround.mesh" );
284        myRootNode->attachObject(pEnt);
285        belowWaterEnts.push_back(pEnt);
286        pEnt = mSceneMgr->createEntity( "PoolFloor", "PoolFloor.mesh" );
287        myRootNode->attachObject(pEnt);
288        belowWaterEnts.push_back(pEnt);
289
290        for (size_t fishNo = 0; fishNo < NUM_FISH; ++fishNo)
291        {
292            pEnt = mSceneMgr->createEntity("fish" + StringConverter::toString(fishNo), "fish.mesh");
293            fishNodes[fishNo] = myRootNode->createChildSceneNode();
294            fishAnimations[fishNo] = pEnt->getAnimationState("swim");
295            fishAnimations[fishNo]->setEnabled(true);
296            fishNodes[fishNo]->attachObject(pEnt);
297            belowWaterEnts.push_back(pEnt);
298
299
300            // Generate a random selection of points for the fish to swim to
301            fishSplines[fishNo].setAutoCalculate(false);
302            Vector3 lastPos;
303            for (size_t waypoint = 0; waypoint < NUM_FISH_WAYPOINTS; ++waypoint)
304            {
305                Vector3 pos = Vector3(
306                    Math::SymmetricRandom() * 700, -10, Math::SymmetricRandom() * 700);
307                if (waypoint > 0)
308                {
309                    // check this waypoint isn't too far, we don't want turbo-fish ;)
310                    // since the waypoints are achieved every 5 seconds, half the length
311                    // of the pond is ok
312                    while ((lastPos - pos).length() > 750)
313                    {
314                        pos = Vector3(
315                            Math::SymmetricRandom() * 700, -10, Math::SymmetricRandom() * 700);
316                    }
317                }
318                fishSplines[fishNo].addPoint(pos);
319                lastPos = pos;
320            }
321            // close the spline
322            fishSplines[fishNo].addPoint(fishSplines[fishNo].getPoint(0));
323            // recalc
324            fishSplines[fishNo].recalcTangents();
325
326
327        }
328
329
330
331
332    }
333
334    void createFrameListener(void)
335    {
336        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
337        mFrameListener->showDebugOverlay(true);
338        mRoot->addFrameListener(mFrameListener);
339    }
340
341};
342
343
344
345#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
346#define WIN32_LEAN_AND_MEAN
347#include "windows.h"
348#endif
349
350#ifdef __cplusplus
351extern "C" {
352#endif
353
354#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
355INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
356#else
357int main(int argc, char **argv)
358#endif
359{
360    // Create application object
361    FresnelApplication app;
362
363    try {
364        app.go();
365    } catch( Exception& e ) {
366#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
367        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
368#else
369        std::cerr << "An exception has occured: " << e.getFullDescription();
370#endif
371    }
372
373
374    return 0;
375}
376
377#ifdef __cplusplus
378}
379#endif
Note: See TracBrowser for help on using the repository browser.