第11讲 天空文档格式.docx
- 文档编号:18236744
- 上传时间:2022-12-14
- 格式:DOCX
- 页数:18
- 大小:944.95KB
第11讲 天空文档格式.docx
《第11讲 天空文档格式.docx》由会员分享,可在线阅读,更多相关《第11讲 天空文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
#defineD3DFVF_CUSTOMVETEX2(D3DFVF_XYZ|D3DFVF_TEX1)
classCCubeSky
private:
LPDIRECT3DDEVICE9m_pd3dDevice;
LPDIRECT3DVERTEXBUFFER9m_pVB;
LPDIRECT3DINDEXBUFFER9m_pIB;
LPDIRECT3DTEXTURE9m_pTexScene[6];
floatlen;
public:
CCubeSky(LPDIRECT3DDEVICE9pd3dDevice);
~CCubeSky(void);
HRESULTVBInit();
voidRender();
boolSetTexture(constWCHAR*FileTexture,intflag);
CCubeSky.cpp
#include"
CubeSky.h"
CCubeSky:
:
CCubeSky(LPDIRECT3DDEVICE9pd3dDevice)
m_pd3dDevice=pd3dDevice;
this->
m_pIB=NULL;
m_pVB=NULL;
len=100.0f;
}
~CCubeSky(void)
{}
HRESULTCCubeSky:
VBInit()
//创建天空盒需要的8个顶点
CUSTOMVERTEX2gCubeVerts[]=
{
//z方向点和纹理坐标
{-len,0.0f,-len,1.0f,1.0f},//0
{-len,len,-len,1.0f,0.0f},//1
{len,0.0f,-len,0.0f,1.0f},//2
{len,len,-len,0.0f,0.0f},//3
{len,0.0f,len,1.0f,1.0f},//4
{len,len,len,1.0f,0.0f},//5
{-len,0.0f,len,0.0f,1.0f},//6
{-len,len,len,0.0f,0.0f},//7
//x方向点和纹理坐标
{len,0.0f,-len,1.0f,1.0f},//2-8
{len,len,-len,1.0f,0.0f},//3-9
{len,0.0f,len,0.0f,1.0f},//4-10
{len,len,len,0.0f,0.0f},//5-11
{-len,0.0f,-len,0.0f,1.0f},//0-12
{-len,len,-len,0.0f,0.0f},//1-13
{-len,0.0f,len,1.0f,1.0f},//6-14
{-len,len,len,1.0f,0.0f},//7-15
//y方向点和纹理坐标
{-len,0.0f,-len,1.0f,0.0f},//0-16
{len,0.0f,-len,0.0f,0.0f},//2-17
{-len,0.0f,len,1.0f,1.0f},//6-18
{len,0.0f,len,0.0f,1.0f},//4-19
{-len,len,-len,1.0f,1.0f},//1-20
{len,len,-len,0.0f,1.0f},//3-21
{len,len,len,0.0f,0.0f},//5-22
{-len,len,len,1.0f,0.0f},//7-23
};
//创建天空盒需要的顶点的索引
WORDgCubeIndices[]=
{2,3,1,//z方向
2,1,0,//
6,7,5,//
6,5,4,//
10,11,9,//x方向
10,9,8,//
12,13,15,//
12,15,14,//
16,18,19,//y方向
16,19,17,//
20,21,22,//
20,22,23
//创建顶点缓冲区
if(FAILED(m_pd3dDevice->
CreateVertexBuffer(sizeof(gCubeVerts),
0,
D3DFVF_CUSTOMVETEX2,
D3DPOOL_DEFAULT,
&
m_pVB,
NULL
)))
returnE_FAIL;
}
VOID*pVertices;
//锁定顶点缓冲区
if(FAILED(m_pVB->
Lock(0,sizeof(gCubeVerts),
(void**)&
pVertices,0)))
//把顶点数组的数据拷贝到顶点缓冲区中
memcpy(pVertices,gCubeVerts,sizeof(gCubeVerts));
m_pVB->
Unlock();
//解锁顶点缓冲区
//创建索引缓冲区
CreateIndexBuffer(sizeof(gCubeIndices),
D3DFMT_INDEX16,
m_pIB,
VOID*pIndices;
//锁定索引缓冲区
if(FAILED(m_pIB->
Lock(0,sizeof(gCubeIndices),
pIndices,0)))
//把索引数组的值拷贝索引缓冲区中
memcpy(pIndices,gCubeIndices,sizeof(gCubeIndices));
m_pIB->
//解锁索引缓冲区
returnS_OK;
boolCCubeSky:
SetTexture(constWCHAR*FileTexture,intflag)
if(FAILED(D3DXCreateTextureFromFile(m_pd3dDevice,FileTexture,
m_pTexScene[flag])))
returnfalse;
returntrue;
voidCCubeSky:
Render()
D3DXMATRIXmatrix,smatrix,tmatrix,rmatrix;
//m_Camera.ProcInput();
//设置数据源
m_pd3dDevice->
SetStreamSource(0,m_pVB,0,sizeof(CUSTOMVERTEX2));
SetFVF(D3DFVF_CUSTOMVETEX2);
SetIndices(m_pIB);
SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
//背面消隐
SetRenderState(D3DRS_LIGHTING,false);
//光照关闭
SetRenderState(D3DRS_ZENABLE,false);
//关闭Zbuffer
//SetProjection();
//投影
//画天空盒设置纹理
SetTexture(0,m_pTexScene[0]);
DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);
SetTexture(0,m_pTexScene[1]);
DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,4,4,6,2);
SetTexture(0,m_pTexScene[2]);
DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,8,4,12,2);
SetTexture(0,m_pTexScene[3]);
DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,12,4,18,2);
SetTexture(0,m_pTexScene[4]);
DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,16,4,24,2);
SetTexture(0,m_pTexScene[5]);
DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,20,4,30,2);
球形天空构造
球面天空是通过在半球面上进行纹理贴图实现的,因此,需要分割一个半球面获得各个顶点,然后定义顶点的灵活顶点格式,设置和计算每个顶点的xyz坐标和纹理uv坐标,最后将顶点数据送入渲染管道流水线进行处理,如图所示
假设半球面上的任意点p=(px,py,pz)半球体的半径为r,α和β为相应的经度角和纬度角,如图下所示。
从图中可以看出,经度角α的取值范围在区间[0,2π]内,而纬度角β的取值范围在区间[0,π/2]内。
所以顶点p的坐标计算公式如下:
接下来考虑纹理坐标的计算。
若将2π除以经度角就可以得到维度线的条数,而若将π/2除以维度角就可以得到经度线的条数。
因此,根据p点的经度角α和维度角β就可以计算出p点的纹理坐标。
可以按照下面代码计算出p点的坐标和纹理坐标。
m_fSkyboxRadius=fRadius;
//半球体的半径
m_nNumLatitudes=360/nAlpha;
//维度线的条数
m_nNumLongitudes=90/nBeta;
//经度线的条数
m_nVertsPerLongi=m_nNumLatitudes+1;
//每条经度线上的顶点数
m_nVertsPerLati=m_nNumLongitudes+1;
//每条维度线上的顶点数
m_nNumVertices=m_nVertsPerLati*m_nVertsPerLongi;
//灵活顶点格式
structSkyBoxVERTEX
FLOAT_x,_y,_z;
FLOAT_u,_v;
SkyBoxVERTEX(FLOATx,FLOATy,FLOATz,FLOATu,FLOATv)
:
_x(x),_y(y),_z(z),_u(u),_v(v){}
staticconstDWORDFVF=D3DFVF_XYZ|D3DFVF_TEX1;
//计算地形的灵活顶点
if(FAILED(m_pd3dDevice->
CreateVertexBuffer(m_nNumVertices*sizeof(SKYBOXVERTEX),
D3DUSAGE_WRITEONLY,SKYBOXVERTEX:
FVF,D3DPOOL_MANAGED,&
m_pVertexBuf,0)))
returnFALSE;
SKYBOXVERTEX*pVertices=NULL;
m_pVertexBuf->
Lock(0,0,(void**)&
pVertices,0);
intnIndex=0;
FLOATfAlpha=2.0f*D3DX_PI*nAlpha/360.0f;
//经度角转换为弧度表示
FLOATfBeta=2.0f*D3DX_PI*nBeta/360.0f;
//维度角转换为弧度表示
for(introw=0;
row<
m_nNumLongitudes+1;
row++)
for(intcol=0;
col<
m_nNumLatitudes+1;
col++)
//计算顶点的坐标
pVertices[nIndex]._x=fRadius*cosf(row*fBeta)*cosf(col*fAlpha);
pVertices[nIndex]._y=fRadius*sinf(row*fBeta);
pVertices[nIndex]._z=fRadius*cosf(row*fBeta)*sinf(col*fAlpha);
//计算顶点的纹理坐标
pVertices[nIndex]._u=col*fAlpha/(2.0f*D3DX_PI);
pVertices[nIndex]._v=row*fBeta/(D3DX_PI/2.0f);
nIndex++;
对于半球面上的任意点A,并以该点为起始顶点的两个相邻三角形的顶点B、C、D点,它们的位置关系将如图所示。
pIndices[nIndex+0]=row*m_nVertsPerLongi+col;
pIndices[nIndex+1]=(row+1)*m_nVertsPerLongi+col;
pIndices[nIndex+2]=(row+1)*m_nVertsPerLongi+col+1;
pIndices[nIndex+3]=row*m_nVertsPerLongi+col;
pIndices[nIndex+4]=(row+1)*m_nVertsPerLongi+col+1;
pIndices[nIndex+5]=row*m_nVertsPerLongi+col+1;
nIndex+=6;
球形天空类定义:
CSkyBox.h
classCSkybox
LPDIRECT3DTEXTURE9m_pTexture;
LPDIRECT3DINDEXBUFFER9m_pIndexBuf;
LPDIRECT3DVERTEXBUFFER9m_pVertexBuf;
INTm_nNumLatitudes;
//维度的数目
INTm_nNumLongitudes;
//经度的数目
INTm_nVertsPerLati;
//每条维度上包含的顶点数
INTm_nVertsPerLongi;
//每条经度上包含的顶点数
INTm_nNumVertices;
//顶点总数
FLOATm_fSkyboxRadius;
//球形天空的半径
structSKYBOXVERTEX//球形天空的顶点结构
SKYBOXVERTEX(FLOATx,FLOATy,FLOATz,FLOATu,FLOATv)
CSkybox(IDirect3DDevice9*pd3dDevice);
virtual~CSkybox(void);
BOOLLoadSkybox(wchar_t*pTextureFile);
//加载纹理
BOOLInitSkybox(INTnAlpha,INTnBeta,FLOATnRadius);
//初始化球形天空
BOOLDrawSkybox(D3DXMATRIX*pMatWorld,BOOLbDrawFrame=FALSE);
//绘制天空
球形天空类的实现SkyBox.cpp
SkyBox.h"
CSkyBox:
CSkyBox(IDirect3DDevice9*pd3dDevice)
m_pTexture=NULL;
m_pIndexBuf=NULL;
m_pVertexBuf=NULL;
m_nNumVertices=0;
m_nNumLatitudes=0;
m_nNumLongitudes=0;
m_nVertsPerLongi=0;
m_nVertsPerLati=0;
m_fSkyBoxRadius=0;
~CSkyBox(void)
if(m_pIndexBuf!
=NULL)
m_pIndexBuf->
Release();
if(m_pTexture!
m_pTexture->
if(m_pVertexBuf!
m_pVertexBuf->
BOOLCSkyBox:
LoadSkyBox(wchar_t*pTextureFile)
//加载天空纹理
if(FAILED(D3DXCreateTextureFromFile(m_pd3dDevice,pTextureFile,&
m_pTexture)))
returnTRUE;
InitSkyBox(INTnAlpha,INTnBeta,FLOATfRadius)
m_fSkyBoxRadius=fRadius;
//半球体的半径
m_nNumLatitudes=360/nAlpha;
//维度线的条数
m_nNumLongitudes=90/nBeta;
//经度线的条数
m_nVertsPerLongi=m_nNumLatitudes+1;
//每条经度线上的顶点数
m_nVertsPerLati=m_nNumLongitudes+1;
m_nNumVertices=m_nVertsPerLati*m_nVertsPerLongi;
//计算天空的灵活顶点
CreateVertexBuffer(m_nNumVertices*sizeof(SkyBoxVERTEX),
D3DUSAGE_WRITEONLY,SkyBoxVERTEX:
FVF,D3DPOOL_MANAGED,&
m_pVertexBuf,0)))
SkyBoxVERTEX*pVertices=NULL;
m_pVertexBuf->
intnIndex=0;
FLOATfAlpha=2.0f*D3DX_PI*nAlpha/360.0f;
FLOATfBeta=2.0f*D3DX_PI*nBeta/360.0f;
for(introw=0;
Unlock(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第11讲 天空 11