- Mesaj
- 4.376
- Çözümler
- 439
- Beğeni
- 4.906
- Puan
- 1.849
- Ticaret Puanı
- 0
UYARI:
Bu düzenleme hemen eklenip kullanılabilecek bir düzenleme değildir. Buradaki işlemleri yaptıktan sonra oyununuzda kaç tane gökyüzü seçeneği varsa, artık hiçbiri mevcut haliyle çalışmayacaktır ve dünya sahnesini bozacaktır. Buradaki işlemlerden sonra tüm gökyüzü dokularınızı Photoshop, GIMP vb. programlarla yeniden düzenlemek zorundasınız.
Ambiyans,material, ışık konumu ve diğer özellikleri bu yeni düzenleme ve doku işleme mantığına uygun şekilde düzenlemeniz gerekir!
Bu düzenleme hemen eklenip kullanılabilecek bir düzenleme değildir. Buradaki işlemleri yaptıktan sonra oyununuzda kaç tane gökyüzü seçeneği varsa, artık hiçbiri mevcut haliyle çalışmayacaktır ve dünya sahnesini bozacaktır. Buradaki işlemlerden sonra tüm gökyüzü dokularınızı Photoshop, GIMP vb. programlarla yeniden düzenlemek zorundasınız.
Ambiyans,material, ışık konumu ve diğer özellikleri bu yeni düzenleme ve doku işleme mantığına uygun şekilde düzenlemeniz gerekir!
Uzun zaman önce bir merakla ya da hevesle yapmaya başlayıp sonra kenarda beklettiğim sistemi az önce itibariyle bitirdim. Metin2'nin gökyüzü yapısında küp şeklinde çalışıyor ve bu küpün(6) her bir yüzü için ayrı ayrı dokular kullanılıyor ve giydiriliyor. Ben bu mantığı değiştirip tek bir yatay cross dokusuyla bu küpü giydirmenin daha kullanışlı olacağını düşünüyorum. Böylelikle yeni ve farklı bir gökyüzü kullanmak için sırf Metin2'ye uyumlu olması için tüm forumları araştırmak yerine, Google'dan bile bulduğunuz bir gökyüzünü artık oyuna ekleyebilirsiniz.
Hazırlaması zahmetliydi, kullanması da kullanıcılar için zahmetli olacak. Ancak temel yapıyı oluşturup oturttuktan sonra, ilerleyen süreçlerde bu düzenleme size esneklik ve rahatlık verecektir. Buradaki tek şart, kullanacağınız dokunun "cross" yapısında ve yatay olmasıdır. Kullanımı dinamikleştirmek için böyle bir şey düşünmüştüm ve sonunda hazır hale geldi. Geliştirmeye ve düzenlemeye açık ve müsait bir yapıdadır.
Başlamadan önce:
Cross gökyüzü nedir?
Cubemap türünde olan bir doku haritasıdır ve her projede farklı ölçülerde kullanılabiliyor. (1:1, 3:2, 4:3 vb.)
Metin2'nin kullandığı ölçü ise genellikle 4x3'dür.
Bu anlatımda kullanılan örnek(4 sütun, 3 satır):
Daha açık anlatmak gerekirse; sadece bu tür bir görseli pack içine atarak gökyüzü olarak kullanabilirsiniz. Ancak konuyla ilgili küçük ve önemli bir detay var. Onu aşağıda belirteceğim.
Anlatımı dikkatli olunması için basit ve geniş yapacağım. Lütfen işlemlere dikkat edin.
Locale_inc.h:
C++:
#define REWORK_SKYBOX
EterLib/SkyBox.h:
C++:
// Bul:
void SetFaceTexture( const char* c_szFileName, int iFaceIndex);
// Değiştir:
#ifdef REWORK_SKYBOX
void SetFaceTexture( const char* c_szFileName);
void GetCrossUVCoordinates(int faceIndex, float& uMin, float& uMax, float& vMin, float& vMax);
#else
void SetFaceTexture( const char* c_szFileName, int iFaceIndex );
#endif
////////////////////////////////////////
// Bul:
void SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints);
void SetSkyObjectQuadHorizon(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR3 * c_pv3QuadPoints);
// Değiştir:
#ifdef REWORK_SKYBOX
void SetSkyObjectQuadVertical(TSkyObjectQuadVector* pSkyObjectQuadVector, const D3DXVECTOR2* c_pv2QuadPoints, int faceIndex);
void SetSkyObjectQuadHorizon(TSkyObjectQuadVector* pSkyObjectQuadVector, const D3DXVECTOR3* c_pv3QuadPoints, int faceIndex);
#else
void SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints);
void SetSkyObjectQuadHorizon(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR3 * c_pv3QuadPoints);
#endif
EterLib/SkyBox.cpp:
Bunu bulun:
C++:
void CSkyBox::SetFaceTexture(const char* c_szFileName)
{
[...]
}
Tamamen değiştirin(#else kısmına dikkat edin!):
C++:
#ifdef REWORK_SKYBOX
void CSkyBox::GetCrossUVCoordinates(int faceIndex, float& uMin, float& uMax, float& vMin, float& vMax)
{
/*
* WARNING:
Kaiser:
UV koordinatları ve dokularin dikilmesi "maksimum" hassasiyet gerektirir.
Burayı düzenlemek veya degistirmek isterseniz bunu göz önünde bulundurun!
*/
const float texWidth = 4096.0f;
const float texHeight = 3072.0f;
const float faceWidth = texWidth / 4.0f;
const float faceHeight = texHeight / 3.0f;
float pixelOverlapU = 3.0f / texWidth;
float pixelOverlapV = 3.0f / texHeight;
int col = 0, row = 0;
switch (faceIndex)
{
case 0: // Ön (+Z)
col = 2; row = 1;
break;
case 1: // Arka (-Z)
col = 0; row = 1;
break;
case 2: // Sol (-X)
col = 1; row = 1;
break;
case 3: // Sağ (+X)
col = 3; row = 1;
break;
case 4: // Üst (+Y)
col = 1; row = 0;
break;
case 5: // Alt (-Y)
col = 1; row = 2;
break;
default:
uMin = 0.0f; uMax = 1.0f;
vMin = 0.0f; vMax = 1.0f;
return;
}
float pxMinU = col * faceWidth;
float pxMaxU = (col + 1) * faceWidth;
float pxMinV = row * faceHeight;
float pxMaxV = (row + 1) * faceHeight;
uMin = (pxMinU / texWidth) + pixelOverlapU;
uMax = (pxMaxU / texWidth) - pixelOverlapU;
vMin = (pxMinV / texHeight) + pixelOverlapV;
vMax = (pxMaxV / texHeight) - pixelOverlapV;
}
void CSkyBox::SetFaceTexture(const char* c_szFileName)
{
if (!c_szFileName || strlen(c_szFileName) <= 0)
return;
TGraphicImageInstanceMap::iterator itor = m_GraphicImageInstanceMap.find(c_szFileName);
if (itor != m_GraphicImageInstanceMap.end())
return;
CGraphicImageInstance* pGraphicImageInstance = GenerateTexture(c_szFileName);
if (pGraphicImageInstance)
{
m_GraphicImageInstanceMap.insert(TGraphicImageInstanceMap::value_type(c_szFileName, pGraphicImageInstance));
}
for (int i = 0; i < 6; ++i)
{
m_Faces[i].m_strFaceTextureFileName = c_szFileName;
}
}
#else
// BURAYA ORJINAL SetFaceTexture KOD BLOĞUNU YAPIŞTIRIN!!!!!
#endif
Bu 3 fonksiyonu bulun: genellikle alt alta bulunurlar:
C++:
void CSkyBox::SetSkyObjectQuadVertical(TSkyObjectQuadVector * pSkyObjectQuadVector, const D3DXVECTOR2 * c_pv2QuadPoints)
{
[...]
}
void CSkyBox::SetSkyObjectQuadHorizon(TSkyObjectQuadVector* pSkyObjectQuadVector, const D3DXVECTOR3* c_pv3QuadPoints)
{
[...]
}
void CSkyBox::Refresh()
{
[...]
}
C++:
#ifdef REWORK_SKYBOX
void CSkyBox::SetSkyObjectQuadVertical(TSkyObjectQuadVector* pSkyObjectQuadVector, const D3DXVECTOR2* c_pv2QuadPoints, int faceIndex)
{
TPDTVertex aPDTVertex;
DWORD dwIndex = 0;
pSkyObjectQuadVector->clear();
pSkyObjectQuadVector->resize(m_ucVirticalGradientLevelUpper + m_ucVirticalGradientLevelLower);
float uMin, uMax, vMin, vMax;
GetCrossUVCoordinates(faceIndex, uMin, uMax, vMin, vMax);
unsigned char ucY;
for (ucY = 0; ucY < m_ucVirticalGradientLevelUpper; ++ucY)
{
CSkyObjectQuad& rSkyObjectQuad = pSkyObjectQuadVector->at(dwIndex++);
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
aPDTVertex.position.z = 1.0f - (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper);
aPDTVertex.texCoord.x = uMin;
aPDTVertex.texCoord.y = vMin + ((float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(0, aPDTVertex);
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
aPDTVertex.position.z = 1.0f - (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper);
aPDTVertex.texCoord.x = uMin;
aPDTVertex.texCoord.y = vMin + ((float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(1, aPDTVertex);
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
aPDTVertex.position.z = 1.0f - (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper);
aPDTVertex.texCoord.x = uMax;
aPDTVertex.texCoord.y = vMin + ((float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(2, aPDTVertex);
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
aPDTVertex.position.z = 1.0f - (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper);
aPDTVertex.texCoord.x = uMax;
aPDTVertex.texCoord.y = vMin + ((float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(3, aPDTVertex);
}
for (ucY = 0; ucY < m_ucVirticalGradientLevelLower; ++ucY)
{
CSkyObjectQuad& rSkyObjectQuad = pSkyObjectQuadVector->at(dwIndex++);
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
aPDTVertex.position.z = -(float)(ucY + 1) / (float)(m_ucVirticalGradientLevelLower);
aPDTVertex.texCoord.x = uMin;
aPDTVertex.texCoord.y = vMin + (0.5f + (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(0, aPDTVertex);
aPDTVertex.position.x = c_pv2QuadPoints[0].x;
aPDTVertex.position.y = c_pv2QuadPoints[0].y;
aPDTVertex.position.z = -(float)(ucY) / (float)(m_ucVirticalGradientLevelLower);
aPDTVertex.texCoord.x = uMin;
aPDTVertex.texCoord.y = vMin + (0.5f + (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(1, aPDTVertex);
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
aPDTVertex.position.z = -(float)(ucY + 1) / (float)(m_ucVirticalGradientLevelLower);
aPDTVertex.texCoord.x = uMax;
aPDTVertex.texCoord.y = vMin + (0.5f + (float)(ucY + 1) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(2, aPDTVertex);
aPDTVertex.position.x = c_pv2QuadPoints[1].x;
aPDTVertex.position.y = c_pv2QuadPoints[1].y;
aPDTVertex.position.z = -(float)(ucY) / (float)(m_ucVirticalGradientLevelLower);
aPDTVertex.texCoord.x = uMax;
aPDTVertex.texCoord.y = vMin + (0.5f + (float)(ucY) / (float)(m_ucVirticalGradientLevelUpper) * (vMax - vMin));
rSkyObjectQuad.SetVertex(3, aPDTVertex);
}
}
void CSkyBox::SetSkyObjectQuadHorizon(TSkyObjectQuadVector* pSkyObjectQuadVector, const D3DXVECTOR3* c_pv3QuadPoints, int faceIndex)
{
pSkyObjectQuadVector->clear();
pSkyObjectQuadVector->resize(1);
CSkyObjectQuad& rSkyObjectQuad = pSkyObjectQuadVector->at(0);
float uMin, uMax, vMin, vMax;
GetCrossUVCoordinates(faceIndex, uMin, uMax, vMin, vMax);
TPDTVertex aPDTVertex;
aPDTVertex.position = c_pv3QuadPoints[0];
aPDTVertex.texCoord.x = uMin;
aPDTVertex.texCoord.y = vMax;
rSkyObjectQuad.SetVertex(0, aPDTVertex);
aPDTVertex.position = c_pv3QuadPoints[1];
aPDTVertex.texCoord.x = uMin;
aPDTVertex.texCoord.y = vMin;
rSkyObjectQuad.SetVertex(1, aPDTVertex);
aPDTVertex.position = c_pv3QuadPoints[2];
aPDTVertex.texCoord.x = uMax;
aPDTVertex.texCoord.y = vMax;
rSkyObjectQuad.SetVertex(2, aPDTVertex);
aPDTVertex.position = c_pv3QuadPoints[3];
aPDTVertex.texCoord.x = uMax;
aPDTVertex.texCoord.y = vMin;
rSkyObjectQuad.SetVertex(3, aPDTVertex);
}
void CSkyBox::Refresh()
{
D3DXVECTOR3 v3QuadPoints[4];
if (m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_DEFAULT || m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_DIFFUSE)
{
if (m_ucVirticalGradientLevelUpper + m_ucVirticalGradientLevelLower <= 0)
return;
D3DXVECTOR2 v2QuadPoints[2];
// Face 0: FRONT
v2QuadPoints[0] = D3DXVECTOR2(1.0f, -1.0f);
v2QuadPoints[1] = D3DXVECTOR2(-1.0f, -1.0f);
SetSkyObjectQuadVertical(&m_Faces[0].m_SkyObjectQuadVector, v2QuadPoints, 0);
m_Faces[0].m_strfacename = "front";
// Face 1: BACK
v2QuadPoints[0] = D3DXVECTOR2(-1.0f, 1.0f);
v2QuadPoints[1] = D3DXVECTOR2(1.0f, 1.0f);
SetSkyObjectQuadVertical(&m_Faces[1].m_SkyObjectQuadVector, v2QuadPoints, 1);
m_Faces[1].m_strfacename = "back";
// Face 2: LEFT
v2QuadPoints[0] = D3DXVECTOR2(-1.0f, -1.0f);
v2QuadPoints[1] = D3DXVECTOR2(-1.0f, 1.0f);
SetSkyObjectQuadVertical(&m_Faces[2].m_SkyObjectQuadVector, v2QuadPoints, 2);
m_Faces[2].m_strfacename = "left";
// Face 3: RIGHT
v2QuadPoints[0] = D3DXVECTOR2(1.0f, 1.0f);
v2QuadPoints[1] = D3DXVECTOR2(1.0f, -1.0f);
SetSkyObjectQuadVertical(&m_Faces[3].m_SkyObjectQuadVector, v2QuadPoints, 3);
m_Faces[3].m_strfacename = "right";
// Face 4: TOP
v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
SetSkyObjectQuadHorizon(&m_Faces[4].m_SkyObjectQuadVector, v3QuadPoints, 4);
m_Faces[4].m_strfacename = "top";
// Face 5: BOTTOM
v3QuadPoints[0] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
v3QuadPoints[3] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
SetSkyObjectQuadHorizon(&m_Faces[5].m_SkyObjectQuadVector, v3QuadPoints, 5);
m_Faces[5].m_strfacename = "bottom";
}
else if (m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_TEXTURE)
{
// Face 0: FRONT (+Z)
v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
v3QuadPoints[1] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
SetSkyObjectQuadHorizon(&m_Faces[0].m_SkyObjectQuadVector, v3QuadPoints, 0);
m_Faces[0].m_strfacename = "front";
// Face 1: BACK (-Z)
v3QuadPoints[0] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
v3QuadPoints[2] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
v3QuadPoints[3] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
SetSkyObjectQuadHorizon(&m_Faces[1].m_SkyObjectQuadVector, v3QuadPoints, 1);
m_Faces[1].m_strfacename = "back";
// Face 2: LEFT (-X)
v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
v3QuadPoints[3] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
SetSkyObjectQuadHorizon(&m_Faces[2].m_SkyObjectQuadVector, v3QuadPoints, 2);
m_Faces[2].m_strfacename = "left";
// Face 3: RIGHT (+X)
v3QuadPoints[0] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
SetSkyObjectQuadHorizon(&m_Faces[3].m_SkyObjectQuadVector, v3QuadPoints, 3);
m_Faces[3].m_strfacename = "right";
// Face 4: TOP (+Y)
v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
SetSkyObjectQuadHorizon(&m_Faces[4].m_SkyObjectQuadVector, v3QuadPoints, 4);
m_Faces[4].m_strfacename = "top";
// Face 5: BOTTOM (-Y)
v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
v3QuadPoints[1] = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
v3QuadPoints[2] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
SetSkyObjectQuadHorizon(&m_Faces[5].m_SkyObjectQuadVector, v3QuadPoints, 5);
m_Faces[5].m_strfacename = "bottom";
}
// Clouds
v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
v3QuadPoints[1] = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
v3QuadPoints[2] = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
SetSkyObjectQuadHorizon(&m_FaceCloud.m_SkyObjectQuadVector, v3QuadPoints, 0); // Kaiser: bulutlar bu duzenlemeden muaftir = 0
}
#else
// BU 3 FONKSIYONUN ORJINAL KOD BLOKLARINI BURAYA YAPIŞTIRIN !!!!!!!!!!!!!!
#endif
Bulun:
C++:
void CSkyBox::Render()
{
[...]
}
Tamamen değiştirin(#else kısmına dikkat edin!):
C++:
#ifdef REWORK_SKYBOX
void CSkyBox::Render()
{
STATEMANAGER.SaveRenderState(D3DRS_ZENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld);
// Render Face
if (m_ucRenderMode == CSkyObject::SKY_RENDER_MODE_TEXTURE)
{
CGraphicImageInstance* pFaceImageInstance = m_GraphicImageInstanceMap[m_Faces[0].m_strFaceTextureFileName];
if (!pFaceImageInstance)
{
TraceError("Skybox Face Texture NULL!");
return;
}
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
STATEMANAGER.SetTexture(0, pFaceImageInstance->GetTextureReference().GetD3DTexture());
for (unsigned int i = 0; i < 6; ++i)
{
m_Faces[i].Render();
}
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_ADDRESSU);
STATEMANAGER.RestoreSamplerState(0, D3DSAMP_ADDRESSV);
}
else
{
for (unsigned int i = 0; i < 6; ++i)
{
m_Faces[i].Render();
}
}
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
STATEMANAGER.RestoreRenderState(D3DRS_ZENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2);
}
#else
// BURAYA ORJINAL Render FONKSIYON KOD BLOĞUNU YAPIŞTIRIN !!!!!!!!!!
#endif
GameLib/MapOutdoor.cpp:
Bulun:
C++:
for( int i = 0; i < 6; ++i )
{
if (!mc_pEnvironmentData->strSkyBoxFaceFileName[i].empty())
m_SkyBox.SetFaceTexture( mc_pEnvironmentData->strSkyBoxFaceFileName[i].c_str(), i );
}
C++:
#ifdef REWORK_SKYBOX
if (!mc_pEnvironmentData->strSkyBoxFaceFileName.empty())
m_SkyBox.SetFaceTexture(mc_pEnvironmentData->strSkyBoxFaceFileName.c_str());
#else
for( int i = 0; i < 6; ++i )
{
if (!mc_pEnvironmentData->strSkyBoxFaceFileName[i].empty())
m_SkyBox.SetFaceTexture( mc_pEnvironmentData->strSkyBoxFaceFileName[i].c_str(), i );
}
#endif
GameLib/MapType.h:
Bulun ve değiştirin:
C++:
#ifdef REWORK_SKYBOX
std::string strSkyBoxFaceFileName; // AIO
#else
std::string strSkyBoxFaceFileName[6]; //order
#endif
Bulun:
C++:
textLoader.GetTokenString("frontfacefilename", &envData.strSkyBoxFaceFileName[0]);
textLoader.GetTokenString("backfacefilename", &envData.strSkyBoxFaceFileName[1]);
textLoader.GetTokenString("leftfacefilename", &envData.strSkyBoxFaceFileName[2]);
textLoader.GetTokenString("rightfacefilename", &envData.strSkyBoxFaceFileName[3]);
textLoader.GetTokenString("topfacefilename", &envData.strSkyBoxFaceFileName[4]);
textLoader.GetTokenString("bottomfacefilename", &envData.strSkyBoxFaceFileName[5]);
Değiştirin:
C++:
#ifdef REWORK_SKYBOX
textLoader.GetTokenString("setskyboximage", &envData.strSkyBoxFaceFileName);
#else
textLoader.GetTokenString("frontfacefilename", &envData.strSkyBoxFaceFileName[0]);
textLoader.GetTokenString("backfacefilename", &envData.strSkyBoxFaceFileName[1]);
textLoader.GetTokenString("leftfacefilename", &envData.strSkyBoxFaceFileName[2]);
textLoader.GetTokenString("rightfacefilename", &envData.strSkyBoxFaceFileName[3]);
textLoader.GetTokenString("topfacefilename", &envData.strSkyBoxFaceFileName[4]);
textLoader.GetTokenString("bottomfacefilename", &envData.strSkyBoxFaceFileName[5]);
#endif
Tüm değişiklikler bu kadar. Yukarıda bahsettiğim küçük ve önemli detay ise, kullanacağınız gökyüzü dokusunda +Y konumunu(en üst) 90° derece sağ döndürmeniz gerek. Sebebini anlamadım fakat Metin2 bu koordinattaki dokuyu bu şekilde işliyor. Aksi halde gökyüzünde en tepe noktasının dokusu ters olacaktır.
Görsel:
.msenv Dosyasında Örnek kullanım:
Kod:
Group SkyBox
{
bTextureRenderMode 1
Scale 1500.000000 3000.000000 1500.000000
GradientLevelUpper 4
GradientLevelLower 1
SetSkyBoxImage "D:\ymir work\environment\Skybox\vanilia\test1.dds"
CloudScale 0.000000 0.000000
CloudHeight 30000.000000
CloudTextureScale 0.000000 0.000000
CloudSpeed 0.000000 0.000000
CloudTextureFileName ""
List CloudColor
{
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
}
List Gradient
{
0.764706 0.792157 0.823529 0.000000
0.000000 0.000000 0.000000 0.000000
0.796078 0.835294 0.874510 0.000000
0.000000 0.000000 0.000000 0.000000
}
}
Dosya formatı PNG ve DDS olarak tercih edilebilir.
Alpha kanalı olmadan DDS formatı: DXT1
Alpha kanalı varsa DDS formatı: DXT5 (Dosya boyutu artabilir.)
Final: