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

Revision 657, 10.0 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
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/**     Generate 3D julia sets and render them as volume texture
15        This demonstrates
16           - User generated textures
17           - Procedural volume textures (Julia makes nice dust clouds)
18           - Custom renderables
19        @author W.J. van der Laan
20*/
21
22#include "ExampleApplication.h"
23#include <OgreTexture.h>
24#include <OgreHardwarePixelBuffer.h>
25#include <OgreTextureManager.h>
26#include <OgreLogManager.h>
27#include <sstream>
28
29#include "VolumeRenderable.h"
30#include "ThingRenderable.h"
31#include "Julia.h"
32
33TexturePtr ptex;
34SimpleRenderable *vrend;
35SimpleRenderable *trend;
36Overlay* overlay;
37float xtime = 0.0f;
38SceneNode *snode,*fnode;
39AnimationState* mOgreAnimState = 0;
40
41class VolumeTexFrameListener : public ExampleFrameListener
42{
43public:
44        float global_real, global_imag, global_theta;
45       
46    VolumeTexFrameListener(RenderWindow* win, Camera* cam) : ExampleFrameListener( win, cam )
47    {
48                global_real = 0.4f;
49                global_imag = 0.6f;
50                global_theta = 0.0f;
51                generate();
52               
53                updateInfoParamReal();
54                updateInfoParamImag();
55                updateInfoParamTheta();
56    }
57       
58        void generate()
59        {
60                /* Evaluate julia fractal for each point */
61                Julia julia(global_real, global_imag, global_theta);
62                const float scale = 2.5;
63                const float vcut = 29.0f;
64                const float vscale = 1.0f/vcut;
65               
66                HardwarePixelBufferSharedPtr buffer = ptex->getBuffer(0, 0);
67                std::stringstream d;
68                d << "HardwarePixelBuffer " << buffer->getWidth() << " " << buffer->getHeight() << " " << buffer->getDepth();
69                LogManager::getSingleton().logMessage(d.str());
70               
71                buffer->lock(HardwareBuffer::HBL_NORMAL);
72                const PixelBox &pb = buffer->getCurrentLock();
73                d.str("");
74                d << "PixelBox " << pb.getWidth() << " " << pb.getHeight() << " " << pb.getDepth() << " " << pb.rowPitch << " " << pb.slicePitch << " " << pb.data << " " << PixelUtil::getFormatName(pb.format);
75                LogManager::getSingleton().logMessage(d.str());
76               
77                uint32 *pbptr = static_cast<uint32*>(pb.data);
78                for(size_t z=pb.front; z<pb.back; z++)
79        {
80            for(size_t y=pb.top; y<pb.bottom; y++)
81            {
82                for(size_t x=pb.left; x<pb.right; x++)
83                {
84                    if(z==pb.front || z==(pb.back-1) || y==pb.top|| y==(pb.bottom-1) ||
85                                                x==pb.left || x==(pb.right-1))
86                                        {
87                                                // On border, must be zero
88                                                pbptr[x] = 0;
89                    }
90                                        else
91                                        {
92                                                float val = julia.eval(((float)x/pb.getWidth()-0.5f) * scale,
93                                                                ((float)y/pb.getHeight()-0.5f) * scale,
94                                                                ((float)z/pb.getDepth()-0.5f) * scale);
95                                                if(val > vcut)
96                                                        val = vcut;
97                                               
98                                                PixelUtil::packColour((float)x/pb.getWidth(), (float)y/pb.getHeight(), (float)z/pb.getDepth(), (1.0f-(val*vscale))*0.7f, PF_A8R8G8B8, &pbptr[x]);
99                                               
100                                        }       
101                }
102                pbptr += pb.rowPitch;
103            }
104            pbptr += pb.getSliceSkip();
105        }
106                buffer->unlock();
107        }
108        void updateInfoParamReal()
109        {
110                OverlayManager::getSingleton().getOverlayElement("Example/VolTex/Param_real") \
111                        ->setCaption("[1/2]real: "+StringConverter::toString(global_real));
112        }
113        void updateInfoParamImag()
114        {
115                OverlayManager::getSingleton().getOverlayElement("Example/VolTex/Param_imag") \
116                        ->setCaption("[3/4]imag: "+StringConverter::toString(global_imag));
117        }
118        void updateInfoParamTheta()
119        {
120                OverlayManager::getSingleton().getOverlayElement("Example/VolTex/Param_theta") \
121                        ->setCaption("[5/6]theta: "+StringConverter::toString(global_theta));
122        }
123
124    bool frameStarted( const FrameEvent& evt )
125    {
126                static float mTimeUntilNextToggle = 0.0f;
127        bool bOK = ExampleFrameListener::frameStarted( evt );
128               
129                mTimeUntilNextToggle -= evt.timeSinceLastFrame;
130               
131        if( (mInputDevice->isKeyDown( KC_1 ) || mInputDevice->isKeyDown( KC_2 ))
132                                && mTimeUntilNextToggle <= 0) {
133                global_real += mInputDevice->isKeyDown( KC_1 )? -0.1f : 0.1f;
134                        generate();
135                        mTimeUntilNextToggle = 0.5;
136                        updateInfoParamReal();
137                }
138                 if( (mInputDevice->isKeyDown( KC_3 ) || mInputDevice->isKeyDown( KC_4 ))
139                                && mTimeUntilNextToggle <= 0) {
140                global_imag += mInputDevice->isKeyDown( KC_3 )? -0.1f : 0.1f;
141                        generate();
142                        mTimeUntilNextToggle = 0.5;
143                        updateInfoParamImag();
144                }
145                if( (mInputDevice->isKeyDown( KC_5 ) || mInputDevice->isKeyDown( KC_6 ))
146                                && mTimeUntilNextToggle <= 0) {
147                global_theta += mInputDevice->isKeyDown( KC_5 )? -0.1f : 0.1f;
148                        generate();
149                        mTimeUntilNextToggle = 0.5;
150                        updateInfoParamTheta();
151                }
152               
153                xtime += evt.timeSinceLastFrame;
154                xtime = fmod(xtime, 10.0f);
155                //snode->roll(Degree(evt.timeSinceLastFrame * 20.0f));
156                //fnode->roll(Degree(evt.timeSinceLastFrame * 20.0f));
157                static_cast<ThingRenderable*>(trend)->addTime(evt.timeSinceLastFrame * 0.05f);
158                mOgreAnimState->addTime(evt.timeSinceLastFrame);
159        return bOK;
160    }
161        ~VolumeTexFrameListener()
162        {
163                delete vrend;
164                delete trend;
165        }
166};
167
168
169
170class VolumeTexApplication : public ExampleApplication
171{
172public:
173    VolumeTexApplication() {}
174
175
176protected:
177       
178    virtual void createFrameListener(void)
179    {
180        mFrameListener= new VolumeTexFrameListener(mWindow, mCamera);
181        mFrameListener->showDebugOverlay(true);
182        mRoot->addFrameListener(mFrameListener);
183    }
184
185
186        virtual void createViewports(void)
187    {
188                // Create one viewport, entire window
189        Viewport* vp = mWindow->addViewport(mCamera);
190        vp->setBackgroundColour(ColourValue(0,0,0));
191
192        // Alter the camera aspect ratio to match the viewport
193        mCamera->setAspectRatio(
194            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
195    }
196        void createCamera(void)
197        {
198                // Create the camera
199        mCamera = mSceneMgr->createCamera("PlayerCam");
200        mCamera->setPosition(Vector3(220,-2,176));
201        mCamera->lookAt(Vector3(0,0,0));
202        mCamera->setNearClipDistance(5);
203                mCamera->setFixedYawAxis(false);
204        }
205    // Just override the mandatory create scene method
206    void createScene(void)
207    {
208                // Check capabilities
209        /*
210                const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
211        if (!caps->hasCapability(RSC_TEXTURE_3D))
212        {
213            OGRE_EXCEPT(1, "Your card does not support 3D textures (or you selected D3D7), so cannot "
214                "run this demo. Sorry!",
215                "VolTex::createScene");
216        }
217        */
218               
219        // Create dynamic texture
220                ptex = TextureManager::getSingleton().createManual(
221                        "DynaTex","General", TEX_TYPE_3D, 64, 64, 64, 0, PF_A8R8G8B8);
222               
223
224
225                // Set ambient light
226        mSceneMgr->setAmbientLight(ColourValue(0.6, 0.6, 0.6));
227                mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox", 50 );
228
229        //mRoot->getRenderSystem()->clearFrameBuffer(FBT_COLOUR, ColourValue(255,255,255,0));
230
231        // Create a light
232        Light* l = mSceneMgr->createLight("MainLight");
233        l->setDiffuseColour(0.75, 0.75, 0.80);
234                l->setSpecularColour(0.9, 0.9, 1);
235        l->setPosition(-100,80,50);
236                mSceneMgr->getRootSceneNode()->attachObject(l);
237
238                // Create manual material
239               
240               
241                // Create volume renderable
242                snode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0));     
243               
244        vrend = new VolumeRenderable(32, 750.0f, "DynaTex");
245        snode->attachObject( vrend );
246               
247                trend = new ThingRenderable(90.0f, 32, 7.5f);
248                trend->setMaterial("Examples/VTDarkStuff");
249                snode->attachObject(trend);
250               
251                // Ogre head node
252                fnode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0));
253                // Load ogre head
254                Entity* head = mSceneMgr->createEntity("head", "ogrehead.mesh");
255                fnode->attachObject(head);
256               
257                // Animation for ogre head
258                // Create a track for the light
259        Animation* anim = mSceneMgr->createAnimation("OgreTrack", 10);
260        // Spline it for nice curves
261        anim->setInterpolationMode(Animation::IM_SPLINE);
262        // Create a track to animate the camera's node
263        AnimationTrack* track = anim->createTrack(0, fnode);
264        // Setup keyframes
265        KeyFrame* key = track->createKeyFrame(0); // A startposition
266        key->setTranslate(Vector3(0.0f, -15.0f, 0.0f));
267        key = track->createKeyFrame(5);//B
268        key->setTranslate(Vector3(0.0f, 15.0f, 0.0f));
269        key = track->createKeyFrame(10);//C
270        key->setTranslate(Vector3(0.0f, -15.0f, 0.0f));
271        // Create a new animation state to track this
272        mOgreAnimState = mSceneMgr->createAnimationState("OgreTrack");
273        mOgreAnimState->setEnabled(true);
274     
275        //mFountainNode->attachObject(pSys2);
276                // show GUI
277                overlay = OverlayManager::getSingleton().getByName("Example/VolTexOverlay");   
278                overlay->show();
279    }
280
281        void destroyScene()
282        {
283                ptex.setNull();
284        }
285
286};
287
288#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
289#define WIN32_LEAN_AND_MEAN
290#include "windows.h"
291#endif
292
293#ifdef __cplusplus
294extern "C" {
295#endif
296
297#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
298INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
299#else
300int main(int argc, char *argv[])
301#endif
302{
303    // Create application object
304    VolumeTexApplication app;
305
306    SET_TERM_HANDLER;
307   
308    try {
309        app.go();
310    } catch( Ogre::Exception& e ) {
311#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
312        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
313#else
314        std::cerr << "An exception has occured: " <<
315            e.getFullDescription().c_str() << std::endl;
316#endif
317    }
318
319    return 0;
320}
321
322#ifdef __cplusplus
323}
324#endif
Note: See TracBrowser for help on using the repository browser.