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

📄 gemvipm.cpp

📁 游戏编程精粹2第四章源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* Copyright (C) Tom Forsyth, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) Tom Forsyth, 2001"
 */



#include "TomsD3DLib.h"


#define STRICT
#define D3D_OVERLOADS
#include <windows.h>
#include <tchar.h>
#include <math.h>
#include <stdio.h>
#include <D3DX8.h>
#include <DInput.h>
#include "D3DApp.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "DXUtil.h"
#include "resource.h"
#include "commctrl.h"
#include <list>


#include "object.h"



//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
struct CUSTOMVERTEX
{
    D3DXVECTOR3 v;
    DWORD       diffuse;
    DWORD       specular;
    FLOAT       tu, tv;
};

#define CUSTOMVERTEX_FVF (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX1)


struct CUSTOM3VERTEX
{
    D3DXVECTOR3 v;
    DWORD       diffuse;
    DWORD       specular;
    FLOAT       tu, tv, tt;
};

#define CUSTOM3VERTEX_FVF (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE3(0))




struct TVERTEX
{
    D3DXVECTOR3 v;
	float		rhw;
};

#define TVERTEX_FVF (D3DFVF_XYZRHW)




// Fudge - exposes m_pd3dDevice to the outside world.
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;





// DInput stuff.

IDirectInput8*			g_pDI			= NULL;
IDirectInputDevice8*	g_pMouse		= NULL;
HINSTANCE				g_hInst			= NULL;
BOOL					g_bActive		= TRUE;
BOOL					g_bExclusive	= FALSE;
BOOL					g_bKeyDownCtrl	= FALSE;
BOOL					g_bKeyDownShift	= FALSE;
BOOL					m_bOrbitStrafe	= TRUE;


DIMOUSESTATE2			g_dims;      // DirectInput mouse state structure



//-----------------------------------------------------------------------------
// Function: SetAcquire
//
// Description: 
//      Acquire or unacquire the mouse, depending on if the app is active
//       Input device must be acquired before the GetDeviceState is called
//
//-----------------------------------------------------------------------------
HRESULT SetAcquire( HWND hWnd )
{
	// nothing to do if g_pMouse is NULL
	if (NULL == g_pMouse)
		return S_FALSE;

	if (g_bActive) 
	{
		// acquire the input device 
		g_pMouse->Acquire();
	} 
	else 
	{
		// unacquire the input device 
		g_pMouse->Unacquire();
	}

	return S_OK;
}




//-----------------------------------------------------------------------------
// Function: UpdateInputState
//
// Description: 
//      Get the input device's state and display it.
//
//-----------------------------------------------------------------------------
char g_szMouseText[256];    // current  mouse state text
HRESULT UpdateInputState( HWND hWnd )
{
	if (NULL != g_pMouse) 
	{
		HRESULT hr;

		hr = DIERR_INPUTLOST;

		// if input is lost then acquire and keep trying 
		while ( DIERR_INPUTLOST == hr ) 
		{
			// get the input's device state, and put the state in g_dims
			hr = g_pMouse->GetDeviceState( sizeof(DIMOUSESTATE2), &g_dims );

			if ( hr == DIERR_INPUTLOST )
			{
				// DirectInput is telling us that the input stream has
				// been interrupted.  We aren't tracking any state
				// between polls, so we don't have any special reset
				// that needs to be done.  We just re-acquire and
				// try again.
				hr = g_pMouse->Acquire();
				if ( FAILED(hr) )
				{
					return hr;
				}
			}
		}

		if ( FAILED(hr) )
		{
			return hr;
		}

	}
	else
	{
		// No mouse!
	}

	return S_OK;
}




//-----------------------------------------------------------------------------
// Function: InitDirectInput
//
// Description: 
//      Initialize the DirectInput variables.
//
//-----------------------------------------------------------------------------
HRESULT InitDirectInput( HWND hWnd, bool bExclusive = FALSE )
{
	HRESULT hr;

	// Register with the DirectInput subsystem and get a pointer
	// to a IDirectInput interface we can use.
	hr = DirectInput8Create( g_hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&g_pDI, NULL );
	if ( FAILED(hr) )
	{
		ASSERT ( FALSE );
		return hr;
	}

	// Obtain an interface to the system mouse device.
	hr = g_pDI->CreateDevice( GUID_SysMouse, &g_pMouse, NULL );
	if ( FAILED(hr) )
	{
		ASSERT ( FALSE );
		return hr;
	}

	// Set the data format to "mouse format" - a predefined data format 
	//
	// A data format specifies which controls on a device we
	// are interested in, and how they should be reported.
	//
	// This tells DirectInput that we will be passing a
	// DIMOUSESTATE2 structure to IDirectInputDevice::GetDeviceState.
	hr = g_pMouse->SetDataFormat( &c_dfDIMouse2 );
	if ( FAILED(hr) )
	{
		ASSERT ( FALSE );
		return hr;
	}

	// Set the cooperativity level to let DirectInput know how
	// this device should interact with the system and with other
	// DirectInput applications.
	DWORD dwFlags = DISCL_FOREGROUND;


// KLUDGE! Win2k really hates FOREGROUND+EXCLUSIVE devices - don't know why.
#if 0
	if ( bExclusive )
	{
		dwFlags |= DISCL_EXCLUSIVE;
	}
	else
	{
		dwFlags |= DISCL_NONEXCLUSIVE;
	}
#else
	dwFlags |= DISCL_NONEXCLUSIVE;
#endif


	hr = g_pMouse->SetCooperativeLevel( hWnd, dwFlags );
	if ( FAILED(hr) )
	{
		ASSERT ( FALSE );
		return hr;
	}

	// And acquire it the first time (the windows message has already missed us).
	SetAcquire( hWnd );

	return S_OK;
}





//-----------------------------------------------------------------------------
// Function: FreeDirectInput
//
// Description: 
//      Initialize the DirectInput variables.
//
//-----------------------------------------------------------------------------
HRESULT FreeDirectInput()
{
	// Unacquire and release any DirectInputDevice objects.
	if (NULL != g_pMouse) 
	{
		// Unacquire the device one last time just in case 
		// the app tried to exit while the device is still acquired.
		g_pMouse->Unacquire();

		g_pMouse->Release();
		g_pMouse = NULL;
	}

	// Release any DirectInput objects.
	if (NULL != g_pDI) 
	{
		g_pDI->Release();
		g_pDI = NULL;
	}

	return S_OK;
}



// Enter or leave exclusive mode.
HRESULT SetExclusiveMode ( bool bExclusive, HWND hWnd )
{
	if ( ( bExclusive && g_bExclusive ) || ( !bExclusive && !g_bExclusive ) )
	{
		return ( DI_OK );
	}


	// Need to rip it all down and recreate - what a hassle.
	FreeDirectInput();

	HRESULT hr = InitDirectInput ( hWnd, bExclusive );
	if ( FAILED ( hr ) )
	{
		return ( hr );
	}

	g_bExclusive = bExclusive;

	return ( hr );
}








//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc: Application class. The base class (CD3DApplication) provides the 
//       generic functionality needed in all Direct3D samples. CMyD3DApplication 
//       adds functionality specific to this sample program.
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
    CD3DFont*          m_pFont;

	BOOL				m_bIgnoreBackFaced;
	BOOL				m_bShowSlidingWindowInfo;
	float				m_fSlidingWindowErrorTolerance;
	int					m_iFindBestErrorCountdown;
	VIPMTypeEnum		m_vteCurrentDisplayStyle;

	BOOL				m_bCreateCollapseMode;

	int					m_iTargetNumCollapses;
	float				m_fTargetErrorFactor;
	BOOL				m_bTargetErrorAutoGen;
	BOOL				m_bWireframe;
	int					m_iCreateThisManyCollapses;


	MeshEdge			*m_pedgeBestError;
	MeshPt				*m_pptBestError;


	ObjectInstance		m_ObjectInstRoot;
	Object				*m_pObject;
	D3DXMATRIX			m_matView;
	D3DXMATRIX			m_matProjClose;
	D3DXMATRIX			m_matProjCloseZbias;
	D3DXMATRIX			m_matProjFar;

    HRESULT ConfirmDevice( D3DCAPS8*, DWORD, D3DFORMAT );
    LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

protected:
    HRESULT OneTimeSceneInit();
    HRESULT InitDeviceObjects();
    HRESULT RestoreDeviceObjects();
    HRESULT InvalidateDeviceObjects();
    HRESULT DeleteDeviceObjects();
    HRESULT Render();
    HRESULT FrameMove();
    HRESULT FinalCleanup();
	void SetMenuItems();

public:
    CMyD3DApplication();
};




//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
//       message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    CMyD3DApplication d3dApp;

	// DInput needs the instance.
    g_hInst = hInst;


    if( FAILED( d3dApp.Create( hInst ) ) )
        return 0;

    return d3dApp.Run();
}




