第11讲 天空文档格式.docx

上传人:b****6 文档编号:18236744 上传时间:2022-12-14 格式:DOCX 页数:18 大小:944.95KB
下载 相关 举报
第11讲 天空文档格式.docx_第1页
第1页 / 共18页
第11讲 天空文档格式.docx_第2页
第2页 / 共18页
第11讲 天空文档格式.docx_第3页
第3页 / 共18页
第11讲 天空文档格式.docx_第4页
第4页 / 共18页
第11讲 天空文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

第11讲 天空文档格式.docx

《第11讲 天空文档格式.docx》由会员分享,可在线阅读,更多相关《第11讲 天空文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

第11讲 天空文档格式.docx

#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(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1