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

📄 cgame.cpp

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


// INCLUDES
#include "CGame.h"
#include "CPictureLoader.h"
#include "C3DBase.h"
#include "C3DRenderer.h"
#include "CPolygonObject.h"
#include "3DObjects.h"
#include "CFpsCounter.h"
#include "Example3D.hrh"

#include <e32math.h>
#include <eikenv.h>
#include <e32svr.h>
#include <eikenv.h>
#include <eikappui.h>
#include <eikapp.h>
#include <f32file.h>


// CONSTANTS
// steering wheel turning speed
// bigger value turns steering wheel faster
const TInt KSteeringSpeed = 4;	

// Maximum steering wheel "angle"
const TInt KSteerLimit = 100;

// car turning divider
// greater value makes car turn slower
const TInt KCarTurnDivider = 256;

// car combined friction factor
// affects car top speed
const TInt KFriction = 10000;

// force that affects forwards/backwards car tilting
const TInt KCarTiltForce = 100;

// spring force that tries to stop fwd/back tilting
const TInt KCarTiltSpringFactor = 1000;

#include "GLES/egl.h"
#include "GLES/gl.h"

// CONSTANTS
const TInt KFrontWheelRadius = 100;
const TInt KRearWheelRadius = 150;
const TInt KRideHeight = 100;		// car ride height

const TInt KTileSize = 2999;		// tile size in 3D-space

// MEMBER FUNCTIONS
CGame* CGame::NewL( TDisplayMode aDisplayMode )
	{
	CGame* self = new( ELeave )CGame( aDisplayMode );
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	return self;
	}

CGame::~CGame()
	{
	delete[] iTexture.iData;
	delete[] iTexture2.iData;
	delete[] iTextureFont.iData;

	delete i3DBase;
	delete iRender;

	delete i3dHouse;
	delete i3dCar;
	delete i3dRoad;
	delete i3dGrass;
	delete i3dFrontWheel;
	delete i3dRearWheel;
	delete i3dText;

	delete iFps;
	}

void CGame::ConstructL()
	{
	//
	// load texture
	//
	CPictureLoader* loader = CPictureLoader::NewL();
	CleanupStack::PushL( loader );
	iTexture = loader->LoadL( _L("picture.jpg"), iDisplayMode );
	iTexture2 = loader->LoadL( _L("picture2.jpg"), iDisplayMode );
	iTextureFont = loader->LoadL( _L("font.gif"), iDisplayMode );
	CleanupStack::PopAndDestroy( loader );

	//
	// Create texture objects for OpenGL
	//
	glGenTextures( 1, &iGlTexture );
	glGenTextures( 1, &iGlTexture2 );
	glGenTextures( 1, &iGlTextureFont );
	
	TUint colorFlag;

	switch( iDisplayMode )
		{
		case EColor16MU:
		case EColor16M:
			{
			colorFlag = GL_UNSIGNED_BYTE;
			break;
			}	
		case EColor64K:
			{
			colorFlag = GL_UNSIGNED_SHORT_5_6_5;
			break;
			}
		case EColor4K:
		default:
			{
			colorFlag = GL_UNSIGNED_SHORT_4_4_4_4;
			break;
			}
		}

	// create texture1
	glBindTexture( GL_TEXTURE_2D, iGlTexture );
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 
		iTexture.iSize.iWidth, iTexture.iSize.iHeight,
		0, GL_RGB, colorFlag, iTexture.iData );
	glTexEnvx( GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE );
	glTexParameterx( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
	glTexParameterx( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

	// create texture2
	glBindTexture( GL_TEXTURE_2D, iGlTexture2 );
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 
		iTexture2.iSize.iWidth, iTexture2.iSize.iHeight,
		0, GL_RGB, colorFlag, iTexture2.iData );
	glTexEnvx( GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE );
	glTexParameterx( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
	glTexParameterx( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

	// create texture font
	glBindTexture( GL_TEXTURE_2D, iGlTextureFont );
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 
		iTextureFont.iSize.iWidth, iTextureFont.iSize.iHeight,
		0, GL_RGB, colorFlag, iTextureFont.iData );
	glTexEnvx( GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE );
	glTexParameterx( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
	glTexParameterx( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

	// 
	// OpenGL makes copies of textures
	// the original textures can be deleted now
	// 
	delete[] iTexture.iData;
	iTexture.iData = NULL;
	delete[] iTexture2.iData;
	iTexture2.iData = NULL;
	delete[] iTextureFont.iData;
	iTextureFont.iData = NULL;

	//
	// construct 3D base classes
	//
	i3DBase = C3DBase::NewL( TSize( 0,0 ) ); // unknown screen size
	iRender = C3DRenderer::NewL( i3DBase, 1000 );

	//
	// create 3D-objects
	//
	
	// house
	i3dHouse = CreateObject( KHouseVertexData, KHouseFaceData, KNumHouseVertices, KNumHouseFaces,
							TPoint( 0,0 ), 1 );
							

	// road
	i3dRoad = CreateObject( KRoadVertexData, KRoadFaceData, KNumRoadVertices, KNumRoadFaces,
							TPoint( 0,0 ), 1 );

	
	// grass tile
	i3dGrass = CreateObject( KGrassVertexData, KGrassFaceData, KNumGrassVertices, KNumGrassFaces,
							TPoint( 0,0 ), 1 );

	
	// wheels
	i3dFrontWheel = CreateWheel( KFrontWheelRadius, 50, 6 );

	i3dRearWheel = CreateWheel( KRearWheelRadius, 150, 6 );

	// car
	i3dCar = CreateObject( KCarVertexData, KCarFaceData, KNumCarVertices, KNumCarFaces,
							TPoint( 0,128 ), 10 );

	i3dText = CPolygonObject::NewL( i3DBase, 1, 1 );

	// set textures for all objects:
	i3dHouse->SetTexture( iGlTexture2 );
	i3dRoad->SetTexture( iGlTexture );
	i3dGrass->SetTexture( iGlTexture2 );
	i3dFrontWheel->SetTexture( iGlTexture );
	i3dRearWheel->SetTexture( iGlTexture );
	i3dCar->SetTexture( iGlTexture );
	i3dText->SetTexture( iGlTextureFont );

	//
	// add objects to renderer
	//
	// Adjust object priorities so they seem to render in right order
	// ( wheel shouldn't show through car etc... )
	//
	TInt n;
	n = iRender->AddObject( i3dRearWheel );
	iRender->SetObjectPriority( n, 500 );
	n = iRender->AddObject( i3dFrontWheel );
	iRender->SetObjectPriority( n, 500 );
	n = iRender->AddObject( i3dRearWheel );
	iRender->SetObjectPriority( n, 500 );
	n = iRender->AddObject( i3dFrontWheel );
	iRender->SetObjectPriority( n, 500 );
	
	n = iRender->AddObject( i3dCar );
	iRender->SetObjectPosition( n, TVertex( 0, -300,4250 ) );
	iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );

	
	TInt y;
	TInt x;

	//
	// Tilemapped city
	//


	for( y=0; y<KMapHeight; y++ )
		{
		TUint8* p = (TUint8*)KMap[ y ];
		for( x=0; x<KMapWidth; x++ )
			{
			switch( *p++ )
				{
				case '0':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );
					iRender->SetObjectPriority( n, 1000 );
					break;
					}
				case '1':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 1024, 0 ) );
					iRender->SetObjectPriority( n, 1000 );
					break;
					}
				case '2':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 2048, 0 ) );
					iRender->SetObjectPriority( n, 1000 );
					break;
					}
				case '3':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 3072, 0 ) );
					iRender->SetObjectPriority( n, 1000 );
					break;
					}
				case 'a':
					{
					n = iRender->AddObject( i3dHouse );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );
					iRender->SetObjectPriority( n, 0 );
					break;
					}
				case 'x':
					{
					n = iRender->AddObject( i3dGrass );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );
					iRender->SetObjectPriority( n, 1000 );
					break;
					}

				}
			}
		}
	
	// 3D text:
	n = iRender->AddObject( i3dText );
	iRender->SetObjectPosition( n, TVertex( KTileSize * 2, -1000, KTileSize * 2+1 ) );
	iRender->SetObjectAngle( n, TVertex( 0,0,0 ) );

	// some initializations
	// start driving from tile 2,2 ( x,y on map )
	iCarPosition = TVertex( KTileSize * 2, 0, KTileSize * 2 );	
	iCarPositionAdd = TVertex( 0,0,0 );
	iCarSpeed = 0;

	//iCameraMode = ECameraSouth;
	iCameraMode = ECameraBehind;

	// every object's Init() has to be called after all changes
	i3dHouse->Init();
	i3dCar->Init();
    i3dText->Init();
	i3dRoad->Init();
	i3dGrass->Init();
	i3dFrontWheel->Init();
	i3dRearWheel->Init();

	// OpenGl ES initialization
	
	// states
	glDisable		(GL_LIGHTING);
	glEnable		(GL_CULL_FACE);
	glFrontFace 	(GL_CW);
	glDisable		(GL_DITHER);
	glDisable		(GL_MULTISAMPLE);

	glEnable		(GL_DEPTH_TEST);
	glDepthMask 	(GL_TRUE);
	glClearDepthf	(1);

	// if you would like to see everything perspective correct:
	//glHint			(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	
	// and this is without perspective correction
	glHint			(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

	glShadeModel	(GL_FLAT);

	// modelview
	glMatrixMode	(GL_MODELVIEW);
	glLoadIdentity	();
	glClearColor	(0, 0, 0, 0);

	iFps = CFpsCounter::NewL( 2 );

	}

