Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Samples/Fresnel/src/Fresnel.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 12.4 KB
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-2006 Torus Knot Software Ltd
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
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29/*
30-----------------------------------------------------------------------------
31Filename:    Fresnel.cpp
32Description: Fresnel reflections and refractions
33-----------------------------------------------------------------------------
34*/
35
36#include "ExampleApplication.h"
37#include "OgreHardwarePixelBuffer.h"
38// Hacky globals
39Camera* theCam;
40Entity* pPlaneEnt;
41std::vector<Entity*> aboveWaterEnts;
42std::vector<Entity*> belowWaterEnts;
43
44// Fish!
45#define NUM_FISH 30
46#define NUM_FISH_WAYPOINTS 10
47#define FISH_PATH_LENGTH 200
48#define FISH_SCALE 1.2
49AnimationState* fishAnimations[NUM_FISH];
50SimpleSpline fishSplines[NUM_FISH];
51Vector3 fishLastPosition[NUM_FISH];
52SceneNode* fishNodes[NUM_FISH];
53Real animTime = 0.0f;
54
55
56Plane reflectionPlane;
57
58
59class RefractionTextureListener : public RenderTargetListener
60{
61public:
62    void preRenderTargetUpdate(const RenderTargetEvent& evt)
63    {
64        // Hide plane and objects above the water
65        pPlaneEnt->setVisible(false);
66        std::vector<Entity*>::iterator i, iend;
67        iend = aboveWaterEnts.end();
68        for (i = aboveWaterEnts.begin(); i != iend; ++i)
69        {
70            (*i)->setVisible(false);
71        }
72
73    }
74    void postRenderTargetUpdate(const RenderTargetEvent& evt)
75    {
76        // Show plane and objects above the water
77        pPlaneEnt->setVisible(true);
78        std::vector<Entity*>::iterator i, iend;
79        iend = aboveWaterEnts.end();
80        for (i = aboveWaterEnts.begin(); i != iend; ++i)
81        {
82            (*i)->setVisible(true);
83        }
84    }
85
86};
87class ReflectionTextureListener : public RenderTargetListener
88{
89public:
90    void preRenderTargetUpdate(const RenderTargetEvent& evt)
91    {
92        // Hide plane and objects below the water
93        pPlaneEnt->setVisible(false);
94        std::vector<Entity*>::iterator i, iend;
95        iend = belowWaterEnts.end();
96        for (i = belowWaterEnts.begin(); i != iend; ++i)
97        {
98            (*i)->setVisible(false);
99        }
100        theCam->enableReflection(reflectionPlane);
101
102    }
103    void postRenderTargetUpdate(const RenderTargetEvent& evt)
104    {
105        // Show plane and objects below the water
106        pPlaneEnt->setVisible(true);
107        std::vector<Entity*>::iterator i, iend;
108        iend = belowWaterEnts.end();
109        for (i = belowWaterEnts.begin(); i != iend; ++i)
110        {
111            (*i)->setVisible(true);
112        }
113        theCam->disableReflection();
114    }
115
116};
117
118class FresnelFrameListener : public ExampleFrameListener
119{
120public:
121
122    FresnelFrameListener(RenderWindow* win, Camera* cam)
123        : ExampleFrameListener(win, cam, false, false)
124    {}
125    bool frameStarted(const FrameEvent &evt)
126    {
127        animTime += evt.timeSinceLastFrame;
128        while (animTime > FISH_PATH_LENGTH)
129            animTime -= FISH_PATH_LENGTH;
130
131        for (size_t fish = 0; fish < NUM_FISH; ++fish)
132        {
133            // Animate the fish
134            fishAnimations[fish]->addTime(evt.timeSinceLastFrame*2);
135            // Move the fish
136            Vector3 newPos = fishSplines[fish].interpolate(animTime / FISH_PATH_LENGTH);
137            fishNodes[fish]->setPosition(newPos);
138            // Work out the direction
139            Vector3 direction = fishLastPosition[fish] - newPos;
140            direction.normalise();
141                        // Test for opposite vectors
142                        Real d = 1.0f + Vector3::UNIT_X.dotProduct(direction);
143                        if (fabs(d) < 0.00001)
144                        {
145                                // Diametrically opposed vectors
146                                Quaternion orientation;
147                                orientation.FromAxes(Vector3::NEGATIVE_UNIT_X, 
148                                        Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_Z);
149                                fishNodes[fish]->setOrientation(orientation);
150                        }
151                        else
152                        {
153                                fishNodes[fish]->setOrientation(
154                                        Vector3::UNIT_X.getRotationTo(direction));
155                        }
156            fishLastPosition[fish] = newPos;
157
158        }
159
160
161
162        return ExampleFrameListener::frameStarted(evt);
163    }
164
165};
166
167class FresnelApplication : public ExampleApplication
168{
169protected:
170    RefractionTextureListener mRefractionListener;
171    ReflectionTextureListener mReflectionListener;
172public:
173    FresnelApplication() {
174   
175   
176    }
177
178    ~FresnelApplication() 
179    {
180    }
181protected:
182   
183
184
185    // Just override the mandatory create scene method
186    void createScene(void)
187    {
188
189        // Check prerequisites first
190                const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
191        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
192        {
193            OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs, so cannot "
194                "run this demo. Sorry!", 
195                "Fresnel::createScene");
196        }
197        else
198        {
199            if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") &&
200                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") &&
201                                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4")
202                                )
203            {
204                OGRE_EXCEPT(1, "Your card does not support advanced fragment programs, "
205                    "so cannot run this demo. Sorry!", 
206                "Fresnel::createScene");
207            }
208        }
209
210        theCam = mCamera;
211        theCam->setPosition(-50,125,760);
212                theCam->setDirection (0,0,-1);
213        // Set ambient light
214        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
215
216        // Create a point light
217        Light* l = mSceneMgr->createLight("MainLight");
218        l->setType(Light::LT_DIRECTIONAL);
219        l->setDirection(-Vector3::UNIT_Y);
220
221        Entity* pEnt;
222
223        TexturePtr mTexture = TextureManager::getSingleton().createManual( "Refraction", 
224                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 
225                        512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
226        //RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
227        RenderTarget *rttTex = mTexture->getBuffer()->getRenderTarget();
228               
229        {
230            Viewport *v = rttTex->addViewport( mCamera );
231            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
232            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
233            v->setOverlaysEnabled(false);
234            rttTex->addListener(&mRefractionListener);
235        }
236       
237                mTexture = TextureManager::getSingleton().createManual( "Reflection", 
238                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 
239                        512, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
240        //rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
241        rttTex = mTexture->getBuffer()->getRenderTarget();
242        {
243            Viewport *v = rttTex->addViewport( mCamera );
244            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
245            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
246            v->setOverlaysEnabled(false);
247            rttTex->addListener(&mReflectionListener);
248        }
249       
250       
251        // Define a floor plane mesh
252        reflectionPlane.normal = Vector3::UNIT_Y;
253        reflectionPlane.d = 0;
254        MeshManager::getSingleton().createPlane("ReflectPlane",
255            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
256            reflectionPlane,
257            700,1300,10,10,true,1,3,5,Vector3::UNIT_Z);
258        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
259        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
260        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
261
262       
263        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
264
265        // My node to which all objects will be attached
266        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
267
268                // above water entities
269        pEnt = mSceneMgr->createEntity( "RomanBathUpper", "RomanBathUpper.mesh" );
270                myRootNode->attachObject(pEnt);       
271        aboveWaterEnts.push_back(pEnt);
272
273        pEnt = mSceneMgr->createEntity( "Columns", "Columns.mesh" );
274                myRootNode->attachObject(pEnt);       
275        aboveWaterEnts.push_back(pEnt);
276
277                Ogre::SceneNode *headNode = myRootNode->createChildSceneNode ();
278                pEnt = mSceneMgr->createEntity( "OgreHead", "ogrehead.mesh" );
279                pEnt->setMaterialName ("RomanBath/OgreStone");
280        headNode->attachObject(pEnt);
281                headNode->setPosition(-350,55,130);
282                headNode->rotate(Vector3::UNIT_Y, Degree (90));
283        aboveWaterEnts.push_back(pEnt);
284
285                // below water entities
286                pEnt = mSceneMgr->createEntity( "RomanBathLower", "RomanBathLower.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                        fishNodes[fishNo]->setScale(FISH_SCALE, FISH_SCALE, FISH_SCALE);
295            fishAnimations[fishNo] = pEnt->getAnimationState("swim");
296            fishAnimations[fishNo]->setEnabled(true);
297            fishNodes[fishNo]->attachObject(pEnt);
298            belowWaterEnts.push_back(pEnt);
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() * 270, -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() * 270, -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.