Files
2026-06-01 12:46:52 +02:00

1372 lines
39 KiB
C++

#include "stdafx.h"
#include "KRenderDeviceDX.h"
#include "KResourceDX.h"
#include <dump/XException.h>
#include "SDebug_Util.h"
int g_TexRef = 0;
static inline D3DFORMAT GetD3DFormat( K3DFORMAT fmt )
{
return D3DFORMAT( fmt );
//switch ( fmt )
//{
// default:
// case K3DFMT_UNKNOWN : return D3DFMT_UNKNOWN ;
//
// case K3DFMT_R8G8B8 : return K3DFMT_R8G8B8 ;
// case K3DFMT_A8R8G8B8 : return K3DFMT_A8R8G8B8 ;
// case K3DFMT_X8R8G8B8 : return K3DFMT_X8R8G8B8 ;
// case K3DFMT_R5G6B5 : return K3DFMT_R5G6B5 ;
// case K3DFMT_X1R5G5B5 : return K3DFMT_X1R5G5B5 ;
// case K3DFMT_A1R5G5B5 : return K3DFMT_A1R5G5B5 ;
// case K3DFMT_A4R4G4B4 : return K3DFMT_A4R4G4B4 ;
// case K3DFMT_R3G3B2 : return K3DFMT_R3G3B2 ;
// case K3DFMT_A8 : return K3DFMT_A8 ;
// case K3DFMT_A8R3G3B2 : return K3DFMT_A8R3G3B2 ;
// case K3DFMT_X4R4G4B4 : return K3DFMT_X4R4G4B4 ;
// case K3DFMT_A2B10G10R10 : return K3DFMT_A2B10G10R10 ;
// case K3DFMT_G16R16 : return K3DFMT_G16R16 ;
//
// case K3DFMT_A8P8 : return K3DFMT_A8P8 ;
// case K3DFMT_P8 : return K3DFMT_P8 ;
//
// case K3DFMT_L8 : return K3DFMT_L8 ;
// case K3DFMT_A8L8 : return K3DFMT_A8L8 ;
// case K3DFMT_A4L4 : return K3DFMT_A4L4 ;
//
// case K3DFMT_V8U8 : return K3DFMT_V8U8 ;
// case K3DFMT_L6V5U5 : return K3DFMT_L6V5U5 ;
// case K3DFMT_X8L8V8U8 : return K3DFMT_X8L8V8U8 ;
// case K3DFMT_Q8W8V8U8 : return K3DFMT_Q8W8V8U8 ;
// case K3DFMT_V16U16 : return K3DFMT_V16U16 ;
// case K3DFMT_W11V11U10 : return K3DFMT_W11V11U10 ;
// case K3DFMT_A2W10V10U10 : return K3DFMT_A2W10V10U10 ;
//
// case K3DFMT_UYVY : return K3DFMT_UYVY ;
// case K3DFMT_YUY2 : return K3DFMT_YUY2 ;
// case K3DFMT_DXT1 : return K3DFMT_DXT1 ;
// case K3DFMT_DXT2 : return K3DFMT_DXT2 ;
// case K3DFMT_DXT3 : return K3DFMT_DXT3 ;
// case K3DFMT_DXT4 : return K3DFMT_DXT4 ;
// case K3DFMT_DXT5 : return K3DFMT_DXT5 ;
//
// case K3DFMT_D16_LOCKABLE : return K3DFMT_D16_LOCKABLE ;
// case K3DFMT_D32 : return K3DFMT_D32 ;
// case K3DFMT_D15S1 : return K3DFMT_D15S1 ;
// case K3DFMT_D24S8 : return K3DFMT_D24S8 ;
// case K3DFMT_D16 : return K3DFMT_D16 ;
// case K3DFMT_D24X8 : return K3DFMT_D24X8 ;
// case K3DFMT_D24X4S4 : return K3DFMT_D24X4S4 ;
//
// case K3DFMT_VERTEXDATA : return K3DFMT_VERTEXDATA ;
// case K3DFMT_INDEX16 : return K3DFMT_INDEX16 ;
// case K3DFMT_INDEX32 : return K3DFMT_INDEX32 ;
//
// case K3DFMT_R32F : return K3DFMT_R32F ;
//}
}
K3DTextureDX::K3DTextureDX( K3DRenderDeviceDX *dev )
{
m_bLocked = false;
m_dev = dev;
m_d3dtex = NULL;
m_usage = 0;
m_pool = D3DPOOL_MANAGED;
// _oprint( "TC:(%08X)\n", this );
}
K3DTextureDX::~K3DTextureDX()
{
//if( m_strName.length() )
// _oprint( "TD:(%08X : %s)\n", this, m_strName.c_str() );
//else
// _oprint( "TD:(%08X)\n", this );
if ( m_d3dtex) g_TexRef--;
SAFE_RELEASE(m_d3dtex);
}
template< typename T > static inline T _max( const T& a, const T& b ) { return a > b ? a : b; }
template< typename T > static inline T _min( const T& a, const T& b ) { return a < b ? a : b; }
bool K3DTextureDX::Initialize( KStream &stream, int nQuality, D3DPOOL pool/* = D3DPOOL_MANAGED*/, K3DFORMAT fmt/* = K3DFMT_UNKNOWN*/ )
{
//if( pool == D3DPOOL_DEFAULT )
// _oprint( "K3DTextureDX::Initialize : (0x%08X)\n", this );
void *pSrc = stream.GetMappedPtr( KStream::MAPPED_READ );
if ( pSrc == NULL ) return false;
bool original = false;
if(nQuality >= 10000 || nQuality < 0)
{
nQuality = 0;
original = true;
}
HRESULT res;
m_nQuality = nQuality;
D3DXIMAGE_INFO infoImg;
D3DXGetImageInfoFromFileInMemory( pSrc, static_cast<UINT>(stream.GetLength()), &infoImg );
m_origin_size.width = infoImg.Width;
m_origin_size.height = infoImg.Height;
if ( m_nQuality != 0 )
{
// 너무 작은 텍스쳐는 뭉게지는것 같아서.. 임시로 추가해봄 -.-
infoImg.Width = _max( infoImg.Width / (1 << m_nQuality), _min( infoImg.Width, 32U ) );
infoImg.Height = _max( infoImg.Height / (1 << m_nQuality), _min( infoImg.Height, 32U ) );
infoImg.MipLevels = _max( (int) (infoImg.MipLevels - m_nQuality), 1 );
res = D3DXCreateTextureFromFileInMemoryEx( m_dev->GetD3DDevice(), pSrc,
static_cast<UINT>(stream.GetLength()), infoImg.Width, infoImg.Height,
infoImg.MipLevels, 0, GetD3DFormat( fmt ), pool, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &m_d3dtex );
}
else {
res = D3DXCreateTextureFromFileInMemoryEx( m_dev->GetD3DDevice(), pSrc,
static_cast<UINT>(stream.GetLength()), infoImg.Width, infoImg.Height,
infoImg.MipLevels, 0, GetD3DFormat( fmt ), pool, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &m_d3dtex );
// infoImg.MipLevels, 0, D3DFMT_UNKNOWN, original ? D3DPOOL_MANAGED : D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &m_d3dtex );
// infoImg.MipLevels, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_POINT, D3DX_FILTER_POINT, 0, NULL, NULL, &m_d3dtex );
}
stream.FreeMappedPtr( pSrc );
if ( res != D3D_OK )
{
/// 2011.05.12 - prodongi
std::string errStr;
if( res == D3DERR_NOTAVAILABLE ) errStr = "D3DERR_NOTAVAILABLE";
else if( res == D3DERR_OUTOFVIDEOMEMORY ) errStr = "D3DERR_OUTOFVIDEOMEMORY";
else if( res == D3DERR_INVALIDCALL ) errStr = "D3DERR_INVALIDCALL";
else if( res == E_OUTOFMEMORY ) errStr = "E_OUTOFMEMORY";
else errStr = "";
_oprint("***DEVICE ERROR : %s[%d]\n", errStr.c_str(), res);
#ifdef _DEV
MessageBox(HWND_DESKTOP, errStr.c_str(), "Failed D3DXCreateTextureFromFileInMemoryEx", MB_OK);
#endif
/*
if( res == D3DERR_NOTAVAILABLE ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_NOTAVAILABLE" ); }
else if( res == D3DERR_OUTOFVIDEOMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_OUTOFVIDEOMEMORY" ); }
else if( res == D3DERR_INVALIDCALL ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_INVALIDCALL" ); }
else if( res == E_OUTOFMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "E_OUTOFMEMORY" ); }
*/
m_d3dtex = NULL;
m_pSurface = NULL;
return false;
}
g_TexRef++;
m_fmt = fmt;
m_pool = pool;
m_pSurface = m_d3dtex;
m_size.width = infoImg.Width ;
m_size.height = infoImg.Height;
m_nMipsLevels = infoImg.MipLevels;
m_format = static_cast<K3DFORMAT>(infoImg.Format);
return true;
}
bool K3DTextureDX::CreateNew( DWORD width, DWORD height, DWORD usage, K3DFORMAT format, D3DPOOL pool/* = D3DPOOL_DEFAULT*/ )
{
//if( pool == D3DPOOL_DEFAULT )
// _oprint( "DeviceLost : K3DTextureDX::CreateNew : (0x%08X)\n", this );
HRESULT res = m_dev->GetD3DDevice()->CreateTexture( width, height, 1, usage, GetD3DFormat(format), pool, &m_d3dtex, NULL );
if ( res != D3D_OK )
{
if( res == D3DERR_NOTAVAILABLE ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_NOTAVAILABLE" ); }
else if( res == D3DERR_OUTOFVIDEOMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_OUTOFVIDEOMEMORY" ); }
else if( res == D3DERR_INVALIDCALL ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_INVALIDCALL" ); }
else if( res == E_OUTOFMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "E_OUTOFMEMORY" ); }
m_d3dtex = NULL;
m_pSurface = NULL;
return false;
}
m_pool = pool;
m_usage = usage;
m_pSurface = m_d3dtex;
D3DSURFACE_DESC desc;
m_d3dtex->GetLevelDesc( 0, &desc );
m_size.width = desc.Width;
m_size.height = desc.Height;
g_TexRef++;
m_nMipsLevels = 1;
m_fmt = format;
m_format = static_cast<K3DFORMAT>(desc.Format);
return true;
}
bool K3DTextureDX::CreateNew( DWORD width, DWORD height, K3DFORMAT format, D3DPOOL pool/* = D3DPOOL_MANAGED*/, int nLevel /*= 1*/ )
{
//if( pool == D3DPOOL_DEFAULT )
// _oprint( "DeviceLost : K3DTextureDX::CreateNew : (0x%08X)\n", this );
HRESULT res = D3DXCreateTexture( m_dev->GetD3DDevice(), width, height, nLevel, 0, GetD3DFormat(format), pool, &m_d3dtex );
if ( res != D3D_OK )
{
if( res == D3DERR_NOTAVAILABLE ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_NOTAVAILABLE" ); }
else if( res == D3DERR_OUTOFVIDEOMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_OUTOFVIDEOMEMORY" ); }
else if( res == D3DERR_INVALIDCALL ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_INVALIDCALL" ); }
else if( res == E_OUTOFMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "E_OUTOFMEMORY" ); }
m_d3dtex = NULL;
m_pSurface = NULL;
return false;
}
g_TexRef++;
m_pSurface = m_d3dtex;
D3DSURFACE_DESC desc;
m_d3dtex->GetLevelDesc( 0, &desc );
m_size.width = desc.Width;
m_size.height = desc.Height;
m_format = static_cast<K3DFORMAT>(desc.Format);
return true;
}
bool K3DTextureDX::IsValid() const
{
return m_d3dtex ? true : false;
}
void K3DTextureDX::Refresh( KStream &stream, int nQuality )
{
if ( m_d3dtex) g_TexRef--;
SAFE_RELEASE(m_d3dtex);
Initialize( stream, nQuality );
}
void K3DTextureDX::LockRect( KRect *rect, void** ppBuf, int& stride )
{
if ( !m_bLocked && m_d3dtex != NULL )
{
D3DLOCKED_RECT rt;
HRESULT hr = m_d3dtex->LockRect( 0, &rt, (const RECT*)rect, 0/*D3DLOCK_NOSYSLOCK*/ );
if ( hr == D3D_OK )
{
*ppBuf = rt.pBits;
stride = rt.Pitch;
m_bLocked = true;
}
}
else
{
*ppBuf = NULL;
stride = 0;
}
}
void K3DTextureDX::Unlock()
{
if ( m_bLocked )
{
m_d3dtex->UnlockRect(0);
m_bLocked = false;
}
}
bool K3DTextureDX::PreReload()
{
if (m_d3dtex) g_TexRef--;
SAFE_RELEASE(m_d3dtex);
return true;
}
bool K3DTextureDX::Reload()
{
//Device Lost 처리
if( m_pool == D3DPOOL_DEFAULT )
{
if (m_d3dtex) g_TexRef--;
SAFE_RELEASE(m_d3dtex);
CreateNew( m_size.width, m_size.height, m_usage, m_format, m_pool );
}
return true;
}
bool K3DTextureDX::SaveToFile( const std::string& strFile )
{
if( D3DXSaveTextureToFile( strFile.c_str(), D3DXIFF_DDS, m_d3dtex, NULL ) == D3D_OK ) return true;
return false;
}
// 추가. bintitle.
#include <dxerr9.h>
bool K3DTextureDX::LoadFromFile( const std::string& strFile )
{
HRESULT hr;
if( !FAILED( hr = D3DXCreateTextureFromFile( m_dev->GetD3DDevice(), strFile.c_str(), &m_d3dtex ) ) )
{
m_origin_size.width = 20; // 테스트 강제 적용.
m_origin_size.height = 20;
return true;
}
else
{
const TCHAR* szError = DXGetErrorString9(hr);
::MessageBox( NULL, szError, "Load Fail", MB_OK );
}
return false;
}
struct Color_RGB {
// 2010.04.23 순서를 수정했습니다. - prodongi
double red,green,blue; //doubles used for best accuracy
//double red,blue, green; //doubles used for best accuracy
};
struct Color_HSV {
double hue, sat, val;
};
struct Color_HSV RGBtoHSV(struct Color_RGB RGB)
{
struct Color_HSV HSV; //structure to return
double vals[3]; //thue = temporary var (linked to hue)
unsigned char maxc=0, minc=0; //red=0, green=1, blue=2
vals[0]=RGB.red;
vals[1]=RGB.green;
vals[2]=RGB.blue;
//red is set as maximum and minimum
if(vals[1]>vals[maxc]) maxc=1; //if green is greater, make green the max.
if(vals[2]>vals[maxc]) maxc=2; //if blue is greater, make blue the max
if(vals[1]<vals[minc]) minc=1; //if green is less, make green the min.
if(vals[2]<vals[minc]) minc=2; //if blue is less, make blue the min.
HSV.val = vals[maxc]; //set the HSV.val to the maximum component value (this is a final value)
if(vals[maxc]==0) //if maximum component is 0, color must be black
HSV.sat = HSV.hue = 0; //so set values to 0 manually to avoid div by 0 errors
else
{ //otherwise, calculate the values
HSV.sat=255*(1-(vals[minc]/vals[maxc])); //compressed equation - original: HSV.sat=((vals[maxc]-vals[minc])/vals[maxc])*255;
HSV.hue = 60 * ((maxc*2) + (vals[(maxc+1)%3] - vals[(maxc+2)%3])/(vals[maxc] - vals[minc])); //this cannot be simplified - and i havn't got time to explain it
}
if(HSV.hue < 0) HSV.hue += 360; //corrector for hues in -60 to 0 range
return HSV;
}
struct Color_RGB HSVtoRGB(struct Color_HSV HSV)
{
struct Color_RGB RGB; //structure to return
double min,thue,vals[3]; //thue = temporary var (linked to hue)
unsigned char maxc; //red=0, green=1, blue=2
/* The biggest component (r,g or b) of the colour can be detemined
* by where the hue lies.
* The maximum component is eaqul to the 'value' in HSV,
* so we can set the biggest component to HSV.val,
* and also set the marker for which is the biggest component(maxc)
*
* The maximum component can be determined by where the hue lies:
* it lies in one of three groups
*
* If the maximum component is red (0), it lies in the third of the
* spectrum around red, i.e. -60 to 60
* If the maximum component is green (120), it lies in the third of the
* spectrum around green, i.e. 60 to 180
* If the maximum component is blue (240), it lies in the third of the
* spectrum around blue, i.e. 180 to 300
*/
/* since the spectrum is circular, we can take the 300-360 section and
* fit it into -60 -> 0, to fit help the group seperation
*/
if(HSV.hue>300)
HSV.hue-=360;
/* we now determine the maximum component (maxc) by the hue groups
*/
if(HSV.hue<60) //if it is below 60, then it is red (maxc 0)
maxc=0; //The range is -60 -> 60, and there is never anything below -60
else if(HSV.hue>=180) //if it is above 180, then it is blue (maxc 2)
maxc=2; //The range is 180 -> 300, and there is never anything above 300, or it would have been modified earlier
else //otherwise, it must be between 60 and 180, which is green (maxc 1)
maxc=1; //The range is 60 -> 180
vals[maxc]=HSV.val; //vals holds the r, g, and b values temporarialy, so set the maximum one to HSV.val (the value of the maximim component is HSV.val)
/* the first of these formulae calculates the minimum
* value. it has been "shrink-wrapped", so dont try to make sense of it
*
* I dont understand it anymore, and i'm not sure if i even did when i wrote it
*/
min = (HSV.val*(255-HSV.sat)) / 255;
/* the second of these formulae calculates a value 'thue'.
* the formaula results in a value between -1 and 1, representing
* the position of the hue in it's group
* this may help: (green "hue group" used as an example.)
*
* lwr bound ## green ## upr bound
* 60 120 180 -----> Hue
* |-----|-----|-----------|
* hue= 90
*
* lwr bound ## green ## upr bound
* -1 0 1 -----> tHue
* |-----|-----|-----------|
* hue= -0.5
*
* this part is done in the first half of the equation ((HSV.hue/60)-(2*maxc))
*
* the second part multiplies it by the difference between
* the maximum and minimum to get a value that is
* the difference between the minimum component and the middle component.
* i dont really understand why, but it works. * (HSV.val-min)
*/
thue=(((HSV.hue/60)-(2*maxc)) * (HSV.val-min));
if(thue>0) //if the hue is more like the color group above it,
{ //i.e. a green that is more 'bluey' than 'reddy'
vals[(maxc+2)%3] = min; //then the minimum component is the one it is less like, the group below
vals[(maxc+1)%3] = min+thue; //and the middle component is the one it is more like, the group above
}
else //otherwise, it must be more like the colour group below it
{ //i.e. a green that is more 'reddy' than 'bluey'
vals[(maxc+1)%3] = min; //then the minimum component is the one it is less like, the group above
vals[(maxc+2)%3] = min+thue; //and the middle component is the one it is more like, the group below
}
RGB.red=vals[0]; // now stuff the aray values into the return structure
RGB.green=vals[1];
RGB.blue=vals[2];
return RGB;
}
HRESULT K3DTextureDX::LoadSurfaceFromSurface( K3DTexture* pDestTexture, DWORD c1, DWORD c2, DWORD c3, DWORD c4, short nMode )
{
if( !IsValid() ) return S_FALSE;
if( pDestTexture == NULL || !pDestTexture->IsValid() ) return S_FALSE;
K3DTextureDX* pDestTextureDX = (K3DTextureDX*)pDestTexture;
int nMipCount = GetMipsLevels();
D3DSURFACE_DESC sd;
HRESULT hr;
LPDIRECT3DSURFACE9 psurfSrc = NULL;
LPDIRECT3DSURFACE9 psurfDest = NULL;
KColor cols[4];
int i, fr[4], fg[4], fb[4];
cols[0].color = c1; cols[1].color = c2; cols[2].color = c3; cols[3].color = c4;
for ( i=0 ; i<4 ; ++i )
{
if ( cols[i].color == 0 )
fr[i] = fg[i] = fb[i] = 0;
else
{
fr[i] = int(cols[i].r) - 128;
fg[i] = int(cols[i].g) - 128;
fb[i] = int(cols[i].b) - 128;
}
}
int r,g,b;
KColor *colbuf, *newcolbuf;
for( int i(0); nMipCount>i; i++ )
{
m_d3dtex->GetLevelDesc(i, &sd);
hr = m_d3dtex->GetSurfaceLevel(i, &psurfSrc);
hr = pDestTextureDX->GetD3DTexture()->GetSurfaceLevel(i, &psurfDest);
if( psurfSrc && psurfDest )
{
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_FILTER_LINEAR/*D3DX_FILTER_TRIANGLE*/, 0);
//Colorized
if( (c1 != 0 || c2 != 0 || c3 != 0 || c4 != 0) && hr== S_OK )
{
D3DLOCKED_RECT lr;
hr = psurfDest->LockRect(&lr, NULL, 0);
DWORD xp;
DWORD yp;
DWORD* pdwRow = (DWORD*)lr.pBits;
LONG dataBytesPerRow = 4 * sd.Width;
colbuf = NULL;
newcolbuf= NULL;
if( nMode == COLORIZED_DEF )
{
Color_RGB rgb = {cols[1].r, cols[1].g, cols[1].b};
Color_HSV hsv = RGBtoHSV(rgb);
for (yp = 0; yp < sd.Height; yp++)
{
colbuf = (KColor*)pdwRow;
newcolbuf = (KColor*)pdwRow;
for (xp = 0; xp < sd.Width; xp++)
{
switch( (int)(colbuf->a >> 5) )
{
case 0:
newcolbuf->color = colbuf->color;
break;
case 1:
case 2:
r = int(colbuf->r) + fr[0];
g = int(colbuf->g) + fg[0];
b = int(colbuf->b) + fb[0];
newcolbuf->r = unsigned char((r > 255) ? (255) : ( (r<0) ? (0) : r ));
newcolbuf->g = unsigned char((g > 255) ? (255) : ( (g<0) ? (0) : g ));
newcolbuf->b = unsigned char((b > 255) ? (255) : ( (b<0) ? (0) : b ));
break;
case 3:
case 4:
r = int(colbuf->r) + fr[1];
g = int(colbuf->g) + fg[1];
b = int(colbuf->b) + fb[1];
newcolbuf->r = unsigned char((r > 255) ? (255) : ( (r<0) ? (0) : r ));
newcolbuf->g = unsigned char((g > 255) ? (255) : ( (g<0) ? (0) : g ));
newcolbuf->b = unsigned char((b > 255) ? (255) : ( (b<0) ? (0) : b ));
break;
case 5:
case 6:
r = int(colbuf->r) + fr[2];
g = int(colbuf->g) + fg[2];
b = int(colbuf->b) + fb[2];
newcolbuf->r = unsigned char((r > 255) ? (255) : ( (r<0) ? (0) : r ));
newcolbuf->g = unsigned char((g > 255) ? (255) : ( (g<0) ? (0) : g ));
newcolbuf->b = unsigned char((b > 255) ? (255) : ( (b<0) ? (0) : b ));
break;
case 7:
r = int(colbuf->r) + fr[3];
g = int(colbuf->g) + fg[3];
b = int(colbuf->b) + fb[3];
newcolbuf->r = unsigned char((r > 255) ? (255) : ( (r<0) ? (0) : r ));
newcolbuf->g = unsigned char((g > 255) ? (255) : ( (g<0) ? (0) : g ));
newcolbuf->b = unsigned char((b > 255) ? (255) : ( (b<0) ? (0) : b ));
break;
}
//0~127 사이의 알파값은 유지
if( colbuf->a >= 128 )
newcolbuf->a = 255;
colbuf++;
newcolbuf++;
}
pdwRow += lr.Pitch / 4;
}//for
}
else if( nMode == COLORIZED_KEEP_ALPHA )
{
for (yp = 0; yp < sd.Height; yp++)
{
colbuf = (KColor*)pdwRow;
newcolbuf = (KColor*)pdwRow;
for (xp = 0; xp < sd.Width; xp++)
{
if( colbuf->a != 0 )
{
r = int(colbuf->r) + fr[0];
g = int(colbuf->g) + fg[0];
b = int(colbuf->b) + fb[0];
newcolbuf->r = unsigned char((r > 255) ? (255) : ( (r<0) ? (0) : r ));
newcolbuf->g = unsigned char((g > 255) ? (255) : ( (g<0) ? (0) : g ));
newcolbuf->b = unsigned char((b > 255) ? (255) : ( (b<0) ? (0) : b ));
}
colbuf++;
newcolbuf++;
}
pdwRow += lr.Pitch / 4;
}//for
}
else if( nMode == COLORIZED_USEALPHA )
{
for (yp = 0; yp < sd.Height; yp++)
{
colbuf = (KColor*)pdwRow;
newcolbuf = (KColor*)pdwRow;
for (xp = 0; xp < sd.Width; xp++)
{
if( colbuf->a != 0 )
{
newcolbuf->r = cols[0].r;
newcolbuf->g = cols[0].g;
newcolbuf->b = cols[0].b;
}
colbuf++;
newcolbuf++;
}
pdwRow += lr.Pitch / 4;
}//for
}
else if( nMode == COLORIZED_GRAY )
{
Color_RGB rgb = {cols[1].r, cols[1].g, cols[1].b};
Color_HSV hsv = RGBtoHSV(rgb);
for (yp = 0; yp < sd.Height; yp++)
{
colbuf = (KColor*)pdwRow;
newcolbuf = (KColor*)pdwRow;
for (xp = 0; xp < sd.Width; xp++)
{
//if (colbuf->a == 172)
// _oprint( "alpha : %d\n", colbuf->a );
switch ((int)(colbuf->a >> 5))
{
case 3:
case 4:
{
// 2010.04.27 nrgb값이 -가 나올때가 있어서, 적용 방식을 수정했습니다. - prodongi
/*
Color_RGB irgb = { colbuf->r, colbuf->g, colbuf->b };
Color_HSV ohsv = RGBtoHSV(irgb);
hsv.val = ohsv.val;
Color_RGB nrgb = HSVtoRGB(hsv);
// 2010.04.23 형변환 워닝 수정 - prodongi
newcolbuf->r = (unsigned char)nrgb.red;
newcolbuf->g = (unsigned char)nrgb.green;
newcolbuf->b = (unsigned char)nrgb.blue;
*/
float ratio = (float)(colbuf->r)/255.0f;
float inv_ratio = 1.0f - ratio;
newcolbuf->r = (unsigned char)((float)colbuf->r * inv_ratio + (float)rgb.red * ratio);
newcolbuf->g = (unsigned char)((float)colbuf->g * inv_ratio + (float)rgb.green * ratio);
newcolbuf->b = (unsigned char)((float)colbuf->b * inv_ratio + (float)rgb.blue * ratio);
}
break;
default:
newcolbuf->r = colbuf->r;
newcolbuf->g = colbuf->g;
newcolbuf->b = colbuf->b;
}
//0~127 사이의 알파값은 유지
if( colbuf->a >= 128 )
newcolbuf->a = 255;
colbuf++;
newcolbuf++;
}
pdwRow += lr.Pitch / 4;
}//for
}
psurfDest->UnlockRect();
}
SAFE_RELEASE(psurfSrc );
SAFE_RELEASE(psurfDest);
}
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
K3DRenderTargetDX::K3DRenderTargetDX( K3DRenderDeviceDX *dev )
{
m_bLocked = false;
m_dev = dev;
m_d3dtex = NULL;
m_pD3DDepth = NULL;
//m_pD3DDepthTex = NULL;
}
K3DRenderTargetDX::~K3DRenderTargetDX()
{
Clear();
}
void K3DRenderTargetDX::Clear()
{
SAFE_RELEASE(m_d3dtex);
SAFE_RELEASE(m_pD3DDepth);
//SAFE_RELEASE(m_pD3DDepthTex);
m_pSurface = NULL;
}
bool K3DRenderTargetDX::CreateNew( DWORD width, DWORD height, UINT nLevels, K3DFORMAT format, DWORD dwDepthUsage, bool bDepth16Bit /*=false*/ )
{
Clear();
m_nLevels = nLevels;
HRESULT res = D3DXCreateTexture( m_dev->GetD3DDevice(), width, height, m_nLevels, D3DUSAGE_RENDERTARGET,
GetD3DFormat(format), D3DPOOL_DEFAULT, &m_d3dtex );
if ( res != D3D_OK )
{
if( res == D3DERR_NOTAVAILABLE ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_NOTAVAILABLE" ); }
else if( res == D3DERR_OUTOFVIDEOMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_OUTOFVIDEOMEMORY" ); }
else if( res == D3DERR_INVALIDCALL ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_INVALIDCALL" ); }
else if( res == E_OUTOFMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "E_OUTOFMEMORY" ); }
//m_d3dtex = NULL;
//m_pSurface = NULL;
Clear();
return false;
}
//m_bUseDepth = bUseDepth;
m_dwDepthUsage = dwDepthUsage;
#ifdef _KUI_INVALIDATION
m_bDepth16Bit = bDepth16Bit;
#endif
D3DSURFACE_DESC desc;
m_d3dtex->GetLevelDesc( 0, &desc );
m_size.width = desc.Width;
m_size.height = desc.Height;
m_format = static_cast<K3DFORMAT>(desc.Format);
if( dwDepthUsage == DEPTH_ENABLE )
{
if( bDepth16Bit )
{
res = m_dev->GetD3DDevice()->CreateDepthStencilSurface( m_size.width, m_size.height,
D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, TRUE, &m_pD3DDepth, NULL );
}
else
{
res = m_dev->GetD3DDevice()->CreateDepthStencilSurface( m_size.width, m_size.height,
D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &m_pD3DDepth, NULL );
}
if ( res != D3D_OK )
{
Clear();
return false;
}
}
// if( dwDepthUsage == DEPTH_ENABLE || dwDepthUsage == DEPTH_USEASTEXTURE)
// {
// //ATI 계열은 D3DFMT_D24X8, D3DFMT_D24S8 만들 수 없다.
// res = m_dev->GetD3DDevice()->CreateTexture( width, height, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_D24X8, D3DPOOL_DEFAULT, &m_pD3DDepth, NULL );
//// res = m_dev->GetD3DDevice()->CreateTexture( width, height, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_D24S8, D3DPOOL_DEFAULT, &m_pD3DDepth, NULL );
// if ( res != D3D_OK )
// {
// Clear();
// return false;
// }
// }
//if( dwDepthUsage == DEPTH_USEASTEXTURE )
//{
// m_pSurface = m_pD3DDepth;
//}
//else
//{
m_pSurface = m_d3dtex;
//}
return true;
}
bool K3DRenderTargetDX::IsValid() const
{
return m_d3dtex ? true : false;
}
void K3DRenderTargetDX::LockRect( KRect *rect, void** ppBuf, int& stride )
{
*ppBuf = NULL;
stride = 0;
}
void K3DRenderTargetDX::Unlock()
{
}
void K3DRenderTargetDX::CopyTo( K3DTexture *pTex )
{
LPDIRECT3DDEVICE9 d3ddev = m_dev->GetD3DDevice();
LPDIRECT3DSURFACE9 src, dst;
m_d3dtex->GetSurfaceLevel( 0, &src );
K3DTextureDX *pDXTex = reinterpret_cast<K3DTextureDX*>(pTex);
pDXTex->GetD3DTexture()->GetSurfaceLevel( 0, &dst );
HRESULT hr;
hr = d3ddev->StretchRect( src, NULL, dst, NULL, D3DTEXF_NONE );
assert( hr == S_OK );
SAFE_RELEASE(src);
SAFE_RELEASE(dst);
}
K3DTexture *K3DRenderTargetDX::CreateCloneTexture()
{
K3DTexture *pTex = m_dev->CreateTexture( GetWidth(), GetHeight(), GetFormat() );
CopyTo( pTex );
return pTex;
}
bool K3DRenderTargetDX::PreReload()
{
Clear();
return true;
}
bool K3DRenderTargetDX::Reload()
{
#ifdef _KUI_INVALIDATION
CreateNew( m_size.width, m_size.height, m_nLevels, m_format, m_dwDepthUsage, m_bDepth16Bit );
#else
CreateNew( m_size.width, m_size.height, m_nLevels, m_format, m_dwDepthUsage );
#endif
return true;
}
bool K3DRenderTargetDX::SaveToFile( const std::string& strFile )
{
if( D3DXSaveTextureToFile( strFile.c_str(), D3DXIFF_DDS, m_d3dtex, NULL ) == D3D_OK ) return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
///CubeTexture
K3DRenderTargetCubeDX::K3DRenderTargetCubeDX( K3DRenderDeviceDX* dev ) : m_dev( dev ),
m_d3dcubetex( NULL ),
m_pD3DDepth( NULL ),
m_bLocked( false )
{
}
K3DRenderTargetCubeDX::~K3DRenderTargetCubeDX()
{
Clear();
}
void K3DRenderTargetCubeDX::Clear()
{
SAFE_RELEASE(m_d3dcubetex);
SAFE_RELEASE(m_pD3DDepth);
m_pSurface = NULL;
}
bool K3DRenderTargetCubeDX::CreateNew( DWORD size, UINT nLevels, K3DFORMAT format, DWORD dwDepthUsage )
{
Clear();
m_nLevels = nLevels;
HRESULT res = D3DXCreateCubeTexture( m_dev->GetD3DDevice(), size, m_nLevels, D3DUSAGE_RENDERTARGET,
GetD3DFormat(format), D3DPOOL_DEFAULT, &m_d3dcubetex );
if ( res != D3D_OK )
{
if( res == D3DERR_NOTAVAILABLE ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_NOTAVAILABLE" ); }
else if( res == D3DERR_OUTOFVIDEOMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_OUTOFVIDEOMEMORY" ); }
else if( res == D3DERR_INVALIDCALL ) { _oprint( "***DEVICE ERROR : %s\n", "D3DERR_INVALIDCALL" ); }
else if( res == E_OUTOFMEMORY ) { _oprint( "***DEVICE ERROR : %s\n", "E_OUTOFMEMORY" ); }
Clear();
return false;
}
m_dwDepthUsage = dwDepthUsage;
D3DSURFACE_DESC desc;
m_d3dcubetex->GetLevelDesc( 0, &desc );
m_size.width = desc.Width;
m_size.height = desc.Height;
m_format = static_cast<K3DFORMAT>(desc.Format);
if( dwDepthUsage == DEPTH_ENABLE )
{
res = m_dev->GetD3DDevice()->CreateDepthStencilSurface( m_size.width, m_size.height,
D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &m_pD3DDepth, NULL );
if ( res != D3D_OK )
{
Clear();
return false;
}
}
m_pSurface = m_d3dcubetex;
return true;
}
bool K3DRenderTargetCubeDX::IsValid() const
{
return m_d3dcubetex ? true : false;
}
void K3DRenderTargetCubeDX::LockRect( KRect *rect, void** ppBuf, int& stride )
{
*ppBuf = NULL;
stride = 0;
}
void K3DRenderTargetCubeDX::Unlock()
{
}
void K3DRenderTargetCubeDX::CopyTo( K3DTexture *pTex )
{
K3DRenderTargetCubeDX *pDXCubeTex = reinterpret_cast<K3DRenderTargetCubeDX*>(pTex);
for( int nCubeface = 0; nCubeface < 6; ++nCubeface )
GetCubeMapSurface( pDXCubeTex, (D3DCUBEMAP_FACES)nCubeface );
}
void K3DRenderTargetCubeDX::GetCubeMapSurface( K3DRenderTargetCubeDX* pCubeTexture, D3DCUBEMAP_FACES cubeFace )
{
LPDIRECT3DDEVICE9 d3ddev = m_dev->GetD3DDevice();
LPDIRECT3DSURFACE9 src, dst;
m_d3dcubetex->GetCubeMapSurface( cubeFace, 0, &src );
pCubeTexture->GetD3DCubeTexture()->GetCubeMapSurface( cubeFace, 0, &dst );
HRESULT hr;
hr = d3ddev->StretchRect( src, NULL, dst, NULL, D3DTEXF_NONE );
assert( hr == S_OK );
SAFE_RELEASE(src);
SAFE_RELEASE(dst);
}
K3DTexture *K3DRenderTargetCubeDX::CreateCloneTexture()
{
K3DTexture *pTex = m_dev->CreateTexture( GetWidth(), GetHeight(), GetFormat() );
CopyTo( pTex );
return pTex;
}
bool K3DRenderTargetCubeDX::PreReload()
{
Clear();
return true;
}
bool K3DRenderTargetCubeDX::Reload()
{
CreateNew( m_size.width, m_nLevels, m_format, m_dwDepthUsage );
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//IndexBufferDX
K3DIndexBufferDX::K3DIndexBufferDX( K3DRenderDeviceDX *dev )
{
m_dev = dev;
m_bLocked = false;
m_d3dib = NULL;
}
K3DIndexBufferDX::~K3DIndexBufferDX()
{
if ( m_bLocked ) Unlock();
SAFE_RELEASE(m_d3dib);
}
bool K3DIndexBufferDX::Initialize( KStream &stream, int count, bool use32bit )
{
int formatsize;
int fmt;
if ( use32bit )
{
formatsize = 4;
fmt = D3DFMT_INDEX32;
}
else
{
formatsize = 2;
fmt = D3DFMT_INDEX16;
}
HRESULT hr = m_dev->GetD3DDevice()->CreateIndexBuffer(
count * formatsize, D3DUSAGE_WRITEONLY, static_cast<D3DFORMAT>(fmt), D3DPOOL_MANAGED, &m_d3dib, NULL );
unsigned char *pBuf;
if( hr == D3D_OK )
{
m_d3dib->Lock( 0, count * formatsize, (void**)&pBuf, 0 );
assert(pBuf && "m_d3dib->Lock( 0, count * formatsize, (void**)&pBuf, 0 );");
stream.Read( pBuf, count * formatsize );
m_d3dib->Unlock();
SetValidVtx( true );
m_format = static_cast<K3DFORMAT>(fmt);
m_idxCount = count;
return true;
}
return false;
}
bool K3DIndexBufferDX::CreateNew( int count, bool use32bit )
{
int formatsize;
int fmt;
if ( use32bit )
{
formatsize = 4;
fmt = D3DFMT_INDEX32;
}
else
{
formatsize = 2;
fmt = D3DFMT_INDEX16;
}
m_format = static_cast<K3DFORMAT>(fmt);
m_idxCount = count;
HRESULT hr = m_dev->GetD3DDevice()->CreateIndexBuffer(
count * formatsize, D3DUSAGE_WRITEONLY, static_cast<D3DFORMAT>(fmt), D3DPOOL_MANAGED, &m_d3dib, NULL );
if( hr == D3D_OK )
{
SetValidVtx( true );
return true;
}
return false;
}
void K3DIndexBufferDX::Lock( void** ppBuf, int& size, DWORD flags )
{
if ( m_bLocked == false && m_d3dib != NULL )
{
//int formatsize = (m_format == K3DFMT_INDEX16) ? 2 : 4;
if ( m_d3dib->Lock( 0, 0, ppBuf, flags ) == D3D_OK )
{
m_bLocked = true;
}
}
else
{
ppBuf = NULL;
}
}
void K3DIndexBufferDX::Unlock()
{
if ( m_bLocked == true )
{
m_d3dib->Unlock();
m_bLocked = false;
}
}
bool K3DIndexBufferDX::PreReload()
{
return true;
}
bool K3DIndexBufferDX::Reload()
{
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//#define _VB_DEBUG_
#ifdef _VB_DEBUG_
volatile int g_nVB_RefCount = 0;
#endif
K3DVertexBufferDX::K3DVertexBufferDX()
{
#ifdef _VB_DEBUG_
InterlockedIncrement( (volatile LONG *)&g_nVB_RefCount );
// _performance_print( "K3DVertexBufferDX 01 : %d\n", g_nVB_RefCount );
#endif
m_usage = D3DUSAGE_WRITEONLY;
m_type = RESTYPE_VERTEXBUFFER;
m_dev = NULL;
m_bLocked = false;
m_d3dvb = NULL;
//Device Lost 처리
m_pBackUpBuf = NULL;
m_bIsDeviceLost = false;
}
K3DVertexBufferDX::K3DVertexBufferDX( K3DRenderDeviceDX *dev )
{
#ifdef _VB_DEBUG_
InterlockedIncrement( (volatile LONG *)&g_nVB_RefCount );
// _performance_print( "K3DVertexBufferDX 02 : %d\n", g_nVB_RefCount );
#endif
m_usage = D3DUSAGE_WRITEONLY;
m_type = RESTYPE_VERTEXBUFFER;
m_dev = dev;
m_bLocked = false;
m_d3dvb = NULL;
//Device Lost 처리
m_pBackUpBuf = NULL;
m_bIsDeviceLost = false;
}
K3DVertexBufferDX::~K3DVertexBufferDX()
{
#ifdef _VB_DEBUG_
InterlockedDecrement( (volatile LONG *)&g_nVB_RefCount );
_performance_print( "K3DVertexBufferDX ~ : %d\tStride:%d\tvtxCount:%d\tFVF:%d\tUsage:%d\n", g_nVB_RefCount, m_vtxStride, m_vtxCount, m_format, m_usage );
#endif
//백업 버퍼 삭제
SAFE_DELETE_ARRAY( m_pBackUpBuf );
SAFE_RELEASE(m_d3dvb);
if( m_bIsDeviceLost && GetRefCount() <= 1 )
m_dev->DelReloadVertexList(this);
}
void K3DVertexBufferDX::Recycle() // 재사용
{
// KResource::Recycle(); //삭제 됨
// return;
if( m_bUseRecycle )
m_dev->AddRecycleVertexBuffer( this, m_format, m_usage, m_vtxStride, m_vtxCount );
else
KResource::Recycle(); //삭제 됨
}
bool K3DVertexBufferDX::Initialize( KStream &stream, int vertexformat, int count )
{
m_format = vertexformat;
m_vtxCount = count;
m_vtxStride = K3DVertexBuffer::CalcVertexStride( vertexformat );
HRESULT hr = m_dev->GetD3DDevice()->CreateVertexBuffer(
m_vtxStride * m_vtxCount, D3DUSAGE_WRITEONLY, vertexformat, D3DPOOL_MANAGED, &m_d3dvb, NULL );
if( hr == D3D_OK )
{
unsigned char *pBuf;
m_d3dvb->Lock( 0, m_vtxStride * m_vtxCount, (void**)&pBuf, 0 );
assert(pBuf && "m_d3dvb->Lock( 0, m_vtxStride * m_vtxCount, (void**)&pBuf, 0 );");
stream.Read( pBuf, m_vtxStride * m_vtxCount );
m_d3dvb->Unlock();
SetValidVtx( true );
}
return true;
}
bool K3DVertexBufferDX::CreateNewSpeedTree( unsigned int nStride, DWORD Usage, int count, int vertexformat )
{
m_bIsDeviceLost = true;
m_usage = Usage;
m_format = vertexformat;
m_vtxCount = count;
m_vtxStride = nStride;
m_type = RESTYPE_VERTEXBUFFERSPEEDTREE;
HRESULT hr;
if(m_usage & D3DUSAGE_DYNAMIC)
m_Pool = D3DPOOL_DEFAULT;
else
m_Pool = D3DPOOL_MANAGED;
hr = m_dev->GetD3DDevice()->CreateVertexBuffer( nStride * m_vtxCount, m_usage, vertexformat, m_Pool, &m_d3dvb, NULL );
if( hr == D3D_OK )
SetValidVtx( true );
return true;
}
bool K3DVertexBufferDX::CreateNewSpeedGrass( unsigned int nStride, DWORD Usage, int count, int vertexformat )
{
m_bIsDeviceLost = true;
m_usage = Usage;
m_format = vertexformat;
m_vtxCount = count;
m_vtxStride = nStride;
m_type = RESTYPE_VERTEXBUFFERSPEEDGRASS;
HRESULT hr;
if(m_usage & D3DUSAGE_DYNAMIC)
m_Pool = D3DPOOL_DEFAULT;
else
m_Pool = D3DPOOL_MANAGED;
hr = m_dev->GetD3DDevice()->CreateVertexBuffer( nStride * m_vtxCount, m_usage, vertexformat, m_Pool, &m_d3dvb, NULL );
if( hr == D3D_OK )
SetValidVtx( true );
return true;
}
//Blend 용 버텍스~
bool K3DVertexBufferDX::CreateNewBlend( unsigned int nStride, int count, int vertexformat )
{
m_format = vertexformat;
m_vtxCount = count;
m_vtxStride = nStride;
m_Pool = D3DPOOL_MANAGED;
HRESULT hr = m_dev->GetD3DDevice()->CreateVertexBuffer( nStride * m_vtxCount, m_usage, vertexformat, D3DPOOL_MANAGED, &m_d3dvb, NULL );
m_type = RESTYPE_VERTEXBUFFERBLEND;
if( hr == D3D_OK )
SetValidVtx( true );
return true;
}
bool K3DVertexBufferDX::CreateNewPoolDefault( unsigned int nStride, int count, int vertexformat, DWORD Usage )
{
m_format = vertexformat;
m_vtxCount = count;
m_vtxStride = nStride;
m_usage = Usage;
m_Pool = D3DPOOL_DEFAULT;
HRESULT hr = m_dev->GetD3DDevice()->CreateVertexBuffer( nStride * m_vtxCount, m_usage, vertexformat, D3DPOOL_DEFAULT, &m_d3dvb, NULL );
m_type = RESTYPE_VERTEXBUFFERPOOLDEFAULT;
if( hr == D3D_OK )
SetValidVtx( true );
return true;
}
bool K3DVertexBufferDX::CreateNew( int vertexformat, int count )
{
m_format = vertexformat;
m_vtxCount = count;
m_vtxStride = K3DVertexBuffer::CalcVertexStride( vertexformat );
m_Pool = D3DPOOL_MANAGED;
HRESULT hr = m_dev->GetD3DDevice()->CreateVertexBuffer(
m_vtxStride * m_vtxCount, D3DUSAGE_WRITEONLY, vertexformat, D3DPOOL_MANAGED, &m_d3dvb, NULL );
if( hr == D3D_OK )
SetValidVtx( true );
return true;
}
void K3DVertexBufferDX::Lock( void** pBuf, int& size, DWORD flags )
{
if ( m_bLocked == false && m_d3dvb != NULL )
{
if ( m_d3dvb->Lock( 0, 0, pBuf, flags ) == D3D_OK )
m_bLocked = true;
}
else
{
*pBuf = NULL;
}
}
void K3DVertexBufferDX::Unlock()
{
if ( m_bLocked == true && m_d3dvb )
{
m_d3dvb->Unlock();
m_bLocked = false;
}
}
bool K3DVertexBufferDX::Backup()
{
//버퍼에 백업..
int nSize = m_vtxCount*m_vtxStride;
SAFE_DELETE_ARRAY( m_pBackUpBuf );
m_pBackUpBuf = new char[nSize];
memset( m_pBackUpBuf, 0, sizeof(char)*nSize );
void *pTempBuf = NULL;
if(m_usage & D3DUSAGE_DYNAMIC)
Lock( (void**)&pTempBuf, nSize, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD );
else
Lock( (void**)&pTempBuf, nSize );
if( pTempBuf )
{
memcpy( m_pBackUpBuf, pTempBuf, sizeof(char)*nSize );
Unlock();
}
return true;
}
bool K3DVertexBufferDX::PreReload()
{
SAFE_RELEASE(m_d3dvb);
return true;
}
bool K3DVertexBufferDX::Reload()
{
//백업 버퍼로 복구
int nSize = m_vtxCount*m_vtxStride;
void *pTempBuf = NULL;
if( m_type == RESTYPE_VERTEXBUFFERSPEEDGRASS || m_type == RESTYPE_VERTEXBUFFERSPEEDTREE )
{
CreateNewSpeedTree( m_vtxStride, m_usage, m_vtxCount, m_format );
Lock( (void**)&pTempBuf, nSize );
}
else if ( m_type == RESTYPE_VERTEXBUFFERPOOLDEFAULT )
{
CreateNewPoolDefault( m_vtxStride, m_vtxCount, m_format, m_usage );
Lock( (void**)&pTempBuf, nSize, D3DLOCK_NOOVERWRITE );
if( pTempBuf == NULL )
Lock( (void**)&pTempBuf, nSize, D3DLOCK_DISCARD );
}
if( pTempBuf && m_pBackUpBuf )
{
memcpy( pTempBuf, m_pBackUpBuf, sizeof(char)*nSize );
}
Unlock();
return true;
}