📄 sky.cpp
字号:
#include "HEADERS.H"
#include "SKY.H"
USING NAMESPACE CGE::SKY;
SKYDOME::SKYDOME()
{
m_vSkyVert = 0;
m_pSkyVB = 0;
m_pSkyTexture = 0;
}
SKYDOME::~SKYDOME()
{
SAFE_DELETE_ARRAY(m_vSkyVert);
SAFE_RELEASE(m_pSkyVB);
SAFE_RELEASE(m_pSkyTexture);
}
VOID SKYDOME::GenerateDome(LPDIRECT3DDEVICE8 device,FLOAT radius, FLOAT dtheta, FLOAT dphi,
FLOAT hTile, FLOAT vTile)
{
LONG theta, phi;
if ( device == NULL ) return;
m_pD3DDevice = device;
// Make sure our vertex array is clear
if (m_vSkyVert)
{
SAFE_DELETE_ARRAY(m_vSkyVert);
m_vSkyVert = NULL;
m_NumberOfVert = 0;
}
// Initialize our Vertex array
m_NumberOfVert = (LONG)((360/dtheta)*(90/dphi)*4);
m_vSkyVert = new SKYVERTEX[m_NumberOfVert];
ZeroMemory(m_vSkyVert, sizeof(SKYVERTEX)*m_NumberOfVert);
// Used to calculate the UV coordinates
FLOAT vx, vy, vz, mag;
// Generate the dome
LONG n = 0;
for (phi=0; phi <= 90 - dphi; phi += (INT)dphi)
{
for (theta=0; theta <= 360 - dtheta; theta += (int)dtheta)
{
// Calculate the vertex at phi, theta
m_vSkyVert[n].x = radius * sinf(D3DXToRadian(phi)) * cosf(D3DXToRadian(theta));
m_vSkyVert[n].y = radius * sinf(D3DXToRadian(phi)) * sinf(D3DXToRadian(theta));
m_vSkyVert[n].z = radius * cosf(D3DXToRadian(phi));
// Create a vector from the origin to this vertex
vx = m_vSkyVert[n].x;
vy = m_vSkyVert[n].y;
vz = m_vSkyVert[n].z;
// Normalize the vector
mag = (FLOAT)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
// Calculate the spherical texture coordinates
m_vSkyVert[n].tu = hTile * (FLOAT)(atan2(vx, vz)/(D3DX_PI*2)) + 0.5f;
m_vSkyVert[n].tv = vTile * (FLOAT)(asinf(vy) / D3DX_PI) + 0.5f;
n++;
// Calculate the vertex at phi+dphi, theta
m_vSkyVert[n].x = radius * sinf(D3DXToRadian(phi+dphi)) * cosf(D3DXToRadian(theta));
m_vSkyVert[n].y = radius * sinf(D3DXToRadian(phi+dphi)) * sinf(D3DXToRadian(theta));
m_vSkyVert[n].z = radius * cosf(D3DXToRadian(phi+dphi));
// Calculate the texture coordinates
vx = m_vSkyVert[n].x;
vy = m_vSkyVert[n].y;
vz = m_vSkyVert[n].z;
mag = (FLOAT)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
m_vSkyVert[n].tu = hTile * (FLOAT)(atan2(vx, vz)/(D3DX_PI*2)) + 0.5f;
m_vSkyVert[n].tv = vTile * (FLOAT)(asinf(vy) / D3DX_PI) + 0.5f;
n++;
// Calculate the vertex at phi, theta+dtheta
m_vSkyVert[n].x = radius * sinf(D3DXToRadian(phi)) * cosf(D3DXToRadian(theta+dtheta));
m_vSkyVert[n].y = radius * sinf(D3DXToRadian(phi)) * sinf(D3DXToRadian(theta+dtheta));
m_vSkyVert[n].z = radius * cosf(D3DXToRadian(phi));
// Calculate the texture coordinates
vx = m_vSkyVert[n].x;
vy = m_vSkyVert[n].y;
vz = m_vSkyVert[n].z;
mag = (FLOAT)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
m_vSkyVert[n].tu = hTile * (FLOAT)(atan2(vx, vz)/(D3DX_PI*2)) + 0.5f;
m_vSkyVert[n].tv = vTile * (FLOAT)(asinf(vy) / D3DX_PI) + 0.5f;
n++;
if (phi > -90 && phi < 90)
{
// Calculate the vertex at phi+dphi, theta+dtheta
m_vSkyVert[n].x = radius * sinf(D3DXToRadian(phi+dphi)) * cosf(D3DXToRadian(theta+dtheta));
m_vSkyVert[n].y = radius * sinf(D3DXToRadian(phi+dphi)) * sinf(D3DXToRadian(theta+dtheta));
m_vSkyVert[n].z = radius * cosf(D3DXToRadian(phi+dphi));
// Calculate the texture coordinates
vx = m_vSkyVert[n].x;
vy = m_vSkyVert[n].y;
vz = m_vSkyVert[n].z;
mag = (FLOAT)sqrt(SQR(vx)+SQR(vy)+SQR(vz));
vx /= mag;
vy /= mag;
vz /= mag;
m_vSkyVert[n].tu = hTile * (FLOAT)(atan2(vx, vz)/(D3DX_PI*2)) + 0.5f;
m_vSkyVert[n].tv = vTile * (FLOAT)(asinf(vy) / D3DX_PI) + 0.5f;
n++;
}
}
}
// Fix the problem at the seam
for (int i=0; i < m_NumberOfVert-2; i++)
{
if (m_vSkyVert[i].tu - m_vSkyVert[i+1].tu > 0.9f)
m_vSkyVert[i+1].tu += 1.0f;
if (m_vSkyVert[i+1].tu - m_vSkyVert[i].tu > 0.9f)
m_vSkyVert[i].tu += 1.0f;
if (m_vSkyVert[i].tu - m_vSkyVert[i+2].tu > 0.9f)
m_vSkyVert[i+2].tu += 1.0f;
if (m_vSkyVert[i+2].tu - m_vSkyVert[i].tu > 0.9f)
m_vSkyVert[i].tu += 1.0f;
if (m_vSkyVert[i+1].tu - m_vSkyVert[i+2].tu > 0.9f)
m_vSkyVert[i+2].tu += 1.0f;
if (m_vSkyVert[i+2].tu - m_vSkyVert[i+1].tu > 0.9f)
m_vSkyVert[i+1].tu += 1.0f;
if (m_vSkyVert[i].tv - m_vSkyVert[i+1].tv > 0.8f)
m_vSkyVert[i+1].tv += 1.0f;
if (m_vSkyVert[i+1].tv - m_vSkyVert[i].tv > 0.8f)
m_vSkyVert[i].tv += 1.0f;
if (m_vSkyVert[i].tv - m_vSkyVert[i+2].tv > 0.8f)
m_vSkyVert[i+2].tv += 1.0f;
if (m_vSkyVert[i+2].tv - m_vSkyVert[i].tv > 0.8f)
m_vSkyVert[i].tv += 1.0f;
if (m_vSkyVert[i+1].tv - m_vSkyVert[i+2].tv > 0.8f)
m_vSkyVert[i+2].tv += 1.0f;
if (m_vSkyVert[i+2].tv - m_vSkyVert[i+1].tv > 0.8f)
m_vSkyVert[i+1].tv += 1.0f;
}
SkyDomeVB();
}
VOID SKYDOME::SkyDomeInScene(const D3DXVECTOR3 & vTransPos,FLOAT fElapse)
{
D3DXMATRIX mat,matTrans,matRotY,matRotX,matWorld;
m_pD3DDevice->GetTransform(D3DTS_WORLD,&mat);
D3DXMatrixRotationY(&matRotY,fElapse);
D3DXMatrixRotationX(&matRotX,D3DXToRadian(270));
D3DXMatrixTranslation(&matTrans,vTransPos.x,vTransPos.y,vTransPos.z);
D3DXMatrixMultiply(&matWorld,&matRotX,&matRotY);
D3DXMatrixMultiply(&matWorld,&matWorld,&matTrans);
m_pD3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
m_pD3DDevice->SetTexture(0,m_pSkyTexture);
m_pD3DDevice->SetStreamSource(0,m_pSkyVB,sizeof(SKY::SKYVERTEX));
m_pD3DDevice->SetVertexShader(SKY::SKYVERTEX::SKYFVF_VERTEX);
m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,m_NumberOfVert-2);
m_pD3DDevice->SetTexture(0,0);
m_pD3DDevice->SetTransform(D3DTS_WORLD,&mat);
}
BOOL SKYDOME::SkyDomeVB()
{
if ( m_vSkyVert == NULL )
return FALSE;
if ( FAILED(m_pD3DDevice->CreateVertexBuffer( m_NumberOfVert * sizeof(SKY::SKYVERTEX),0,0,
D3DPOOL_MANAGED,&m_pSkyVB)))
return FALSE;
BYTE * pointer;
m_pSkyVB->Lock(0,0,(BYTE**)&pointer,0);
memcpy(pointer,m_vSkyVert,m_NumberOfVert*sizeof(SKY::SKYVERTEX));
m_pSkyVB->Unlock();
return TRUE;
}
VOID SKYDOME::SetSkyTexture(LPDIRECT3DTEXTURE8 Sky)
{
m_pSkyTexture = Sky;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -