243 lines
7.7 KiB
C++
243 lines
7.7 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2002.
|
|
// -------------------------------------------------------------------------
|
|
// File name: terrain_sector_tex.cpp
|
|
// Version: v1.00
|
|
// Created: 28/5/2001 by Vladimir Kajalin
|
|
// Compilers: Visual Studio.NET
|
|
// Description: terrain texture management
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "terrain_sector.h"
|
|
#include "terrain.h"
|
|
#include "objman.h"
|
|
|
|
// set texture for sector
|
|
void CSectorInfo::SetTextures(bool bMakeUncompressedForEditing)
|
|
{
|
|
FUNCTION_PROFILER( GetSystem(),PROFILE_3DENGINE );
|
|
|
|
if(m_bLockTexture) // always keep full texture detail during editing
|
|
m_cNewTextMML = 0;
|
|
|
|
{ // required actions
|
|
if(!m_nLowLodTextureID)
|
|
m_nLowLodTextureID = MakeSectorTextureDDS( GetSecIndex(), MAX_TEX_MML_LEVEL, bMakeUncompressedForEditing );
|
|
|
|
if(!m_nTextureID)
|
|
{
|
|
m_nTextureID = m_nLowLodTextureID;
|
|
m_cTextureMML = MAX_TEX_MML_LEVEL;
|
|
}
|
|
}
|
|
|
|
// desired actions
|
|
if(m_cTextureMML > m_cNewTextMML)
|
|
{ // increase tex resolution
|
|
if(!m_bLockTexture)
|
|
{
|
|
if(m_pTerrain->m_nUploadsInFrame>1)
|
|
return; // no more than 1 upload per frame
|
|
|
|
// remove hi res texture if it's not needed
|
|
if(m_cGeometryMML>=MAX_MML_LEVEL) // NOTE: in testing
|
|
{
|
|
if(m_nTextureID != m_nLowLodTextureID)
|
|
{
|
|
m_pTerrain->m_pTexturePool->RemoveTexture(m_nTextureID);
|
|
assert(m_nTextureID);
|
|
assert(m_nTextureID != m_nLowLodTextureID);
|
|
m_nTextureID = m_nLowLodTextureID;
|
|
m_cTextureMML = MAX_TEX_MML_LEVEL;
|
|
}
|
|
return;
|
|
}
|
|
|
|
m_pTerrain->m_nUploadsInFrame++;
|
|
|
|
if(m_nTextureID != m_nLowLodTextureID)
|
|
GetLog()->Log("CSectorInfo::SetTextureAndLOD: m_nTextureID != m_nLowLodTextureID");
|
|
}
|
|
|
|
m_cTextureMML = m_cNewTextMML;
|
|
m_nTextureID = MakeSectorTextureDDS( GetSecIndex(), m_cTextureMML, bMakeUncompressedForEditing );
|
|
|
|
if(m_pTerrain->GetCVars()->e_terrain_log)
|
|
GetLog()->Log("tex loaded %d(%d)", GetSecIndex(), m_cTextureMML);
|
|
}
|
|
else if(m_cTextureMML < m_cNewTextMML)
|
|
{ // reduce tex resolution
|
|
if(m_nTextureID == m_nLowLodTextureID)
|
|
GetLog()->Log("CSectorInfo::SetTextureAndLOD: m_nTextureID == m_nLowLodTextureID");
|
|
|
|
m_pTerrain->m_pTexturePool->RemoveTexture(m_nTextureID);
|
|
m_nTextureID = m_nLowLodTextureID;
|
|
m_cTextureMML = MAX_TEX_MML_LEVEL;
|
|
}
|
|
}
|
|
|
|
// load compresssed texture from disk
|
|
int CSectorInfo::MakeSectorTextureDDS( int sec_id, int nMipMapLevelToLoad, bool bMakeUncompressedForEditing )
|
|
{
|
|
FUNCTION_PROFILER( GetSystem(),PROFILE_3DENGINE );
|
|
|
|
nMipMapLevelToLoad+=GetCVars()->e_terrain_texture_mip_offset;
|
|
|
|
// open file once
|
|
if(!m_pTerrain->m_fpTerrainTextureFile)
|
|
{
|
|
m_pTerrain->m_fpTerrainTextureFile = GetSystem()->GetIPak()->FOpen(Get3DEngine()->GetLevelFilePath("terrain\\cover.ctc"), "rb");
|
|
|
|
if(!m_pTerrain->m_fpTerrainTextureFile)
|
|
return 0;
|
|
|
|
GetSystem()->GetIPak()->FRead(&m_pTerrain->m_nSectorTextureReadedSize, 1, 4, m_pTerrain->m_fpTerrainTextureFile);
|
|
GetLog()->Log(" TerrainSectorTextureSize %dx%d", m_pTerrain->m_nSectorTextureReadedSize, m_pTerrain->m_nSectorTextureReadedSize);
|
|
|
|
GetSystem()->GetIPak()->FSeek( m_pTerrain->m_fpTerrainTextureFile, 0, SEEK_END);
|
|
int nFileSize = GetSystem()->GetIPak()->FTell(m_pTerrain->m_fpTerrainTextureFile);
|
|
|
|
m_pTerrain->m_nSectorTextureDataSizeBytes = (nFileSize-4)/(m_pTerrain->GetSectorsTableSize()*m_pTerrain->GetSectorsTableSize());
|
|
GetLog()->Log(" SectorTextureDataSizeBytes = %d", m_pTerrain->m_nSectorTextureDataSizeBytes);
|
|
|
|
m_pTerrain->m_ucpTmpTexBuffer = new uchar [m_pTerrain->m_nSectorTextureDataSizeBytes];
|
|
}
|
|
|
|
if(!m_pTerrain->m_fpTerrainTextureFile)
|
|
{ Warning(0,0,"MakeSectorTextureDDS: !m_pTerrain->m_fpTerrainTextureFile"); return 0; }
|
|
|
|
// count mm levels
|
|
int nMipLevels=0;
|
|
int w = m_pTerrain->m_nSectorTextureReadedSize;
|
|
while(w>0)
|
|
{ w/=2; nMipLevels++; }
|
|
|
|
int nDataSize = m_pTerrain->m_nSectorTextureDataSizeBytes;
|
|
int nTexSize = m_pTerrain->m_nSectorTextureReadedSize;
|
|
|
|
// calculate texture offset in file
|
|
int file_offset = 4+sec_id*m_pTerrain->m_nSectorTextureDataSizeBytes;
|
|
|
|
// if not zero mml specified
|
|
for(int m=0; m<nMipMapLevelToLoad; m++)
|
|
{
|
|
file_offset = file_offset + nTexSize*nTexSize/2;
|
|
nDataSize -= nTexSize*nTexSize/2;
|
|
nMipLevels--;
|
|
nTexSize = nTexSize/2;
|
|
}
|
|
|
|
assert(m_pTerrain->m_nSectorTextureDataSizeBytes >= (GetCVars()->e_terrain_texture_mipmaps ? nDataSize : nTexSize*nTexSize/2));
|
|
|
|
// read texture
|
|
GetSystem()->GetIPak()->FSeek( m_pTerrain->m_fpTerrainTextureFile, file_offset, SEEK_SET );
|
|
INT_PTR readed = GetSystem()->GetIPak()->FRead(m_pTerrain->m_ucpTmpTexBuffer, 1, //AMD Port
|
|
GetCVars()->e_terrain_texture_mipmaps ? nDataSize : nTexSize*nTexSize/2,
|
|
m_pTerrain->m_fpTerrainTextureFile);
|
|
|
|
// no reason to use update texture instead create since size is always diferent
|
|
/* int nTexID = GetRenderer()->DownLoadToVideo Memory(m_pTerrain->m_ucpTmpTexBuffer,
|
|
nTexSize, nTexSize, eTF_DXT1, eTF_DXT1,
|
|
GetCVars()->e_terrain_texture_mipmaps ? nMipLevels : 0, false,
|
|
GetCVars()->e_terrain_texture_mipmaps ? FILTER_BILINEAR : FILTER_LINEAR);*/
|
|
|
|
int nTexID = m_pTerrain->m_pTexturePool->MakeTexture(m_pTerrain->m_ucpTmpTexBuffer, nTexSize, this, bMakeUncompressedForEditing);
|
|
|
|
return (nTexID);
|
|
}
|
|
/*
|
|
void CSectorInfo::UpdateSectorTexture(unsigned char * pTexData, int nSizeOffTexData)
|
|
{
|
|
int nTexSize = m_pTerrain->m_nSectorTextureReadedSize;
|
|
|
|
if(nSizeOffTexData != nTexSize*nTexSize*3)
|
|
{
|
|
GetLog()->Log("Error: CSectorInfo::UpdateSectorTexture: nSizeOffTexData error");
|
|
return;
|
|
}
|
|
|
|
if(m_nTextureID)
|
|
{
|
|
GetRenderer()->UpdateTextureInVideoMemory(m_nTextureID,pTexData,0,0,nTexSize,nTexSize,eTF_0888);
|
|
}
|
|
else
|
|
{
|
|
assert(0);
|
|
// m_nTextureID = GetRenderer()->DownLoadToVideo Memory(pTexData,
|
|
// nTexSize,nTexSize,eTF_0888,eTF_DXT1,0,false);
|
|
}
|
|
} */
|
|
|
|
int CSectorInfo::LockSectorTexture(int & nTexDim)
|
|
{
|
|
m_bLockTexture = true;
|
|
nTexDim = m_pTerrain->m_nSectorTextureReadedSize;
|
|
// force texture reloading as uncompressed
|
|
m_cNewTextMML = 0;
|
|
m_cTextureMML = 1;
|
|
SetTextures(true);
|
|
return m_nTextureID;
|
|
}
|
|
|
|
void CSectorInfo::RemoveSectorTextures(bool bRemoveLowLod)
|
|
{
|
|
// remove high
|
|
if(m_nTextureID)
|
|
{
|
|
m_pTerrain->m_pTexturePool->RemoveTexture(m_nTextureID);
|
|
assert(m_nLowLodTextureID);
|
|
m_nTextureID = m_nLowLodTextureID;
|
|
m_cTextureMML = MAX_TEX_MML_LEVEL;
|
|
}
|
|
|
|
// remove low
|
|
if(bRemoveLowLod)
|
|
{
|
|
m_pTerrain->m_pTexturePool->RemoveTexture(m_nLowLodTextureID);
|
|
m_nTextureID = m_nLowLodTextureID = 0;
|
|
}
|
|
}
|
|
|
|
void CSectorInfo::UnloadHeighFieldTexture(float fDistanse, float fMaxViewDist)
|
|
{
|
|
if(m_nTextureID && m_cTextureMML == 0 && m_nTextureID!=m_nLowLodTextureID)
|
|
{ // unload if to far or not in use int time
|
|
if(m_nTextureID == m_nLowLodTextureID)
|
|
GetLog()->Log("unload old secs error");
|
|
|
|
// set low lod tex
|
|
//glDeleteTextures(1, &(m_nTextureID) );
|
|
m_pTerrain->m_pTexturePool->RemoveTexture(m_nTextureID);
|
|
m_nTextureID = m_nLowLodTextureID;
|
|
m_cTextureMML = MAX_TEX_MML_LEVEL;
|
|
|
|
if(GetCVars()->e_terrain_log)
|
|
GetLog()->Log("lod0 tex unloaded");
|
|
}
|
|
else if(m_nTextureID && m_nTextureID == m_nLowLodTextureID)
|
|
{ // only low lod
|
|
if(fDistanse > (1.5f*fMaxViewDist))
|
|
{
|
|
m_pTerrain->m_pTexturePool->RemoveTexture(m_nTextureID);
|
|
m_nTextureID = m_nLowLodTextureID = 0;
|
|
m_cTextureMML = 0;
|
|
|
|
if(GetCVars()->e_terrain_log)
|
|
GetLog()->Log("lod1 tex unloaded");
|
|
}
|
|
}
|
|
else if(!m_nTextureID && !m_nLowLodTextureID)
|
|
{ // no textures
|
|
m_nTextureID = m_nLowLodTextureID;
|
|
}
|
|
else
|
|
{
|
|
Warning(0,0,"CTerrain::UnloadOldSectors: tex management error");
|
|
}
|
|
} |