CGame::CGame( TDisplayMode aDisplayMode )
	: iDisplayMode( aDisplayMode )
	{

	}

void CGame::Draw( const TBitmap& aScreen )
	{
	if( aScreen.iSize != iScreen.iSize )
		{
		// calculate perspective:

		glMatrixMode	(GL_PROJECTION);
		glLoadIdentity	();

		float xmin, xmax, ymin, ymax;
		TInt lens = 512;
		const float zNear = 0.1f;
		const float zFar = 500.0f;

		xmax = zNear * 0.5f * aScreen.iSize.iWidth / lens;
		xmin = -xmax;

		ymax = zNear * 0.5f * aScreen.iSize.iHeight / lens;
		ymin = -ymax;

		glFrustumf( xmin, xmax, ymin, ymax, (float)zNear, (float)zFar );
		glMatrixMode( GL_MODELVIEW );
		glViewport( 0, 0, aScreen.iSize.iWidth, aScreen.iSize.iHeight );
        TRect rect(0, 0, aScreen.iSize.iWidth, aScreen.iSize.iHeight);
		

		i3DBase->InitFrustum( aScreen.iSize );
		}
	iScreen = aScreen;
   
	/* clear */
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	TInt ang = iCarAngleSpeed*5;
	TInt carAngle = ang + iCarAngle;

	// calculate wheel positions in space
	TVertex v;
	v = TVertex( -500, -KRearWheelRadius/2, 350 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 0, v );

	v = TVertex(  500, -KFrontWheelRadius/2, 300 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 1, v );

	v = TVertex(  -500, -KRearWheelRadius/2, -350 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 2, v );

	v = TVertex(  500, -KFrontWheelRadius/2, -300 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 3, v );

	// turn wheels to right direction ( car's direction )
	// add steering angle to front wheels
	// also turn wheels by iCarPos

	iRender->SetObjectAngle( 0, TVertex( 0, carAngle + ( KSinTableSize/2 ), -iCarPos*2 ) );
	iRender->SetObjectAngle( 1, TVertex( 0, -iSteerAngle*4 + carAngle + ( KSinTableSize/2 ), -iCarPos*3 ) );
	iRender->SetObjectAngle( 2, TVertex( 0, carAngle, iCarPos*2 ) );
	iRender->SetObjectAngle( 3, TVertex( 0, -iSteerAngle*4 + carAngle,	iCarPos*3 ) );
	
	if( iCarSpeed < 0 ) ang = -ang;

	// tilt car
	iRender->SetObjectAngle( 4, TVertex( ang, carAngle, -iCarTilt/5 ) );

	// and set car position in space
	iRender->SetObjectPosition( 4, iCarPosition + TVertex( 0,-KRideHeight, 0 ) );
	
	// calculate camera position

⌨️ 快捷键说明

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