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

📄 gemvipm.cpp

📁 游戏编程精粹2第四章源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			char strTemp[1000];
			sprintf ( strTemp, "Collapse-creation mode." );
			m_pFont->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,255,0), strTemp );


			if ( pClosestEdge != NULL )
			{
				// Show the error for this collapse.
				ASSERT ( pClosestPt != NULL );
				float fError = pFirstObj->FindCollapseError ( pClosestPt, pClosestEdge );
				sprintf ( strTemp, "User-selected collapse error %f", fError );
				m_pFont->DrawText( 2, 60, D3DCOLOR_ARGB(255,255,255,0), strTemp );
			}
			if ( m_pedgeBestError != NULL )
			{
				// Show the error for this collapse.
				ASSERT ( m_pptBestError != NULL );
				float fError = pFirstObj->FindCollapseError ( m_pptBestError, m_pedgeBestError );
				sprintf ( strTemp, "Auto-selected collapse error %f", fError );
				m_pFont->DrawText( 2, 80, D3DCOLOR_ARGB(255,255,255,0), strTemp );
			}
			if ( m_bShowSlidingWindowInfo )
			{
				if ( m_pedgeBestError != NULL )
				{
					sprintf ( strTemp, "Best collapse error %f", fBestOfAnyError );
					m_pFont->DrawText( 2, 100, D3DCOLOR_ARGB(255,255,255,0), strTemp );
				}

				sprintf ( strTemp, "Sliding window level %i, error tolerance %f%%", pFirstObj->iCurSlidingWindowLevel, m_fSlidingWindowErrorTolerance * 100.0f );
				m_pFont->DrawText( 2, 120, D3DCOLOR_ARGB(255,255,255,0), strTemp );
			}

			// End the scene.
			m_pd3dDevice->EndScene();
		}


	}
	else
	{
		m_pedgeBestError = NULL;
		m_pptBestError = NULL;

		// Clear the render target
		m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000f, 1.0f, 0L );

		// Begin the scene
		if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
		{


			m_pd3dDevice->SetTransform( D3DTS_VIEW,       &m_matView );
			m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_matProjFar );

			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

			m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
			m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

			m_pd3dDevice->SetRenderState ( D3DRS_LIGHTING, TRUE );
			m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
			m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );

			if ( m_bWireframe )
			{
				m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
			}
			else
			{
				m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
			}

			if ( m_bIgnoreBackFaced )
			{
				m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
			}
			else
			{
				m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
			}

			m_pd3dDevice->SetTexture( 0, NULL );

			D3DMATERIAL8 matNormal;
			matNormal.Ambient = D3DXCOLOR ( 1.0f, 1.0f, 1.0f, 0.0f );
			matNormal.Diffuse = D3DXCOLOR ( 1.0f, 1.0f, 1.0f, 0.0f );
			matNormal.Specular = D3DXCOLOR ( 0.5f, 0.5f, 0.5f, 0.0f );
			matNormal.Emissive= D3DXCOLOR ( 0.0f, 0.0f, 0.0f, 0.0f );
			matNormal.Power = 20.f;

			D3DMATERIAL8 matHighlight;
			matHighlight.Ambient = D3DXCOLOR ( 1.0f, 1.0f, 0.0f, 0.0f );
			matHighlight.Diffuse = D3DXCOLOR ( 1.0f, 1.0f, 0.0f, 0.0f );
			matHighlight.Specular = D3DXCOLOR ( 0.5f, 0.5f, 0.0f, 0.0f );
			matHighlight.Emissive= D3DXCOLOR ( 0.0f, 0.0f, 0.5f, 0.0f );
			matHighlight.Power = 20.f;

			m_pd3dDevice->SetMaterial ( &matNormal );

			for ( ObjectInstance *pObjInst = m_ObjectInstRoot.ListNext(); pObjInst != NULL; pObjInst = pObjInst->ListNext() )
			{

				if ( pObjInst == pFirstObjInst )
				{
					// Set the highlighted material.
					m_pd3dDevice->SetMaterial ( &matHighlight );
				}

				Object *pObj = pObjInst->pObj;

				m_pd3dDevice->SetTransform( D3DTS_WORLD,      &pObjInst->matOrn );

				if ( m_bTargetErrorAutoGen )
				{
					// Calculate the required error.
					// This should of course do something clever with the error values that
					// are associated with each collapse. But it doesn't, so it doesn't
					// look very good. You can get the proper LoD thing going quickly
					// using a small (e.g. 32 entry) lookup table that has desired
					// error against number of collapses, and linearly interpolating that
					// is fairly quick, but still takes account of the most important
					// changes in collapse error. But I haven't done that here.

					D3DXVECTOR3 vDelta;
					vDelta.x = pObjInst->matOrn._41;
					vDelta.y = pObjInst->matOrn._42;
					vDelta.z = pObjInst->matOrn._43;
					D3DXVec3TransformCoord ( &vDelta, &vDelta, &m_matView );
					// Whether you like it proportional to distance or distance squared is up to you.
					// Although mathematically, a distance squared measure keeps the triangle size
					// constant, the eye has a sort of "auto zoom" for distant objects, so you
					// tend to notice the problems quicker. Maybe a non-integer power?
					//float fDist = D3DXVec3Length ( &vDelta );
					float fDist = D3DXVec3LengthSq ( &vDelta );
					pObjInst->SetNumCollapses ( (int)( m_fTargetErrorFactor * fDist ) );
				}
				else
				{
					pObjInst->SetNumCollapses ( m_iTargetNumCollapses );
				}

				pObjInst->RenderCurrentObject ( m_pd3dDevice, 0, -1, TRUE );


				if ( pObjInst == pFirstObjInst )
				{
					// Set the normal material again.
					m_pd3dDevice->SetMaterial ( &matNormal );
				}

				if ( g_iMaxNumTrisDrawn > 0 )
				{
					// If showing tri order, just draw one object.
					break;
				}

			}


			// Output statistics
			m_pFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
			m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );

			char strTemp[1000];
			sprintf ( strTemp, "Optimised VIPM viewing mode." );
			m_pFont->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,255,0), strTemp );

			sprintf ( strTemp, "Current VIPM type: %s", VIPMTypeName(m_vteCurrentDisplayStyle) );
			m_pFont->DrawText( 2, 60, D3DCOLOR_ARGB(255,255,255,0), strTemp );

			sprintf ( strTemp, "Drew %i tris, %i vertices.", g_iNumOfObjectTrisDrawn, g_iNumOfObjectVertsDrawn );
			m_pFont->DrawText( 2, 80, D3DCOLOR_ARGB(255,255,255,0), strTemp );
			g_iNumOfObjectTrisDrawn = 0;
			g_iNumOfObjectVertsDrawn = 0;

			if ( m_bTargetErrorAutoGen )
			{
				// Auto generating collapse LoD.
				sprintf ( strTemp, "Autogenerate LoD factor: %f", m_fTargetErrorFactor );
				m_pFont->DrawText( 2, 100, D3DCOLOR_ARGB(255,255,255,0), strTemp );
			}
			else
			{
				sprintf ( strTemp, "Direct LoD control: %i", m_iTargetNumCollapses );
				m_pFont->DrawText( 2, 100, D3DCOLOR_ARGB(255,255,255,0), strTemp );
			}

			if ( g_bShowVIPMInfo )
			{
				DWORD dwGlobalMem, dwGlobalAGP;
				DWORD dwInstanceMem, dwInstanceAGP;
				DWORD dwVerts, dwTris, dwVertsTotal;

				OptimisedMeshInstance *pomi = pFirstObjInst->GetOpiMeshInst();
				if ( pomi != NULL )
				{
					pomi->InfoGetGlobal ( &dwGlobalMem, &dwGlobalAGP );
					pomi->InfoGetInstance ( &dwInstanceMem, &dwInstanceAGP, &dwVerts, &dwTris, &dwVertsTotal );

					// Don't include AGP in the totals.
					dwGlobalMem -= dwGlobalAGP;
					dwInstanceMem -= dwInstanceAGP;

					sprintf ( strTemp,	"VIPM info: global mem %ikb, global AGP %ikb, "
										"instance mem %ikb, instance AGP %ikb",
										dwGlobalMem / 1024, dwGlobalAGP / 1024,
										dwInstanceMem / 1024, dwInstanceAGP / 1024
										);
					m_pFont->DrawText( 2, 120, D3DCOLOR_ARGB(255,255,255,0), strTemp );

					sprintf ( strTemp,	"%i verts processed, %i tris drawn, "
										"%f verts per tri %s",
										dwVerts, dwTris,
										(float)dwVerts / (float)dwTris,
										g_bOptimiseVertexOrder ? "(optimised)" : "(not optimised)"
										);
					m_pFont->DrawText( 2, 140, D3DCOLOR_ARGB(255,255,255,0), strTemp );

					// When it says "possible", it's not really possible with any sensible cache - just for reference really.
					sprintf ( strTemp,	"%i verts total. (Im)possible best score %f verts per tri",
										dwVertsTotal,
										(float)dwVertsTotal / (float)dwTris
										);
					m_pFont->DrawText( 2, 160, D3DCOLOR_ARGB(255,255,255,0), strTemp );
				}
			}

			if ( g_iMaxNumTrisDrawn > 0 )
			{
				sprintf ( strTemp,	"Limited to %i tris drawn", g_iMaxNumTrisDrawn );
				m_pFont->DrawText( 2, 180, D3DCOLOR_ARGB(255,255,255,0), strTemp );
			}


			// End the scene.
			m_pd3dDevice->EndScene();
		}

	}





	HRESULT hr;

	// Where's the mouse?
	hr = UpdateInputState( m_hWnd );

	DWORD dwButtons = 0;
