首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络游戏 >

为什么天空盒贴图贴下以后,对camera进行变换后会出出现天空盒贴图闪烁

2013-01-08 
为什么天空盒贴图贴上以后,对camera进行变换后会出出现天空盒贴图闪烁?下面是我天空盒的代码,希望高手帮解

为什么天空盒贴图贴上以后,对camera进行变换后会出出现天空盒贴图闪烁?
下面是我天空盒的代码,希望高手帮解答一下~~
头文件
enum SKYBOX_SIDE
{
TOP = 0,
BOTTOM,
LEFT,
RIGHT,
BACK,
FRONT,
NUMBER
};

//天空盒顶点缓冲结构定义
struct SkyboxVertices{
SkyboxVertices(){}
SkyboxVertices(D3DXVECTOR3 tp, 
float tu, float tv)
{
pos = tp;
u = tu;
v = tv;
}
D3DVECTORpos;
floatu;
floatv;
static const DWORDFVF;
};


class CSkyBox
{
public:
CSkyBox(LPDIRECT3DDEVICE9device);
~CSkyBox();

private:
LPDIRECT3DDEVICE9m_pd3dDevice;
LPDIRECT3DTEXTURE9m_Texture[NUMBER];
LPDIRECT3DVERTEXBUFFER9pBufferRec[6];
SkyboxVerticesm_Verts[6][4]; 
CCamera*m_Camera;

public:
HRESULTInit();

HRESULTSetSkyBoxTexture( SKYBOX_SIDE side , const char* texture );

voidRender();

HRESULTInitVertices();

HRESULTInitTexture();

HRESULTInitVertexBuffer(int flag);

HRESULT Draw(int flag);
};


.cpp文件

const DWORDSkyboxVertices::FVF = (D3DFVF_XYZ|D3DFVF_TEX1);

CSkyBox::CSkyBox(LPDIRECT3DDEVICE9pD3DDevice)
{
m_pd3dDevice = pD3DDevice;
}
CSkyBox::~CSkyBox(){}

HRESULTCSkyBox::Init()
{
m_Camera = new CCamera(AIRCRAFT);
//初始化顶点缓冲
if(FAILED(InitVertices()))
return E_FAIL;
if(FAILED(InitTexture()))
return E_FAIL;
return S_OK;
}
HRESULTCSkyBox::SetSkyBoxTexture(SKYBOX_SIDE side , const char* FileTexture)
{
if(FAILED(D3DXCreateTextureFromFile(m_pd3dDevice, FileTexture,
&m_Texture[side])))
{
return S_FALSE;
}
return S_OK;
}

void CSkyBox::Render()
{
D3DXMATRIX  matWorld;
m_Camera->CheckForMovement();
m_pd3dDevice->SetTexture(0,NULL);
D3DXMatrixTranslation(&matWorld,m_Camera->getPosition().x,m_Camera->getPosition().y,m_Camera->getPosition().z);
m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);

D3DXMATRIX V;
m_Camera->getViewMatrix(&V);
m_pd3dDevice->SetTransform(D3DTS_VIEW, &V);

D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI * 0.5f,1.0f,0.0f,1000.0f);
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);


// 禁用深度缓冲
m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
// 更改采样方式,平滑纹理间过度
m_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
m_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

//绘制天空盒六个面


if(FAILED(Draw(TOP)))
return;
if(FAILED(Draw(BOTTOM)))
return;
if(FAILED(Draw(LEFT)))
return;
if(FAILED(Draw(RIGHT)))
return;
if(FAILED(Draw(BACK)))
return;
if(FAILED(Draw(FRONT)))
return;


// 还原默认采样方式
m_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
m_pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
// 重用深度缓冲
m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

D3DXMatrixIdentity(&matWorld);
m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);

}


