401 lines
10 KiB
C++
401 lines
10 KiB
C++
#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<K3DFORMAT>(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;
|
|
}
|
|
|
|
|