#include "stdafx.h" /* KResourceDXDynamic.cpp Software processing용 vertex buffer Note: Resource는 아니지만 인터페이스 통일을 위해 상속함 Created 2006/04, by JiYoung */ #include "KResourceDXDynamic.h" #include "KDeviceManager.h" namespace { // Vertex buffer creation 등등등용으로, 현재의 global rendering device를 얻어옴 K3DRenderDeviceDX * renderDevice = NULL; K3DRenderDeviceDX *getCurrentRenderDevice() { /* if (renderDevice==NULL) { renderDevice = (K3DRenderDeviceDX *)KDeviceManagerDX::GetDeviceManager()->GetRenderDevice(); } return renderDevice; */ return (K3DRenderDeviceDX *)KDeviceManagerDX::GetDeviceManager()->GetRenderDevice(); } } //------------------------------------------- // DynamicVertex vertex format declaration //------------------------------------------- /* const D3DVERTEXELEMENT9 DynamicVertex_old::vertexDeclaration[] = { { 0, 0, D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION , 0 },//size=12 { 0, 12, D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL , 0 },//size=12 { 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR , 0 },//size=4 { 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR , 1 },//size=4 { 0, 32, D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 0 },//size=8 { 0, 40, D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 1 },//size=8 { 0, 48, D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 2 },//size=8 { 0, 56, D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 3 },//size=8 D3DDECL_END() }; */ const D3DVERTEXELEMENT9 DynamicVertex::vertexDeclaration[] = { { 0, 0, D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION , 0 },//size=12 { 0, 12, D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL , 0 },//size=12 { 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR , 0 },//size=4 { 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR , 1 },//size=4 { 0, 32, D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 0 },//size=8 { 0, 40, D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD , 1 },//size=8 { 0, 48, D3DDECLTYPE_UBYTE4 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES , 0 },//size=4 { 0, 52, D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT , 0 },//size=12 D3DDECL_END() }; //------------------------------------------- // Vertex Buffer //------------------------------------------- KVertexBufferDX_dynamic::KVertexBufferDX_dynamic() : K3DVertexBufferDX() { m_bUseRecycle = false; m_bufferSize=0; vertexBuffer=NULL; m_autoDataPreserve=false; // Device lost시 reload()되는 경우, 버퍼의 데이터를 자동으로 refresh한다 m_pDataPreserveBuffer=NULL; // m_autoDataPreserver==true인 경우 Lock()/Unlock()시에 여기다 데이터를 dump한다 m_pLockedPosition=NULL; // Lock()시 ppBuf에 return한 pointer. i.e. !=NULL이면 Lock()된 상태이다. Unlock()에서 NULL로 reset한다 m_bHaveToReloadBuffer=false; } KVertexBufferDX_dynamic::~KVertexBufferDX_dynamic() { clear(); } // Inherited void KVertexBufferDX_dynamic::Lock( void** ppBuf, int& size, DWORD flags) { assert(m_pLockedPosition==NULL); // 두 번 lock방지 if (vertexBuffer==NULL) { *ppBuf=NULL; return; } if ( FAILED( vertexBuffer->Lock( 0, size, ppBuf, flags ) ) ) { *ppBuf=NULL; return; } m_pLockedPosition=*ppBuf; } void KVertexBufferDX_dynamic::Unlock() { if (m_pLockedPosition==NULL) return; // Not locked if (vertexBuffer!=NULL) { vertexBuffer->Unlock(); if (m_autoDataPreserve) { assert(m_pDataPreserveBuffer!=NULL); // Copy buffer memcpy(m_pDataPreserveBuffer, m_pLockedPosition, (size_t)m_bufferSize); } m_pLockedPosition=NULL; } } bool KVertexBufferDX_dynamic::Reload() { K3DRenderDeviceDX *device=getCurrentRenderDevice(); if (device==NULL) return false; if( FAILED( device->GetD3DDevice()->CreateVertexBuffer( m_bufferSize, m_usage, m_format, m_Pool, &vertexBuffer, NULL))) { return false; } m_d3dvb=vertexBuffer; if (m_autoDataPreserve) { // Autopreserve buffer에서 데이터를 카피 void *pBuf; int size=0; Lock(&pBuf, size); if (pBuf!=NULL) { memcpy(pBuf, m_pDataPreserveBuffer, (size_t)m_bufferSize); } Unlock(); } else { // Reload flag설정 m_bHaveToReloadBuffer=true; } return true; } bool KVertexBufferDX_dynamic::PreReload() { m_d3dvb = NULL; // Note : m_d3dvb는 dynamic-vertex-buffer에서는 managed resource가 아니다. So just set to NULL. // SAFE_RELEASE(m_d3dvb); // <- 이거 하면 큰일남 :) if (vertexBuffer!=NULL) { vertexBuffer->Release(); vertexBuffer=NULL; } return true; } // original bool KVertexBufferDX_dynamic::create(UINT length, DWORD usage, DWORD FVF, D3DPOOL pool, bool autoPreserve) // See IDirect3DDevice9::CreateVertexBuffer() for parameters { //clear(); m_d3dvb=NULL; if (vertexBuffer!=NULL) { vertexBuffer->Release(); vertexBuffer=NULL; } K3DRenderDeviceDX *device=getCurrentRenderDevice(); if (device==NULL) return false; if( FAILED( device->GetD3DDevice()->CreateVertexBuffer( length, usage, FVF, pool, &vertexBuffer, NULL))) { return false; } m_bufferSize=length; m_usage = usage; m_format = FVF; m_vtxStride = K3DVertexBuffer::CalcVertexStride( m_format ); m_vtxCount = length/sizeof(DynamicVertex); m_Pool = pool; // WORKAROUND : m_d3dvb는 리소스이지만, 이게 세팅되어 있지 않으면 렌더링이 안 된다 // 나중에 RELEASE()하지 말고 그냥 NULL세팅할 것 m_d3dvb=vertexBuffer; // DeviceLost용 callback device->AddLostVertexBuffer( this ); // Autopreserve buffer if (autoPreserve) { m_pDataPreserveBuffer=new char[m_bufferSize]; m_autoDataPreserve=true; } return true; } bool KVertexBufferDX_dynamic::clear() // Release(); { K3DRenderDeviceDX *device=getCurrentRenderDevice(); if (device) { // DeviceLost용 callback chain에서 삭제 device->RemoveLostVertexBuffer( this ); } // Free the vertex buffer m_d3dvb=NULL; if (vertexBuffer!=NULL) { vertexBuffer->Release(); vertexBuffer=NULL; } // Free the AutoPreserve buffer SAFE_DELETE(m_pDataPreserveBuffer); m_autoDataPreserve=false; m_pLockedPosition=NULL; m_bHaveToReloadBuffer=false; return true; } //------------------------------------------- // Index Buffer //------------------------------------------- KIndexBufferDX_dynamic::KIndexBufferDX_dynamic() : K3DIndexBufferDX(NULL) { m_bufferSize=0; indexBuffer=NULL; m_autoDataPreserve=false; // Device lost시 reload()되는 경우, 버퍼의 데이터를 자동으로 refresh한다 m_pDataPreserveBuffer=NULL; // m_autoDataPreserver==true인 경우 Lock()/Unlock()시에 여기다 데이터를 dump한다 m_pLockedPosition=NULL; // Lock()시 ppBuf에 return한 pointer. i.e. !=NULL이면 Lock()된 상태이다. Unlock()에서 NULL로 reset한다 m_bHaveToReloadBuffer=false; } KIndexBufferDX_dynamic::~KIndexBufferDX_dynamic() { clear(); } // Inherited void KIndexBufferDX_dynamic::Lock( void** ppBuf, int& size, DWORD flags ) { if (indexBuffer==NULL) { *ppBuf=NULL; return; } if ( FAILED( indexBuffer->Lock( 0, size, ppBuf, flags ) ) ) { *ppBuf=NULL; return; } m_pLockedPosition=*ppBuf; } void KIndexBufferDX_dynamic::Unlock() { if (m_pLockedPosition==NULL) return; // Not locked if (indexBuffer!=NULL) { indexBuffer->Unlock(); if (m_autoDataPreserve) { assert(m_pDataPreserveBuffer!=NULL); // Copy buffer memcpy(m_pDataPreserveBuffer, m_pLockedPosition, (size_t)m_bufferSize); } m_pLockedPosition=NULL; } } bool KIndexBufferDX_dynamic::Reload() { K3DRenderDeviceDX *device=getCurrentRenderDevice(); if (device==NULL) return false; if( FAILED( device->GetD3DDevice()->CreateIndexBuffer( m_bufferSize, m_usage, (D3DFORMAT)m_format, m_Pool, &indexBuffer, NULL))) { return false; } m_d3dib=indexBuffer; if (m_autoDataPreserve) { // Autopreserve buffer에서 데이터를 카피 void *pBuf; int size=0; Lock(&pBuf, size); if (pBuf!=NULL) { memcpy(pBuf, m_pDataPreserveBuffer, (size_t)m_bufferSize); } Unlock(); } else { // Reload flag설정 m_bHaveToReloadBuffer=true; } return true; } bool KIndexBufferDX_dynamic::PreReload() { m_d3dib=NULL; // Note : m_d3dib는 dynamic-indextex-buffer에서는 managed resource가 아니다. So just set to NULL. // SAFE_RELEASE(m_d3dib); // <- 이거 하면 큰일남 :) if (indexBuffer!=NULL) { indexBuffer->Release(); indexBuffer=NULL; } return true; } // original bool KIndexBufferDX_dynamic::create(UINT length, DWORD usage, D3DFORMAT format, D3DPOOL pool, bool autoPreserve) // See IDirect3DDevice9::CreateIndexBuffer() for parameters { // clear(); m_d3dib=NULL; if (indexBuffer!=NULL) { indexBuffer->Release(); indexBuffer=NULL; } K3DRenderDeviceDX *device=getCurrentRenderDevice(); if (device==NULL) return false; if( FAILED( device->GetD3DDevice()->CreateIndexBuffer( length, usage, format, pool, &indexBuffer, NULL))) { return false; } m_bufferSize= length; m_vtxStride = sizeof(DWORD); m_idxCount = length/sizeof(DWORD); m_format = static_cast(format); m_usage = usage; m_Pool = pool; // WORKAROUND : m_d3dib는 리소스이지만, 이게 세팅되어 있지 않으면 렌더링이 안 된다 // 나중에 RELEASE()하지 말고 그냥 NULL세팅할 것 m_d3dib=indexBuffer; //DeviceLost용 callback chain에 register device->AddLostIndexBuffer( this ); // Autopreserve buffer if (autoPreserve) { m_pDataPreserveBuffer=new char[m_bufferSize]; m_autoDataPreserve=true; } return true; } bool KIndexBufferDX_dynamic::clear() // Release(); { K3DRenderDeviceDX *device=getCurrentRenderDevice(); if (device) { //DeviceLost용 callback chain에서 삭제 device->RemoveLostIndexBuffer( this ); } m_d3dib=NULL; if (indexBuffer!=NULL) { indexBuffer->Release(); indexBuffer=NULL; } // Free the AutoPreserve buffer SAFE_DELETE(m_pDataPreserveBuffer); m_autoDataPreserve=false; m_pLockedPosition=NULL; m_bHaveToReloadBuffer=false; return true; }