📄 main.cpp
字号:
/**-----------------------------------------------------------------------------
* \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 + -