#define BUTTON_LEFT		0x01
#define BUTTON_RIGHT	0x02
#define BUTTON_MID		0x04

	if ( g_dims.rgbButtons[0] & 0x80 )
	{
		dwButtons |= BUTTON_LEFT;
	}
	if ( g_dims.rgbButtons[1] & 0x80 )
	{
		dwButtons |= BUTTON_RIGHT;
	}
	if ( g_dims.rgbButtons[2] & 0x80 )
	{
		dwButtons |= BUTTON_MID;
	}



	// Spot going-down and going-up buttons.
	static DWORD dwPreviousButtons = 0;
	DWORD dwButtonsGoneDown = dwButtons & ~dwPreviousButtons;
	DWORD dwButtonsGoneUp = ~dwButtons & dwPreviousButtons;
	dwPreviousButtons = dwButtons;



	// Do we premult or postmult the transform?
	// Premult for most things, postmult for camera.
	bool bPremult = TRUE;

#define PrePost_MatrixMultiply(res,varg,barg) if ( bPremult ) {D3DXMatrixMultiply ( res, barg, varg );} else D3DXMatrixMultiply ( res, varg, barg )
	

	// If shift is not down, but some mouse buttons are, this may be a movement of some sort.
	if ( ( dwButtons != 0 ) && !g_bKeyDownShift )
	{
		if ( !g_bExclusive )
		{
			// Enter exclusive mode.
			SetExclusiveMode ( TRUE, m_hWnd );
		}

		{
			D3DXMATRIX *pmat;
			if ( !g_bKeyDownCtrl )
			{
				// Move the viewer.
				pmat = &m_matView;
				bPremult = FALSE;
			}
			else
			{
				// Ctrl key down - move the first object.
				pmat = &(pFirstObjInst->matOrn);
				bPremult = TRUE;
			}


			D3DXMATRIX  mat1;

			if ( dwButtons == ( BUTTON_LEFT | BUTTON_RIGHT ) )
			{
				// Strafe.
				// Magic numbers are scales.
				float fStrafeScale = 1.0f;
				if ( m_bOrbitStrafe && !g_bKeyDownCtrl )
				{
					// Try to keep looking roughly at the origin.
					// Rotate perpendicular to the strafe movement by an amount
					// proportional to the distance from the origin.
					// Sort-of works :-)
					D3DXVECTOR3 vVect;
					vVect.x = pmat->_41;
					vVect.y = pmat->_42;
					vVect.z = pmat->_43;
					float fDistToOrigin = D3DXVec3Length ( &vVect );
					if ( fDistToOrigin < 0.000001f )
					{
						// Sod it - too close.
						fStrafeScale = 1.0f;
					}
					else
					{
						fStrafeScale = fDistToOrigin;
					}
				}

				D3DXMatrixTranslation ( &mat1,
					(float)g_dims.lX * 0.003f * fStrafeScale,
					(float)g_dims.lY * 0.003f * -fStrafeScale,
					0.0f );
				PrePost_MatrixMultiply ( pmat, pmat, &mat1 );

				if ( m_bOrbitStrafe && !g_bKeyDownCtrl )
				{
					D3DXMatrixRotationY( &mat1, (float)g_dims.lX * -0.003f );
					PrePost_MatrixMultiply ( pmat, pmat, &mat1 );
					D3DXMatrixRotationX( &mat1, (float)g_dims.lY * -0.003f );
					PrePost_MatrixMultiply ( pmat, pmat, &mat1 );
				}
			}
			else if ( dwButtons == BUTTON_LEFT )
			{
				// Look.

				// Magic number is X scale.
				D3DXMatrixRotationY( &mat1, (float)g_dims.lX * 0.003f );
				PrePost_MatrixMultiply ( pmat, pmat, &mat1 );

				// Magic number is Y scale.
				D3DXMatrixRotationX( &mat1, (float)g_dims.lY * 0.003f );
				PrePost_MatrixMultiply ( pmat, pmat, &mat1 );
			}
			else if ( dwButtons == BUTTON_RIGHT )
			{
				// Rotate on X, zoom on Y.

				// Magic number is X scale (rotate).
				D3DXMatrixRotationZ( &mat1, (float)g_dims.lX * 0.003f );
				PrePost_MatrixMultiply ( pmat, pmat, &mat1 );

				float fHowMuch;
				if ( m_bCreateCollapseMode )
				{
					// Finer control when creating collapses.
					fHowMuch = (float)g_dims.lY * -0.01f;
				}
				else
				{
					// Coarser control when viewing.
					fHowMuch = (float)g_dims.lY * -0.1f;
				}
				// Magic number is Y scale (zoom).
				D3DXMatrixTranslation( &mat1, 0.0f, 0.0f, fHowMuch );
				PrePost_MatrixMultiply ( pmat, pmat, &mat1 );
			}
		}
	}
	else
	{
		// Not moving.

		// Make sure we are out of exclusive mode.
		SetExclusiveMode ( FALSE, m_hWnd );


		if ( g_bKeyDownShift && !g_bKeyDownCtrl )
		{
			// Shift is down - maybe do a collapse.
			if ( ( ( dwButtonsGoneDown == BUTTON_LEFT ) && ( dwButtons == BUTTON_LEFT ) ) ||
				 ( ( dwButtonsGoneDown == BUTTON_RIGHT ) && ( dwButtons == BUTTON_RIGHT ) ) )
			{
				if ( m_bCreateCollapseMode )
				{
					// Stop doing any collapses.
					m_iCreateThisManyCollapses = 0;

					// Collapse an edge.
					MeshEdge *pedge;
					MeshPt *ppt;
					if ( dwButtons == BUTTON_LEFT )
					{
						// Collapse the user-specified edge.
						pedge = pClosestEdge;
						ppt = pClosestPt;
					}
					else
					{
						// Collapse auto edge.
						pedge = m_pedgeBestError;
						ppt = m_pptBestError;
					}

					if ( ( pedge != NULL ) && ( ppt != NULL ) )
					{
						BOOL bSomeCollapsesDone = FALSE;
						while ( pFirstObj->DoCollapse() )
						{
							bSomeCollapsesDone = TRUE;
						}

						if ( bSomeCollapsesDone )
						{
							// Can't do this collapse if we weren't already fully collapsed - 
							// the edge may not exist any more!
						}
						else
						{
							MeshPt *pKeptPt = pedge->OtherPt ( ppt );
							ASSERT ( pKeptPt != NULL );
							pFirstObj->CreateEdgeCollapse ( ppt, pKeptPt );

							// Set these to NULL, otherwise the silly thing tries
							// to render non-existent stuff.
							pedge = NULL;
							ppt = NULL;
						}
					}
				}
			}
		}
	}



	// Do we need to do any collapses?
	if ( m_bCreateCollapseMode  && ( m_iCreateThisManyCollapses > 0 ) )
	{
		// Collapse auto-found edge.
		if ( ( m_pedgeBestError != NULL ) && ( m_pptBestError != NULL ) )
		{
			m_bCreateCollapseMode = TRUE;
			// First make sure all collapses have been done.
			BOOL bSomeCollapsesDone = FALSE;
			while ( m_pObject->DoCollapse() )
			{
				bSomeCollapsesDone = TRUE;
			}

			if ( bSomeCollapsesDone )
			{
				// Can't do this collapse if we weren't already fully collapsed - 
				// the edge may not exist any more!
			}
			else
			{
				MeshPt *pKeptPt = m_pedgeBestError->OtherPt ( m_pptBestError );
				ASSERT ( pKeptPt != NULL );
				m_pObject->CreateEdgeCollapse ( m_pptBestError, pKeptPt );
				m_iCreateThisManyCollapses--;
			}

			m_pedgeBestError = NULL;
			m_pptBestError = NULL;
		}
		else
		{
			// There wasn't an edge to do. Stop.
			m_iCreateThisManyCollapses = 0;
		}
	}
	ASSERT ( m_iCreateThisManyCollapses >= 0 );


    return S_OK;
}





