Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

GlWindowOSX.cpp

Go to the documentation of this file.
00001 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
00002  *
00003  * VR Juggler is (C) Copyright 1998-2003 by Iowa State University
00004  *
00005  * Original Authors:
00006  *   Allen Bierbaum, Christopher Just,
00007  *   Patrick Hartling, Kevin Meinert,
00008  *   Carolina Cruz-Neira, Albert Baker
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Library General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Library General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Library General Public
00021  * License along with this library; if not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00023  * Boston, MA 02111-1307, USA.
00024  *
00025  * -----------------------------------------------------------------
00026  * File:          $RCSfile: GlWindowOSX.cpp,v $
00027  * Date modified: $Date: 2003/10/12 21:39:23 $
00028  * Version:       $Revision: 1.25 $
00029  * -----------------------------------------------------------------
00030  *
00031  *************** <auto-copyright.pl END do not edit this line> ***************/
00032 
00033 #include <vrj/vrjConfig.h>
00034 
00035 #include <boost/concept_check.hpp>
00036 #include <OpenGL/gl.h>
00037 
00038 #include <vrj/Draw/OGL/GlWindow.h>
00039 #include <vrj/Kernel/Kernel.h>
00040 #include <vrj/Util/Debug.h>
00041 #include <vrj/Display/Display.h>
00042 #include <vrj/Display/DisplayManager.h>
00043 #include <jccl/Config/ConfigElement.h>
00044 
00045 #include <vrj/Draw/OGL/GlWindowOSX.h>
00046 
00047 namespace vrj
00048 {
00049 
00050 AGLContext GlWindowOSX::aglShareContext = NULL;
00051 
00052 GlWindowOSX::GlWindowOSX()
00053    : GlWindow()
00054    , gadget::EventWindowOSX()
00055 {
00056 }
00057 
00058 GlWindowOSX::~GlWindowOSX() {
00059     close();
00060 }
00061 
00062 void GlWindowOSX::swapBuffers() {
00063     vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_HEX_LVL) << "vjGlWindowOSX::swapBuffers()" << std::endl << vprDEBUG_FLUSH;
00064     if(aglContext)
00065     {
00066         aglSwapBuffers (aglContext);
00067 
00068         /* This code is supposed to change the size of the window
00069         ** it works but it is a waste to check to see if the size of the window is a
00070         ** different every frame.  If we want to implement this feature
00071         ** we should capture the window resize event and change based on that
00072         Rect rectPort;
00073         if(gpWindow)
00074         {
00075             //If the window changed size
00076             GetWindowPortBounds (gpWindow, &rectPort);
00077             int newWidth = rectPort.right - rectPort.left;
00078             int newHeight = rectPort.bottom - rectPort.top;
00079             if( newWidth != window_width || newHeight != window_height)
00080             {
00081                 // Refresh the window with black...
00082                 aglUpdateContext (aglContext);
00083                 glViewport (0, 0, rectPort.right - rectPort.left, rectPort.bottom - rectPort.top);
00084                 window_width = newWidth; window_height = newHeight;
00085                 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
00086                 glClear (GL_COLOR_BUFFER_BIT);
00087                 aglSwapBuffers (aglContext);
00088 
00089                 glViewport (0, 0, rectPort.right - rectPort.left, rectPort.bottom - rectPort.top);
00090             }
00091         }
00092         */
00093     }
00094 
00095 }
00096 
00097 int GlWindowOSX::open() {
00098    vpr::DebugOutputGuard(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL,
00099                          "vrj::GlWindowOSX::open()\n",
00100                          "vrj::GlWindowOSX::open() done.\n");
00101 
00102     //Get the size of the screen from core graphics
00103     //I'll need to check to see how this works with multiple monitors
00104     CGRect bounds;
00105     bounds = CGDisplayBounds(kCGDirectMainDisplay);
00106     
00107     // If the size of the window and the size of the screen are the same
00108     // switch to fullscreen mode
00109     // Note: this is not true fullscreen the menu bar and dock are just hiden
00110     // this will not give you the speed increases you could get if you gave GL
00111     // full control of the screen
00112     if( bounds.size.height == window_height && bounds.size.width == window_width)
00113     {
00114         vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL) << "FULLSCREEN Mode enabled" << std::endl << vprDEBUG_FLUSH;
00115         HideMenuBar ();
00116     }
00117 
00118 
00119     //set the window size and location with the height adjusted
00120     SetRect(&rectWin, origin_x , bounds.size.height - origin_y - window_height,
00121                             origin_x + window_width, bounds.size.height - origin_y);
00122                             /* left, top, right, bottom */
00123     /*
00124     rectWin.top = origin_y;
00125     rectWin.left = origin_x;
00126     rectWin.bottom = origin_y + window_height;
00127     rectWin.right = origin_x + window_width;
00128     */
00129     if (noErr != CreateNewWindow (kDocumentWindowClass, kWindowStandardDocumentAttributes | kWindowNoShadowAttribute | kWindowLiveResizeAttribute, &rectWin, &gpWindow))
00130     {
00131         vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) << "vjGlWindowOSX::open()    Window failed to open!" << std::endl << vprDEBUG_FLUSH;
00132         return false;
00133     }
00134     SetWindowTitleWithCFString(gpWindow,window_title);
00135     InstallStandardEventHandler(GetWindowEventTarget(gpWindow));
00136     ChangeWindowAttributes(gpWindow, NULL, kWindowCloseBoxAttribute );
00137 
00138     //This is the an event source window.
00139     if (mAreEventSource == true)
00140     {
00141         vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00142            << "vrj::GlWindowOSX::config(): We will be an event source\n"
00143            << vprDEBUG_FLUSH;
00144 
00145         gadget::EventWindowOSX::mWindow = gpWindow;
00146         gadget::Input* dev_ptr = dynamic_cast<gadget::Input*>(this);
00147         vrj::Kernel::instance()->getInputManager()->addDevice(dev_ptr);
00148 
00149         startSampling();
00150     }
00151 
00152 
00153     ShowWindow (gpWindow);
00154     SetPort ( (GrafPtr) GetWindowPort(gpWindow) );
00155     glInfo.fAcceleratedMust = false;    // must renderer be accelerated?
00156     glInfo.VRAM = 0 * 1048576;          // minimum VRAM (if not zero this is always required)
00157     glInfo.textureRAM = 0 * 1048576;    // minimum texture RAM (if not zero this is always required)
00158     glInfo.fDraggable = false;      // desired vertical refresh frequency in Hz (0 = any)
00159     glInfo.fmt = 0;                 // output pixel format
00160 
00161     int i = 0;
00162     glInfo.aglAttributes [i++] = AGL_RGBA;
00163     glInfo.aglAttributes [i++] = AGL_DOUBLEBUFFER;
00164     glInfo.aglAttributes [i++] = AGL_DEPTH_SIZE;
00165     glInfo.aglAttributes [i++] = 32;
00166     glInfo.aglAttributes [i++] = AGL_NONE;
00167 
00168     BuildGLFromWindow (gpWindow, &aglContext, &glInfo);
00169     if (!aglContext)
00170     {
00171         DestroyGLFromWindow (&aglContext, &glInfo);
00172         vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL) << "vjGlWindowOSX::open()    Window could not create GL Context!" << std::endl << vprDEBUG_FLUSH;
00173         return false;
00174     }
00175     Rect rectPort;
00176     GetWindowPortBounds (gpWindow, &rectPort);
00177     aglUpdateContext (aglContext);
00178     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
00179     glClear (GL_COLOR_BUFFER_BIT);
00180     aglSwapBuffers (aglContext);
00181     glViewport (0, 0, rectPort.right - rectPort.left, rectPort.bottom - rectPort.top);
00182 
00183     window_is_open = true;
00184     return true;
00185 }
00186 
00187 int GlWindowOSX::close() {
00188     vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00189        << "vrj::GlWindowOSX::close()" << std::endl << vprDEBUG_FLUSH;
00190     if(!gpWindow) return false;
00191 
00192     DestroyGLFromWindow (&aglContext, &glInfo);
00193     DisposeWindow (gpWindow);
00194 
00195     gpWindow = NULL;
00196     gFrameWindow = 0;
00197     gTimeWindow.hi = 0;
00198     gTimeWindow.lo = 0;
00199     gRotation = 0.0;
00200     return true;
00201 }
00202 
00203 bool GlWindowOSX::makeCurrent() {
00204     vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_HEX_LVL) << "vjGlWindowOSX::makeCurrent()" << std::endl << vprDEBUG_FLUSH;
00205     if(!aglContext) return false;
00206     aglSetCurrentContext (aglContext);
00207     return true;
00208 }
00209 
00210 void GlWindowOSX::configWindow(vrj::Display* _display)
00211 {
00212    vpr::DebugOutputGuard(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL,
00213                          "vrj::GlWindowOSX::configWindow()\n",
00214                          "vrj::GlWindowOSX::configWindow() done.\n");
00215 
00216    GlWindow::configWindow(_display);
00217 
00218     // Get the vector of display elements.
00219    jccl::ConfigElementPtr disp_sys_elt = DisplayManager::instance()->getDisplaySystemElement();
00220    jccl::ConfigElementPtr display_elt = _display->getConfigElement();
00221 
00222    mPipe = _display->getPipe();
00223    vprASSERT(mPipe >= 0);
00224 
00225    window_title = CFStringCreateWithCString(NULL, _display->getName().c_str(), kCFStringEncodingMacRoman);
00226 
00227    mAreEventSource = display_elt->getProperty<bool>("act_as_event_source");
00228    // if should act as an event source
00229    if ( true == mAreEventSource )
00230    {
00231       vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00232          << "vrj::GlWindowOSX::config(): We will be an event source\n"
00233          << vprDEBUG_FLUSH;
00234 
00235       // Configure keyboard device portion
00236       jccl::ConfigElementPtr event_win_element =
00237          display_elt->getProperty<jccl::ConfigElementPtr>("event_window_device");
00238 
00239       // Set the name of the element to the same as the parent element (so we
00240       // can point at it).
00241       //event_win_element->setProperty("name", display_elt->getName();
00242 
00243       bool test = gadget::EventWindowOSX::config(event_win_element);
00244 
00245       if (test == false)
00246       {
00247          vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CRITICAL_LVL)
00248             << "vrj::GlWindowOSX::config(): Failed to configure gadget::EventWindowOSX\n"
00249             << vprDEBUG_FLUSH;
00250       }
00251 
00252       // Custom configuration These proably do not matter
00253       //gadget::EventWindowOSX::m_width = GlWindowXWin::window_width;
00254       //gadget::EventWindowOSX::m_height = GlWindowXWin::window_height;
00255 
00256       //mWeOwnTheWindow = false;      // Event window device does not own window
00257    }
00258 
00259 
00260 }
00261 
00262 bool GlWindowOSX::createHardwareSwapGroup(std::vector<GlWindow*> wins)
00263 {
00264    boost::ignore_unused_variable_warning(wins);
00265    return true; // This is not supported, just stubbed out.
00266 }
00267 
00268 // ============================================================================
00269 // The following methods come from Carbon SetupGL 1.5 distributed by Apple
00270 // Corporation.  Their use is here is permitted by the license.
00271 // ============================================================================
00272 
00273 // ----------------------------------------------------------------------------
00274 // BuildGLFromWindow
00275 //
00276 // Takes window in the form of an AGLDrawable and geometry request and tries
00277 // to build best context
00278 //
00279 // Inputs:  aglDraw: a valid AGLDrawable (i.e., a WindowPtr)
00280 //      *pcontextInfo: request and requirements for cotext and drawable
00281 //
00282 // Outputs: *paglContext as allocated
00283 //          *pcontextInfo:  allocated parameters
00284 //
00285 // if fail to allocate: paglContext will be NULL
00286 // if error: will return error and paglContext will be NULL
00287 // ----------------------------------------------------------------------------
00288 OSStatus GlWindowOSX::BuildGLFromWindow (WindowPtr pWindow,
00289                                            AGLContext* paglContext,
00290                                            structGLWindowInfo* pcontextInfo)
00291 {
00292    if (!pWindow)
00293       return paramErr;
00294    return BuildGLonWindow(pWindow, paglContext, pcontextInfo);
00295 }
00296 
00297 OSStatus GlWindowOSX::BuildGLonWindow (WindowPtr pWindow,
00298                                          AGLContext* paglContext,
00299                                          structGLWindowInfo* pcontextInfo)
00300 {
00301    GDHandle hGD = NULL;
00302    short numDevices;
00303    GLint depthSizeSupport;
00304    OSStatus err = noErr;
00305 
00306    if (!pWindow || !pcontextInfo)
00307    {
00308       ReportError ("NULL parameter passed to BuildGLonDrawable.");
00309       return paramErr;
00310    }
00311 
00312    // check renderere VRAM and acceleration
00313    numDevices = FindGDHandleFromWindow (pWindow, &hGD);
00314    // so what do we do here?
00315    if (!pcontextInfo->fDraggable)    // if numDevices > 1 then we will only be using the software renderer otherwise check only window device
00316    {
00317       if ((numDevices > 1) || (numDevices == 0)) // this window spans mulitple devices thus will be software only
00318       {
00319          // software renderer
00320          // infinite VRAM, infinite textureRAM, not accelerated
00321          if (pcontextInfo->fAcceleratedMust)
00322          {
00323             ReportError ("Unable to accelerate window that spans multiple devices");
00324             return err;
00325          }
00326       }
00327       else // not draggable on single device
00328       {
00329          if (!CheckRenderer (hGD, &(pcontextInfo->VRAM), &(pcontextInfo->textureRAM), &depthSizeSupport, pcontextInfo->fAcceleratedMust))
00330          {
00331             ReportError ("Renderer check failed");
00332             return err;
00333          }
00334       }
00335    }
00336    // else draggable so must check all for support (each device should have at least one renderer that meets the requirements)
00337    else if (!CheckAllDeviceRenderers (&(pcontextInfo->VRAM), &(pcontextInfo->textureRAM), &depthSizeSupport, pcontextInfo->fAcceleratedMust))
00338    {
00339       ReportError ("Renderer check failed");
00340       return err;
00341    }
00342 
00343    // do agl
00344    if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existance of OpenGL
00345    {
00346       ReportError ("OpenGL not installed");
00347       return NULL;
00348    }
00349    // we successfully passed the renderer check
00350 
00351    if ((!pcontextInfo->fDraggable && (numDevices == 1)))  // not draggable on a single device
00352       pcontextInfo->fmt = aglChoosePixelFormat (&hGD, 1, pcontextInfo->aglAttributes); // get an appropriate pixel format
00353    else
00354       pcontextInfo->fmt = aglChoosePixelFormat (NULL, 0, pcontextInfo->aglAttributes); // get an appropriate pixel format
00355 
00356    aglReportError();
00357 
00358    if (NULL == pcontextInfo->fmt)
00359    {
00360       ReportError("Could not find valid pixel format");
00361       return NULL;
00362    }
00363 
00364    // using a default method of sharing all the contexts enables texture sharing across these contexts by default
00365    *paglContext = aglCreateContext (pcontextInfo->fmt, aglShareContext);            // Create an AGL context
00366    aglReportError ();
00367    if (NULL == *paglContext)
00368    {
00369       ReportError ("Could not create context");
00370       return NULL;
00371    }
00372    if (aglShareContext == NULL)
00373       aglShareContext = *paglContext;
00374 
00375    if (!aglSetDrawable (*paglContext, GetWindowPort (pWindow))) // attach the CGrafPtr to the context
00376       return aglReportError ();
00377 
00378    if(!aglSetCurrentContext (*paglContext)) // make the context the current context
00379       return aglReportError ();
00380 
00381    return err;
00382 }
00383 
00384 // ----------------------------------------------------------------------------
00385 // DestroyGLFromWindow
00386 //
00387 // Destroys context that waas allocated with BuildGLFromWindow
00388 // Ouputs: *paglContext should be NULL on exit
00389 // ----------------------------------------------------------------------------
00390 OSStatus GlWindowOSX::DestroyGLFromWindow (AGLContext* paglContext,
00391                                              structGLWindowInfo* pcontextInfo)
00392 {
00393     OSStatus err;
00394 
00395     if ((!paglContext) || (!*paglContext))
00396         return paramErr; // not a valid context
00397     glFinish ();
00398     aglSetCurrentContext (NULL);
00399     err = aglReportError ();
00400     aglSetDrawable (*paglContext, NULL);
00401     err = aglReportError ();
00402     aglDestroyContext (*paglContext);
00403     err = aglReportError ();
00404     *paglContext = NULL;
00405 
00406     if (pcontextInfo->fmt)
00407     {
00408         aglDestroyPixelFormat (pcontextInfo->fmt); // pixel format is no longer valid
00409         err = aglReportError ();
00410     }
00411     pcontextInfo->fmt = 0;
00412 
00413     return err;
00414 }
00415 
00416 short GlWindowOSX::FindGDHandleFromWindow (WindowPtr pWindow,
00417                                              GDHandle* phgdOnThisDevice)
00418 {
00419    GrafPtr pgpSave;
00420    Rect rectWind, rectSect;
00421    long greatestArea, sectArea;
00422    short numDevices = 0;
00423    GDHandle hgdNthDevice;
00424 
00425    if (!pWindow || !phgdOnThisDevice)
00426       return NULL;
00427 
00428    *phgdOnThisDevice = NULL;
00429 
00430    GetPort (&pgpSave);
00431    SetPortWindowPort (pWindow);
00432 
00433 #if TARGET_API_MAC_CARBON
00434    GetWindowPortBounds (pWindow, &rectWind);
00435 #else
00436    rectWind = pWindow->portRect;
00437 #endif // TARGET_API_MAC_CARBON
00438    LocalToGlobal ((Point*)& rectWind.top);   // convert to global coordinates
00439    LocalToGlobal ((Point*)& rectWind.bottom);
00440    hgdNthDevice = GetDeviceList ();
00441    greatestArea = 0;
00442    // check window against all gdRects in gDevice list and remember
00443    //  which gdRect contains largest area of window}
00444    while (hgdNthDevice)
00445    {
00446       if (TestDeviceAttribute (hgdNthDevice, screenDevice))
00447          if (TestDeviceAttribute (hgdNthDevice, screenActive))
00448          {
00449             // The SectRect routine calculates the intersection
00450             //  of the window rectangle and this gDevice
00451             //  rectangle and returns TRUE if the rectangles intersect,
00452             //  FALSE if they don't.
00453             SectRect (&rectWind, &(**hgdNthDevice).gdRect, &rectSect);
00454             // determine which screen holds greatest window area
00455             //  first, calculate area of rectangle on current device
00456             sectArea = (long) (rectSect.right - rectSect.left) * (rectSect.bottom - rectSect.top);
00457             if (sectArea > 0)
00458                numDevices++;
00459             if (sectArea > greatestArea)
00460             {
00461                greatestArea = sectArea; // set greatest area so far
00462                *phgdOnThisDevice = hgdNthDevice; // set zoom device
00463             }
00464             hgdNthDevice = GetNextDevice(hgdNthDevice);
00465          }
00466    }
00467 
00468    SetPort (pgpSave);
00469    return numDevices;
00470 }
00471 
00472 // ----------------------------------------------------------------------------
00473 // CheckRenderer
00474 //
00475 // looks at renderer attributes it has at least the VRAM is accelerated
00476 //
00477 // Inputs:  hGD: GDHandle to device to look at
00478 //      pVRAM: pointer to VRAM in bytes required; out is actual VRAM
00479 //             if a renderer was found, otherwise it is the input
00480 //             parameter
00481 //      pTextureRAM:  pointer to texture RAM in bytes required; out is
00482 //             same (implementation assume VRAM returned by card is
00483 //             total so we add texture and VRAM)
00484 //      fAccelMust: do we check for acceleration
00485 //
00486 // Returns: true if renderer for the requested device complies, false otherwise
00487 // ----------------------------------------------------------------------------
00488 Boolean GlWindowOSX::CheckRenderer (GDHandle hGD, long* pVRAM,
00489                                       long* pTextureRAM,
00490                                       GLint* pDepthSizeSupport,
00491                                       Boolean fAccelMust)
00492 {
00493    AGLRendererInfo info, head_info;
00494    GLint inum;
00495    GLint dAccel = 0;
00496    GLint dVRAM = 0, dMaxVRAM = 0;
00497    Boolean canAccel = false, found = false;
00498    head_info = aglQueryRendererInfo(&hGD, 1);
00499    aglReportError ();
00500    if(!head_info)
00501    {
00502       ReportError ("aglQueryRendererInfo error");
00503       return false;
00504    }
00505    else
00506    {
00507       info = head_info;
00508       inum = 0;
00509       // see if we have an accelerated renderer, if so ignore non-accelerated ones
00510       // this prevents returning info on software renderer when actually we'll get the hardware one
00511       while (info)
00512       {
00513          aglDescribeRenderer(info, AGL_ACCELERATED, &dAccel);
00514          aglReportError ();
00515          if (dAccel)
00516             canAccel = true;
00517          info = aglNextRendererInfo(info);
00518          aglReportError ();
00519          inum++;
00520       }
00521 
00522       info = head_info;
00523       inum = 0;
00524       while (info)
00525       {
00526          aglDescribeRenderer (info, AGL_ACCELERATED, &dAccel);
00527          aglReportError ();
00528          // if we can accel then we will choose the accelerated renderer
00529          // how about compliant renderers???
00530          if ((canAccel && dAccel) || (!canAccel && (!fAccelMust || dAccel)))
00531          {
00532             aglDescribeRenderer (info, AGL_VIDEO_MEMORY, &dVRAM);   // we assume that VRAM returned is total thus add texture and VRAM required
00533             aglReportError ();
00534             if (dVRAM >= (*pVRAM + *pTextureRAM))
00535             {
00536                if (dVRAM >= dMaxVRAM) // find card with max VRAM
00537                {
00538                   aglDescribeRenderer (info, AGL_DEPTH_MODES, pDepthSizeSupport);   // which depth buffer modes are supported
00539                   aglReportError ();
00540                   dMaxVRAM = dVRAM; // store max
00541                   found = true;
00542                }
00543             }
00544          }
00545          info = aglNextRendererInfo(info);
00546          aglReportError ();
00547          inum++;
00548       }
00549    }
00550    aglDestroyRendererInfo(head_info);
00551    if (found) // if we found a card that has enough VRAM and meets the accel criteria
00552    {
00553       *pVRAM = dMaxVRAM; // return VRAM
00554       return true;
00555    }
00556    // VRAM will remain to same as it did when sent in
00557    return false;
00558 }
00559 
00560 //-----------------------------------------------------------------------------
00561 // CheckAllDeviceRenderers
00562 //
00563 // looks at renderer attributes and each device must have at least one
00564 // renderer that fits the profile
00565 //
00566 // Inputs:  pVRAM: pointer to VRAM in bytes required; out is actual min
00567 //                     VRAM of all renderers found, otherwise it is the input
00568 //                     parameter
00569 //      pTextureRAM:  pointer to texture RAM in bytes required; out is
00570 //             same (implementation assume VRAM returned by card is
00571 //             total so we add texture and VRAM)
00572 //      fAccelMust: do we check fro acceleration
00573 //
00574 // Returns: true if any renderer for on each device complies (not necessarily
00575 // the same renderer), false otherwise
00576 //-----------------------------------------------------------------------------
00577 Boolean GlWindowOSX::CheckAllDeviceRenderers (long* pVRAM, long* pTextureRAM,
00578                                                 GLint* pDepthSizeSupport,
00579                                                 Boolean fAccelMust)
00580 {
00581    AGLRendererInfo info, head_info;
00582    GLint inum;
00583    GLint dAccel = 0;
00584    GLint dVRAM = 0, dMaxVRAM = 0;
00585    Boolean canAccel = false, found = false, goodCheck = true; // can the renderer accelerate, did we find a valid renderer for the device, are we still successfully on all the devices looked at
00586    long MinVRAM = 0x8FFFFFFF; // max long
00587    GDHandle hGD;
00588 
00589    hGD = GetDeviceList (); // get the first screen
00590    while (hGD && goodCheck)
00591    {
00592       head_info = aglQueryRendererInfo(&hGD, 1);
00593       aglReportError ();
00594       if(!head_info)
00595       {
00596          ReportError ("aglQueryRendererInfo error");
00597          return false;
00598       }
00599       else
00600       {
00601          info = head_info;
00602          inum = 0;
00603          // see if we have an accelerated renderer, if so ignore non-accelerated ones
00604          // this prevents returning info on software renderer when actually we'll get the hardware one
00605          while (info)
00606          {
00607                 aglDescribeRenderer(info, AGL_ACCELERATED, &dAccel);
00608             aglReportError ();
00609             if (dAccel)
00610                canAccel = true;
00611             info = aglNextRendererInfo(info);
00612             aglReportError ();
00613             inum++;
00614          }
00615 
00616          info = head_info;
00617          inum = 0;
00618          while (info)
00619          {
00620             aglDescribeRenderer(info, AGL_ACCELERATED, &dAccel);
00621             aglReportError ();
00622             // if we can accel then we will choose the accelerated renderer
00623             // how about compliant renderers???
00624             if ((canAccel && dAccel) || (!canAccel && (!fAccelMust || dAccel)))
00625             {
00626                     aglDescribeRenderer(info, AGL_VIDEO_MEMORY, &dVRAM);   // we assume that VRAM returned is total thus add texture and VRAM required
00627                aglReportError ();
00628                if (dVRAM >= (*pVRAM + *pTextureRAM))
00629                {
00630                   if (dVRAM >= dMaxVRAM) // find card with max VRAM
00631                   {
00632                      aglDescribeRenderer(info, AGL_DEPTH_MODES, pDepthSizeSupport);   // which depth buffer modes are supported
00633                      aglReportError ();
00634                      dMaxVRAM = dVRAM; // store max
00635                      found = true;
00636                   }
00637                }
00638             }
00639             info = aglNextRendererInfo(info);
00640             aglReportError ();
00641             inum++;
00642          }
00643       }
00644       aglDestroyRendererInfo(head_info);
00645       if (found) // if we found a card that has enough VRAM and meets the accel criteria
00646       {
00647          if (MinVRAM > dMaxVRAM)
00648             MinVRAM = dMaxVRAM; // return VRAM
00649 
00650       }
00651       else
00652          goodCheck = false; // one device failed thus entire requirement fails
00653       hGD = GetNextDevice (hGD); // get next device
00654    } // while
00655    if (goodCheck) // we check all devices and each was good
00656    {
00657       *pVRAM = MinVRAM; // return VRAM
00658       return true;
00659    }
00660    return false; //at least one device failed to have mins
00661 }
00662 
00663 void GlWindowOSX::ReportError (const char * strError)
00664 {
00665    char errMsgCStr [256];
00666    Str255 strErr = "\0";
00667 
00668    sprintf (errMsgCStr, "%s", strError);
00669 
00670    // out as debug string
00671 #ifdef kVerboseErrors
00672 #ifdef kQuake3
00673       ri.Printf( PRINT_ALL, errMsgCStr);
00674 #else
00675       // ensure we are faded in
00676       if (gDSpStarted)
00677          DSpContext_CustomFadeGammaIn (NULL, NULL, 0);
00678       CStrToPStr (strErr, errMsgCStr);
00679       DebugStr (strErr);
00680 #endif //  kQuake3
00681 #endif // kVerboseErrors
00682 }
00683 
00684 GLenum GlWindowOSX::aglReportError () {
00685    GLenum err = aglGetError();
00686    if (AGL_NO_ERROR != err)
00687       ReportError ((char *)aglErrorString(err));
00688 
00689    return err;
00690 }
00691 
00692 /* For keyboard input */
00693 
00694 bool GlWindowOSX::startSampling()
00695 {
00696     if(mAmSampling == true)
00697     {
00698         vprDEBUG(vprDBG_ERROR,vprDBG_CRITICAL_LVL)
00699             << clrOutNORM(clrRED,"ERROR:")
00700             << "vrj::GlWindowOSX: startSampling called, when already sampling.\n"
00701             << vprDEBUG_FLUSH;
00702         vprASSERT(false);
00703         return false;
00704     }
00705 
00706     //openTheWindow();
00707 
00708     vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00709        << "vrj::GlWindowOSX::startSampling() starting to sample\n"
00710        << vprDEBUG_FLUSH;
00711 
00712     attachEvents(mWindow);
00713 
00714     mAmSampling = true;
00715 
00716     return true;
00717 }
00718 
00719 }

Generated on Sun May 2 15:10:17 2004 for VR Juggler by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002