学习《Real Time Rendering》后自己实现的代码:
考完试后我就开始继续钻研我的游戏开发。前几天我完成了游戏开发的最基础的工作,也就是说
在此基础上进行游戏开发效率更高,速度更快。而且我在看《Real Time Rendering》这本书受到了很多启发。使用类MFC的开发模式可以很好的提高开发的效率。好了,接下来介绍的是我最近在钻研的矩阵变换的问题。
在游戏中一般有三个矩阵:视角矩阵、世界矩阵和投影矩阵。简单地说,视角矩阵就是观察者眼睛所在的矩阵,世界矩阵则是目标物体所在世界的矩阵,投影矩阵则好比为观察者的眼睛的晶状体。通过三个矩阵的相互作用可以模拟出所有三维的场景。在这里我就不再过多地赘述有关矩阵的内容了。因为书没有直接的代码,所以我靠自己的一点知识就实现了书上的例子程序。程序的截图如下:
要下载程序的代码,请点击下方:
演示程序下载:http://download.csdn.net/detail/jiangcaiyang123/4007231
程序截图:
这是书上的截图:
考完试后我就开始继续钻研我的游戏开发。前几天我完成了游戏开发的最基础的工作,也就是说
在此基础上进行游戏开发效率更高,速度更快。而且我在看《Real Time Rendering》这本书受到了很多启发。使用类MFC的开发模式可以很好的提高开发的效率。好了,接下来介绍的是我最近在钻研的矩阵变换的问题。
在游戏中一般有三个矩阵:视角矩阵、世界矩阵和投影矩阵。简单地说,视角矩阵就是观察者眼睛所在的矩阵,世界矩阵则是目标物体所在世界的矩阵,投影矩阵则好比为观察者的眼睛的晶状体。通过三个矩阵的相互作用可以模拟出所有三维的场景。在这里我就不再过多地赘述有关矩阵的内容了。因为书没有直接的代码,所以我靠自己的一点知识就实现了书上的例子程序。程序的截图如下:
我在代码中添加了必要的注释,所以代码基本上还是好懂的。
// GameStart.h 游戏开始的场景
// 2012年1月5日11:41:29 最后编辑
#ifndef _GAMESTART_H_
#define _GAMESTART_H_
#include <vector>
#include <d3dx9.h>
#include "../DX框架/Scenario.h"
#include "../DX框架/GameShape.h"
#include "../DX框架/JCYInput.h"
#pragma comment( lib, "d3dx9.lib" )
class CGameStart: public IScenario
{
public:
CGameStart( TCHAR* pName, HINSTANCE hInst, HWND hWnd, LPDIRECT3DDEVICE9 pDevice ); // 构造函数
~CGameStart( void ); // 析构函数
void Draw( void ); // 绘图
unsigned long Release( void ); // 释放空间
TCHAR* GetName( void ) // 获取场景名
{
return m_Name;
}
void InitializeViewport( void ); // 初始化视角
private:
TCHAR* m_Name; // 场景名
HWND m_hWnd; // 窗口句柄
LPDIRECT3DDEVICE9 m_pDevice; // D3D设备
LPDIRECT3DVERTEXBUFFER9 m_pBuffer; // 顶点缓存
CInput m_BufferInput, m_ImmediateInput; // 输入系统
D3DXMATRIX m_WorldMatrix; // 世界矩阵
D3DXMATRIX m_ViewMatrix; // 视角矩阵
D3DXMATRIX m_ProjectMatrix; // 投影矩阵
D3DVIEWPORT9 m_RViewport; // 旋转视角
D3DVIEWPORT9 m_SRTViewport; // 比例旋转视角
D3DVIEWPORT9 m_TRViewport; // 转置视角
D3DVIEWPORT9 m_RTRSViewport; // 旋转转置旋转视角
struct STVertex // 定义自己的顶点结构体
{
float x, y, z;
unsigned long color;// 在DirectX中D3DCOLOR被解释成unsigned long
};
static const unsigned short POINT_FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; // 灵活顶点格式
};
#endif
// GameStart.cpp 游戏开始的场景的实现文件
// NUM_VERTICES12年1月5日12:22:17 最后编辑
#include <d3d9.h>
#include "GameStart.h"
#define NUM_VERTICES 50
CGameStart::CGameStart( TCHAR *pName, HINSTANCE hInst, HWND hWnd, LPDIRECT3DDEVICE9 pDevice )// 构造函数
{
m_hWnd = hWnd;
m_pDevice = pDevice;
m_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
D3DXMatrixIdentity( &m_ViewMatrix );
m_pDevice->SetTransform( D3DTS_VIEW, &m_ViewMatrix );
InitializeViewport( );
// 初始化顶点缓存
m_pDevice->CreateVertexBuffer( NUM_VERTICES * sizeof( STVertex ), D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS, POINT_FVF,
D3DPOOL_DEFAULT, &m_pBuffer, NULL );
STVertex* pVertices;
m_pBuffer->Lock( 0, NUM_VERTICES * sizeof( STVertex ), (void**)&pVertices, D3DLOCK_DISCARD );
for ( long i = 0; i < NUM_VERTICES; i++ )
{
float angle = (float)i / (float)NUM_VERTICES * 2.0f * D3DX_PI;
pVertices[i].x = 0.3f * cos( angle );
pVertices[i].y = 0.3f * sin( angle );
pVertices[i].z = 1.0f;
pVertices[i].color = D3DCOLOR_XRGB( 255, 255, 255 );
}
m_pBuffer->Unlock( );
m_pDevice->SetStreamSource( 0, m_pBuffer, 0, sizeof( STVertex ) ); // 相同资源的顶点缓存要在一起为好
m_pDevice->SetFVF( POINT_FVF );
/*----------初始化输入------------*/
m_ImmediateInput.Initialize( IMMEDIATE, hInst, m_hWnd );
m_BufferInput.Initialize( BUFFERED, hInst, m_hWnd );
m_Name = pName;
}
CGameStart::~CGameStart( void ) // 析构函数
{
Release( );
}
unsigned long CGameStart::Release( void ) // 释放空间
{
m_pBuffer->Release( );
m_ImmediateInput.Release( );
m_BufferInput.Release( );
return 0;
}
void CGameStart::Draw( void ) // 绘图
{
RECT windowRect;
GetClientRect( m_hWnd, &windowRect );
D3DXMatrixPerspectiveFovLH( &m_ProjectMatrix, D3DX_PI / 4, float( windowRect.right - windowRect.left ) / float( windowRect.bottom - windowRect.top ), 1.0f, 100.0f );
m_pDevice->SetTransform( D3DTS_PROJECTION, &m_ProjectMatrix );
D3DXMATRIX rotationMatrix1;
D3DXMATRIX rotationMatrix2;
D3DXMATRIX translationMatrix;
D3DXMATRIX scalingMatrix;
D3DVIEWPORT9 mainViewport; // 保存原来视角的副本
m_pDevice->GetViewport( &mainViewport );
D3DXMatrixRotationZ( &rotationMatrix1, (float)GetTickCount( ) / 1000.0f );
D3DXMatrixRotationZ( &rotationMatrix2, -(float)GetTickCount( ) / 1000.0f );
D3DXMatrixTranslation( &translationMatrix, 0.0f, 0.0f, 0.0f ); // 更改第一个浮点数会出现不同的效果!试试看。
D3DXMatrixScaling( &scalingMatrix, 1.0f, 0.5f, 1.0f );
m_pDevice->SetViewport( &m_RViewport );// 左上角图形
m_WorldMatrix = rotationMatrix1;
m_pDevice->SetTransform( D3DTS_WORLD, &m_WorldMatrix );
m_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, NUM_VERTICES );
m_pDevice->SetViewport( &m_SRTViewport );// 右上角图形
m_WorldMatrix = translationMatrix * rotationMatrix1 * scalingMatrix;
m_pDevice->SetTransform( D3DTS_WORLD, &m_WorldMatrix );
m_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, NUM_VERTICES );
m_pDevice->SetViewport( &m_TRViewport );// 左下角图形
m_WorldMatrix = rotationMatrix1 * translationMatrix;
m_pDevice->SetTransform( D3DTS_WORLD, &m_WorldMatrix );
m_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, NUM_VERTICES );
m_pDevice->SetViewport( &m_RTRSViewport );// 右下角图形
m_WorldMatrix = scalingMatrix * rotationMatrix2 * translationMatrix * rotationMatrix1;
m_pDevice->SetTransform( D3DTS_WORLD, &m_WorldMatrix );
m_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, NUM_VERTICES );
m_pDevice->SetViewport( &mainViewport );// 还原原来的视角
}
void CGameStart::InitializeViewport( void ) // 初始化视角
{
D3DVIEWPORT9 mainViewport;
m_pDevice->GetViewport( &mainViewport );
// 为一些视角赋值
m_RViewport.Width = m_SRTViewport.Width = m_TRViewport.Width = m_RTRSViewport.Width = mainViewport.Width / 2;
m_RViewport.Height = m_SRTViewport.Height = m_TRViewport.Height = m_RTRSViewport.Height = mainViewport.Height / 2;
m_RViewport.Y = m_SRTViewport.Y = 0;
m_RViewport.X = m_TRViewport.X = 0;
m_TRViewport.Y = m_RTRSViewport.Y = mainViewport.Height / 2;
m_SRTViewport.X = m_RTRSViewport.X = mainViewport.Width / 2;
m_RViewport.MinZ = m_SRTViewport.MinZ = m_TRViewport.MinZ = m_RTRSViewport.MinZ = 0.0f;
m_RViewport.MaxZ = m_SRTViewport.MaxZ = m_TRViewport.MaxZ = m_RTRSViewport.MaxZ = 1.0f;
}
要下载程序的代码,请点击下方: