📄 cgame.cpp
字号:
/*
============================================================================
* 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 + -