Ticket #32302: patch-README_and_Tutorials_files.diff

File patch-README_and_Tutorials_files.diff, 43.5 KB (added by marin.saric@…, 12 years ago)
  • new file READ_ME_FIRST_OGRE_MACPORTS.txt

    - +  
     1This is a MacPorts-based release of OGRE (www.ogre3d.org)
     2Currently this 64-bit distribution package of OGRE is maintained by Marin Saric.
     3
     4Unlike other releases, this one is STATIC by default. Your code will
     5compile into a single executable that does not depend on ANY extra
     6libraries. Your users will not need to install Ogre, MacPorts or
     7anything else.
     8
     9This port is meant to be used from the command line using "cmake." You
     10can edit/write your code using Aquamacs (a MacOS X version of Emacs)
     11or some other editor of your choice. It is possible to use Xcode to
     12drive the CMake builds.
     13
     14Known issues:
     15
     16NOTE: If you are programming on MacOS X 10.7 and using the OIS system
     17          like the one used by the Sample and Tutorial code, it is
     18          possible that you won't be able to receive any
     19          keystrokes.
     20
     21          This is a libOIS.a problem. This will be fixed in a future
     22          release. After a new release of OIS, you'll need to
     23          recompile your code. You can still use other routines, such
     24          as the ones from MacOS X libraries to capture keystrokes.
     25
     26============================================================
     27To get started you will need to copy the SDKSamples and Tutorials
     28folder into your source directory.
     29============================================================
     30
     31Quick overview of the Contents:
     32   - Docs -- General OGRE Documentation
     33   - SDKSamples -- Sample code that comes with the OGRE SDK
     34   - Tools -- Various miscellanous tools that might be useful
     35   - Tutorials -- Use this to follow the Tutorials on OGRE Wiki
     36
     37============================================================
     38Learning OGRE by going through the tutorials:
     39============================================================
     40
     41http://www.ogre3d.org/tikiwiki/Basic+Tutorial+1&structure=Tutorials
     42
     43
     44The code in the Tutorials folder is ready for Basic Tutorial 1. All
     45you need to do is add your code in TutorialApplication.cpp and
     46TutorialApplication.h
     47
     48The code will compile and run without any modifications:
     49
     50cmake . # <-- Don't forget the dot (.)
     51make
     52./TutorialApp
     53
     54NOTE: The BaseApplication.cpp and BaseApplication.h has been modified
     55from the wiki. The CMakeLists.txt is different as well (and hopefully
     56simpler). The modifications were needed to get the Tutorial working on
     57MacOS X.
     58============================================================
     59
     60
     61============================================================
     62Running the sample code:
     63
     64You can just open the SDKSamples/bin/SampleBrowser.app
     65============================================================
     66Building the sample code:
     67
     68cd SDKSamples
     69cmake .
     70make -j8    # (or use -j4 if you have fewer cores)
     71
     72The file in bin/SampleBrowser.app/Contents/MacOS will now contain the
     73newest version of SampleBrowser
     74============================================================
     75
     76
     77
     78
     79
     80============================================================
     81OGRE is Copyright (c) 2000-2011 Torus Knot Software Ltd
  • new file Tutorials/BaseApplication.cpp

    - +  
     1/* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: nil; c-basic-offset: 4; c-indent-level: 4 -*-
     2-----------------------------------------------------------------------------
     3Filename:    BaseApplication.cpp
     4-----------------------------------------------------------------------------
     5
     6This source file is part of the
     7   ___                 __    __ _ _    _
     8  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
     9 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
     10/ \_// (_| | | |  __/  \  /\  /| |   <| |
     11\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
     12      |___/                             
     13      Tutorial Framework
     14      http://www.ogre3d.org/tikiwiki/
     15-----------------------------------------------------------------------------
     16*/
     17#include "BaseApplication.h"
     18
     19// ---------------------MacOgre----------------------------------
     20#ifdef __APPLE__ & __MACH__
     21
     22#include "mac_app_loop.h"
     23
     24class MacTutorialAppLoop : public MacAppLoop {
     25public:
     26    void RenderFrame(double time_since_last_frame) {
     27        if(Ogre::Root::getSingletonPtr()
     28           && Ogre::Root::getSingleton().isInitialised()) {
     29            Ogre::Root::getSingleton().renderOneFrame(time_since_last_frame);
     30        } else {
     31            RequestShutdown();
     32        }
     33    }
     34};
     35#endif  // __APPLE__ & __MACH__
     36// ---------------------MacOgre----------------------------------
     37
     38
     39//-------------------------------------------------------------------------------------
     40BaseApplication::BaseApplication(void)
     41    : mRoot(0),
     42    mCamera(0),
     43    mSceneMgr(0),
     44    mWindow(0),
     45    mResourcesCfg(Ogre::StringUtil::BLANK),
     46    mPluginsCfg(Ogre::StringUtil::BLANK),
     47    mTrayMgr(0),
     48    mCameraMan(0),
     49    mDetailsPanel(0),
     50    mCursorWasVisible(false),
     51    mShutDown(false),
     52    mInputManager(0),
     53    mMouse(0),
     54    mKeyboard(0)
     55// ---------------------MacOgre----------------------------------
     56#ifdef __APPLE__ & __MACH__
     57    ,mMacLoop(new MacTutorialAppLoop)
     58#endif
     59// ---------------------MacOgre----------------------------------
     60{
     61}
     62
     63//-------------------------------------------------------------------------------------
     64BaseApplication::~BaseApplication(void)
     65{
     66    if (mTrayMgr) delete mTrayMgr;
     67    if (mCameraMan) delete mCameraMan;
     68
     69    //Remove ourself as a Window listener
     70    Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
     71    windowClosed(mWindow);
     72    delete mRoot;
     73
     74// --------------------OgreStatic--------------------------------
     75#ifdef OGRE_STATIC_LIB
     76    mStaticLoader.unload();
     77#endif
     78// --------------------OgreStatic--------------------------------
     79
     80// ---------------------MacOgre----------------------------------
     81#ifdef __APPLE__ & __MACH__
     82    delete mMacLoop;
     83#endif
     84// ---------------------MacOgre----------------------------------
     85}
     86
     87//-------------------------------------------------------------------------------------
     88bool BaseApplication::configure(void)
     89{
     90    // Show the configuration dialog and initialise the system
     91    // You can skip this and use root.restoreConfig() to load configuration
     92    // settings if you were sure there are valid ones saved in ogre.cfg
     93    if(mRoot->showConfigDialog())
     94    {
     95        // If returned true, user clicked OK so initialise
     96        // Here we choose to let the system create a default rendering window by passing 'true'
     97        mWindow = mRoot->initialise(true, "TutorialApplication Render Window");
     98
     99        return true;
     100    }
     101    else
     102    {
     103        return false;
     104    }
     105}
     106//-------------------------------------------------------------------------------------
     107void BaseApplication::chooseSceneManager(void)
     108{
     109    // Get the SceneManager, in this case a generic one
     110    mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
     111}
     112//-------------------------------------------------------------------------------------
     113void BaseApplication::createCamera(void)
     114{
     115    // Create the camera
     116    mCamera = mSceneMgr->createCamera("PlayerCam");
     117
     118    // Position it at 500 in Z direction
     119    mCamera->setPosition(Ogre::Vector3(0,0,80));
     120    // Look back along -Z
     121    mCamera->lookAt(Ogre::Vector3(0,0,-300));
     122    mCamera->setNearClipDistance(5);
     123
     124    mCameraMan = new OgreBites::SdkCameraMan(mCamera);   // create a default camera controller
     125}
     126//-------------------------------------------------------------------------------------
     127void BaseApplication::createFrameListener(void)
     128{
     129    Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
     130    OIS::ParamList pl;
     131    size_t windowHnd = 0;
     132    std::ostringstream windowHndStr;
     133
     134    mWindow->getCustomAttribute("WINDOW", &windowHnd);
     135    windowHndStr << windowHnd;
     136    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
     137
     138    mInputManager = OIS::InputManager::createInputSystem( pl );
     139
     140    mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
     141    mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
     142
     143    mMouse->setEventCallback(this);
     144    mKeyboard->setEventCallback(this);
     145
     146    //Set initial mouse clipping size
     147    windowResized(mWindow);
     148
     149    //Register as a Window listener
     150    Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
     151
     152    mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mMouse, this);
     153    mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
     154    mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);
     155    mTrayMgr->hideCursor();
     156
     157    // create a params panel for displaying sample details
     158    Ogre::StringVector items;
     159    items.push_back("cam.pX");
     160    items.push_back("cam.pY");
     161    items.push_back("cam.pZ");
     162    items.push_back("");
     163    items.push_back("cam.oW");
     164    items.push_back("cam.oX");
     165    items.push_back("cam.oY");
     166    items.push_back("cam.oZ");
     167    items.push_back("");
     168    items.push_back("Filtering");
     169    items.push_back("Poly Mode");
     170
     171    mDetailsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_NONE, "DetailsPanel", 200, items);
     172    mDetailsPanel->setParamValue(9, "Bilinear");
     173    mDetailsPanel->setParamValue(10, "Solid");
     174    mDetailsPanel->hide();
     175
     176    mRoot->addFrameListener(this);
     177}
     178//-------------------------------------------------------------------------------------
     179void BaseApplication::destroyScene(void)
     180{
     181}
     182//-------------------------------------------------------------------------------------
     183void BaseApplication::createViewports(void)
     184{
     185    // Create one viewport, entire window
     186    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
     187    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
     188
     189    // Alter the camera aspect ratio to match the viewport
     190    mCamera->setAspectRatio(
     191        Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
     192}
     193//-------------------------------------------------------------------------------------
     194void BaseApplication::setupResources(void)
     195{
     196    // Load resource paths from config file
     197    Ogre::ConfigFile cf;
     198    cf.load(mResourcesCfg);
     199
     200    // Go through all sections & settings in the file
     201    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
     202
     203    Ogre::String secName, typeName, archName;
     204    while (seci.hasMoreElements())
     205    {
     206        secName = seci.peekNextKey();
     207        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
     208        Ogre::ConfigFile::SettingsMultiMap::iterator i;
     209        for (i = settings->begin(); i != settings->end(); ++i)
     210        {
     211            typeName = i->first;
     212            archName = i->second;
     213            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
     214                archName, typeName, secName);
     215        }
     216    }
     217}
     218//-------------------------------------------------------------------------------------
     219void BaseApplication::createResourceListener(void)
     220{
     221
     222}
     223//-------------------------------------------------------------------------------------
     224void BaseApplication::loadResources(void)
     225{
     226    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
     227}
     228//-------------------------------------------------------------------------------------
     229void BaseApplication::go(void)
     230{
     231#ifdef _DEBUG
     232    mResourcesCfg = "resources_d.cfg";
     233    mPluginsCfg = "plugins_d.cfg";
     234#else
     235    mResourcesCfg = "resources.cfg";
     236    mPluginsCfg = "plugins.cfg";
     237#endif
     238
     239// ---------------------OgreStatic-------------------------------
     240#ifdef OGRE_STATIC_LIB
     241    mPluginsCfg = "";
     242#endif
     243// ---------------------OgreStatic-------------------------------
     244
     245    if (!setup())
     246        return;
     247
     248#ifdef __APPLE__ & __MACH__
     249// ---------------------MacOgre----------------------------------
     250    mMacLoop->Run();
     251// ---------------------MacOgre----------------------------------
     252#else
     253    mRoot->startRendering();
     254#endif
     255
     256    // clean up
     257    destroyScene();
     258}
     259//-------------------------------------------------------------------------------------
     260bool BaseApplication::setup(void)
     261{
     262#ifdef __APPLE__ & __MACH__
     263// ---------------------MacOgre----------------------------------
     264    mMacLoop->Setup();
     265// ---------------------MacOgre----------------------------------
     266#endif
     267
     268    mRoot = new Ogre::Root(mPluginsCfg);
     269// ---------------------OgreStatic-------------------------------
     270#ifdef OGRE_STATIC_LIB
     271    mStaticLoader.load();
     272#endif
     273// ---------------------OgreStatic-------------------------------
     274
     275    setupResources();
     276
     277    bool carryOn = configure();
     278    if (!carryOn) return false;
     279
     280    chooseSceneManager();
     281    createCamera();
     282    createViewports();
     283
     284    // Set default mipmap level (NB some APIs ignore this)
     285    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
     286
     287    // Create any resource listeners (for loading screens)
     288    createResourceListener();
     289    // Load resources
     290    loadResources();
     291
     292    // Create the scene
     293    createScene();
     294
     295    createFrameListener();
     296
     297    return true;
     298};
     299//-------------------------------------------------------------------------------------
     300bool BaseApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
     301{
     302    if(mWindow->isClosed())
     303        return false;
     304
     305#ifdef __APPLE__ & __MACH__
     306// ---------------------MacOgre----------------------------------
     307    if(mShutDown) {
     308        mMacLoop->RequestShutdown();
     309        return false;
     310    }
     311// ---------------------MacOgre----------------------------------
     312#else
     313    if(mShutDown)
     314        return false;
     315#endif
     316
     317    //Need to capture/update each device
     318    mKeyboard->capture();
     319    mMouse->capture();
     320
     321    mTrayMgr->frameRenderingQueued(evt);
     322
     323    if (!mTrayMgr->isDialogVisible())
     324    {
     325        mCameraMan->frameRenderingQueued(evt);   // if dialog isn't up, then update the camera
     326        if (mDetailsPanel->isVisible())   // if details panel is visible, then update its contents
     327        {
     328            mDetailsPanel->setParamValue(0, Ogre::StringConverter::toString(mCamera->getDerivedPosition().x));
     329            mDetailsPanel->setParamValue(1, Ogre::StringConverter::toString(mCamera->getDerivedPosition().y));
     330            mDetailsPanel->setParamValue(2, Ogre::StringConverter::toString(mCamera->getDerivedPosition().z));
     331            mDetailsPanel->setParamValue(4, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().w));
     332            mDetailsPanel->setParamValue(5, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().x));
     333            mDetailsPanel->setParamValue(6, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().y));
     334            mDetailsPanel->setParamValue(7, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().z));
     335        }
     336    }
     337
     338    return true;
     339}
     340//-------------------------------------------------------------------------------------
     341bool BaseApplication::keyPressed( const OIS::KeyEvent &arg )
     342{
     343    if (mTrayMgr->isDialogVisible()) return true;   // don't process any more keys if dialog is up
     344
     345    if (arg.key == OIS::KC_F)   // toggle visibility of advanced frame stats
     346    {
     347        mTrayMgr->toggleAdvancedFrameStats();
     348    }
     349    else if (arg.key == OIS::KC_G)   // toggle visibility of even rarer debugging details
     350    {
     351        if (mDetailsPanel->getTrayLocation() == OgreBites::TL_NONE)
     352        {
     353            mTrayMgr->moveWidgetToTray(mDetailsPanel, OgreBites::TL_TOPRIGHT, 0);
     354            mDetailsPanel->show();
     355        }
     356        else
     357        {
     358            mTrayMgr->removeWidgetFromTray(mDetailsPanel);
     359            mDetailsPanel->hide();
     360        }
     361    }
     362    else if (arg.key == OIS::KC_T)   // cycle polygon rendering mode
     363    {
     364        Ogre::String newVal;
     365        Ogre::TextureFilterOptions tfo;
     366        unsigned int aniso;
     367
     368        switch (mDetailsPanel->getParamValue(9).asUTF8()[0])
     369        {
     370        case 'B':
     371            newVal = "Trilinear";
     372            tfo = Ogre::TFO_TRILINEAR;
     373            aniso = 1;
     374            break;
     375        case 'T':
     376            newVal = "Anisotropic";
     377            tfo = Ogre::TFO_ANISOTROPIC;
     378            aniso = 8;
     379            break;
     380        case 'A':
     381            newVal = "None";
     382            tfo = Ogre::TFO_NONE;
     383            aniso = 1;
     384            break;
     385        default:
     386            newVal = "Bilinear";
     387            tfo = Ogre::TFO_BILINEAR;
     388            aniso = 1;
     389        }
     390
     391        Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
     392        Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(aniso);
     393        mDetailsPanel->setParamValue(9, newVal);
     394    }
     395    else if (arg.key == OIS::KC_R)   // cycle polygon rendering mode
     396    {
     397        Ogre::String newVal;
     398        Ogre::PolygonMode pm;
     399
     400        switch (mCamera->getPolygonMode())
     401        {
     402        case Ogre::PM_SOLID:
     403            newVal = "Wireframe";
     404            pm = Ogre::PM_WIREFRAME;
     405            break;
     406        case Ogre::PM_WIREFRAME:
     407            newVal = "Points";
     408            pm = Ogre::PM_POINTS;
     409            break;
     410        default:
     411            newVal = "Solid";
     412            pm = Ogre::PM_SOLID;
     413        }
     414
     415        mCamera->setPolygonMode(pm);
     416        mDetailsPanel->setParamValue(10, newVal);
     417    }
     418    else if(arg.key == OIS::KC_F5)   // refresh all textures
     419    {
     420        Ogre::TextureManager::getSingleton().reloadAll();
     421    }
     422    else if (arg.key == OIS::KC_SYSRQ)   // take a screenshot
     423    {
     424        mWindow->writeContentsToTimestampedFile("screenshot", ".jpg");
     425    }
     426    else if (arg.key == OIS::KC_ESCAPE)
     427    {
     428        mShutDown = true;
     429    }
     430
     431    mCameraMan->injectKeyDown(arg);
     432    return true;
     433}
     434
     435bool BaseApplication::keyReleased( const OIS::KeyEvent &arg )
     436{
     437    mCameraMan->injectKeyUp(arg);
     438    return true;
     439}
     440
     441bool BaseApplication::mouseMoved( const OIS::MouseEvent &arg )
     442{
     443    if (mTrayMgr->injectMouseMove(arg)) return true;
     444    mCameraMan->injectMouseMove(arg);
     445    return true;
     446}
     447
     448bool BaseApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
     449{
     450    if (mTrayMgr->injectMouseDown(arg, id)) return true;
     451    mCameraMan->injectMouseDown(arg, id);
     452    return true;
     453}
     454
     455bool BaseApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
     456{
     457    if (mTrayMgr->injectMouseUp(arg, id)) return true;
     458    mCameraMan->injectMouseUp(arg, id);
     459    return true;
     460}
     461
     462//Adjust mouse clipping area
     463void BaseApplication::windowResized(Ogre::RenderWindow* rw)
     464{
     465    unsigned int width, height, depth;
     466    int left, top;
     467    rw->getMetrics(width, height, depth, left, top);
     468
     469    const OIS::MouseState &ms = mMouse->getMouseState();
     470    ms.width = width;
     471    ms.height = height;
     472}
     473
     474//Unattach OIS before window shutdown (very important under Linux)
     475void BaseApplication::windowClosed(Ogre::RenderWindow* rw)
     476{
     477    //Only close for window that created OIS (the main window in these demos)
     478    if( rw == mWindow )
     479    {
     480        if( mInputManager )
     481        {
     482            mInputManager->destroyInputObject( mMouse );
     483            mInputManager->destroyInputObject( mKeyboard );
     484
     485            OIS::InputManager::destroyInputSystem(mInputManager);
     486            mInputManager = 0;
     487        }
     488    }
     489}
  • new file Tutorials/BaseApplication.h

    - +  
     1/* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: nil; c-basic-offset: 4; c-indent-level: 4 -*-
     2-----------------------------------------------------------------------------
     3Filename:    BaseApplication.h
     4-----------------------------------------------------------------------------
     5
     6Minor modifications of this file were made to make it build with a
     7static version of OGRE on MacOS X. The modifications for the static
     8build are marked as OgreStatic. The MacOS X modifications are done
     9under the compiler conditional and marked with MacOgre. You can search
     10for these markers to see where the changes to the file have been made.
     11
     12This source file is part of the
     13   ___                 __    __ _ _    _
     14  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
     15 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
     16/ \_// (_| | | |  __/  \  /\  /| |   <| |
     17\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
     18      |___/                             
     19      Tutorial Framework
     20      http://www.ogre3d.org/tikiwiki/
     21-----------------------------------------------------------------------------
     22*/
     23#ifndef __BaseApplication_h_
     24#define __BaseApplication_h_
     25
     26// ---------------------OgreStatic-------------------------------
     27// Added for building the tutorials with a static version of OGRE
     28#define OGRE_STATIC_LIB
     29#define OGRE_STATIC_OctreeSceneManager
     30#define OGRE_STATIC_ParticleFX
     31#define OGRE_STATIC_BSPSceneManager
     32#define OGRE_STATIC_GL
     33
     34#ifdef OGRE_STATIC_LIB
     35#include <OgreStaticPluginLoader.h>
     36#endif
     37// ---------------------OgreStatic-------------------------------
     38
     39#include <OgreCamera.h>
     40#include <OgreEntity.h>
     41#include <OgreLogManager.h>
     42#include <OgreRoot.h>
     43#include <OgreViewport.h>
     44#include <OgreSceneManager.h>
     45#include <OgreRenderWindow.h>
     46#include <OgreConfigFile.h>
     47
     48#include <OISEvents.h>
     49#include <OISInputManager.h>
     50#include <OISKeyboard.h>
     51#include <OISMouse.h>
     52
     53#include <SdkTrays.h>
     54#include <SdkCameraMan.h>
     55
     56#ifdef __APPLE__ & __MACH__
     57//MacOgre
     58class MacTutorialAppLoop;
     59#endif
     60
     61class BaseApplication : public Ogre::FrameListener, public Ogre::WindowEventListener, public OIS::KeyListener, public OIS::MouseListener, OgreBites::SdkTrayListener
     62{
     63public:
     64    BaseApplication(void);
     65    virtual ~BaseApplication(void);
     66
     67    virtual void go(void);
     68
     69protected:
     70    virtual bool setup();
     71    virtual bool configure(void);
     72    virtual void chooseSceneManager(void);
     73    virtual void createCamera(void);
     74    virtual void createFrameListener(void);
     75    virtual void createScene(void) = 0; // Override me!
     76    virtual void destroyScene(void);
     77    virtual void createViewports(void);
     78    virtual void setupResources(void);
     79    virtual void createResourceListener(void);
     80    virtual void loadResources(void);
     81
     82    // Ogre::FrameListener
     83    virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
     84
     85    // OIS::KeyListener
     86    virtual bool keyPressed( const OIS::KeyEvent &arg );
     87    virtual bool keyReleased( const OIS::KeyEvent &arg );
     88    // OIS::MouseListener
     89    virtual bool mouseMoved( const OIS::MouseEvent &arg );
     90    virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
     91    virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
     92
     93    // Ogre::WindowEventListener
     94    //Adjust mouse clipping area
     95    virtual void windowResized(Ogre::RenderWindow* rw);
     96    //Unattach OIS before window shutdown (very important under Linux)
     97    virtual void windowClosed(Ogre::RenderWindow* rw);
     98
     99    Ogre::Root *mRoot;
     100    Ogre::Camera* mCamera;
     101    Ogre::SceneManager* mSceneMgr;
     102    Ogre::RenderWindow* mWindow;
     103    Ogre::String mResourcesCfg;
     104    Ogre::String mPluginsCfg;
     105
     106    // OgreBites
     107    OgreBites::SdkTrayManager* mTrayMgr;
     108    OgreBites::SdkCameraMan* mCameraMan;       // basic camera controller
     109    OgreBites::ParamsPanel* mDetailsPanel;     // sample details panel
     110    bool mCursorWasVisible;                    // was cursor visible before dialog appeared
     111    bool mShutDown;
     112
     113    //OIS Input devices
     114    OIS::InputManager* mInputManager;
     115    OIS::Mouse*    mMouse;
     116    OIS::Keyboard* mKeyboard;
     117
     118// ---------------------OgreStatic-------------------------------
     119#ifdef OGRE_STATIC_LIB
     120    Ogre::StaticPluginLoader mStaticLoader;
     121#endif
     122// ---------------------OgreStatic-------------------------------
     123
     124// ---------------------MacOgre----------------------------------
     125#ifdef __APPLE__ & __MACH__
     126    MacTutorialAppLoop *mMacLoop;
     127#endif
     128// ---------------------MacOgre----------------------------------
     129};
     130
     131#endif // #ifndef __BaseApplication_h_
  • new file Tutorials/CMakeLists.txt

    - +  
     1CMAKE_MINIMUM_REQUIRED (VERSION 2.6.3)
     2
     3IF(APPLE)
     4  LIST(APPEND CMAKE_PREFIX_PATH "/opt/local")
     5  LIST(APPEND CMAKE_MODULE_PATH "/opt/local/share/cmake/modules")
     6  LIST(APPEND CMAKE_FRAMEWORK_PATH "/opt/local/Library/Frameworks")
     7ENDIF(APPLE)
     8
     9ADD_DEFINITIONS(-O3)
     10
     11SET(OGRE_STATIC TRUE)
     12
     13FIND_PACKAGE(OGRE REQUIRED)
     14FIND_PACKAGE(OIS REQUIRED)
     15
     16SET(TUTORIAL_ALL_INCLUDES
     17  ${OGRE_INCLUDE_DIRS}
     18  ${OGRE_RenderSystem_GL_INCLUDE_DIR}
     19  ${OGRE_Plugin_BSPSceneManager_INCLUDE_DIR}
     20  ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIR}
     21  ${OGRE_Plugin_PCZSceneManager_INCLUDE_DIR}
     22  ${OGRE_Plugin_ParticleFX_INCLUDE_DIR}
     23  ${OIS_INCLUDE_DIRS})
     24
     25SET(TUTORIAL_ALL_LIBRARIES
     26  ${OGRE_LIBRARIES}
     27  ${OGRE_RenderSystem_GL_LIBRARIES}
     28  ${OGRE_Plugin_BSPSceneManager_LIBRARIES}
     29  ${OGRE_Plugin_OctreeSceneManager_LIBRARIES}
     30  ${OGRE_Plugin_PCZSceneManager_LIBRARIES}
     31  ${OGRE_Plugin_ParticleFX_LIBRARIES}
     32  ${OIS_LIBRARIES})
     33
     34INCLUDE_DIRECTORIES(${TUTORIAL_ALL_INCLUDES})
     35
     36ADD_EXECUTABLE(TutorialApp
     37  BaseApplication.cpp
     38  TutorialApplication.cpp
     39  mac_app_loop.mm)
     40
     41TARGET_LINK_LIBRARIES(TutorialApp ${TUTORIAL_ALL_LIBRARIES})
     42
     43CONFIGURE_FILE(${OGRE_MEDIA_DIR}/../resources.cfg
     44  ${CMAKE_CURRENT_BINARY_DIR}/resources.cfg
     45  @ONLY)
     46 No newline at end of file
  • new file Tutorials/README.txt

    - +  
     1This folder contains the Tutorial code found on OGRE Wiki, adopted
     2slightly to run on a static version of OGRE for MacOS X. The source
     3code is essentially unchanged, there are just a few emacs markers to
     4preserve the formatting.
     5
     6To build, do:
     7
     8mkdir build
     9cd build
     10cmake ..
     11make
     12
     13There should be an application named TutorialApp after the compile
     14 No newline at end of file
  • new file Tutorials/TutorialApplication.cpp

    - +  
     1/* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: nil; c-basic-offset: 4; c-indent-level: 4 -*-
     2-----------------------------------------------------------------------------
     3Filename:    TutorialApplication.cpp
     4-----------------------------------------------------------------------------
     5
     6This source file is part of the
     7   ___                 __    __ _ _    _
     8  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
     9 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
     10/ \_// (_| | | |  __/  \  /\  /| |   <| |
     11\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
     12      |___/                             
     13      Tutorial Framework
     14      http://www.ogre3d.org/tikiwiki/
     15-----------------------------------------------------------------------------
     16*/
     17#include "TutorialApplication.h"
     18
     19//-------------------------------------------------------------------------------------
     20TutorialApplication::TutorialApplication(void)
     21{
     22}
     23//-------------------------------------------------------------------------------------
     24TutorialApplication::~TutorialApplication(void)
     25{
     26}
     27
     28//-------------------------------------------------------------------------------------
     29void TutorialApplication::createScene(void)
     30{
     31    // create your scene here :)
     32}
     33
     34
     35
     36#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
     37#define WIN32_LEAN_AND_MEAN
     38#include "windows.h"
     39#endif
     40
     41#ifdef __cplusplus
     42extern "C" {
     43#endif
     44
     45#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
     46    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
     47#else
     48    int main(int argc, char *argv[])
     49#endif
     50    {
     51        // Create application object
     52        TutorialApplication app;
     53
     54        try {
     55            app.go();
     56        } catch( Ogre::Exception& e ) {
     57#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
     58            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
     59#else
     60            std::cerr << "An exception has occured: " <<
     61                e.getFullDescription().c_str() << std::endl;
     62#endif
     63        }
     64
     65        return 0;
     66    }
     67
     68#ifdef __cplusplus
     69}
     70#endif
  • new file Tutorials/TutorialApplication.h

    - +  
     1/* -*- mode: c++; c-file-style: "linux"; indent-tabs-mode: nil; c-basic-offset: 4; c-indent-level: 4 -*-
     2-----------------------------------------------------------------------------
     3Filename:    TutorialApplication.h
     4-----------------------------------------------------------------------------
     5
     6This source file is part of the
     7   ___                 __    __ _ _    _
     8  /___\__ _ _ __ ___  / / /\ \ (_) | _(_)
     9 //  // _` | '__/ _ \ \ \/  \/ / | |/ / |
     10/ \_// (_| | | |  __/  \  /\  /| |   <| |
     11\___/ \__, |_|  \___|   \/  \/ |_|_|\_\_|
     12      |___/                             
     13      Tutorial Framework
     14      http://www.ogre3d.org/tikiwiki/
     15-----------------------------------------------------------------------------
     16*/
     17#ifndef __TutorialApplication_h_
     18#define __TutorialApplication_h_
     19
     20#include "BaseApplication.h"
     21
     22class TutorialApplication : public BaseApplication
     23{
     24public:
     25    TutorialApplication(void);
     26    virtual ~TutorialApplication(void);
     27
     28protected:
     29    virtual void createScene(void);
     30};
     31
     32#endif // #ifndef __TutorialApplication_h_
  • new file Tutorials/mac_app_loop.h

    - +  
     1// Copyright (c) 2011 Marin Saric
     2// Portions Copyright (c) 2009-2011 Matt Gallagher
     3//
     4// This software is provided 'as-is', without any express or implied
     5// warranty. In no event will the authors be held liable for any damages
     6// arising from the use of this software.
     7//
     8// Permission is granted to anyone to use this software for any purpose,
     9// including commercial applications, and to alter it and redistribute it
     10// freely, subject to the following restrictions:
     11//
     12// 1. The origin of this software must not be misrepresented; you must not
     13// claim that you wrote the original software. If you use this software in
     14// a product, an acknowledgment in the product documentation would be
     15// appreciated but is not required.
     16//
     17// 2. Altered source versions must be plainly marked as such, and must not
     18// be misrepresented as being the original software.
     19//
     20// 3. This notice may not be removed or altered from any source
     21// distribution.
     22//
     23// MacAppLoop
     24//
     25// The MacAppLoop class abstracts away the MacOS X Cocoa internals
     26//
     27// This class header has a pure C++ interface and does not depend on you
     28// doing an #include of any other files with your code.
     29//
     30// You also do NOT need to setup an Application Bundle, Info.plist, nib
     31// files or do any of the other very MacOS X specific steps.
     32//
     33// To compile mac_app_loop.mm, you need either Apple's version of gcc or
     34// clang. Remember to link with "-framework Cocoa" flag.
     35//
     36// This abstraction isolates you from needing to know about how the
     37// Cocoa stuff works.
     38//
     39// If you just want to "play nice" when calling Cocoa-based routines,
     40// it is probably enough to declare a MacMemoryPool before calling
     41// such code. Creating a MacMemoryPool is comparable to the cost of
     42// allocating a tiny block of memory. Thus, you can use it in
     43// per-frame loops, etc.
     44//
     45// --------------------------------------------------------------------------
     46// Code example for MacAppLoop:
     47// The user of the "mac_app_loop.h" only needs to do this:
     48//
     49// # include "mac_app_loop.h"
     50//
     51// class MyAppLoop : public MacAppLoop {
     52//   void RenderFrame(double time_since_last_frame) {
     53//      do something...
     54//   }
     55// };
     56//
     57// and then
     58//
     59// int main(int argc, char **argv) {
     60//   MyAppLoop app_loop;
     61//
     62//   // make sure to call Setup as early as possible in your code
     63//   app_loop.Setup();
     64//
     65//   app_loop.Run();
     66//   return 0;
     67// }
     68// --------------------------------------------------------------------------
     69// Code example for MacMemoryPool:
     70//
     71// # include "mac_app_loop.h"
     72//
     73// void MyFunctionThatCallsCocoaSystems() {
     74//    MacMemoryPool memory_pool;
     75//
     76//    SomeCocoaBasedRoutine();
     77// }
     78
     79#ifndef MAC_APP_LOOP_H
     80#define MAC_APP_LOOP_H
     81
     82// We hide the actual implementation in this class
     83class MacAppLoopPrivate;
     84
     85class MacAppLoop {
     86 public:
     87  MacAppLoop();
     88  virtual ~MacAppLoop();
     89
     90  // Call this before Run().
     91  // refresh_hz - how many times per second do is RenderFrame called
     92  void Setup(double refresh_hz = 60.0);
     93
     94  // Call this to get the App to Shutdown
     95  void RequestShutdown();
     96
     97  // Override this method to get something to happen
     98  virtual void RenderFrame(double time_since_last_frame) {}
     99
     100  // Call this to enter the application loop
     101  void Run();
     102
     103 private:
     104  MacAppLoopPrivate *private_;
     105
     106  // Disallow copying of this object
     107  MacAppLoop(const MacAppLoop &rhs);
     108  MacAppLoop& operator= (const MacAppLoop &rhs);
     109};
     110
     111// Declare a MacMemoryPool in places that call Cocoa based code.
     112// You will need at least one MacMemoryPool per application
     113class MacMemoryPool {
     114public:
     115  MacMemoryPool();
     116  ~MacMemoryPool();
     117
     118private:
     119  void *data_;
     120
     121  // Disallow copying of this object
     122  MacMemoryPool(const MacAppLoop &rhs);
     123  MacMemoryPool& operator= (const MacAppLoop &rhs);
     124};
     125
     126#endif  // MAC_APP_LOOP_H
  • new file Tutorials/mac_app_loop.mm

    - +  
     1// Copyright (c) 2011 Marin Saric
     2// Portions Copyright (c) 2009-2011 Matt Gallagher
     3//
     4// This software is provided 'as-is', without any express or implied
     5// warranty. In no event will the authors be held liable for any damages
     6// arising from the use of this software.
     7//
     8// Permission is granted to anyone to use this software for any purpose,
     9// including commercial applications, and to alter it and redistribute it
     10// freely, subject to the following restrictions:
     11//
     12// 1. The origin of this software must not be misrepresented; you must not
     13// claim that you wrote the original software. If you use this software in
     14// a product, an acknowledgment in the product documentation would be
     15// appreciated but is not required.
     16//
     17// 2. Altered source versions must be plainly marked as such, and must not
     18// be misrepresented as being the original software.
     19//
     20// 3. This notice may not be removed or altered from any source
     21// distribution.
     22//
     23// MacAppLoop
     24//
     25// The idea of a NSTimer controlled Cocoa application stems from
     26// masterfalcon's (David Rogers') implementation of SampleBrowser for
     27// OGRE (Object-oriented Graphics Rendering Engine).
     28//
     29// The art of implementing a bundle-less, nib-less, Info.plist-less
     30// Objective-C object is owed to Matt Gallagher, and an appropriate
     31// zlib license copyright notice is included with the
     32// MacAppLoopPrivate::Setup code
     33//
     34// This file must be compiled with Objective-C++ aware compiler,
     35// either clang or Apple's version of gcc
     36//
     37// The MacAppLoop header file does not need Objective-C++ and can be
     38// included by C++ programs.
     39// The linkage parameters need to be "-framework Cocoa"
     40
     41# include "mac_app_loop.h"
     42
     43# include <iostream>
     44# include <exception>
     45# import <Cocoa/Cocoa.h>
     46
     47// The private implementation of the Mac Application Loop
     48// The MacAppLoop class forwards all of its calls to MacAppLoopPrivate
     49// The MacAppLoop methods are further down in the file
     50class MacAppLoopPrivate {
     51public:
     52  MacAppLoopPrivate(MacAppLoop &app_loop);
     53  ~MacAppLoopPrivate();
     54
     55  void SetRefreshHz(double refresh_hz) { refresh_hz_ = refresh_hz; }
     56  inline double refresh_hz() { return refresh_hz_; }
     57
     58  void Setup(double refresh_hz);
     59
     60  void RequestShutdown() { exit_called_ = true; }
     61  inline bool wants_shutdown() { return exit_called_; }
     62
     63  void RenderFrame(double time_since_last_frame);
     64
     65  void Run();
     66
     67private:
     68  // Link to the public instance of the class
     69  MacAppLoop &app_loop_;
     70
     71  // Internal variables
     72  double refresh_hz_;  // Refresh rate in Hz
     73  bool is_setup_;      // true if Setup() called
     74  bool exit_called_;   // true if RequestShutdown() called
     75
     76  // Link to the Objective-C Cocoa object
     77  id app_delegate_;
     78
     79  // The Cocoa envrionment autorelease pool
     80  NSAutoreleasePool *pool_;
     81};
     82
     83//--------------------------------------------------------------------------
     84//               The implementation of MacAppLoop
     85//           (simply forwards to MacAppLoopPrivate)
     86
     87MacAppLoop::MacAppLoop()
     88: private_(new MacAppLoopPrivate(*this)) {
     89}
     90
     91MacAppLoop::~MacAppLoop() { delete private_; }
     92
     93void MacAppLoop::Setup(double refresh_hz) { private_->Setup(refresh_hz); }
     94void MacAppLoop::RequestShutdown() { private_->RequestShutdown(); }
     95void MacAppLoop::Run() { private_->Run(); }
     96
     97//--------------------------------------------------------------------------
     98//           The MacAppDelegate Objective-C++ code region
     99//
     100
     101// Supress the warnings for not implementing buttonPressed
     102@implementation NSApplication (_suppressUnimplementedActionWarning)
     103- (void) buttonPressed:(id)sender { /* Do nothing */ }
     104@end
     105
     106// MacAppDelegate is the Objective-C++ Cocoa application delegate based
     107// in essential design on the SampleBrowser_OSX.h code
     108@interface MacAppDelegate : NSObject <NSApplicationDelegate> {
     109  //  An instance of the NSTimer class that will
     110  //  fire at the desired refresh rate.
     111  NSTimer *timer;
     112
     113  // A pointer to a private implementation of MacAppLoop
     114  // (the MacAppLoopPrivate code is  further below in this file)
     115  MacAppLoopPrivate *app_loop_private;
     116}
     117
     118// MacAppDelegate methods:
     119//  initWithPrivateLoop is used as a "constructor"
     120- (MacAppDelegate *)initWithPrivateLoop:(MacAppLoopPrivate *)loop;
     121
     122//  renderFrame is periodically called by the NSTimer instance 'timer'
     123- (void)renderFrame:(id)sender;
     124
     125//  appShutdown is invoked when the MacAppLoop requests a shutdown
     126- (void)appShutdown;
     127@end
     128
     129// Implementation of the MacAppDelegate methods follow
     130@implementation MacAppDelegate
     131// The MacAppDelegate "constructor" accepts a pointer to an instance
     132// of the MacAppLoopPrivate, an instance of C++ class which is a
     133// private implementation
     134- (MacAppDelegate *)initWithPrivateLoop:(MacAppLoopPrivate *)loop {
     135  self = [super init];
     136
     137  if (self) app_loop_private = loop;
     138
     139  return self;
     140}
     141
     142// The MacOS X Cocoa subsystem will call this method as soon as the
     143// application is ready to start executing UI code.
     144- (void)applicationDidFinishLaunching:(NSNotification *)application {
     145  double refresh_hz = app_loop_private->refresh_hz();
     146
     147  // If we have a sane refresh rate specified, we create an instance
     148  // of the NSTimer class, specifying [self renderFrame] as the target.
     149  // The timer invokes renderFrame at the frequency of refresh_hz per second
     150  if (refresh_hz > 0.) {
     151    timer = [NSTimer
     152             scheduledTimerWithTimeInterval:((NSTimeInterval)
     153                                             (1.0 / refresh_hz))
     154                                     target:self
     155                                   selector:@selector(renderFrame:)
     156                                   userInfo:nil
     157                                    repeats:YES];
     158  }
     159}
     160
     161// The renderframe method is called periodically by the timer instance
     162- (void)renderFrame:(id)sender {
     163  // We check whether the Mac application loop requested a shutdown
     164  if (app_loop_private->wants_shutdown()) {
     165    [self appShutdown];
     166    return;
     167  }
     168
     169  // No shutdown was requested so render the frame, passing the time
     170  // elapsed since the last frame
     171  app_loop_private->RenderFrame([timer timeInterval]);
     172}
     173
     174//  appShutdown is invoked when the MacAppLoop requests a shutdown
     175- (void)appShutdown {
     176  // Destroy the timer object
     177  [timer invalidate];
     178  timer = nil;
     179 
     180  // Do [NSapp stop] as soon as possible in the run loop
     181  // (does not execute immediately)
     182  // This will exit the run loop and return control to the caller of [NSApp run]
     183  [NSApp performSelector:@selector(stop:)
     184              withObject:nil
     185              afterDelay:0.0];
     186}
     187
     188- (void)dealloc {
     189  if(timer) {
     190    [timer invalidate];
     191    timer = nil;
     192  }
     193
     194  [super dealloc];
     195}
     196@end
     197
     198//--------------------------------------------------------------------------
     199//                MacAppLoopPrivate implementation
     200
     201MacAppLoopPrivate::MacAppLoopPrivate(MacAppLoop &app_loop)
     202: app_loop_(app_loop),
     203  refresh_hz_(0),
     204  is_setup_(false),
     205  exit_called_(false),
     206  pool_(NULL) {
     207}
     208
     209MacAppLoopPrivate::~MacAppLoopPrivate() {
     210  // Destroy the autorelease pool
     211  if (is_setup_) {
     212    [pool_ release];
     213  }
     214}
     215
     216void MacAppLoopPrivate::Setup(double refresh_hz) {
     217  if (is_setup_ || exit_called_) return;
     218
     219  SetRefreshHz(refresh_hz);
     220
     221  // ----------------------------------------------------------------------
     222  // The code below uses an altered version of Matt Galagher's example:
     223  // http://cocoawithlove.com/2010/09/minimalist-cocoa-programming.html
     224  //
     225  // Copyright (c) 2009-2011 Matt Gallagher. All rights reserved.
     226  //
     227  // This software is provided 'as-is', without any express or implied
     228  // warranty. In no event will the authors be held liable for any damages
     229  // arising from the use of this software. Permission is granted to anyone
     230  // to use this software for any purpose, including commercial
     231  // applications, and to alter it and redistribute it freely, subject to
     232  // the following restrictions:
     233  //
     234  // 1. The origin of this software must not be misrepresented; you must
     235  //    not claim that you wrote the original software. If you use this
     236  //    software in a product, an acknowledgment in the product
     237  //    documentation would be appreciated but is not required.
     238  //
     239  // 2. Altered source versions must be plainly marked as such, and must
     240  //    not be misrepresented as being the original software.
     241  //
     242  // 3. This notice may not be removed or altered from any source
     243  //    distribution.
     244
     245  pool_ = [NSAutoreleasePool new];
     246  [NSApplication sharedApplication];
     247  [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
     248
     249  id menubar = [[NSMenu new] autorelease];
     250  id appMenuItem = [[NSMenuItem new] autorelease];
     251  [menubar addItem:appMenuItem];
     252  [NSApp setMainMenu:menubar];
     253  id appMenu = [[NSMenu new] autorelease];
     254  id appName = [[NSProcessInfo processInfo] processName];
     255  id quitTitle = [@"Quit " stringByAppendingString:appName];
     256  id quitMenuItem =
     257    [[[NSMenuItem alloc]
     258      initWithTitle:quitTitle
     259      action:@selector(stop:)
     260      keyEquivalent:@"q"] autorelease];
     261
     262  [appMenu addItem:quitMenuItem];
     263  [appMenuItem setSubmenu:appMenu];
     264  // ----------------------------------------------------------------------
     265 
     266  app_delegate_ = [[MacAppDelegate alloc]
     267                   initWithPrivateLoop:this];
     268
     269  is_setup_ = true;
     270}
     271
     272void MacAppLoopPrivate::Run() {
     273  if (!is_setup_ || exit_called_) return;
     274
     275  [[NSApplication sharedApplication] setDelegate:app_delegate_];
     276  [NSApp activateIgnoringOtherApps:YES];
     277  [NSApp run];
     278
     279  // Set exit_called_, so that Run cannot be re-entered
     280  exit_called_ = true;
     281}
     282
     283void MacAppLoopPrivate::RenderFrame(double time_since_last_frame) {
     284  try {
     285    app_loop_.RenderFrame(time_since_last_frame);
     286  } catch (const std::exception& e) {
     287    std::cerr << "MacAppLoop::RenderFrame: "
     288              << "Caught an exception: "
     289              << e.what() << std::endl
     290              << "MacAppLoop::RenderFrame: shutting down." << std::endl;
     291    RequestShutdown();
     292  } catch (...) {
     293    std::cerr << "MacAppLoop::RenderFrame: "
     294              << "Exception caught, shutting down." << std::endl;
     295    RequestShutdown();
     296  }
     297}
     298
     299//--------------------------------------------------------------------------
     300//                MacMemoryPool implementation
     301
     302MacMemoryPool::MacMemoryPool() {
     303  data_ = (void *) [NSAutoreleasePool new];
     304}
     305
     306MacMemoryPool::~MacMemoryPool() {
     307  [((NSAutoreleasePool *) data_) release];
     308}