// Sets menu items up correctly.
void CMyD3DApplication::SetMenuItems()
{
	// Set menu states
	CheckMenuItem( GetMenu(m_hWnd), IDM_IGNORE_BACKFACING,
		   m_bIgnoreBackFaced ? MF_CHECKED : MF_UNCHECKED );

	CheckMenuItem( GetMenu(m_hWnd), IDM_SLIDING_WINDOW_SHOW,
		   m_bShowSlidingWindowInfo ? MF_CHECKED : MF_UNCHECKED );

	CheckMenuItem( GetMenu(m_hWnd), IDM_CREATE_COLLAPSE_MODE,
		   m_bCreateCollapseMode ? MF_CHECKED : MF_UNCHECKED );


	CheckMenuItem( GetMenu(m_hWnd), IDM_TARGET_AUTO_TOGGLE,
		   m_bTargetErrorAutoGen ? MF_CHECKED : MF_UNCHECKED );

	CheckMenuItem( GetMenu(m_hWnd), IDM_WIREFRAME,
		   m_bWireframe ? MF_CHECKED : MF_UNCHECKED );

	CheckMenuItem( GetMenu(m_hWnd), IDM_SHOW_VIPM_INFO,
		   g_bShowVIPMInfo ? MF_CHECKED : MF_UNCHECKED );

	CheckMenuItem( GetMenu(m_hWnd), IDM_CACHE_DISPLAY_ENABLE,
		   ( g_iMaxNumTrisDrawn > 0 ) ? MF_CHECKED : MF_UNCHECKED );
	CheckMenuItem( GetMenu(m_hWnd), IDM_CACHE_OPTIMISE,
		   g_bOptimiseVertexOrder ? MF_CHECKED : MF_UNCHECKED );
	CheckMenuItem( GetMenu(m_hWnd), IDM_CACHE_OPTIMISE_CHEAP,
		   g_bUseFastButBadOptimise ? MF_CHECKED : MF_UNCHECKED );

}


//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{

	m_pFont->InitDeviceObjects( m_pd3dDevice );


	SetMenuItems();


#if ALLOW_PROGRESS_BARS
	g_hWndApp = m_hWnd;
#endif

⌨️ 快捷键说明

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