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

📄 main.cpp

📁 《3D游戏编程》随书光盘 12章: 设计阴影的多种技巧, 有详细源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**-----------------------------------------------------------------------------
 * \brief 纹理投影
 * 文件: main.cpp
 *
 * 说明: 显示投影纹理.
 *       
 *------------------------------------------------------------------------------
 */

#define MAINBODY

#include <d3d9.h>
#include <d3dx9.h>
#include "ZCamera.h"
#include "ZFrustum.h"
#include "ZFLog.h"
#include "d3dfile.h"

#define WINDOW_W		500
#define WINDOW_H		500
#define WINDOW_TITLE	"Texture Projection Tutorial"

#define FNAME_MESH		"teapot2.x"
#define	SCALE_MESH		1.0f
#define POS_X_MESH		0.0f
#define POS_Y_MESH		30.0f
#define POS_Z_MESH		0.0f

/**-----------------------------------------------------------------------------
 *  全局参数
 *------------------------------------------------------------------------------
 */
HWND					g_hwnd = NULL;

LPDIRECT3D9             g_pD3D       = NULL; // 创建D3D设备的D3D对象参数
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // 渲染中使用的D3D设备
LPDIRECT3DVERTEXSHADER9	g_pVS = NULL;			/// 顶点着色器
LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL; /// 储存顶点的顶点缓冲
LPDIRECT3DINDEXBUFFER9	g_pIB        = NULL; /// 储存索引的索引缓冲
LPDIRECT3DTEXTURE9      g_pTexFloor  = NULL; /// 底纹理
LPDIRECT3DTEXTURE9      g_pTexProj   = NULL; /// 投影纹理

LPDIRECT3DVERTEXDECLARATION9	g_pDecl = NULL;	/// 顶点声明信息

D3DXMATRIXA16			g_matWorld;
D3DXMATRIXA16			g_matView;
D3DXMATRIXA16			g_matProj;
D3DXMATRIXA16			g_matTexProj;
D3DXMATRIXA16			g_matWorld2Light;
D3DXVECTOR3				g_vLightPos;

float					g_xRot = 0.0f;
float					g_yRot = 0.0f;
DWORD					g_dwMouseX = 0;			// 鼠标的坐标
DWORD					g_dwMouseY = 0;			// 鼠标的坐标
BOOL					g_bWireframe;			// 是否绘制线框?
BOOL					g_bFrustum = TRUE;
BOOL					g_bLight = TRUE;
BOOL					g_bActive = TRUE;

ZCamera*				g_pCamera = NULL;	// Camera 类
ZFrustum*				g_pFrustum = NULL;
CD3DMesh*				g_pMesh = NULL;

/// 定义用户顶点的结构体
struct MYVERTEX
{
	enum { FVF = (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2) };
    float	px, py, pz;		/// 顶点的变换坐标
	float	nx, ny, nz;		/// 顶点的颜色
	float	tx, ty;		/// 纹理坐标
	float	sx, sy;		/// 纹理坐标
};

/**-----------------------------------------------------------------------------
 * Direct3D初始化
 *------------------------------------------------------------------------------
 */
HRESULT InitD3D( HWND hWnd )
{
    // 创建一个用来创建设备的D3D对象
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    // 创建设备的结构体
    // 绘制复杂对象时需要Z-缓冲.
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

	D3DCAPS9 caps;
	DWORD dwVSProcess;
	// 读取设备的能力值(caps)
	g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps );

	// 如果说支持的顶点着色器版本为1.0以下,创建SW着色器,如果是1.0以上,创建HW着色器.
	dwVSProcess = ( caps.VertexShaderVersion < D3DVS_VERSION(1,0) ) ? D3DCREATE_SOFTWARE_VERTEXPROCESSING : D3DCREATE_HARDWARE_VERTEXPROCESSING;

    /// 创建设备
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      dwVSProcess, 
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    // 基本卷起, CCW
	g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

    // 起到Z-缓冲功能.
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    return S_OK;
}

/**-----------------------------------------------------------------------------
 * 创建顶点缓冲,设置顶点值.
 *------------------------------------------------------------------------------
 */
HRESULT InitVB()
{
	MYVERTEX Verts[4] = 
	{
		{ -100, 0, -100, 0, 1, 0, 0, 1, 0, 1 },
		{ -100, 0,  100, 0, 1, 0, 0, 0, 0, 1 },
		{  100, 0, -100, 0, 1, 0, 1, 1, 0, 1 },
		{  100, 0,  100, 0, 1, 0, 1, 0, 0, 1 }
	};

    /// 创建顶点缓冲
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( sizeof(Verts), 0, MYVERTEX::FVF, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
    {
        return E_FAIL;
    }

    /// 顶点缓冲填写数据.
    VOID* pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof(Verts), (void**)&pVertices, 0 ) ) )
        return E_FAIL;
    memcpy( pVertices, Verts, sizeof(Verts) );
    g_pVB->Unlock();


	return S_OK;
}

/**-----------------------------------------------------------------------------
 * 读取着色器.
 *------------------------------------------------------------------------------
 */