//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application constructor. Sets attributes for the app.
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
    m_strWindowTitle  = _T("VIPM tester");
    m_bUseDepthBuffer = TRUE;

    m_pFont                = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );

	m_bIgnoreBackFaced = TRUE;
	m_bShowSlidingWindowInfo = TRUE;
	m_bCreateCollapseMode = TRUE;
	m_fSlidingWindowErrorTolerance = 0.1f;	// 10%
	m_iFindBestErrorCountdown = 0;
	m_vteCurrentDisplayStyle = VIPMType_Vanilla;

	m_iTargetNumCollapses = 0;
	m_fTargetErrorFactor = 1.0f;
	m_bTargetErrorAutoGen = TRUE;
	m_bWireframe = FALSE;
	m_iCreateThisManyCollapses = 0;

	m_pedgeBestError = NULL;
	m_pptBestError = NULL;



	g_iMaxNumTrisDrawn = -1;	// No limit.
	g_bOptimiseVertexOrder = FALSE;
	g_bShowVIPMInfo = FALSE;
#if ALLOW_PROGRESS_BARS
	g_hWndApp = NULL;		// Will be set later.
#endif


}




//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
//       permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{

	m_pObject = new Object;
	ObjectInstance *pInst;
	D3DXMATRIX mat;
	D3DXMatrixIdentity ( &mat );
	
	pInst = &m_ObjectInstRoot;

	// First one should always be at the origin - it's used for editing.
	pInst = new ObjectInstance ( m_pObject, pInst );
	pInst->matOrn = mat;
	pInst->iRenderMethod = m_vteCurrentDisplayStyle;


	// Now create loads of objects randomly distributed in a cube or something.
	DWORD dwSeed = 0x12345678;
	float fSize = 100.f;
	for ( int i = 0; i < 1000; i++ )
	{
		pInst = new ObjectInstance ( m_pObject, pInst );
		pInst->matOrn = mat;
		pInst->matOrn._41 = ( ( (float)( ( dwSeed >>  0 ) & 0xff ) * ( 1.0f / 255.0f ) ) - 0.5f ) * fSize;
		pInst->matOrn._42 = ( ( (float)( ( dwSeed >>  8 ) & 0xff ) * ( 1.0f / 255.0f ) ) - 0.5f ) * fSize;
		pInst->matOrn._43 = ( ( (float)( ( dwSeed >> 16 ) & 0xff ) * ( 1.0f / 255.0f ) ) - 0.5f ) * fSize;
		pInst->iRenderMethod = m_vteCurrentDisplayStyle;

		D3DXMATRIX matTemp;

		D3DXMatrixRotationX( &matTemp, (float)( ( dwSeed >> 4 ) & 0xff ) * ( 3.14 / 255.0f ) );
		D3DXMatrixMultiply ( &(pInst->matOrn), &matTemp, &(pInst->matOrn) );
		D3DXMatrixRotationY( &matTemp, (float)( ( dwSeed >> 12 ) & 0xff ) * ( 3.14 / 255.0f ) );
		D3DXMatrixMultiply ( &(pInst->matOrn), &matTemp, &(pInst->matOrn) );
		D3DXMatrixRotationZ( &matTemp, (float)( ( dwSeed >> 20 ) & 0xff ) * ( 3.14 / 255.0f ) );
		D3DXMatrixMultiply ( &(pInst->matOrn), &matTemp, &(pInst->matOrn) );
																			
		// This has no mathematical rigour whatsoever. Just letting you know.
		dwSeed += 0x61902856;
		dwSeed *= 0x34977;
		dwSeed ^= dwSeed >> 23;
	}

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
//       the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{

    return S_OK;
}







void DrawScreenSpacePoint ( D3DXVECTOR3 &vec )
{
	TVERTEX vert[4];
	vert[0].rhw = 0.5f;		// Random non-wierd value.
	vert[1].rhw = 0.5f;
	vert[2].rhw = 0.5f;
	vert[3].rhw = 0.5f;

	HRESULT hres;
	hres = g_pd3dDevice->SetVertexShader ( TVERTEX_FVF );
	const float fSizeOfDot = 4.0f;

	vert[0].v		= vec;
	vert[0].v.y -= fSizeOfDot;

	vert[1].v		= vec;
	vert[1].v.x -= fSizeOfDot * 0.866f;
	vert[1].v.y += fSizeOfDot * 0.5f;

	vert[2].v		= vec;
	vert[2].v.x += fSizeOfDot * 0.866f;
	vert[2].v.y += fSizeOfDot * 0.5f;

	vert[3].v		= vert[0].v;

	hres = g_pd3dDevice->DrawPrimitiveUP ( D3DPT_LINESTRIP, 3, vert, sizeof(vert[0]) );
}

void DrawScreenSpacePoint ( D3DXVECTOR4 &vec )
{
	if ( vec.w > 0.0f )
	{
		D3DXVECTOR3 vec3 ( vec.x, vec.y, vec.z );
		DrawScreenSpacePoint ( vec3 );
	}
}


void DrawScreenSpaceEdge ( D3DXVECTOR3 &vecBig, D3DXVECTOR3 &vecSmall )
{
	TVERTEX vert[4];

⌨️ 快捷键说明

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