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

📄 cpolygonobject.cpp

📁 Symbian平台下的一个3D赛车游戏源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	delete[] iVertex;
	iVertex = new( ELeave )TVertex[ iMaxNumVertices ];
	
	delete[] iRVertex;
	iRVertex = new( ELeave )TVertex[ iMaxNumVertices ];
	iNumVertices = 0;

	delete[] iFaceN;
	iFaceN = new( ELeave )TInt[ iMaxNumFaces ];

	delete[] iFaceZ;
	iFaceZ = new( ELeave )TInt[ iMaxNumFaces ];

	delete[] iDrawList;
	iDrawList = new( ELeave )TDrawFace[ iMaxNumFaces ];

	}


TInt CPolygonObject::AddVertex( const TVertex& aVertex )
	{
	__ASSERT_DEBUG( iNumVertices < iMaxNumVertices, User::Panic( _L("Too many vertices"), iNumVertices ) );

	iVertex[ iNumVertices++ ] = aVertex;
	return iNumVertices-1;
	}

void CPolygonObject::SetVertex( TInt aIndex, const TVertex& aVertex )
	{
	__ASSERT_DEBUG( aIndex < iNumVertices, User::Panic( _L("Illegal vertex index"), aIndex ) );
	iVertex[ aIndex ] = aVertex;
	}

TInt CPolygonObject::AddFace( const TFace& aFace )
	{
	__ASSERT_DEBUG( iNumFaces < iMaxNumFaces, User::Panic( _L("Too many faces"), iNumFaces ) );

	iFace[ iNumFaces++ ] = aFace;
	return iNumFaces;
	}

void CPolygonObject::Init()
	{
	//
	// Calculate bounding radius for object clipping
	//
	TInt r = 0;

	TInt i;
	for( i=0; i<iNumVertices; i++ )
		{
		TVertex& v = iVertex[ i ];
		TInt r2 = v.iX * v.iX + v.iY * v.iY + v.iZ * v.iZ;
		if( r2 > r ) r = r2;
		}
	TReal ra;
	Math::Sqrt( ra, r );
	iBoundingRadius = ( TInt )ra;
	
#ifdef GLES

	// if using OpenGL ES, convert vertices and faces
	// to opengl world

	delete[] iGlVerts;
	delete[] iGlTexCoords;
	delete[] iGlTris;
	
	iGlTriCount = iNumFaces*3;
	iGlVerts=new GLfixed[ iGlTriCount*3];
	iGlTexCoords=new GLfixed[ iGlTriCount*2 ];
	iGlTris=new GLushort[ iGlTriCount ];

	TInt ic=0;
	TInt vc=0;

	const TInt textureSize = 256;
	const TInt GlShift = 16;
	const TInt shift = GlShift - KShift;

	for (i=0;i<iNumFaces;i++)
		{
		int a,b,c;
		a=iFace[i].iV1;
		b=iFace[i].iV2;
		c=iFace[i].iV3;

		iGlVerts[vc*3] = iVertex[a].iX << shift;
		iGlVerts[vc*3+1] = iVertex[a].iY << shift;
		iGlVerts[vc*3+2] = iVertex[a].iZ << shift;

		iGlTexCoords[vc*2] = ( iFace[i].iTx1 << GlShift ) / textureSize;
		iGlTexCoords[vc*2+1] = ( iFace[i].iTy1 << GlShift ) / textureSize;
		iGlTris[ic] = (GLushort)vc;
		ic++;	
		vc++;

		iGlVerts[vc*3] = iVertex[b].iX << shift;
		iGlVerts[vc*3+1] = iVertex[b].iY << shift;
		iGlVerts[vc*3+2] = iVertex[b].iZ << shift;
		iGlTexCoords[vc*2] = ( iFace[i].iTx2 << GlShift ) / textureSize;
		iGlTexCoords[vc*2+1] = ( iFace[i].iTy2 << GlShift ) / textureSize;
		iGlTris[ic] = (GLushort)vc;
		ic++;
		vc++;

		iGlVerts[vc*3] = iVertex[c].iX << shift;
		iGlVerts[vc*3+1] = iVertex[c].iY << shift;
		iGlVerts[vc*3+2] = iVertex[c].iZ << shift;
		iGlTexCoords[vc*2] = ( iFace[i].iTx3 << GlShift) / textureSize;
		iGlTexCoords[vc*2+1] = ( iFace[i].iTy3 << GlShift) / textureSize;
		iGlTris[ic] = (GLushort)vc;
		ic++;
		vc++;		
		}


#endif

	}


