|
S60 3rd Edition SDK for Symbian OS Example Applications Guide |
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 |