S60 3rd Edition SDK for Symbian OS
Example Applications Guide

SimpleCubePbufferContainer.cpp

00001 /*
00002 * ==============================================================================
00003 *  Name        : SimpleCubePbufferContainer.cpp
00004 *  Part of     : OpenGLEx / SimpleCubePbuffer
00005 *  Interface   : 
00006 *  Description : 
00007 *  Version     : 
00008 *
00009 *  Copyright (c) 2004-2006 Nokia Corporation.
00010 *  This material, including documentation and any related 
00011 *  computer programs, is protected by copyright controlled by 
00012 *  Nokia Corporation.
00013 * ==============================================================================
00014 */
00015 
00016 
00017 // INCLUDE FILES
00018 #include "SimpleCubePbufferContainer.h"
00019 #include <Eikenv.h>
00020 #include <w32std.h>
00021 
00022 // ================= MEMBER FUNCTIONS =======================
00023 
00024 // ---------------------------------------------------------
00025 // CSimpleCubePbufferContainer::ConstructL
00026 // EPOC two phased constructor
00027 // ---------------------------------------------------------
00028 //
00029 void CSimpleCubePbufferContainer::ConstructL(const TRect& /*aRect*/)
00030     {
00031     iOpenGlInitialized = EFalse;
00032     CreateWindowL();
00033 
00034     SetExtentToWholeScreen();                // Take the whole screen into use
00035     ActivateL();
00036     
00037     iFrame = 0;                              // Initialize frame counter
00038     
00039     // Get the display for drawing graphics
00040     iEglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
00041     if ( iEglDisplay == NULL )
00042         {
00043         _LIT(KGetDisplayFailed, "eglGetDisplay failed");
00044         User::Panic( KGetDisplayFailed, 0 );
00045         }
00046 
00047     // Initialize display 
00048     if ( eglInitialize( iEglDisplay, NULL, NULL ) == EGL_FALSE )
00049         {
00050         _LIT(KInitializeFailed, "eglInitialize failed");
00051         User::Panic( KInitializeFailed, 0 );
00052         }
00053 
00054     EGLConfig *configList = NULL;            // Pointer for EGLConfigs
00055     EGLint numOfConfigs = 0; 
00056     EGLint configSize   = 0;
00057 
00058     // Get the number of possible EGLConfigs 
00059     if ( eglGetConfigs( iEglDisplay, configList, configSize, &numOfConfigs ) 
00060          == EGL_FALSE )
00061         {
00062         _LIT(KGetConfigsFailed, "eglGetConfigs failed");
00063         User::Panic( KGetConfigsFailed, 0 );
00064         }
00065 
00066     configSize = numOfConfigs;
00067 
00068     // Allocate memory for the configList 
00069     configList = (EGLConfig*) User::Alloc( sizeof(EGLConfig)*configSize );
00070     if ( configList == NULL )
00071         {
00072         _LIT(KConfigAllocFailed, "config alloc failed");
00073         User::Panic( KConfigAllocFailed, 0 );
00074         }
00075 
00076     /* Define properties for the wanted EGLSurface 
00077        To get the best possible performance, choose
00078        an EGLConfig with a buffersize matching
00079        the current window's display mode*/
00080     TDisplayMode DMode = Window().DisplayMode();
00081     TInt BufferSize = 0;
00082 
00083     switch ( DMode )
00084          {
00085          case(EColor4K):
00086              BufferSize = 12;
00087              break;
00088          case(EColor64K):
00089              BufferSize = 16;
00090              break;
00091          case(EColor16M):
00092              BufferSize = 24;
00093              break;
00094          case(EColor16MU):
00095              BufferSize = 32;
00096              break;
00097          default:
00098              _LIT(KDModeError,       "unsupported displaymode");
00099              User::Panic( KDModeError, 0 );
00100              break;
00101          }
00102 
00103     // Define properties for the wanted EGLSurface 
00104     const EGLint attrib_list[] = { EGL_BUFFER_SIZE,
00105                                    BufferSize,
00106                                    EGL_SURFACE_TYPE,
00107                                    EGL_PBUFFER_BIT,
00108                                    EGL_NONE };
00109 
00110     // Choose an EGLConfig that best matches to the properties in attrib_list 
00111     if ( eglChooseConfig( iEglDisplay, attrib_list, configList, configSize, 
00112                           &numOfConfigs ) == EGL_FALSE )
00113         {
00114         _LIT(KChooseConfigFailed, "eglChooseConfig failed");
00115         User::Panic( KChooseConfigFailed, 0 );
00116         }
00117 
00118     iConfig = configList[0];   // Choose the best EGLConfig. EGLConfigs 
00119                               // returned by eglChooseConfig are sorted so 
00120                               // that the best matching EGLConfig is first in
00121                               // the list.
00122     User::Free( configList ); // Free configList, not used anymore.
00123 
00124 
00125     TSize size;
00126     size = this->Size();
00127 
00128     // Create a Symbian bitmap where the graphics from the Pbuffer are copied
00129     iPixmap = new CWsBitmap( iEikonEnv->WsSession() );
00130     iPixmap->Create( Window().Size(), DMode);
00131 
00132     const EGLint attrib_list2[] = { EGL_WIDTH,
00133                                     size.iWidth,
00134                                     EGL_HEIGHT,
00135                                     size.iHeight,
00136                                     EGL_NONE };
00137 
00138     iEglSurface = eglCreatePbufferSurface( iEglDisplay, iConfig, attrib_list2 );
00139 
00140     if ( iEglSurface == NULL )
00141         {
00142         _LIT(KCreatePbufferSurfaceFailed, "eglCreatePbufferSurface failed");
00143         User::Panic( KCreatePbufferSurfaceFailed, 0 );
00144         }
00145 
00146     // Create a rendering context 
00147     iEglContext = eglCreateContext( iEglDisplay, iConfig, EGL_NO_CONTEXT, NULL );
00148     if ( iEglContext == NULL )
00149         {
00150         _LIT(KCreateContextFailed, "eglCreateContext failed");
00151         User::Panic( KCreateContextFailed, 0 );
00152         }
00153 
00154     /* Make the context current. Binds context to the current rendering thread
00155        and surface.*/
00156     if ( eglMakeCurrent( iEglDisplay, iEglSurface, iEglSurface, iEglContext ) 
00157         == EGL_FALSE )
00158         {
00159         _LIT(KMakeCurrentFailed, "eglMakeCurrent failed");
00160         User::Panic( KMakeCurrentFailed, 0 );
00161         }
00162 
00163 
00164     // Create an instance of SimpleCubePbuffer
00165     iSimpleCubePbuffer = CSimpleCubePbuffer::NewL( size.iWidth, size.iHeight ); 
00166     iSimpleCubePbuffer->AppInit();                           // Initialize OpenGL ES
00167     
00168     iOpenGlInitialized = ETrue;
00169     
00170     iPeriodic = CPeriodic::NewL( CActive::EPriorityIdle );  // Create an active object for
00171                                                             // animating the scene
00172     iPeriodic->Start( 100, 100, TCallBack( CSimpleCubePbufferContainer::DrawCallBack, this ) );
00173     }
00174 
00175 // Destructor
00176 CSimpleCubePbufferContainer::~CSimpleCubePbufferContainer()
00177     {
00178     delete iPeriodic;
00179 
00180     /* AppExit call is made to release 
00181        any allocations made in AppInit. */
00182     if ( iSimpleCubePbuffer )
00183         {
00184         iSimpleCubePbuffer->AppExit();
00185         delete iSimpleCubePbuffer;
00186         }
00187 
00188     eglMakeCurrent( iEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
00189     eglDestroySurface( iEglDisplay, iEglSurface ); 
00190     eglDestroyContext( iEglDisplay, iEglContext );
00191     eglTerminate( iEglDisplay );                   // Release resources associated
00192                                                    // with EGL and OpenGL ES
00193 
00194     delete iPixmap;
00195     }
00196 
00197 // ---------------------------------------------------------
00198 // CSimpleCubePbufferContainer::SizeChanged
00199 // Called by framework when the view size is changed
00200 // ---------------------------------------------------------
00201 //
00202 void CSimpleCubePbufferContainer::SizeChanged()
00203     {
00204     if( iOpenGlInitialized && iSimpleCubePbuffer )
00205         {
00206         TSize size;
00207         size = this->Size();
00208 
00209         // Delete previous context etc.
00210         eglMakeCurrent( iEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
00211         eglDestroySurface( iEglDisplay, iEglSurface ); 
00212         eglDestroyContext( iEglDisplay, iEglContext );
00213         if( iPixmap )
00214             {
00215             delete iPixmap;
00216             }
00217         
00218 
00219         // Recreate the Symbian bitmap where the graphics from the Pbuffer are copied
00220 
00221         iPixmap = new CWsBitmap( iEikonEnv->WsSession() );
00222         iPixmap->Create( Window().Size(), Window().DisplayMode() );
00223         
00224         // Recreate and bind the new surface and rendering context
00225         const EGLint attrib_list2[] = { EGL_WIDTH,
00226                                         size.iWidth,
00227                                         EGL_HEIGHT,
00228                                         size.iHeight,
00229                                         EGL_NONE };
00230 
00231         iEglSurface = eglCreatePbufferSurface( iEglDisplay, iConfig, attrib_list2 );
00232 
00233         if ( iEglSurface == NULL )
00234             {
00235             _LIT(KCreatePbufferSurfaceFailed, "eglCreatePbufferSurface failed");
00236             User::Panic( KCreatePbufferSurfaceFailed, 0 );
00237             }
00238 
00239         // Create a rendering context 
00240         iEglContext = eglCreateContext( iEglDisplay, iConfig, EGL_NO_CONTEXT, NULL );
00241         if ( iEglContext == NULL )
00242             {
00243             _LIT(KCreateContextFailed, "eglCreateContext failed");
00244             User::Panic( KCreateContextFailed, 0 );
00245             }
00246 
00247         /* Make the context current. Binds context to the current rendering thread
00248            and surface.*/
00249         if ( eglMakeCurrent( iEglDisplay, iEglSurface, iEglSurface, iEglContext ) 
00250             == EGL_FALSE )
00251             {
00252             _LIT(KMakeCurrentFailed, "eglMakeCurrent failed");
00253             User::Panic( KMakeCurrentFailed, 0 );
00254             }
00255         
00256         
00257         // Notify the renderer class
00258         iSimpleCubePbuffer->SetScreenSize( size.iWidth, size.iHeight );
00259         }
00260     }
00261 
00262 
00263 // ---------------------------------------------------------
00264 // CSimpleCubePbufferContainer::HandleResourceChange(
00265 //     TInt aType)
00266 // Dynamic screen resize changes by calling the
00267 // SetExtentToWholeScreen() method again.
00268 // ---------------------------------------------------------
00269 //
00270  void CSimpleCubePbufferContainer::HandleResourceChange(TInt aType)
00271     {
00272         switch( aType )
00273         {
00274             case KEikDynamicLayoutVariantSwitch:
00275                     SetExtentToWholeScreen();
00276                     break;
00277             }
00278     }
00279 
00280 // ---------------------------------------------------------
00281 // CSimpleCubePbufferContainer::CountComponentControls
00282 // ---------------------------------------------------------
00283 //
00284 TInt CSimpleCubePbufferContainer::CountComponentControls() const
00285     {
00286     return 0;
00287     }
00288 
00289 // ---------------------------------------------------------
00290 // CSimpleCubePbufferContainer::ComponentControl
00291 // ---------------------------------------------------------
00292 //
00293 CCoeControl* CSimpleCubePbufferContainer::ComponentControl(TInt /*aIndex*/) const
00294     {
00295     return NULL;
00296     }
00297 // ---------------------------------------------------------
00298 // CSimpleCubePbufferContainer::Draw
00299 // ---------------------------------------------------------
00300 //
00301 void CSimpleCubePbufferContainer::Draw(const TRect& /*aRect*/ ) const
00302     {
00303     CWindowGc& gc = SystemGc();
00304     gc.BitBlt( TPoint( 0, 0 ), iPixmap );
00305     }
00306 
00307 // ---------------------------------------------------------
00308 // CSimpleCubePbufferContainer::DrawCallBack
00309 // Called by the CPeriodic in order to draw the graphics 
00310 // ---------------------------------------------------------
00311 //
00312 int CSimpleCubePbufferContainer::DrawCallBack( TAny* aInstance )
00313     {
00314     CSimpleCubePbufferContainer* instance 
00315       = (CSimpleCubePbufferContainer*) aInstance;
00316     instance->iFrame++;
00317     
00318     // Call the main OpenGL ES Symbian rendering 'loop' 
00319     instance->iSimpleCubePbuffer->AppCycle( instance->iFrame );
00320     
00321     // Copy contents of Pbuffer surface to a native Pixmap
00322     eglCopyBuffers( instance->iEglDisplay, instance->iEglSurface, instance->iPixmap );
00323 
00324     /* eglSwapBuffers is not called when using Pixmap surface.
00325        Instead, standard Symbian BitBlt has to be used. */
00326     instance->DrawNow( );
00327     
00328     // To keep the background light on 
00329     if ( !(instance->iFrame%100) )
00330         {
00331         User::ResetInactivityTime();
00332         }
00333     
00334     /* Suspend the current thread for a short while. Give some time 
00335        to other threads and AOs, avoids the ViewSrv error in ARMI and
00336        THUMB release builds. One may try to decrease the callback 
00337        function instead of this. */ 
00338     if ( !(instance->iFrame%50) )
00339         {
00340         User::After(0);
00341         }
00342     
00343     return 0; 
00344     }
00345 
00346 // ---------------------------------------------------------
00347 // CSimpleCubePbufferContainer::HandleControlEventL
00348 // ---------------------------------------------------------
00349 //
00350 void CSimpleCubePbufferContainer::HandleControlEventL(
00351     CCoeControl* /*aControl*/,TCoeEvent /*aEventType*/)
00352     {
00353     }
00354 
00355 
00356 // End of File  

© Nokia 2006

Back to top