📄 gemvipm.cpp
字号:
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 + -