HRESULT InitVS()
{
	D3DVERTEXELEMENT9	decl[MAX_FVF_DECL_SIZE];
	// 使用FVF自动填写顶点声明值
	D3DXDeclaratorFromFVF( MYVERTEX::FVF, decl );
	// 通过顶点声明值生成 g_pDecl.
	g_pd3dDevice->CreateVertexDeclaration( decl, &g_pDecl );
	LPD3DXBUFFER pCode;

	// 读取simple.vs 文件,生成顶点着色器界面.
	if( FAILED( D3DXAssembleShaderFromFile( "shadow.vs", NULL, NULL, 0, &pCode, NULL ) ) )
		return E_FAIL;

	g_pd3dDevice->CreateVertexShader( (DWORD*)pCode->GetBufferPointer(), &g_pVS);

	S_REL( pCode );

	return S_OK;
}

void InitTexture()
{
	D3DXCreateTextureFromFile( g_pd3dDevice, "panda.jpg", &g_pTexFloor );
	D3DXCreateTextureFromFile( g_pd3dDevice, "hiah.bmp", &g_pTexProj );
}

/**-----------------------------------------------------------------------------
 * 创建矩阵
 *------------------------------------------------------------------------------
 */
void InitMatrix()
{
	/// 创建世界矩阵
	D3DXMatrixIdentity( &g_matWorld );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld );

    /// 创建视图矩阵
    D3DXVECTOR3 vEyePt( 0.0f, 100.0f, -(float)200.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &g_matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView );

    /// 实际投影矩阵
	D3DXMatrixPerspectiveFovLH( &g_matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj );

	/// 摄像机初始化
	g_pCamera->SetView( &vEyePt, &vLookatPt, &vUpVec );
}

/**-----------------------------------------------------------------------------
 * 几何信息初始化
 *------------------------------------------------------------------------------
 */
HRESULT InitObjects()
{
	S_DEL( g_pCamera );
	S_DEL( g_pLog );

	g_pCamera = new ZCamera;			// 摄像机初始化
	g_pFrustum = new ZFrustum;
	g_pLog = new ZFLog( ZF_LOG_TARGET_WINDOW );	// loging对象初始化
	g_pMesh = new CD3DMesh();
	g_pMesh->Create( g_pd3dDevice, FNAME_MESH );
	g_pMesh->SetFVF( g_pd3dDevice, MYVERTEX::FVF );
	g_pMesh->RestoreDeviceObjects( g_pd3dDevice );

	InitVB();
	InitVS();
	InitTexture();

	return S_OK;
}

void DeleteObjects()
{
	/// 删除注册的类
	S_DEL( g_pCamera );
	S_DEL( g_pFrustum );
	S_DEL( g_pLog );
	g_pMesh->InvalidateDeviceObjects();
	g_pMesh->Destroy();
	S_DEL( g_pMesh );
}

HRESULT InitGeometry()
{
	InitMatrix();

	// 保存最初的鼠标位置
	POINT	pt;
	GetCursorPos( &pt );
	g_dwMouseX = pt.x;
	g_dwMouseY = pt.y;
	g_xRot = 0.0f;
	g_yRot = 0.0f;
	return S_OK;
}


/**-----------------------------------------------------------------------------
 * 删除初始化对象
 *------------------------------------------------------------------------------
 */
VOID Cleanup()
{
	S_REL( g_pVB );
	S_REL( g_pIB );
	S_REL( g_pVS );
	S_REL( g_pDecl );
	S_REL( g_pTexProj );
	S_REL( g_pTexFloor );
	S_REL( g_pd3dDevice );
	S_REL( g_pD3D );
}


/**-----------------------------------------------------------------------------
 * 创建光源
 *------------------------------------------------------------------------------
 */
VOID SetupLights()
{
	g_vLightPos = D3DXVECTOR3( 100, 100, -100 );
	g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );			/// 打开光源设置
	g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00a0a0a0 );		/// 设定环境光源(ambient light)的值
	/// 创建光源
	if( g_bLight )
	{
		D3DXMATRIXA16	m;
		D3DXMatrixRotationY( &m, GetTickCount() / 1000.0f );
		D3DXVec3TransformCoord( &g_vLightPos, &g_vLightPos, &m );
	}
}
/**-----------------------------------------------------------------------------
 * 输出Status信息
 *------------------------------------------------------------------------------
 */
void LogStatus( void )
{
	g_pLog->Log( "FillMode:%s", g_bWireframe ? "wireframe" : "Solid");
	g_pLog->Log( "Animation:%s", g_bLight ? "On" : "Off" );
	g_pLog->Log( "Eye:[%f,%f,%f]", g_pCamera->GetEye()->x, g_pCamera->GetEye()->y, g_pCamera->GetEye()->z ); 
}


/**-----------------------------------------------------------------------------
 * FPS(Frame Per Second)输出
 *------------------------------------------------------------------------------
 */
void LogFPS(void)
{
	static DWORD	nTick = 0;
	static DWORD	nFPS = 0;

	/// 1秒过去?
	if( GetTickCount() - nTick > 1000 )
	{
		nTick = GetTickCount();
		/// FPS值输出
		g_pLog->Log("FPS:%d", nFPS );

		nFPS = 0;
		LogStatus();	/// 输出状态信息(1秒1次)
		return;
	}

⌨️ 快捷键说明

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