//=============================================================================
// Name: SkyBoxClass.h
// Des: 一个封装了三维天空盒系统的类的头文件
// 2013年 3月24日 Create by 浅墨
//=============================================================================
#pragma once
#include "D3DUtil.h"
//为天空盒类定义一个FVF灵活顶点格式
struct SKYBOXVERTEX
{
float x,y,z;
float u,v;
};
#define D3DFVF_SKYBOX D3DFVF_XYZ|D3DFVF_TEX1
class SkyBoxClass
{
private:
LPDIRECT3DDEVICE9 m_pd3dDevice; //D3D设备对象
LPDIRECT3DVERTEXBUFFER9 m_pVertexBuffer; //顶点缓存对象
LPDIRECT3DTEXTURE9 m_pTexture[5]; //5个纹理接口对象
float m_Length; //天空盒边长
public:
SkyBoxClass( LPDIRECT3DDEVICE9 pDevice ); //构造函数
virtual ~SkyBoxClass(void); //析构函数
public:
BOOL InitSkyBox( float Length ); //初始化天空盒函数
//从文件加载天空盒五个方向上的纹理
BOOL LoadSkyTextureFromFile(wchar_t *pFrontTextureFile, wchar_t *pBackTextureFile, wchar_t *pLeftTextureFile,
wchar_t *pRightTextureFile, wchar_t *pTopTextureFile);
//渲染天空盒,根据第一个参数设定天空盒世界矩阵,第二个参数选择是否渲染出线框
VOID RenderSkyBox( D3DXMATRIX *pMatWorld, BOOL bRenderFrame );
};
//=============================================================================
// Name: SkyBoxClass.cpp
// Des: 一个封装了三维天空盒系统的类的源文件
// 2013年 3月24日 Create by 浅墨
//=============================================================================
#include "d3dx9.h"
#include "SkyBoxClass.h"
#include "D3DUtil.h"
//-------------------------------------------------------------------------------------------------
// Desc: 构造函数
//-------------------------------------------------------------------------------------------------
SkyBoxClass::SkyBoxClass( LPDIRECT3DDEVICE9 pDevice )
{
//给各个参数赋初值
m_pVertexBuffer=NULL;
m_pd3dDevice=pDevice;
for(int i=0; i<5; i++)
m_pTexture[i] = NULL;
m_Length = 0.0f;
}
//-------------------------------------------------------------------------------------------------
// Name: SkyBoxClass::InitSkyBox( )
// Desc: 天空盒初始化函数,顶点缓冲区的赋值
//-------------------------------------------------------------------------------------------------
BOOL SkyBoxClass::InitSkyBox( float Length )
{
m_Length=Length;
//1.创建。创建顶点缓存
m_pd3dDevice->CreateVertexBuffer( 20 * sizeof(SKYBOXVERTEX), 0,
D3DFVF_SKYBOX, D3DPOOL_MANAGED, &m_pVertexBuffer, 0 );
//用一个结构体把顶点数据先准备好
SKYBOXVERTEX vertices[] =
{
//前面的四个顶点
{ -m_Length/2, 0.0f, m_Length/2, 0.0f, 1.0f, },
{ -m_Length/2, m_Length/2, m_Length/2, 0.0f, 0.0f, },
{ m_Length/2, 0.0f, m_Length/2, 1.0f, 1.0f, },
{ m_Length/2, m_Length/2, m_Length/2, 1.0f, 0.0f, },
//背面的四个顶点
{ m_Length/2, 0.0f, -m_Length/2, 0.0f, 1.0f, },
{ m_Length/2, m_Length/2, -m_Length/2, 0.0f, 0.0f, },
{ -m_Length/2, 0.0f, -m_Length/2, 1.0f, 1.0f, },
{ -m_Length/2, m_Length/2, -m_Length/2, 1.0f, 0.0f, },
//左面的四个顶点
{ -m_Length/2, 0.0f, -m_Length/2, 0.0f, 1.0f, },
{ -m_Length/2, m_Length/2, -m_Length/2, 0.0f, 0.0f, },
{ -m_Length/2, 0.0f, m_Length/2, 1.0f, 1.0f, },
{ -m_Length/2, m_Length/2, m_Length/2, 1.0f, 0.0f, },
//右面的四个顶点
{ m_Length/2, 0.0f, m_Length/2, 0.0f, 1.0f, },
{ m_Length/2, m_Length/2, m_Length/2, 0.0f, 0.0f, },
{ m_Length/2, 0.0f, -m_Length/2, 1.0f, 1.0f, },
{ m_Length/2, m_Length/2, -m_Length/2, 1.0f, 0.0f, },
//上面的四个顶点
{ m_Length/2, m_Length/2, -m_Length/2, 1.0f, 0.0f, },
{ m_Length/2, m_Length/2, m_Length/2, 1.0f, 1.0f, },
{ -m_Length/2, m_Length/2, -m_Length/2, 0.0f, 0.0f, },
{ -m_Length/2, m_Length/2, m_Length/2, 0.0f, 1.0f, },
};
//准备填充顶点数据
void* pVertices;
//2.加锁
m_pVertexBuffer->Lock( 0, 0, (void**)&pVertices, 0 );
//3.访问。把结构体中的数据直接拷到顶点缓冲区中
memcpy( pVertices, vertices, sizeof(vertices) );
//4.解锁
m_pVertexBuffer->Unlock();
return TRUE;
}
//-------------------------------------------------------------------------------------------------
// Name: SkyBoxClass::LoadSkyTextureFromFile( )
// Desc: 天空盒纹理加载函数
//-------------------------------------------------------------------------------------------------
BOOL SkyBoxClass::LoadSkyTextureFromFile(wchar_t *pFrontTextureFile, wchar_t *pBackTextureFile,wchar_t *pLeftTextureFile, wchar_t *pRightTextureFile,wchar_t *pTopTextureFile)
{
//从文件加载五张纹理
D3DXCreateTextureFromFile( m_pd3dDevice , pFrontTextureFile, &m_pTexture[0] ); //前面
D3DXCreateTextureFromFile( m_pd3dDevice , pBackTextureFile, &m_pTexture[1] ); //后面
D3DXCreateTextureFromFile( m_pd3dDevice , pLeftTextureFile, &m_pTexture[2] ); //左面
D3DXCreateTextureFromFile( m_pd3dDevice , pRightTextureFile, &m_pTexture[3] ); //右面
D3DXCreateTextureFromFile( m_pd3dDevice , pTopTextureFile, &m_pTexture[4] ); //上面
return TRUE;
}
//--------------------------------------------------------------------------------------
// Name: SkyBoxClass::RenderSkyBox()
// Desc: 绘制出天空盒,可以通过第二个参数选择是否绘制出线框
//--------------------------------------------------------------------------------------
void SkyBoxClass::RenderSkyBox( D3DXMATRIX *pMatWorld, BOOL bRenderFrame )
{
//D3DTSS_COLOROP: 纹理颜色的混合方法
//D3DTOP_SELECTARG1: 将颜色混合阶段的第一个参数的颜色值输出
//D3DTSS_COLORARG1: 对纹理颜色混合阶段的第一个参数进行操作
//D3DTA_TEXTURE: 默认值,表示纹理阶段的参数就取纹理的颜色
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);//将纹理颜色混合的第一个参数的颜色值用于输出
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); //纹理颜色混合的第一个参数的值就取纹理颜色值
m_pd3dDevice->SetTransform( D3DTS_WORLD, pMatWorld ); //设置世界矩阵
m_pd3dDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(SKYBOXVERTEX)); //把包含的几何体信息的顶点缓存和渲染流水线相关联
m_pd3dDevice->SetFVF(D3DFVF_SKYBOX); //设置FVF灵活顶点格式
//一个for循环,将5个面绘制出来
for(int i =0; i<5; i++)
{
m_pd3dDevice->SetTexture(0, m_pTexture[i]);
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, i*4, 2);
}
//对是否渲染线框的处理代码
if (bRenderFrame) //如果要渲染出线框的话
{
m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); //把填充模式设为线框填充
//一个for循环,将5个面的线框绘制出来
for(int i =0; i<5; i++)
{
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, i*4, 2); //绘制顶点
}
m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); //把填充模式调回实体填充
}
}
//-------------------------------------------------------------------------------------------------
// Desc: 析构函数
//-------------------------------------------------------------------------------------------------
SkyBoxClass::~SkyBoxClass(void)
{
SAFE_RELEASE( m_pVertexBuffer );
for(int i=0; i<5; i++)
{
SAFE_RELEASE( m_pTexture[i] );
}
}
调用:
Objects_Init()
描述:渲染资源初始化函数,在此函数中进行要被渲染的物体的资源的初始化
//创建并初始化天空对象
g_pSkyBox = new SkyBoxClass( g_pd3dDevice );
g_pSkyBox->LoadSkyTextureFromFile(L"GameMedia\\frontsnow1.jpg",L"GameMedia\\backsnow1.jpg",L"GameMedia\\leftsnow1.jpg",
L"GameMedia\\rightsnow1.jpg", L"GameMedia\\topsnow1.jpg");//从文件加载前、后、左、右、顶面5个面的纹理图
g_pSkyBox->InitSkyBox(20000); //设置天空盒的边长
Direct3D_Render()
描述:使用Direct3D进行渲染
//绘制天空
D3DXMATRIX matSky, matTransSky, matRotSky;
D3DXMatrixTranslation(&matTransSky, 0.0f, -3500.0f, 0.0f);
D3DXMatrixRotationY(&matRotSky, -0.000005f*timeGetTime()); //旋转天空网格, 简单模拟云彩运动效果
matSky = matTransSky * matRotSky;
g_pSkyBox->RenderSkyBox(&matSky, false);