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

📄 cpolygonobject.cpp

📁 Symbian平台下的一个3D赛车游戏源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   /*
============================================================================
    * Name : CPolygonObject.cpp
    * Part of : Example3D
    * Description : Definition of CPolygonObject
    * Copyright (c) 2005 Nokia Corporation
============================================================================
    */

// INCLUDES
#include "CPolygonObject.h"
#include <e32math.h>
#include <e32svr.h>		// for debug prints

// CONSTANTS
const TUint KInvalidTextureObject = 0xffffffff;

// MEMBER FUNCTIONS

CPolygonObject* CPolygonObject::NewL( C3DBase* a3DBase, TInt aNumVertices, TInt aNumFaces )
	{
	CPolygonObject* self = new( ELeave )CPolygonObject( a3DBase, aNumVertices, aNumFaces );
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	return self;
	}

CPolygonObject::~CPolygonObject()
	{
	delete[] iFace;
	delete[] iVertex;
	delete[] iRVertex;

	delete[] iDrawList;
	delete[] iFaceZ;
	delete[] iFaceN;
#ifdef GLES
	delete[] iGlVerts;
	delete[] iGlTexCoords;
	delete[] iGlTris;
	if( iTextureObject != KInvalidTextureObject )
		{
		glDeleteTextures( 1, &iTextureObject );
		}
#endif
	}

CPolygonObject::CPolygonObject( C3DBase* a3DBase, TInt aNumVertices, TInt aNumFaces )
	: i3DBase( a3DBase )
	, iMaxNumVertices( aNumVertices )
	, iMaxNumFaces( aNumFaces )
	{
	}

void CPolygonObject::ConstructL()
	{
	iFace = new( ELeave )TFace[ iMaxNumFaces ];
	iVertex = new( ELeave )TVertex[ iMaxNumVertices ];
	iRVertex = new( ELeave )TVertex[ iMaxNumVertices ];

	iCos = i3DBase->CosTable();
	iSin = i3DBase->SinTable();

	iFaceN = new( ELeave )TInt[ iMaxNumFaces ];
	iFaceZ = new( ELeave )TInt[ iMaxNumFaces ];
	iDrawList = new( ELeave )TDrawFace[ iMaxNumFaces ];

#ifdef GLES
	// OpenGl texture object handle
	// valid texture handle is '0'
	// so set the handle as KInvalidTextureObject here.
	iTextureObject = KInvalidTextureObject;
#endif

	}