void CPolygonObject::Rotate()
	{
	// multiply all vertices by rotate matrix
	// rotate matrix is calculated by C3DRenderer

	for( TInt i=0; i<iNumVertices; i++ )
		{
		iRVertex[ i ] = iVertex[ i ];
		iRVertex[ i ].MulMatrix( iRotateMatrix );
		}
	}


void CPolygonObject::Project( TDrawFace* aFaceList, TInt aNumFaces )
	{
	
	const TInt mul = 512;
	TInt i;
	TInt mx = iScreen.iSize.iWidth / 2;
	TInt my = iScreen.iSize.iHeight / 2;
	
	for( i=0; i<aNumFaces; i++ )
		{
		TDrawFace& f = aFaceList[ i ];
		
		f.iV1.iX = f.iV1.iX * mul / f.iV1.iZ + mx;
		f.iV1.iY = f.iV1.iY * mul / f.iV1.iZ + my;
		f.iV2.iX = f.iV2.iX * mul / f.iV2.iZ + mx;
		f.iV2.iY = f.iV2.iY * mul / f.iV2.iZ + my;
		f.iV3.iX = f.iV3.iX * mul / f.iV3.iZ + mx;
		f.iV3.iY = f.iV3.iY * mul / f.iV3.iZ + my;		
		}

	}




inline void CPolygonObject::Swap( TAny* aV1, TAny* aV2 )
	{
	TUint32 temp = *(TUint32*)aV1;
	*(TUint32*)aV1 = *(TUint32*)aV2;
	*(TUint32*)aV2 = temp;
	}


	// disable warning of local variable may be used without initialized
	// these variables are always initialized but compiler doesn't know it.
#pragma warning( disable : 4701 )

