/*
D3D9渲染系统
Copyright (C) 2006 彭爱峰
http://fdyjfd.cnblogs.com/
*/
#include "Spark_Direct3D9_D3D9RenderSystem.h"
#include "Spark_Direct3D9_D3D9Mapping.h"
#include "Spark_Direct3D9_D3D9InputLayout.h"
#include "Spark_Direct3D9_D3D9RasterizerState.h"
#include "Spark_Direct3D9_D3D9DepthStencilState.h"
#include "Spark_Direct3D9_D3D9BlendState.h"
#include "Spark_Direct3D9_D3D9SamplerState.h"
#include "Spark_Direct3D9_D3D9VertexBuffer.h"
#include "Spark_Direct3D9_D3D9IndexBuffer.h"
#include "Spark_Direct3D9_D3D9Texture.h"
#include "Spark_Direct3D9_D3D9VertexShader.h"
#include "Spark_Direct3D9_D3D9PixelShader.h"
#include "Spark_Direct3D9_D3D9FixedFunctionVertexShader.h"
#include "Spark_Direct3D9_D3D9FixedFunctionPixelShader.h"
#include "Spark_Direct3D9_D3D9ShaderParameter.h"
#include "..\Graphics\Spark_Graphics_Mesh.h"
#include "..\Graphics\Spark_Graphics_RenderParameter.h"
#include "..\Utility\Spark_Utility_New.h"
#ifdef _DEBUG
#define new SPARK_DEBUG_NEW
#endif
BEGIN_SPARK
bool CompareD3D9InputLayout::operator()(const D3D9InputLayout* p1, const D3D9InputLayout* p2) const
{
if(p1->m_NumVertexElements == p2->m_NumVertexElements)
{
return memcmp(p1->m_pVertexElement, p2->m_pVertexElement, sizeof(D3D9RENDERSTATE)*p1->m_NumVertexElements) < 0;
}
return p1->m_NumVertexElements < p2->m_NumVertexElements;
}
bool CompareD3D9RasterizerState::operator()(const D3D9RasterizerState* p1, const D3D9RasterizerState* p2) const
{
if(p1->m_NumRenderStates == p2->m_NumRenderStates)
{
return memcmp(p1->m_RenderStates, p2->m_RenderStates, sizeof(D3D9RENDERSTATE)*p1->m_NumRenderStates) < 0;
}
return p1->m_NumRenderStates < p2->m_NumRenderStates;
}
bool CompareD3D9DepthStencilState::operator()(const D3D9DepthStencilState* p1, const D3D9DepthStencilState* p2) const
{
if(p1->m_NumRenderStates == p2->m_NumRenderStates)
{
return memcmp(p1->m_RenderStates, p2->m_RenderStates, sizeof(D3D9RENDERSTATE)*p1->m_NumRenderStates) < 0;
}
return p1->m_NumRenderStates < p2->m_NumRenderStates;
}
bool CompareD3D9BlendState::operator()(const D3D9BlendState* p1, const D3D9BlendState* p2) const
{
if(p1->m_NumRenderStates == p2->m_NumRenderStates)
{
return memcmp(p1->m_RenderStates, p2->m_RenderStates, sizeof(D3D9RENDERSTATE)*p1->m_NumRenderStates) < 0;
}
return p1->m_NumRenderStates < p2->m_NumRenderStates;
}
bool CompareD3D9SamplerState::operator()(const D3D9SamplerState* p1, const D3D9SamplerState* p2) const
{
if(p1->m_NumSamplerStates == p2->m_NumSamplerStates)
{
return memcmp(p1->m_SamplerStates, p2->m_SamplerStates, sizeof(D3D9SAMPLERSTATE)*p1->m_NumSamplerStates) < 0;
}
return p1->m_NumSamplerStates < p2->m_NumSamplerStates;
}
bool CompareD3D9VertexShader::operator()(const D3D9VertexShader* p1, const D3D9VertexShader* p2) const
{
if(p1->m_CodeSize == p2->m_CodeSize)
{
return memcmp(p1->m_pCode, p2->m_pCode, p1->m_CodeSize) < 0;
}
return p1->m_CodeSize < p2->m_CodeSize;
}
bool CompareD3D9PixelShader::operator()(const D3D9PixelShader* p1, const D3D9PixelShader* p2) const
{
if(p1->m_CodeSize == p2->m_CodeSize)
{
return memcmp(p1->m_pCode, p2->m_pCode, p1->m_CodeSize) < 0;
}
return p1->m_CodeSize < p2->m_CodeSize;
}
////////////////////////////////////////////////////////////////////////////////
D3D9RenderSystem::D3D9RenderSystem(IDirect3DDevice9* pDevice, const D3D9DeviceDesc& deviceDesc)
: m_pDevice(pDevice), m_EffectCompiler(this)
{
SPARK_ASSERT(0 != m_pDevice);
m_DeviceDesc = deviceDesc;
InitializeDefaultStates();
m_NumChangedBlendStates = 0;
m_NumChangedDepthStencilStates = 0;
m_NumChangedRasterizerStates = 0;
m_NumChangedFixedFunctionVertexShaderRenderStates = 0;
m_NumChangedFixedFunctionPixelShaderRenderStates = 0;
m_NumChangedTextureStageStates = 0;
m_pLastMesh = 0;
m_pLastVertexShader = 0;
m_pLastPixelShader = 0;
for(uint_t i = 0; i < D3D9_NUM_TEXTURE_STAGES; ++i)
{
m_ppLastTexture[i] = 0;
}
m_NumLastTextures = 0;
for(uint_t i = 0; i < D3D9_NUM_STREAMS; ++i)
{
m_ppLastVertexBuffer[i] = 0;
}
m_pLastIndexBuffer = 0;
m_pLastInputLayout = 0;
m_pLastRasterizerState = 0;
m_pLastDepthStencilState = 0;
m_pLastBlendState = 0;
for(uint_t i = 0; i < D3D9_NUM_SAMPLER_STAGES; ++i)
{
m_NumChangedSamplerStates[i] = 0;
m_ppLastSamplerState[i] = 0;
}
m_LastNumSamplerStage = 0;
}
D3D9RenderSystem::~D3D9RenderSystem()
{
}
EffectCompiler* D3D9RenderSystem::GetEffectCompiler()
{
return &m_EffectCompiler;
}
InputLayout* D3D9RenderSystem::CreateInputLayout(const InputElementDesc * pInputElementDescs, uint_t numElements, const void * pShaderBytecodeWithInputSignature)
{
//将InputElementDesc映射到D3DVERTEXELEMENT9
const size_t MAX_NUM_VERTEXELEMENTS = 64;
SPARK_ASSERT(numElements < MAX_NUM_VERTEXELEMENTS);
const D3DVERTEXELEMENT9 d3ddeclEnd = D3DDECL_END();
D3DVERTEXELEMENT9 vertexElements[MAX_NUM_VERTEXELEMENTS];
for(uint_t i = 0; i < numElements; ++i)
{
D3D9Mapping::Mapping(vertexElements[i], pInputElementDescs[i]);
}
vertexElements[numElements] = d3ddeclEnd;
//检查是否有相同的InputLayout
byte_t dummyInputLayout[sizeof(D3D9InputLayout)];
D3D9InputLayout* pDummyInputLayout = (D3D9InputLayout*)dummyInputLayout;
pDummyInputLayout->m_NumVertexElements = numElements + 1;
pDummyInputLayout->m_pVertexElement = vertexElements;
D3D9InputLayoutContainer::iterator it = m_D3D9InputLayouts.find(pDummyInputLayout);
if(m_D3D9InputLayouts.end() == it)
{
//返回新的InputLayout
IDirect3DVertexDeclaration9* pVertexDeclaration;
HRESULT hr = m_pDevice->CreateVertexDeclaration(vertexElements, &pVertexDeclaration);
SPARK_ASSERT(SUCCEEDED(hr));
return new D3D9InputLayout(this, pVertexDeclaration, vertexElements, numElements + 1);
}
else
{
//返回已有的InputLayout
D3D9InputLayout* pInputLayout = *it;
pInputLayout->AddRef();
return pInputLayout;
}
}
RasterizerState* D3D9RenderSystem::CreateRasterizerState(const RasterizerDesc& desc)
{
D3D9RasterizerDesc d3dDesc;
D3D9Mapping::Mapping(d3dDesc, desc);
byte_t dummyRasterizerState[sizeof(D3D9RasterizerState)];
D3D9RasterizerState* pDummyRasterizerState = (D3D9RasterizerState*)dummyRasterizerState;
D3D9RENDERSTATE* pRenderState = pDummyRasterizerState->m_RenderStates;
if(GetDefaultRenderState(D3DRS_FILLMODE) != d3dDesc.fillMode)
{
pRenderState->type = D3DRS_FILLMODE;
pRenderState->value = d3dDesc.fillMode;
++pRenderState;
}
if(GetDefaultRenderState(D3DRS_CULLMODE) != d3dDesc.cullMode)
{
pRenderState->type = D3DRS_CULLMODE;
pRenderState->value = d3dDesc.cullMode;
++pRenderState;
}
if(GetDefaultRenderState(D3DRS_DEPTHBIAS) != d3dDesc.depthBias)
{
pRenderState->type = D3DRS_DEPTHBIAS;
pRenderState->value = d3dDesc.depthBias;
++pRenderState;
}
if(GetDefaultRenderState(D3DRS_SLOPESCALEDEPTHBIAS) != d3dDesc.slopeScaledDepthBias)
{
pRenderState->type = D3DRS_SLOPESCALEDEPTHBIAS;
pRenderState->value = d3dDesc.slopeScaledDepthBias;
++pRenderState;
}
if(GetDefaultRenderState(D3DRS_SCISSORTESTENABLE) != d3dDesc.scissorEnable)
{
pRenderState->type = D3DRS_SCISSORTESTENABLE;
pRenderState->value = d3dDesc.scissorEnable;
++pRenderState;
}
if(GetDefaultRenderState(D3DRS_MULTISAMPLEANTIALIAS) != d3dDesc.multisampleEnable)
{
pRenderState->type = D3DRS_MULTISAMPLEANTIALIAS;
pRenderState->value = d3dDesc.multisampleEnable;
++pRenderState;
}
size_t numRenderStates = pRenderState - pDummyRasterizerState->m_RenderStates;
//如果指定的参数与默认值相同同就返回空。
if(0 == numRenderStates)
{
return 0;
}
//检查是否有相同的RasterizerState
pDummyRasterizerState->m_NumRenderStates = numRenderStates;
D3D9RasterizerStateContainer::iterator it = m_D3D9RasterizerStates.find(pDummyRasterizerState);
if(m_D3D9RasterizerStates.end() == it)
{
//返回新的RasterizerState