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