Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Samples/VolumeTex/src/VolumeTex.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 10.0 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
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        using namespace OIS;
127        static float mTimeUntilNextToggle = 0.0f;
128        if( ExampleFrameListener::frameStarted( evt ) == false )
129                return false;
130               
131                mTimeUntilNextToggle -= evt.timeSinceLastFrame;
132               
133        if( (mKeyboard->isKeyDown( KC_1 ) || mKeyboard->isKeyDown( KC_2 )) 
134                                && mTimeUntilNextToggle <= 0) {
135                global_real += mKeyboard->isKeyDown( KC_1 )? -0.1f : 0.1f;
136                        generate();
137                        mTimeUntilNextToggle = 0.5;
138                        updateInfoParamReal();
139                }
140                 if( (mKeyboard->isKeyDown( KC_3 ) || mKeyboard->isKeyDown( KC_4 )) 
141                                && mTimeUntilNextToggle <= 0) {
142                global_imag += mKeyboard->isKeyDown( KC_3 )? -0.1f : 0.1f;
143                        generate();
144                        mTimeUntilNextToggle = 0.5;
145                        updateInfoParamImag();
146                }
147                if( (mKeyboard->isKeyDown( KC_5 ) || mKeyboard->isKeyDown( KC_6 )) 
148                                && mTimeUntilNextToggle <= 0) {
149                global_theta += mKeyboard->isKeyDown( KC_5 )? -0.1f : 0.1f;
150                        generate();
151                        mTimeUntilNextToggle = 0.5;
152                        updateInfoParamTheta();
153                }
154               
155                xtime += evt.timeSinceLastFrame;
156                xtime = fmod(xtime, 10.0f);
157                //snode->roll(Degree(evt.timeSinceLastFrame * 20.0f));
158                //fnode->roll(Degree(evt.timeSinceLastFrame * 20.0f));
159                static_cast<ThingRenderable*>(trend)->addTime(evt.timeSinceLastFrame * 0.05f);
160                mOgreAnimState->addTime(evt.timeSinceLastFrame);
161        return true;
162    }
163        ~VolumeTexFrameListener()
164        {
165                delete vrend;
166                delete trend;
167        }
168};
169
170
171
172class VolumeTexApplication : public ExampleApplication
173{
174public:
175    VolumeTexApplication() {}
176
177
178protected:
179       
180    virtual void createFrameListener(void)
181    {
182        mFrameListener= new VolumeTexFrameListener(mWindow, mCamera);
183        mFrameListener->showDebugOverlay(true);
184        mRoot->addFrameListener(mFrameListener);
185    }
186
187
188        virtual void createViewports(void)
189    {
190                // Create one viewport, entire window
191        Viewport* vp = mWindow->addViewport(mCamera);
192        vp->setBackgroundColour(ColourValue(0,0,0));
193
194        // Alter the camera aspect ratio to match the viewport
195        mCamera->setAspectRatio( 
196            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
197    }
198        void createCamera(void)
199        {
200                // Create the camera
201        mCamera = mSceneMgr->createCamera("PlayerCam");
202        mCamera->setPosition(Vector3(220,-2,176));
203        mCamera->lookAt(Vector3(0,0,0));
204        mCamera->setNearClipDistance(5);
205                mCamera->setFixedYawAxis(false);
206        }
207    // Just override the mandatory create scene method
208    void createScene(void)
209    {
210                // Check capabilities
211        /*
212                const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
213        if (!caps->hasCapability(RSC_TEXTURE_3D))
214        {
215            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support 3D textures, so cannot "
216                "run this demo. Sorry!",
217                "VolTex::createScene");
218        }
219        */
220               
221        // Create dynamic texture
222                ptex = TextureManager::getSingleton().createManual(
223                        "DynaTex","General", TEX_TYPE_3D, 64, 64, 64, 0, PF_A8R8G8B8);
224               
225
226
227                // Set ambient light
228        mSceneMgr->setAmbientLight(ColourValue(0.6, 0.6, 0.6));
229                mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox", 50 );
230
231        //mRoot->getRenderSystem()->clearFrameBuffer(FBT_COLOUR, ColourValue(255,255,255,0));
232
233        // Create a light
234        Light* l = mSceneMgr->createLight("MainLight");
235        l->setDiffuseColour(0.75, 0.75, 0.80);
236                l->setSpecularColour(0.9, 0.9, 1);
237        l->setPosition(-100,80,50);
238                mSceneMgr->getRootSceneNode()->attachObject(l);
239
240                // Create manual material
241               
242               
243                // Create volume renderable
244                snode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0));     
245               
246        vrend = new VolumeRenderable(32, 750.0f, "DynaTex");
247        snode->attachObject( vrend );
248               
249                trend = new ThingRenderable(90.0f, 32, 7.5f);
250                trend->setMaterial("Examples/VTDarkStuff");
251                snode->attachObject(trend);
252               
253                // Ogre head node
254                fnode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0));
255                // Load ogre head
256                Entity* head = mSceneMgr->createEntity("head", "ogrehead.mesh");
257                fnode->attachObject(head);
258               
259                // Animation for ogre head
260                // Create a track for the light
261        Animation* anim = mSceneMgr->createAnimation("OgreTrack", 10);
262        // Spline it for nice curves
263        anim->setInterpolationMode(Animation::IM_SPLINE);
264        // Create a track to animate the camera's node
265        NodeAnimationTrack* track = anim->createNodeTrack(0, fnode);
266        // Setup keyframes
267        TransformKeyFrame* key = track->createNodeKeyFrame(0); // A startposition
268        key->setTranslate(Vector3(0.0f, -15.0f, 0.0f));
269        key = track->createNodeKeyFrame(5);//B
270        key->setTranslate(Vector3(0.0f, 15.0f, 0.0f));
271        key = track->createNodeKeyFrame(10);//C
272        key->setTranslate(Vector3(0.0f, -15.0f, 0.0f));
273        // Create a new animation state to track this
274        mOgreAnimState = mSceneMgr->createAnimationState("OgreTrack");
275        mOgreAnimState->setEnabled(true);
276     
277        //mFountainNode->attachObject(pSys2);
278                // show GUI
279                overlay = OverlayManager::getSingleton().getByName("Example/VolTexOverlay");   
280                overlay->show();
281    }
282
283        void destroyScene()
284        {
285                ptex.setNull();
286        }
287
288};
289
290#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
291#define WIN32_LEAN_AND_MEAN
292#include "windows.h"
293#endif
294
295#ifdef __cplusplus
296extern "C" {
297#endif
298
299#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
300INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
301#else
302int main(int argc, char *argv[])
303#endif
304{
305    // Create application object
306    VolumeTexApplication app;
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.