void CPolygonObject::Draw( const TBitmap& aScreen, TMatrix* aRotateMatrix )
	{


#ifdef GLES

	// Here the drawing is done with OpenGl ES
	// We are using Z-buffered draw with opengl
	// so we don't need to sort the polygons

	const TInt glShift = 16;

	// shift adjustor
	// OpenGl uses 16-bit decimals
	// and this example uses KShift-bit decimals
	// this is the difference to convert values to same decimal depth
	const TInt shift = glShift - KShift;
	const TInt mul = 1 << shift;

    glMatrixMode    (GL_MODELVIEW);
	
	// Generate rotate matrix for OpenGl from example's rotate matrix
	GLfixed mat[4*4]={ (*aRotateMatrix)[0]*mul, -(*aRotateMatrix)[4]*mul, -(*aRotateMatrix)[ 8]*mul, 0,
					   (*aRotateMatrix)[1]*mul, -(*aRotateMatrix)[5]*mul, -(*aRotateMatrix)[ 9]*mul, 0,
					   (*aRotateMatrix)[2]*mul, -(*aRotateMatrix)[6]*mul, -(*aRotateMatrix)[10]*mul, 0,
					   (*aRotateMatrix)[3]*mul, -(*aRotateMatrix)[7]*mul, -(*aRotateMatrix)[11]*mul, 1 << glShift };
    
	// Init OpenGl for drawing
	glLoadMatrixx( mat );
	
	glEnableClientState( GL_VERTEX_ARRAY );
	glVertexPointer( 3, GL_FIXED, 0, iGlVerts );
	
	if( iTextureObject != KInvalidTextureObject )
		{
		glBindTexture( GL_TEXTURE_2D, iTextureObject );
		glEnable( GL_TEXTURE_2D );
		glEnableClientState( GL_TEXTURE_COORD_ARRAY );
		glTexCoordPointer( 2, GL_FIXED, 0, iGlTexCoords );
		}
	else
		{
		glDisable( GL_TEXTURE_2D );
		glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
		}
	glColor4x( 1<<glShift, 1<<glShift, 1<<glShift, 1<<glShift );
	glDrawElements( GL_TRIANGLES, iGlTriCount, GL_UNSIGNED_SHORT, iGlTris );

	// This isn't really accurate number of polygons drawn
	// but number of polygons feeded to OpenGL drawing pipeline
	// some of the polygons are backface culled off etc.
	i3DBase->AddPolygonCount( iGlTriCount );

#else

	// Here is the software renderer
	// Vertices are rotated with rotate matrix
	// polygons are clipped against view frustrum
	// remaining polygons are sorted by their distance to camera
	// and then drawn to screen back to front ( painter's algorithm )

	// rotate matrix from C3DRenderer
	iRotateMatrix = aRotateMatrix;

	iScreen = aScreen;

	TFrustum& frustum = i3DBase->ViewFrustum();

	// rotate vertices to iRVertex list
	Rotate();
	
	// clipped triangle has more than 3 vertices:
	TDrawVertex polygon1[ 10 ];
	TDrawVertex polygon2[ 10 ];

	TBool clipped;
	TInt  inCount = 0;

	// polygon's vertex distance from clipping plane
	TInt d[ 10 ];

	TInt numDrawn = 0;

	TInt i;
	for( i=0; i<iNumFaces; i++ )
		{
		TBool visible = ETrue;
		clipped = EFalse;

		TFace& f = iFace[ i ];

		TVertex& v1 = iRVertex[ f.iV1 ];
		TVertex& v2 = iRVertex[ f.iV2 ];
		TVertex& v3 = iRVertex[ f.iV3 ];


		polygon1[ 0 ] = TDrawVertex( v1, f.iTx1, f.iTy1 );
		polygon1[ 1 ] = TDrawVertex( v2, f.iTx2, f.iTy2 );
		polygon1[ 2 ] = TDrawVertex( v3, f.iTx3, f.iTy3 );

		TDrawVertex* poly1 = polygon1;
		TDrawVertex* poly2 = polygon2;

		TInt numPoints = 3;


		for( TInt n=0; n<frustum.iNumPlanes; n++ )
			{
			TInt vn = numPoints;
			TInt p;

			for( p=0; p<numPoints; p++ )
				{
				TVertex& mv1 = frustum.iPlane[ n ].iNormal;
				TDrawVertex& mv2 = poly1[ p ];
				
				// calculate dot product to get point distance to plane:
				TInt l = mv1.iX * mv2.iX + mv1.iY * mv2.iY + mv1.iZ * mv2.iZ;
				l += frustum.iPlane[ n ].iDistance;
				if( l <= 0 ) vn--;
				d[ p ] = l;
				inCount++;
				}

			if( vn == numPoints )
				{
				// all visible, do not clip
				continue;
				}

			if( vn == 0 )
				{
				// none visible, do not draw, do not continue clipping
				visible = EFalse;
				break;
				}
			
			clipped = ETrue;

			TInt np = 0;

			for( TInt p1=0; p1<numPoints; p1++ )
				{
				
				TInt p0 = p1-1;
				TInt p2 = p1+1;
				if( p0<0 ) p0 += numPoints;
				if( p2>=numPoints ) p2 -= numPoints;

				TDrawVertex& dv0 = poly1[ p0 ];
				TDrawVertex& dv1 = poly1[ p1 ];
				TDrawVertex& dv2 = poly1[ p2 ];

				// if point is out of plane, check if one or more points can be
				// added to drawarea's edge in straight line to other points
				// ( actual clipping )
				if( d[ p1 ] < 0 )
					{
					
					if( d[ p0 ] > 0 )
						{
						TInt s = ( d[ p0 ] << KShift ) / ( d[ p0 ]-d[ p1 ] );
						poly2[ np ].iX = dv0.iX + ( ( s*( dv1.iX - dv0.iX ) ) >> KShift );
						poly2[ np ].iY = dv0.iY + ( ( s*( dv1.iY - dv0.iY ) ) >> KShift );
						poly2[ np ].iZ = dv0.iZ + ( ( s*( dv1.iZ - dv0.iZ ) ) >> KShift );
						poly2[ np ].iTx = dv0.iTx + ( ( s*( dv1.iTx - dv0.iTx ) ) >> KShift );
						poly2[ np ].iTy = dv0.iTy + ( ( s*( dv1.iTy - dv0.iTy ) ) >> KShift );
						np++;
						}

					if( d[ p2 ] > 0 )
						{
						TInt s = ( d[ p2 ] << KShift ) / ( d[ p2 ]-d[ p1 ] );
						poly2[ np ].iX = dv2.iX + ( ( s*( dv1.iX - dv2.iX ) ) >> KShift );
						poly2[ np ].iY = dv2.iY + ( ( s*( dv1.iY - dv2.iY ) ) >> KShift );
						poly2[ np ].iZ = dv2.iZ + ( ( s*( dv1.iZ - dv2.iZ ) ) >> KShift );
						poly2[ np ].iTx = dv2.iTx + ( ( s*( dv1.iTx - dv2.iTx ) ) >> KShift );
						poly2[ np ].iTy = dv2.iTy + ( ( s*( dv1.iTy - dv2.iTy ) ) >> KShift );
						np++;
						}
				

					}
				else
					{
					poly2[ np++ ] = poly1[ p1 ];
					}
				}

			numPoints = np;

			TDrawVertex* temp = poly1; 
			poly1 = poly2; 
			poly2 = temp;
			}
				
		TInt t;
		if( visible )
			{
			if( numDrawn < iMaxNumFaces )
				{
				// split polygon to triangles:
				// ( polygon draw other but triangles are not supported )
				for( t=0; t<numPoints-2; t++ )
					{
					iDrawList[ numDrawn++ ] = TDrawFace( poly1[ 0 ], poly1[ 1 + t ], poly1[ 2 + t ] );
					}
				}
			}
		}

	// draw if there's something to draw
	if( numDrawn > 0 )
		{
		// add number of polygons to drawn counter
		i3DBase->AddPolygonCount( numDrawn );
		
		// project vertices in iRVertex list to screen coordinates
		Project( iDrawList, numDrawn );

		// sort faces by their Z-values

		for( i=0; i<numDrawn; i++ )
			{
			TDrawFace& f = iDrawList[ i ];
			iFaceZ[ i ] = f.iV1.iZ + f.iV2.iZ + f.iV3.iZ;
			iFaceN[ i ] = i;
			}

		i3DBase->QSort( iFaceZ, iFaceN, 0, numDrawn-1 );


		// and draw faces from back to front
		for( i=numDrawn-1; i>=0; i-- )
			{
			TDrawFace& f = iDrawList[ iFaceN[ i ] ];
			// textured
			DrawTexTri( &f.iV1, &f.iV2, &f.iV3 );
			}

		}
#endif
	}




#ifdef GLES

// OpenGl uses it's own texture handles
void CPolygonObject::SetTexture( TInt aTextureObjectHandle )
	{
	iTextureObject = aTextureObjectHandle;
	}

#else

// Software renderer understands TBitmap-type textures
void CPolygonObject::SetTexture( TBitmap aTexture )
	{
	iTexture = aTexture.iData;
	}
	
#endif




void CPolygonObject::Reset( TInt aNumVertices, TInt aNumFaces )
	{
	iMaxNumVertices = aNumVertices;
	iMaxNumFaces = aNumFaces;


	delete[] iFace;
	iFace = new( ELeave )TFace[ iMaxNumFaces ];
	iNumFaces = 0;

⌨️ 快捷键说明

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