⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cengine.cpp

📁 S60 3D游戏引擎开发案例 S60 3D游戏引擎开发案例
💻 CPP
字号:
   /*
============================================================================
    * Name : CEngine.cpp
    * Part of : Example3D
    * Description : Definition of CEngine
    * Copyright (c) 2007 Nokia Corporation
============================================================================
    */

// INCLUDES
#include "CEngine.h"
#include "CGameTimer.h"
#include "CGame.h"
#include "CPictureLoader.h"
#include <eikenv.h>
#include <eikappui.h>
#include <f32file.h>

// CONSTANTS
const TInt KUpdateInterval = 1000000 / 64;	// 64 times per second "Move" update
const TInt KMaxNumUpdates = 10;

// MEMBER FUNCTIONS
CEngine* CEngine::NewL( CWindowGc& aGc, RWindow& aWindow, 
						TDisplayMode aDisplayMode )
	{
	CEngine* self = new( ELeave )CEngine( aGc, aWindow, aDisplayMode );
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	return self;
	}

CEngine::~CEngine()
	{
	delete iFbsBitmapBuffer;
	delete iTimer;
	delete iGame;
	delete iFbsScreenDevice;
	delete iBitmapUtil;

	eglMakeCurrent( iGldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
	eglDestroyContext( iGldisplay, iGlcontext );
	eglDestroySurface( iGldisplay, iGlsurface );
	eglTerminate( iGldisplay );
	}

void CEngine::ConstructL()
	{
	iPaused = ETrue;

	// Define properties for the preferred EGLSurface, try to match with window depth
	EGLint attribList[ ] = { EGL_BUFFER_SIZE, 0,
	EGL_DEPTH_SIZE, 15,
	EGL_NONE };

	switch( iWindow.DisplayMode() )
		{
		case( EColor4K ) : { attribList[1] = 12; break; }
		case( EColor64K ): { attribList[1] = 16; break; }
		case( EColor16M ): { attribList[1] = 24; break; }
		default: attribList[1] = 32; // for EColor16MU
		}	
	
	EGLint numConfigs;
	EGLint majorVersion;
	EGLint minorVersion;
	 
	iGldisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY );
	if( iGldisplay == EGL_NO_DISPLAY )
		{
		User::Panic( _L("GL No Display"),0 );
		}
	if( !eglInitialize( iGldisplay, &majorVersion, &minorVersion ) ) 
		{
		User::Panic( _L("GL Init"), 0 );
		}
	if( !eglChooseConfig( iGldisplay, attribList, &iGlconfig, 1, &numConfigs ) )
		{
		User::Panic(_L("GL Config"), 0 );
		}
	iGlcontext = eglCreateContext( iGldisplay, iGlconfig, NULL, NULL );
	if( iGlcontext==0 )
		{
		User::Panic( _L("GL Context"), 0 );
		}
	iGlsurface = eglCreateWindowSurface( iGldisplay, iGlconfig, &iWindow, NULL );
	if( iGlsurface==0 )
		{
		User::Panic( _L("GL Surface"), 0 );
		}
	
	eglMakeCurrent( iGldisplay, iGlsurface, iGlsurface, iGlcontext );

	iGame = CGame::NewL( iDisplayMode );
	iTimer = CGameTimer::NewL( *this );
	iTime.HomeTime();

	// Some devices have difficulties to multitask with
	// this application using idle time.
	// This should help it a little
	//RProcess().SetPriority( EPriorityLow );
	}

void CEngine::InitScreen( const TRect& aRect )
	{
	iDrawRect = aRect;
	iBuffer.iSize = iDrawRect.Size();
	iBuffer.iMode = iDisplayMode;
	}

CEngine::CEngine( CWindowGc& aGc, RWindow& aWindow, 
				  TDisplayMode aDisplayMode )
	: iGc( aGc ), iWindow( aWindow ), iDisplayMode( aDisplayMode )
	{
	}

TInt CEngine::DoGameFrameL()
	{
	if( iPaused )
		{
		// stop gametimer
		return EFalse;
		}

	TPoint pos = iWindow.Position();
	TSize size = iWindow.Size();
	if( size != iDrawRect.Size() || pos != iDrawRect.iTl )
		{
		TRect rect( pos, size );
		InitScreen( rect );
		return ETrue;
		}
	
	// Calculate number of updates that should happen since last game frame
	TTime time;
	time.HomeTime();
	TInt updates = I64LOW(time.MicroSecondsFrom( iTime ).Int64());
	iUpdates += updates;
	updates = iUpdates / KUpdateInterval;
	
	iTime = time.Int64();
	
	TInt i;
	for( i=0; i<updates; i++ )
		{
		iGame->Move( iKey );
		}
	iUpdates -= updates * KUpdateInterval;
	
	// Draw with OpenGL
	// GL double buffer swap
	eglSwapBuffers( iGldisplay, iGlsurface);
	iGame->Draw( iBuffer );
	RRegion drawRegion;
	drawRegion.AddRect( iDrawRect );
	drawRegion.Clear();
			
	// continue gametimer
	return ETrue;
	}

void CEngine::KeyEvent( const TKeyEvent& aKeyEvent,TEventCode aType )
	{
	switch( aType )
		{
		case EEventKeyDown:
			{
			iKey[ aKeyEvent.iScanCode ] = 1;
			break;
			}
		case EEventKeyUp:
			{
			iKey[ aKeyEvent.iScanCode ] = 0;
			break;
			}
		default:
			{
			break;
			}
		}
	}

void CEngine::Start()
	{
	if( !iPaused ) return;
	iPaused = EFalse;
	iTimer->Start();
	}

void CEngine::Stop()
	{
	if( iPaused ) return;
	iPaused = ETrue;
	iTimer->Cancel();
	}

void CEngine::Command( TInt aCommand )
	{
	if( iGame )
		{
		iGame->Command( aCommand );
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -