S60 3rd Edition SDK for Symbian OS
Example Applications Guide

MultiTexContainer.cpp

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

© Nokia 2006

Back to top