HRESULT CSkyBox::InitVertices()
{
// 初始化顶点缓冲
const float t = 1.0f;


const float o = 0.0f;



// top
m_Verts[TOP][0].pos = D3DXVECTOR3(-1,1,1);m_Verts[TOP][0].u =o;m_Verts[TOP][0].v =t;
m_Verts[TOP][1].pos = D3DXVECTOR3(-1,1,-1);m_Verts[TOP][1].u =o;m_Verts[TOP][1].v =o;
m_Verts[TOP][2].pos = D3DXVECTOR3(1,1,1);m_Verts[TOP][2].u =t;m_Verts[TOP][2].v =t;
m_Verts[TOP][3].pos = D3DXVECTOR3(1,1,-1);m_Verts[TOP][3].u =t;m_Verts[TOP][3].v =o;

// bottom
m_Verts[BOTTOM][0].pos = D3DXVECTOR3(-1,-1,-1);m_Verts[BOTTOM][0].u =o;m_Verts[BOTTOM][0].v =t;
m_Verts[BOTTOM][1].pos = D3DXVECTOR3(-1,-1,1);m_Verts[BOTTOM][1].u =o;m_Verts[BOTTOM][1].v =o;
m_Verts[BOTTOM][2].pos = D3DXVECTOR3(1,-1,-1);m_Verts[BOTTOM][2].u =t;m_Verts[BOTTOM][2].v=t;
m_Verts[BOTTOM][3].pos = D3DXVECTOR3(1,-1,1);m_Verts[BOTTOM][3].u = t;m_Verts[BOTTOM][3].v =o;

// left
m_Verts[LEFT][0].pos = D3DXVECTOR3(-1,-1,-1);m_Verts[LEFT][0].u =o;m_Verts[LEFT][0].v =t;
m_Verts[LEFT][1].pos = D3DXVECTOR3(-1,1,-1);m_Verts[LEFT][1].u = o;m_Verts[LEFT][1].v =o;
m_Verts[LEFT][2].pos = D3DXVECTOR3(-1,-1,1);m_Verts[LEFT][2].u = t;m_Verts[LEFT][2].v =t;
m_Verts[LEFT][3].pos = D3DXVECTOR3(-1,1,1);m_Verts[LEFT][3].u = t;m_Verts[LEFT][3].v = o;

// right
m_Verts[RIGHT][0].pos = D3DXVECTOR3(1,-1,1);m_Verts[RIGHT][0].u = o;m_Verts[RIGHT][0].v =t;
m_Verts[RIGHT][1].pos = D3DXVECTOR3(1,1,1);m_Verts[RIGHT][1].u =o;m_Verts[RIGHT][1].v =o;
m_Verts[RIGHT][2].pos = D3DXVECTOR3(1,-1,-1);m_Verts[RIGHT][2].u =t;m_Verts[RIGHT][2].v =t;
m_Verts[RIGHT][3].pos = D3DXVECTOR3(1,1,-1);m_Verts[RIGHT][3].u =t;m_Verts[RIGHT][3].v =o;

// back
m_Verts[BACK][0].pos = D3DXVECTOR3(1,-1,-1);m_Verts[BACK][0].u =o;m_Verts[BACK][0].v =t;
m_Verts[BACK][1].pos = D3DXVECTOR3(1,1,-1);m_Verts[BACK][1].u =o;m_Verts[BACK][1].v =o;
m_Verts[BACK][2].pos = D3DXVECTOR3(-1,-1,-1);m_Verts[BACK][2].u =t;m_Verts[BACK][2].v =t;
m_Verts[BACK][3].pos = D3DXVECTOR3(-1,1,-1);m_Verts[BACK][3].u =t;m_Verts[BACK][3].v =o;

// front
m_Verts[FRONT][0].pos = D3DXVECTOR3(-1,-1,1);m_Verts[FRONT][0].u =o;m_Verts[FRONT][0].v =t;
m_Verts[FRONT][1].pos = D3DXVECTOR3(-1,1,1);m_Verts[FRONT][1].u =o;m_Verts[FRONT][1].v =o;
m_Verts[FRONT][2].pos = D3DXVECTOR3(1,-1,1);m_Verts[FRONT][2].u =t;m_Verts[FRONT][2].v =t;
m_Verts[FRONT][3].pos = D3DXVECTOR3(1,1,1);m_Verts[FRONT][3].u =t;m_Verts[FRONT][3].v =o;

if (FAILED(InitVertexBuffer(TOP)))
return S_FALSE;
if (FAILED(InitVertexBuffer(BOTTOM)))
return S_FALSE;
if (FAILED(InitVertexBuffer(LEFT)))
return S_FALSE;
if (FAILED(InitVertexBuffer(RIGHT)))
return S_FALSE;
if (FAILED(InitVertexBuffer(BACK)))
return S_FALSE;
if (FAILED(InitVertexBuffer(FRONT)))
return S_FALSE;

return S_OK;
}

HRESULT CSkyBox::InitTexture()
{
if(FAILED(SetSkyBoxTexture(TOP,"image\\background.jpg")))
return S_FALSE;
if(FAILED(SetSkyBoxTexture(BOTTOM,"image\\background.jpg")))
return S_FALSE;
if(FAILED(SetSkyBoxTexture(LEFT,"image\\background.jpg")))
return S_FALSE;
if(FAILED(SetSkyBoxTexture(RIGHT,"image\\background.jpg")))
return S_FALSE;
if(FAILED(SetSkyBoxTexture(BACK,"image\\background.jpg")))
return S_FALSE;


if(FAILED(SetSkyBoxTexture(FRONT,"image\\background.jpg")))
return S_FALSE;

return S_OK;
}

HRESULTCSkyBox::InitVertexBuffer(int flag)
{
//创建顶点缓冲区
if(FAILED(m_pd3dDevice->CreateVertexBuffer(
4*sizeof(SkyboxVertices)
,0
,SkyboxVertices::FVF
,D3DPOOL_DEFAULT
,&pBufferRec[flag]
,NULL)))
{
return E_FAIL;
}

SkyboxVertices*pVertices;

if(FAILED(pBufferRec[flag]->Lock(0, 4*sizeof(SkyboxVertices),(void**)&pVertices,
0)))
{
return E_FAIL;
}

pVertices[0] = m_Verts[flag][0];
pVertices[1] = m_Verts[flag][1];
pVertices[2] = m_Verts[flag][2];
pVertices[3] = m_Verts[flag][3];

pBufferRec[flag]->Unlock();

return S_OK;
}


HRESULT CSkyBox::Draw(int flag)
{
m_pd3dDevice->SetStreamSource(0,pBufferRec[flag],0,sizeof(SkyboxVertices));
m_pd3dDevice->SetFVF( SkyboxVertices::FVF );
m_pd3dDevice->SetTexture( 0 , m_Texture[flag] );
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
return S_OK;
}

[解决办法]
代码太长没看下去,但根据你的描述应该是z-fighting问题,即深度冲突,当两个多边形共存在一个平面上时候,他们就会有相同的z-buffer值,因而就会产生“z-fighting”(z冲突)问题,早期的DX版本(DX8.0)中使用
z-bias(z偏移)来解决z-fighting问题(使用D3DRS_ZBIAS渲染状态)。当时使用z-bias是一个有效的办法,但它在不同的显卡上会产生不同的效果(A卡和N卡产生的效果不同),
现在DX9.0c使用D3DRS_SLOPESCALEDEPTHBIAS和D3DRS_DEPTHBIAS渲染状态(depth-bias深度偏移)和替换
D3DRS_ZBIAS渲染状态。

在你希望在后面的物体渲染前使用如下代码能解决z-fighting问题

SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS,1);
SetRenderState(D3DRS_DEPTHBIAS,0 );


热点排行