320 likes | 326 Views
Understand the crucial elements like BaseApplication, Root setup, rendering, and frame listeners in OGRE3D programming.
E N D
Introduction to OGRE3D Programming: Main Loop 1 1
Major part of call graph BaseApplication::go() BaseApplication::setup() Root::startRendering() Root::renderOneFrame() Root::_fireFrameStarted() Root::_fireFrameEnded(); Root::_updateAllRenderTargets(); 2
Main program int main(int argc, char **argv) { BaseApplication *MyGameApp = new BaseApplication; try { MyGameApp go(); } catch( Exception& e ) { … … } return 1; }
The implementation of go() virtual void BaseApplication::go(void) { if (!setup()) return; mRoot->startRendering(); // clean up destroyScene(); }
The implementation of setup() The function setup() instantiates mRoot, setups resources, loads plugins, creates scene and creates frame listener. mRoot = new Ogre::Root(mPluginsCfg); setupResources(); bool carryOn = configure(); if (!carryOn) return false; chooseSceneManager(); createCamera(); createViewports(); createResourceListener(); loadResources(); createScene(); createFrameListener();
bool Root::_fireFrameStarted(FrameEvent& evt) OgreProfileBeginGroup("Frame", OGREPROF_GENERAL); // Remove all marked listeners … // Tell all listeners for ( i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i ) { if ( !(*i)frameStarted(evt) ) return false; } return true;
bool Root::_updateAllRenderTargets(void) // update all targets but don't swap buffers mActiveRenderer->_updateAllRenderTargets(false); // give client app opportunity to use queued GPU time bool ret = _fireFrameRenderingQueued(); // This belongs here, as all render targets must be updated // before events are triggered, otherwise targets could be // mismatched. This could produce artifacts, e.g. with shadows. …… return ret;
bool Root::_fireFrameRenderingQueued(FrameEvent& evt) // Increment next frame number ++mNextFrame; // Remove all marked listeners …… // Tell all listeners for ( i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i ) { if ( !(*i)->frameRenderingQueued( evt ) ) return false; } return true;
bool Root::_fireFrameEnded(FrameEvent& evt) // Remove all marked listeners …… // Tell all listeners bool ret = true; for ( i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i ) { if ( !(*i)->frameEnded(evt) ) { ret = false; break; } } // Tell buffer manager to free temp buffers used this frame return ret;
Remove all marked Listener set<FrameListener*>::type::iterator i; for ( i = mRemovedFrameListeners.begin(); i != mRemovedFrameListeners.end(); i++) { mFrameListeners.erase(*i); } mRemovedFrameListeners.clear();
Major functions (3/3) • bool myFrameListener::frameStarted(const FrameEvent& evt) • { • if(mWindow->isClosed()) return false; • ... ... • //Need to capture/update each device • mKeyboard->capture(); • mMouse->capture(); • if( mJoy ) mJoy->capture(); • ... ... • handleKeyEvent(evt); • handleMouseEvent(evt); • ... ... • ... ... • ... ... • return true; • }
Major part of call graph GameApplication::go() GameApplication::setup() Root::startRendering() Root::renderOneFrame() Root::_fireFrameStarted() Root::_fireFrameEnded(); Root::_updateAllRenderTargets(); 14
Frame listener Frame listeners are the only way we can invoke your own code during the Ogre render loop when using the startRendering() method. A frame listener is simply a class that implements the FrameListener interface, and is just a callback that allows OGRE to invoke our code at the beginning and/or end of each.
Demo: main_loop Use ExampleApplication and ExampleFrameListener In the main .cpp file, we have: class GameApplication: public ExampleApplication { public: GameApplication() {} void createScene() {} }; GameApplication *app = new GameApplication; int main(int argc, char **argv) { try { app->go(); } catch( Exception& e ) { ……. } } 16
Object-Oriented Graphics Rendering Engine ( OGRE 3D) - The Main Program
FrameStarted • bool myFrameListener::frameStarted(const FrameEvent& evt) • { • if(mWindow->isClosed()) return false; • . . . . . . • //Need to capture/update each device • mKeyboard->capture(); • mMouse->capture(); • if( mJoy ) mJoy->capture(); • . . . . . . • handleKeyEvent(evt); • handleMouseEvent(evt); • . . . . . . • moveMainChar(evt); • updateCreaturesAction(evt); • . . . . . . • . . . . . . • . . . . . . • return true; • }
moveMainChar void moveMainChar(const FrameEvent& evt) { mCameraNode->yaw(mRotX); // move the head node along the camera viewing direction const Quaternion q = mCameraNode->getOrientation(); mCameraNode->setOrientation(q); SceneNode *node = mHeadNode->getSceneNode(); node->setOrientation(q); node->translate( q*(-mTranslateVector) ); // maintain the distance between the camera and mHeadNode const Vector3 v3 = node->getPosition(); Vector3 cv = v3; Vector3 hv = Vector3(0.0, 0.0, -1.0); hv = q*hv; float d0 = -mCamerViewDistanceFromMainChar; float d1 = 30; mCameraNode->setPosition(cv-hv*d0+Vector3(0.0, d1, 0.0)); }
updateCreatureActions void updateCreaturesAction(const FrameEvent& evt) { if (mRobot) { mRobot->checkAlive(evt); } if (mRobot && mHeadNode) { mRobot->UpdateAction(evt, mHeadNode); } }
FrameEvent namespace Ogre { struct FrameEvent { /** Elapsed time in seconds since the last event. This gives you time between frame start & frame end, and between frame end and next frame start. @remarks This may not be the elapsed time but the average elapsed time between recently fired events. */ Real timeSinceLastEvent; /** Elapsed time in seconds since the last event of the same type, i.e. time for a complete frame. @remarks This may not be the elapsed time but the average elapsed time between recently fired events of the same type. */ Real timeSinceLastFrame; }; };
Introduction to dynamic-link library (DLL) • On Windows • Microsoft’s implementation of shared library • File format same as for the Windows EXE files • Containing • Code • Data • Resources, • or in any combination
Symbol resolution and binding Each function exported by a DLL is identified by a numeric ordinal and optionally a name Functions can be imported from a DLL either by ordinal or by a name The ordinal represents the position of the functions address pointer in the DLL Export Address table
Symbol resolution and binding • Ordinal: subject to change • Names: preserved across different Windows releases
Load-time dynamic linking • Use the information the linker placed in the file to locate the names of the DLLs that are used by the process • Fail to locate a required DLL • -> terminate the process and report the error • Locate successfully -> map the DLL into the virtual address space of the process 25
Load-time dynamic linking • Call a DLL function explicitly. • The application must be linked with the import library myMessage.lib. • extern "C" int __cdecl myMessage(LPWSTR); • // a function from a DLL • int main(VOID) { • int Ret = 1; • Ret = myMessage (L“Message\n”); • return Ret; • } 26
Explicit run-time linking • LoadLibrary (or LoadLibraryEx): explicitly load at run time • GetProcAddress: lookup exported symbols by name • FreeLibrary: unload the DLL
Example: creating a DLL #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface #endif __declspec(dllexport) void* createSceneCreator() { … … return static_cast< void* > (new DemoApp); } #ifdef __cplusplus } #endif 28
Module definition file (.def) file : a text file that contains statements defining an executable (.exe) file or dynamic-link library (DLL). Some commands: LIBRARY: Specify the internal name of the DLL EXPORTS: Make one or more definitions available as exports to other applications Syntax of an export definition: entryname[=internalname] [@ordinal[NONAME]] 29
Creating a DLL:Setup module definition file Project>properties->Linker-> input->module definition file Content of sceneCreator.def LIBRARY sceneCreator EXPORTS createSceneCreator @1 30
Explicit run-time linking DLL HINSTANCE hdll = NULL; typedef void* (*pvFunctv)(); pvFunctv sceneCreator; hdll = LoadLibrary(TEXT("./dll/sceneCreator.dll")); if (hdll) { … } else { ……; return; } sceneCreator = (pvFunctv) (GetProcAddress( hdll, "createSceneCreator" ) ); DemoApp *app = static_cast< DemoApp* > ( sceneCreator() ); 31
Useful links for DLL • About DLL: http://msdn2.microsoft.com/en-us/library/ms686912(VS.85).aspx • Module definition file: http://msdn2.microsoft.com/en-us/library/ms923590.aspx 32