void CPolygonObject::DrawTexTri( TDrawVertex* aV1, TDrawVertex* aV2, TDrawVertex* aV3 )
	{
	TInt d = ( aV1->iX - aV3->iX ) * ( aV2->iY - aV3->iY ) -
			 ( aV2->iX - aV3->iX ) * ( aV1->iY - aV3->iY );
	
	if( d <= 0 ) return;

	TInt id = ( 1 << 24 ) / d;

	TInt dudx = ( ( aV1->iTx - aV3->iTx ) * ( aV2->iY - aV3->iY ) -
				  ( aV2->iTx - aV3->iTx ) * ( aV1->iY - aV3->iY ) ) * id / ( 1 << 16 );

	TInt dvdx = ( ( aV1->iTy - aV3->iTy ) * ( aV2->iY - aV3->iY ) -
				  ( aV2->iTy - aV3->iTy ) * ( aV1->iY - aV3->iY ) ) * id / ( 1 << 16 );
	
	if( aV1->iY > aV2->iY ) { Swap( &aV1, &aV2 ); d = -d; }
	if( aV2->iY > aV3->iY ) { Swap( &aV2, &aV3 ); d = -d; }
	if( aV1->iY > aV2->iY ) { Swap( &aV1, &aV2 ); d = -d; }
	

	TInt h1 = ( aV2->iY - aV1->iY );
	TInt h2 = ( aV3->iY - aV2->iY );
	TInt h3 = ( aV3->iY - aV1->iY );



	if( h3 == 0 ) return;

	TInt h1i = 0;
	if( h1 ) h1i = 65536 / h1; 
	TInt h2i = 0;
	if( h2 ) h2i = 65536 / h2; 
	TInt h3i = 65536 / h3;

	TInt y = aV1->iY;

	TInt x1, x2;
	TInt x1a, x2a;
	TInt txya;
	TInt tyya;
	TInt otx;
	TInt oty;
	
	for( ;; )
		{

		//
		// First half:
		//
		if( y==aV1->iY )
			{
			x1 = 256 * aV1->iX;
			x2 = x1;
			if( d > 0 ) // long side left
				{
				x1a = h3i * ( aV3->iX - aV1->iX ) >> 8;
				x2a = h1i * ( aV2->iX - aV1->iX ) >> 8;

				txya = h3i * ( aV3->iTx - aV1->iTx ) >> 8;
				tyya = h3i * ( aV3->iTy - aV1->iTy ) >> 8;
				otx = aV1->iTx << 8;
				oty = aV1->iTy << 8;
				}
			else		// long side right
				{
				x1a = h1i * ( aV2->iX - aV1->iX ) >> 8;
				x2a = h3i * ( aV3->iX - aV1->iX ) >> 8;
				txya = h1i * ( aV2->iTx - aV1->iTx ) >> 8;
				tyya = h1i * ( aV2->iTy - aV1->iTy ) >> 8;
				otx = aV1->iTx << 8;
				oty = aV1->iTy << 8;
				}

			}

		//
		// Second half:
		//
		if( y==aV2->iY )
			{
			if( d > 0 )	// long side left
				{
				x1a = h3i * ( aV3->iX - aV1->iX ) >> 8;
				x2a = h2i * ( aV3->iX - aV2->iX ) >> 8;
				x1 = 256 * aV1->iX + x1a * h1;
				x2 = 256 * aV2->iX;

				txya = h3i * ( aV3->iTx - aV1->iTx ) >> 8;
				tyya = h3i * ( aV3->iTy - aV1->iTy ) >> 8;
				otx = 256 * aV1->iTx + txya * h1;
				oty = 256 * aV1->iTy + tyya * h1;
				}
			else		// long side right
				{
				x1a = h2i * ( aV3->iX - aV2->iX ) >> 8;
				x2a = h3i * ( aV3->iX - aV1->iX ) >> 8;
				x1 = 256 * aV2->iX;
				x2 = 256 * aV1->iX + x2a * h1;

				txya = h2i * ( aV3->iTx - aV2->iTx ) >> 8;
				tyya = h2i * ( aV3->iTy - aV2->iTy ) >> 8;
				otx = 256 * aV2->iTx;
				oty = 256 * aV2->iTy;
				}
			}

		//
		// End of polygon
		//
		if( y==aV3->iY )
			{
			break;
			}

		if (iScreen.iMode == EColor64K)
			{
			// Left edge pointer
			TUint16* p = (TUint16*)iScreen.iData + y * iScreen.iSize.iWidth;

			// Right edge pointer
			TUint16* p2 = p + ( x2 >> 8 );
			p += x1 >> 8;

			TInt tx = otx;
			TInt ty = oty;
			
			// scanline filler
			register TUint16* sp = (TUint16*)iTexture;
			register TInt txa = dudx;
			register TInt tya = dvdx;
			while( p <= p2 )
				{
				*p++ = sp[ ( tx >> 8 ) + ( ty & 0xff00 ) ];
				tx += txa;
				ty += tya;
				}

			x1 += x1a;
			x2 += x2a;
			otx += txya;
			oty += tyya;
			y++;
			}
		else if (iScreen.iMode == EColor16MU)
			{
			// Left edge pointer
			TUint32* p = (TUint32*)iScreen.iData + y * iScreen.iSize.iWidth;

			// Right edge pointer
			TUint32* p2 = p + ( x2 >> 8 );
			p += x1 >> 8;

			TInt tx = otx;
			TInt ty = oty;
			
			// scanline filler
			register TUint32* sp = (TUint32*)iTexture;
			register TInt txa = dudx;
			register TInt tya = dvdx;
			while( p <= p2 )
				{
				*p++ = sp[ ( tx >> 8 ) + ( ty & 0xff00 ) ];
				tx += txa;
				ty += tya;
				}

			x1 += x1a;
			x2 += x2a;
			otx += txya;
			oty += tyya;
			y++;
			}
		}

	}

	// enable warning "local variable may be used without initialized"
#pragma warning( default : 4701 )

⌨️ 快捷键说明

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