/*
-------------------------------------
代码清单:Skybox.cpp
来自:
http://www.cnblogs.com/kenkao
-------------------------------------
*/
#include
"
StdAfx.h
"
#include
"
Skybox.h
"
#include
"
D3DGame.h
"
#include
"
D3DCamera.h
"
extern
IDirect3DDevice9
*
g_pD3DDevice;
extern
CD3DCamera
*
g_pD3DCamera;
//
顶点格式的初始化放到.cpp里,避免重定义错误
const
DWORD VertexSkybox::FVF
=
(D3DFVF_XYZ
|
D3DFVF_NORMAL
|
D3DFVF_DIFFUSE
|
D3DFVF_TEX1);
CSkybox::CSkybox(
void
) : m_ppTextureArray(NULL),
m_pVertex(NULL),
m_pIndices(NULL)
{
}
CSkybox::
~
CSkybox(
void
)
{
}
bool
CSkybox::Create(
char
*
szFrontTex,
char
*
szBackTex,
char
*
szLeftTex,
char
*
szRightTex,
char
*
szTopTex,
char
*
szBottomTex)
{
//
初始化顶点及索引缓冲区
InitVertices();
//
初始化天空盒纹理
m_ppTextureArray
=
new
CTexture2D
*
[
6
];
for
(
int
ti
=
0
;ti
<
6
;ti
++
)
{
m_ppTextureArray[ti]
=
new
CTexture2D;
}
//
如果初始化过程中失败,则立即释放已有资源
if
(
!
m_ppTextureArray[
0
]
->
LoadTexture(szFrontTex)
||
!
m_ppTextureArray[
1
]
->
LoadTexture(szBackTex)
||
!
m_ppTextureArray[
2
]
->
LoadTexture(szLeftTex)
||
!
m_ppTextureArray[
3
]
->
LoadTexture(szRightTex)
||
!
m_ppTextureArray[
4
]
->
LoadTexture(szTopTex)
||
!
m_ppTextureArray[
5
]
->
LoadTexture(szBottomTex)
)
{
Release();
return
false
;
}
return
true
;
}
void
CSkybox::InitVertices()
{
//
初始化索引缓冲
m_pIndices
=
new
UINT16[
6
];
m_pIndices[
0
]
=
0
;
m_pIndices[
1
]
=
1
;
m_pIndices[
2
]
=
2
;
m_pIndices[
3
]
=
0
;
m_pIndices[
4
]
=
2
;
m_pIndices[
5
]
=
3
;
//
初始化顶点缓冲
const
float
t
=
1.0f
;
const
float
o
=
0.0f
;
m_pVertex
=
new
VertexSkybox[
24
];
//
前
m_pVertex[
0
]
=
VertexSkybox(
-
1
,
-
1
,
-
1
,
0
,
0
,
1
, D3DXCOLOR_WHITE, t, t);
m_pVertex[
1
]
=
VertexSkybox(
1
,
-
1
,
-
1
,
0
,
0
,
1
, D3DXCOLOR_WHITE, o, t);
m_pVertex[
2
]
=
VertexSkybox(
1
,
1
,
-
1
,
0
,
0
,
1
, D3DXCOLOR_WHITE, o, o);
m_pVertex[
3
]
=
VertexSkybox(
-
1
,
1
,
-
1
,
0
,
0
,
1
, D3DXCOLOR_WHITE, t, o);
//
后
m_pVertex[
4
]
=
VertexSkybox(
1
,
-
1
,
1
,
0
,
0
,
-
1
, D3DXCOLOR_WHITE, t, t);
m_pVertex[
5
]
=
VertexSkybox(
-
1
,
-
1
,
1
,
0
,
0
,
-
1
, D3DXCOLOR_WHITE, o, t);
m_pVertex[
6
]
=
VertexSkybox(
-
1
,
1
,
1
,
0
,
0
,
-
1
, D3DXCOLOR_WHITE, o, o);
m_pVertex[
7
]
=
VertexSkybox(
1
,
1
,
1
,
0
,
0
,
-
1
, D3DXCOLOR_WHITE, t, o);
//
左
m_pVertex[
8
]
=
VertexSkybox(
1
,
-
1
,
-
1
,
-
1
,
0
,
0
, D3DXCOLOR_WHITE, t, t);
m_pVertex[
9
]
=
VertexSkybox(
1
,
-
1
,
1
,
-
1
,
0
,
0
, D3DXCOLOR_WHITE, o, t);
m_pVertex[
10
]
=
VertexSkybox(
1
,
1
,
1
,
-
1
,
0
,
0
, D3DXCOLOR_WHITE, o, o);
m_pVertex[
11
]
=
VertexSkybox(
1
,
1
,
-
1
,
-
1
,
0
,
0
, D3DXCOLOR_WHITE, t, o);
//
右
m_pVertex[
12
]
=
VertexSkybox(
-
1
,
-
1
,
1
,
1
,
0
,
0
, D3DXCOLOR_WHITE, t, t);
m_pVertex[
13
]
=
VertexSkybox(
-
1
,
-
1
,
-
1
,
1
,
0
,
0
, D3DXCOLOR_WHITE, o, t);
m_pVertex[
14
]
=
VertexSkybox(
-
1
,
1
,
-
1
,
1
,
0
,
0
, D3DXCOLOR_WHITE, o, o);
m_pVertex[
15
]
=
VertexSkybox(
-
1
,
1
,
1
,
1
,
0
,
0
, D3DXCOLOR_WHITE, t, o);
//
上
m_pVertex[
16
]
=
VertexSkybox(
1
,
1
,
-
1
,
0
,
-
1
,
0
, D3DXCOLOR_WHITE, t, t);
m_pVertex[
17
]
=
VertexSkybox(
1
,
1
,
1
,
0
,
-
1
,
0
, D3DXCOLOR_WHITE, o, t);
m_pVertex[
18
]
=
VertexSkybox(
-
1
,
1
,
1
,
0
,
-
1
,
0
, D3DXCOLOR_WHITE, o, o);
m_pVertex[
19
]
=
VertexSkybox(
-
1
,
1
,
-
1
,
0
,
-
1
,
0
, D3DXCOLOR_WHITE, t, o);
//
下
m_pVertex[
20
]
=
VertexSkybox(
1
,
-
1
,
1
,
0
,
1
,
0
, D3DXCOLOR_WHITE, o, o);
m_pVertex[
21
]
=
VertexSkybox(
1
,
-
1
,
-
1
,
0
,
1
,
0
, D3DXCOLOR_WHITE, t, o);
m_pVertex[
22
]
=
VertexSkybox(
-
1
,
-
1
,
-
1
,
0
,
1
,
0
, D3DXCOLOR_WHITE, t, t);
m_pVertex[
23
]
=
VertexSkybox(
-
1
,
-
1
,
1
,
0
,
1
,
0
, D3DXCOLOR_WHITE, o, t);
}
void
CSkybox::Release()
{
//
释放天空盒纹理
for
(
int
ti
=
0
;ti
<
6
;ti
++
)
{
ReleaseCOM(m_ppTextureArray[ti]);
}
delete[] m_ppTextureArray;
//
释放索引缓冲
delete[] m_pIndices;
//
释放顶点缓冲
delete[] m_pVertex;
}
void
CSkybox::Draw()
{
//
绘制之前,根据摄影机位置,更新世界矩阵
D3DXVECTOR3 pos
=
g_pD3DCamera
->
GetCameraPos();
D3DXMatrixTranslation(
&
m_WorldTransMatrix,pos.x,pos.y,pos.z);
g_pD3DDevice
->
GetTransform(D3DTS_WORLD,
&
m_OriWorldTransMatrix);
g_pD3DDevice
->
SetTransform(D3DTS_WORLD,
&
m_WorldTransMatrix);
//
禁用深度缓冲
g_pD3DDevice
->
SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
//
更改采样方式,平滑纹理间过度
g_pD3DDevice
->
SetSamplerState(
0
, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
g_pD3DDevice
->
SetSamplerState(
0
, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
//
分6次绘制天空盒6个面
for
(
int
i
=
0
;i
<
6
;i
++
)
{
//
应用纹理
g_pD3DDevice
->
SetTexture(
0
, m_ppTextureArray[i]
->
GetTexture());
//
应用顶点格式
g_pD3DDevice
->
SetFVF(VertexSkybox::FVF);
//
绘制一个面的4个顶点
g_pD3DDevice
->
DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,
0
,
4
,
2
,
&
m_pIndices[
0
],
D3DFMT_INDEX16,
&
m_pVertex[i
*
4
],
sizeof
(VertexSkybox));
}
//
还原默认采样方式
g_pD3DDevice
->
SetSamplerState(
0
, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
g_pD3DDevice
->
SetSamplerState(
0
, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
//
重用深度缓冲
g_pD3DDevice
->
SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
//
还原世界矩阵
g_pD3DDevice
->
SetTransform(D3DTS_WORLD,
&
m_OriWorldTransMatrix);
}