811 lines
24 KiB
C++
811 lines
24 KiB
C++
#include "stdafx.h"
|
|
#include "RCKShader.h"
|
|
#include "ShaderManager.h"
|
|
|
|
#if defined(_XBOX) && (_XBOX_VER<200)
|
|
#include <XGraphics.h>
|
|
#include <XGMath.h>
|
|
#include "CKDX8Rasterizer.h"
|
|
char* FourCC2String(DWORD fcc);
|
|
BOOL gRestoreConstantMode = FALSE;
|
|
#else
|
|
#include "CKDX9Rasterizer.h"
|
|
#define FourCC2String(a) (a)
|
|
#endif
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
RCKShader::RCKShader(ShaderManager *man) :
|
|
m_ShaderManager(man),
|
|
m_CurrTechniqueIndex(-1),
|
|
m_ShaderText("// Shader")
|
|
#if defined(MULTIPLESHADERMANAGER)
|
|
,m_ShaderName(NULL)
|
|
#endif
|
|
#if DIRECT3D_VERSION<0x0900
|
|
,m_CurrentTechnique(0)
|
|
#endif
|
|
{
|
|
//--- Initialize the DXEffect for all render context
|
|
const int rcCount = man->m_rcList.Size();
|
|
m_DXEffect.Resize(rcCount);
|
|
m_DXEffect.Fill(NULL);
|
|
|
|
//--- Allocate a ShaderDescriptor for each RenderContext
|
|
m_ShaderDescriptor.Resize(rcCount);
|
|
for( int rcIndex=0 ; rcIndex<rcCount ; ++rcIndex ){
|
|
m_ShaderDescriptor[rcIndex] = new ShaderDescriptor::Shader;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
RCKShader::~RCKShader()
|
|
{
|
|
|
|
#if DIRECT3D_VERSION<0x0900
|
|
SAFERELEASE(m_CurrentTechnique);
|
|
#endif // _XBOX
|
|
|
|
//--- Release all DXEffects for all Render Context
|
|
///// and deallocate every ShaderDescriptor of each RenderContext
|
|
const int rcCount = m_DXEffect.Size();
|
|
for( int rcIndex=0 ; rcIndex<rcCount ; ++rcIndex ){
|
|
if( m_DXEffect[rcIndex] ) SAFELASTRELEASE( m_DXEffect[rcIndex] );
|
|
delete m_ShaderDescriptor[rcIndex];
|
|
}
|
|
m_DXEffect.Clear();
|
|
m_ShaderDescriptor.Clear();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CKBOOL RCKShader::IsSupported() const
|
|
{
|
|
const int rcCount = m_DXEffect.Size();
|
|
for( int rcIndex=0 ; rcIndex<rcCount ; ++rcIndex ){
|
|
if( !m_DXEffect[rcIndex] ) return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
void RCKShader::SetText(const XString& Text){
|
|
if(m_Hide) return;
|
|
|
|
CKBOOL isTagged = Text.Contains(CKHideContentManager::GetTag());
|
|
if(Text.Contains("Please contact the Author if you want to get full access to this shader.")) {
|
|
XASSERT(m_Hide);
|
|
return;
|
|
}
|
|
|
|
if(m_Hide && (!isTagged)) {
|
|
|
|
const XString& hiddenText = CKHideContentManager::Hide(GetProtectable(), Text);
|
|
m_ShaderText = hiddenText;
|
|
delete &hiddenText;
|
|
|
|
m_Hide = TRUE;
|
|
}
|
|
else if(isTagged&&(!m_Hide)) {
|
|
m_ShaderText = Text;
|
|
m_Hide = TRUE;
|
|
}
|
|
else {
|
|
m_ShaderText = Text;
|
|
m_Hide = FALSE;
|
|
}
|
|
}
|
|
void RCKShader::SetText(const XString& Text, CK_SHADER_MANAGER_TYPE type){
|
|
if(m_Hide) return;
|
|
|
|
CKBOOL isTagged = Text.Contains(CKHideContentManager::GetTag());
|
|
if(Text.Contains("Please contact the Author if you want to get full access to this shader.")) {
|
|
XASSERT(m_Hide);
|
|
return;
|
|
}
|
|
|
|
if(m_Hide && (!isTagged)) {
|
|
|
|
const XString& hiddenText = CKHideContentManager::Hide((CKProtectable*)this, Text);
|
|
m_ShaderText = hiddenText;
|
|
delete &hiddenText;
|
|
|
|
m_Hide = TRUE;
|
|
}
|
|
else if(isTagged&&(!m_Hide)) {
|
|
m_ShaderText = Text;
|
|
m_Hide = TRUE;
|
|
}
|
|
else {
|
|
m_ShaderText = Text;
|
|
m_Hide = FALSE;
|
|
}
|
|
}
|
|
|
|
void RCKShader::SetHideFlag(CKBOOL hide) {
|
|
if(hide) {
|
|
CKBOOL isTagged = m_ShaderText.Contains(CKHideContentManager::GetTag());
|
|
if(!isTagged) {
|
|
|
|
const XString& hiddenSrc = CKHideContentManager::Hide(GetProtectable(), m_ShaderText);
|
|
m_ShaderText = hiddenSrc;
|
|
delete &hiddenSrc;
|
|
|
|
}
|
|
m_Hide = TRUE;
|
|
}
|
|
}
|
|
|
|
void RCKShader::UnLock(const char* pass) {
|
|
if(CKHideContentManager::CheckAgainst(this->GetProtectable(), pass)) {
|
|
if(m_Hide) {
|
|
|
|
const XString& clearSrc = GetTextInternal();
|
|
|
|
m_Hide = FALSE;
|
|
SetText(clearSrc);
|
|
|
|
delete &clearSrc;
|
|
}
|
|
}
|
|
}
|
|
|
|
const XString& RCKShader::GetTextInternal() const{
|
|
CKBOOL isTagged = m_ShaderText.Contains(CKHideContentManager::GetTag());
|
|
|
|
if(isTagged||m_Hide) {
|
|
return CKHideContentManager::Clarify((CKProtectable*)this, m_ShaderText);
|
|
}
|
|
else
|
|
return m_ShaderText;
|
|
}
|
|
|
|
const XString& RCKShader::GetTextInternal(CK_SHADER_MANAGER_TYPE type){
|
|
CKBOOL isTagged = m_ShaderText.Contains(CKHideContentManager::GetTag());
|
|
|
|
if(isTagged||m_Hide) {
|
|
return CKHideContentManager::Clarify(GetProtectable(), m_ShaderText);
|
|
}
|
|
else
|
|
return m_ShaderText;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
int RCKShader::Begin( CKRenderContext* rc )
|
|
{
|
|
PIXE_RENDER_L3("RCKShader::Begin");
|
|
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
UINT NumPasses;
|
|
|
|
#if DIRECT3D_VERSION<0x0900
|
|
if(!m_CurrentTechnique){
|
|
HRESULT hr = m_DXEffect[rcIndex]->GetTechnique(0,&m_CurrentTechnique);
|
|
}
|
|
XASSERT(m_CurrentTechnique);
|
|
D3DXTECHNIQUE_DESC tdesc;
|
|
HRESULT hr = m_CurrentTechnique->GetDesc(&tdesc);
|
|
NumPasses = tdesc.Passes;
|
|
#else
|
|
#ifdef _XBOX
|
|
HRESULT hr = m_DXEffect[rcIndex]->Begin( &NumPasses, D3DXFX_DONOTSAVESTATE |D3DXFX_DONOTSAVESHADERSTATE);
|
|
#else
|
|
HRESULT hr = m_DXEffect[rcIndex]->Begin( &NumPasses, 0);
|
|
#endif
|
|
|
|
#endif // _XBOX
|
|
XASSERT( SUCCEEDED(hr) );
|
|
return NumPasses;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::BeginPass( CKDWORD Num, CKRenderContext* rc )
|
|
{
|
|
PIXE_RENDER_L4("RCKShader::BeginPass");
|
|
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
#if DIRECT3D_VERSION<0x0900
|
|
XASSERT(m_CurrentTechnique);
|
|
|
|
if(Num == 0){
|
|
UINT NumPasses;
|
|
HRESULT hr = m_CurrentTechnique->Begin(&NumPasses);
|
|
}
|
|
|
|
HRESULT hr = m_CurrentTechnique->Pass(Num);
|
|
|
|
D3DSURFACE_DESC desc;
|
|
for(int i=0;i<4;i++){
|
|
LPDIRECT3DTEXTURE8 tex = NULL;
|
|
D3DDevice::GetTexture(i,(D3DBaseTexture**)&tex);
|
|
if(tex){
|
|
tex->GetLevelDesc(0,&desc);
|
|
if(VxIsSignedFormat(desc.Format)){
|
|
D3DDevice::SetTextureStageState(i,D3DTSS_COLORSIGN,D3DTSIGN_RSIGNED | D3DTSIGN_GSIGNED | D3DTSIGN_BSIGNED);
|
|
}else{
|
|
D3DDevice::SetTextureStageState(i,D3DTSS_COLORSIGN,0);
|
|
}
|
|
|
|
if(!VxIsSwizzledFormat(desc.Format)){
|
|
DWORD valU,valV;
|
|
D3DDevice::GetTextureStageState(i,D3DTSS_ADDRESSU,&valU);
|
|
D3DDevice::GetTextureStageState(i,D3DTSS_ADDRESSU,&valV);
|
|
|
|
if(valU < D3DTADDRESS_CLAMP || valV < D3DTADDRESS_CLAMP ){
|
|
rc->SetTextureStageState(CKRST_TSS_ADDRESS,VXTEXTURE_ADDRESSCLAMP,i);
|
|
}
|
|
}
|
|
tex->Release();
|
|
}
|
|
}
|
|
#else
|
|
HRESULT hr = m_DXEffect[rcIndex]->BeginPass(Num);
|
|
XASSERT(SUCCEEDED(hr));
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::EndPass( CKRenderContext* rc )
|
|
{
|
|
PIXE_RENDER_L4("RCKShader::EndPass");
|
|
|
|
#if DIRECT3D_VERSION>=0x0900
|
|
const INT rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
HRESULT hr = m_DXEffect[rcIndex]->EndPass();
|
|
XASSERT(SUCCEEDED(hr));
|
|
#else
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
if((m_ShaderManager->m_CurrentPassCount-1) == m_ShaderManager->m_CurrentPassIndex){
|
|
|
|
XASSERT(m_CurrentTechnique);
|
|
if(gRestoreConstantMode){
|
|
D3DDevice::SetVertexShaderInputDirect(NULL,0,NULL);
|
|
D3DDevice::SetShaderConstantMode(D3DSCM_96CONSTANTS);
|
|
}
|
|
|
|
m_CurrentTechnique->End();
|
|
|
|
for(int i=0;i<4;i++){
|
|
D3DDevice::SetTextureStageState(i,D3DTSS_COLORSIGN,0);
|
|
D3DDevice::SetTexture(i,NULL);
|
|
}
|
|
}
|
|
#endif // _XBOX
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::CommitChanges( CKRenderContext* rc )
|
|
{
|
|
PIXE_RENDER_L4("RCKShader::CommitChanges");
|
|
|
|
#if DIRECT3D_VERSION>=0x0900
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
HRESULT hr = m_DXEffect[rcIndex]->CommitChanges();
|
|
XASSERT(SUCCEEDED(hr));
|
|
#endif // _XBOX
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::End( CKRenderContext* rc )
|
|
{
|
|
PIXE_RENDER_L3("RCKShader::End");
|
|
|
|
#if DIRECT3D_VERSION<0x0900
|
|
HRESULT hr = S_OK;
|
|
#else
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
HRESULT hr = m_DXEffect[rcIndex]->End();
|
|
#endif // _XBOX
|
|
XASSERT(SUCCEEDED(hr));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::SetTechnique( const XString& iTechName )
|
|
{
|
|
PIXE_RENDER_L4("RCKShader::SetTechnique");
|
|
|
|
int techIndex = -1;
|
|
if( !GetTechIndexByName( iTechName, techIndex ) ) return;
|
|
|
|
SetTechnique( techIndex );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::SetTechnique( int iTechIndex )
|
|
{
|
|
PIXE_RENDER_L4("RCKShader::SetTechnique");
|
|
|
|
// if(m_CurrTechniqueIndex == iTechIndex)
|
|
// return;
|
|
|
|
m_CurrTechniqueIndex = iTechIndex;
|
|
|
|
const int rcCount = m_DXEffect.Size();
|
|
for( int rcIndex=0 ; rcIndex<rcCount ; ++rcIndex ){
|
|
|
|
XArray<ShaderDescriptor::TechMeaning*>& meanings = m_ShaderDescriptor[rcIndex]->GetTechMeanings();
|
|
ShaderDescriptor::TechMeaning* techMeaning = meanings[ m_CurrTechniqueIndex ];
|
|
XASSERT( techMeaning!=NULL );
|
|
#if DIRECT3D_VERSION<0x0900
|
|
SAFERELEASE(m_CurrentTechnique);
|
|
HRESULT hr = m_DXEffect[rcIndex]->GetTechnique(techMeaning->m_D3DHandle,&m_CurrentTechnique);
|
|
|
|
#else
|
|
HRESULT hr = m_DXEffect[rcIndex]->SetTechnique( techMeaning->m_D3DHandle );
|
|
#endif // _XBOX
|
|
XASSERT(SUCCEEDED(hr));
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int
|
|
RCKShader::GetTechniquesCount() const
|
|
{
|
|
//--- Same count for all render context
|
|
if( !m_ShaderDescriptor.Size() ) return 0;
|
|
return m_ShaderDescriptor[0]->GetTechMeanings().Size();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
RCKShader::GetTechIndexByName( const XString& iTechName, int& oPos ) const
|
|
{
|
|
//--- Tech Name Should be the same for all Render Contexts
|
|
if( !m_ShaderDescriptor.Size() ) return false;
|
|
oPos = m_ShaderDescriptor[0]->GetTechIndexByName( iTechName );
|
|
if( oPos == -1 ) return false;
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
RCKShader::GetTechniqueInfo( int iTechIndex, TechniqueInfo& oTechInfo ) const
|
|
{
|
|
if( !m_ShaderDescriptor.Size() ) return;
|
|
XArray<ShaderDescriptor::TechMeaning*>& techMeanings = m_ShaderDescriptor[0]->GetTechMeanings();
|
|
ShaderDescriptor::TechMeaning& techMeaning = *techMeanings[ iTechIndex ];
|
|
oTechInfo.name = FourCC2String(techMeaning.m_TechDesc.Name);
|
|
oTechInfo.desc = techMeaning.m_DescStr;
|
|
oTechInfo.isValid = techMeaning.m_Validated;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool RCKShader::FindNextValidTechnique( int& ioTechIndex, XString* oTechName ) const
|
|
{
|
|
if( !m_ShaderDescriptor.Size() ) return false;
|
|
|
|
//--- Use Shader Descriptor of Render Context 0 (validation should be the same for all RC)
|
|
ShaderDescriptor::Shader& shaderDescriptor = *m_ShaderDescriptor[0];
|
|
|
|
//--- Parse all technique from the given one
|
|
TechniqueInfo techInfo;
|
|
|
|
int techIndex = ioTechIndex;
|
|
if( techIndex == -1 ) techIndex = 0;
|
|
|
|
const int techCount = GetTechniquesCount();
|
|
for( ; techIndex<techCount ; ++techIndex ){
|
|
|
|
GetTechniqueInfo( techIndex, techInfo );
|
|
if( techInfo.isValid ){
|
|
|
|
ioTechIndex = techIndex;
|
|
|
|
if( oTechName != NULL ) *oTechName = techInfo.name;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int
|
|
RCKShader::GetTechniqueEnumValue( const XString& iTechName ) const
|
|
{
|
|
int techIndex = -1;
|
|
if( !GetTechIndexByName( iTechName, techIndex ) ) return 0;
|
|
return techIndex;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
RCKShader::GetTechniqueEnumString( int num, XString& oName ) const
|
|
{
|
|
TechniqueInfo techInfo;
|
|
GetTechniqueInfo( num, techInfo );
|
|
|
|
oName = techInfo.name;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int
|
|
RCKShader::GetPassCount( int iTechIndex ) const
|
|
{
|
|
if( (CKShader*)this == m_ShaderManager->GetDefaultShader() ) return 1;
|
|
|
|
if( !m_ShaderDescriptor.Size() ) return 0;
|
|
|
|
XArray<ShaderDescriptor::TechMeaning*>& techMeanings = m_ShaderDescriptor[0]->GetTechMeanings();
|
|
ShaderDescriptor::TechMeaning& techMeaning = *techMeanings[ iTechIndex ];
|
|
|
|
return techMeaning.m_Passes.Size();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
RCKShader::GetPassInfo( int iTechIndex, int iPassIndex, PassInfo& oPassInfo ) const
|
|
{
|
|
if( !m_ShaderDescriptor.Size() ) return;
|
|
|
|
//--- Should be the same for RC0 than for other RC
|
|
XArray<ShaderDescriptor::TechMeaning*>& techMeanings = m_ShaderDescriptor[0]->GetTechMeanings();
|
|
ShaderDescriptor::TechMeaning& techMeaning = *techMeanings[ iTechIndex ];
|
|
|
|
ShaderDescriptor::PassMeaning& passMeaning = *techMeaning.m_Passes[ iPassIndex ];
|
|
oPassInfo.name = FourCC2String(passMeaning.m_PassDesc.Name);
|
|
oPassInfo.desc = passMeaning.m_DescStr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
RCKShader::GetPassIndexByName( int iTechIndex, const char* iPassName, int& oPos ) const
|
|
{
|
|
if( !m_ShaderDescriptor.Size() ) return false;
|
|
|
|
//--- Should be the same for RC0 than for other RC
|
|
XArray<ShaderDescriptor::TechMeaning*>& techMeanings = m_ShaderDescriptor[0]->GetTechMeanings();
|
|
ShaderDescriptor::TechMeaning& techMeaning = *techMeanings[ iTechIndex ];
|
|
|
|
//--- Find index of given technique
|
|
int passIndex = techMeaning.GetPassIndexByName( iPassName );
|
|
|
|
//--- Cannot find the given pass
|
|
if( passIndex == -1 ) return false;
|
|
|
|
oPos = passIndex;
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Effect parameters feature
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Execute Exposed Params Meanings
|
|
void RCKShader::SetParameters(const XArray<CKParameterLocal*>& params)
|
|
{
|
|
|
|
PIXE_RENDER_L4("RCKShader::SetParameters");
|
|
|
|
CKRenderManager* rm = m_ShaderManager->m_Context->GetRenderManager();
|
|
|
|
const int rcCount = m_DXEffect.Size();
|
|
for( int rcIndex=0 ; rcIndex<rcCount ; ++rcIndex ){
|
|
|
|
CKRenderContext* rc = m_ShaderManager->m_rcList[rcIndex];
|
|
|
|
ShaderDescriptor::MeaningProcessingInfo
|
|
MPI( NULL, NULL, m_DXEffect[rcIndex], rc, NULL, m_ShaderDescriptor[rcIndex], NULL );
|
|
|
|
for (int i = 0; i < params.Size(); ++i)
|
|
{
|
|
CKParameterLocal* param = params[i];
|
|
|
|
ShaderDescriptor::ExposedParamMeaning* exposedParamMeaning =
|
|
m_ShaderManager->_GetRegisteredParamMeaning( param, rcIndex );
|
|
|
|
if( !exposedParamMeaning ) continue;
|
|
|
|
MPI.param = param;
|
|
exposedParamMeaning->ProcessCallBack( MPI );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Execute Params Meanings (non-exposed)
|
|
// called by SetValuesOfUsedAutomatics()
|
|
//
|
|
void RCKShader::ExecuteMeanings( CK3dEntity* iEnt, CKMaterial* iMat, CKMaterialShader* iMatShader, CKRenderContext* iRC )
|
|
{
|
|
PIXE_RENDER_L4("RCKShader::ExecuteMeanings");
|
|
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex( iRC );
|
|
ShaderDescriptor::MeaningProcessingInfo mpi( iEnt, iMat, m_DXEffect[rcIndex], iRC, iMatShader, m_ShaderDescriptor[rcIndex], NULL );
|
|
m_ShaderDescriptor[rcIndex]->ExecuteMeanings( mpi );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::ExecutePerPassMeanings( CK3dEntity* iEnt, CKMaterial* iMat, CKMaterialShader* iMatShader, CKRenderContext* iRC )
|
|
{
|
|
PIXE_RENDER_L4("RCKShader::ExecutePerPassMeanings");
|
|
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex( iRC );
|
|
ShaderDescriptor::MeaningProcessingInfo mpi( iEnt, iMat, m_DXEffect[rcIndex], iRC, iMatShader, m_ShaderDescriptor[rcIndex], NULL );
|
|
m_ShaderDescriptor[rcIndex]->ExecutePerPassMeanings( mpi );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int RCKShader::GetAutoParameterCount( CKRenderContext* rc )
|
|
{
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
if( !m_ShaderDescriptor[rcIndex] ) return 0;
|
|
|
|
return m_ShaderDescriptor[rcIndex]->GetParamMeanings().Size();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int RCKShader::GetExposedParameterCount( CKRenderContext* rc )
|
|
{
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
if( !m_ShaderDescriptor[rcIndex] ) return 0;
|
|
|
|
return m_ShaderDescriptor[rcIndex]->GetExposedParamMeanings().Size();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::GetAutoParameterInfo( int paramIndex, ParamInfo& paramInfo, CKRenderContext* rc )
|
|
{
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
if( !m_ShaderDescriptor[rcIndex] ) return;
|
|
|
|
XArray<ShaderDescriptor::ParamMeaning*>& paramMeanings
|
|
= m_ShaderDescriptor[rcIndex]->GetParamMeanings();
|
|
paramInfo.name = FourCC2String(paramMeanings[paramIndex]->m_ParamDesc.Name);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::GetExposedParameterInfo( int paramIndex, ParamInfo& paramInfo, CKRenderContext* rc )
|
|
{
|
|
const int rcIndex = m_ShaderManager->_GetRenderContextIndex(rc);
|
|
if( !m_ShaderDescriptor[rcIndex] ) return;
|
|
|
|
XArray<ShaderDescriptor::ExposedParamMeaning*>& exposedParamMeanings
|
|
= m_ShaderDescriptor[rcIndex]->GetExposedParamMeanings();
|
|
paramInfo.name = FourCC2String(exposedParamMeanings[paramIndex]->m_ParamDesc.Name);
|
|
paramInfo.guid = exposedParamMeanings[paramIndex]->m_Guid;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool RCKShader::LinkParameters(int& CompID, XArray<CKParameterLocal*>& params, CKBOOL cleanup)
|
|
{
|
|
//--- If comes from the same compilation, nothing to do.
|
|
if( CompID == m_CompID ) return false;
|
|
|
|
//--- Updates the compilation id.
|
|
CompID = m_CompID;
|
|
|
|
CKRenderManager* rm = m_ShaderManager->m_Context->GetRenderManager();
|
|
|
|
const int rcCount = m_DXEffect.Size();
|
|
for( int rcIndex=0 ; rcIndex<rcCount ; ++rcIndex ){
|
|
|
|
if( !m_DXEffect[rcIndex] ) return false;
|
|
|
|
CKRenderContext* rc = m_ShaderManager->m_rcList[rcIndex];
|
|
|
|
VxDirectXData *dat = rc->GetDirectXInfo();
|
|
|
|
|
|
//--- Set index of the CKParam* to the corresponding ExposedParamMeaning*,
|
|
///// and remove CKParam* that doesn't appear anymore in the shader code.
|
|
ParamInfo pInfo;
|
|
int ckParamCount = params.Size();
|
|
for( int ip=0; ip<ckParamCount ; ++ip )
|
|
{
|
|
CKParameterLocal* p = params[ip];
|
|
if( !p ) continue;
|
|
|
|
const char* name = params[ip]->GetName();
|
|
|
|
ShaderDescriptor::ExposedParamMeaning* paramMeaning
|
|
= m_ShaderDescriptor[rcIndex]->GetParamMeaningByName( name );
|
|
|
|
//--- If parameter is found...
|
|
if( paramMeaning ){
|
|
|
|
CKGUID prevGUID = p->GetGUID();
|
|
|
|
//--- If its guid has changed (for example because its annotation has changed)
|
|
///// then change its type
|
|
if( !paramMeaning->m_Guid.IsValid() ||
|
|
prevGUID != paramMeaning->m_Guid )
|
|
{
|
|
p->SetGUID( paramMeaning->m_Guid );
|
|
}
|
|
//--- Kindly update UI for FLOATSLIDER because update UIMin and UIMax
|
|
///// may have changed in the shader code
|
|
if( paramMeaning->m_Guid == CKPGUID_FLOATSLIDER ){
|
|
|
|
float valueToKeep = *(float*)p->GetWriteDataPtr();
|
|
|
|
ShaderDescriptor::MeaningProcessingInfo
|
|
mpi( NULL, NULL, m_DXEffect[rcIndex], NULL, NULL, NULL, p );
|
|
paramMeaning->CopyDefaultValueFromShaderToParamCB( mpi );
|
|
|
|
//--- UIMin and UIMax have been change, but we don't want the Value
|
|
///// to change so restore the previous one
|
|
*(float*)p->GetWriteDataPtr() = valueToKeep;
|
|
}
|
|
|
|
//--- Link the ExposedMeaning* this name-matching CKParam*
|
|
m_ShaderManager->_RegisterExposedParameterMeaning( params[ip], paramMeaning, rcIndex );
|
|
|
|
} else {
|
|
|
|
//--- Destroy params which name does not match
|
|
///// any Exposed Meaning, and remove them from input list
|
|
m_ShaderManager->m_Context->DestroyObject( p, CK_DESTROY_NONOTIFY );
|
|
m_ShaderManager->_UnregisterExposedParameter( p );
|
|
params.RemoveAt(ip);
|
|
--ip;
|
|
--ckParamCount;
|
|
}
|
|
}
|
|
|
|
//--- Now parse all ExposedMeaning* and create new CKParam*
|
|
///// if there wasn't any CKParam* associated with the ExposedMeaning*
|
|
XArray<ShaderDescriptor::ExposedParamMeaning*>& exposedMeanings =
|
|
m_ShaderDescriptor[rcIndex]->GetExposedParamMeanings();
|
|
|
|
const int exposedMeaningCount = exposedMeanings.Size();
|
|
for( int exposedMeaningIndex=0 ; exposedMeaningIndex<exposedMeaningCount ; ++exposedMeaningIndex ){
|
|
|
|
ShaderDescriptor::ExposedParamMeaning* exposedMeaning
|
|
= exposedMeanings[exposedMeaningIndex];
|
|
|
|
//--- Find one of the CKParam* that is already linked to this ExposedMeaning*
|
|
bool found = false;
|
|
ckParamCount = params.Size();
|
|
for( int paramIndex=0 ; paramIndex<ckParamCount ; ++paramIndex )
|
|
{
|
|
CKParameterLocal* p = params[paramIndex];
|
|
|
|
if( m_ShaderManager->_GetRegisteredParamMeaning( p, rcIndex ) == exposedMeaning )
|
|
{
|
|
found=true;
|
|
|
|
//--- Ensure parameter is located at the natural position
|
|
if( paramIndex != exposedMeaningIndex ){
|
|
|
|
//--- And if not, then move it to the desired position
|
|
params.Move( ¶ms[exposedMeaningIndex], ¶ms[paramIndex] );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//--- No CKParam* linked to the ExposedMeaning*, so create one
|
|
if( !found ){
|
|
|
|
//--- So let's create a new CKParameter
|
|
CKParameterLocal* p =
|
|
m_ShaderManager->m_Context->CreateCKParameterLocal(
|
|
(char*)FourCC2String(exposedMeaning->m_ParamDesc.Name), exposedMeaning->m_Guid );
|
|
|
|
//--- Insert it in the CKParameter array at the natural position if possible
|
|
if( params.Size() > exposedMeaningIndex ){
|
|
params.Insert( exposedMeaningIndex, p );
|
|
} else {
|
|
params.PushBack(p);
|
|
}
|
|
|
|
m_ShaderManager->_RegisterExposedParameterMeaning( p, exposedMeaning, rcIndex );
|
|
|
|
//--- We must register the parameter for the others handles
|
|
///// of all other render context, to make sure no other local param
|
|
///// will be created (as we must have only 1 ckparam for all RCs)
|
|
for( int otherRCIndex=0 ; otherRCIndex<rcCount ; ++otherRCIndex ){
|
|
|
|
if( otherRCIndex==rcIndex ) continue;
|
|
|
|
XArray<ShaderDescriptor::ExposedParamMeaning*>& exposedMeaningsOfOtherRC =
|
|
m_ShaderDescriptor[otherRCIndex]->GetExposedParamMeanings();
|
|
|
|
ShaderDescriptor::ExposedParamMeaning* meaningOfOtherRC =
|
|
exposedMeaningsOfOtherRC[ exposedMeaningIndex ];
|
|
|
|
m_ShaderManager->_RegisterExposedParameterMeaning( p, meaningOfOtherRC, otherRCIndex );
|
|
}
|
|
|
|
//--- While we are at it, tries to give the brand new parameter
|
|
///// the same value as the one in the shader.
|
|
///// Note: In principle, for the CopyDefaultValue callback we only need
|
|
///// to provide the FX and the CKParam
|
|
ShaderDescriptor::MeaningProcessingInfo
|
|
mpi( NULL, NULL, m_DXEffect[rcIndex], NULL, NULL, NULL, p );
|
|
|
|
exposedMeaning->CopyDefaultValueFromShaderToParamCB( mpi );
|
|
}
|
|
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool
|
|
RCKShader::LinkTechnique( int& CompID, const XString& iTechName, BOOL iFNVT, int& oTechIndex )
|
|
{
|
|
//--- If comes from the same compilation, nothing to do.
|
|
if( CompID == m_CompID ) return false;
|
|
|
|
//--- Updates the compilation id.
|
|
CompID = m_CompID;
|
|
|
|
//--- Retrieves Technique index From Name
|
|
if( !GetTechIndexByName( iTechName, oTechIndex ) ) return false;
|
|
|
|
//--- Finds the next valid technique.
|
|
if( iFNVT ){
|
|
return FindNextValidTechnique( oTechIndex );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Compiling
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::Compile(CKContext* Context)
|
|
{
|
|
XClassArray<XString> output;
|
|
m_ShaderManager->CompileShader(this, output);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::_AddRenderContextSlot()
|
|
{
|
|
//--- Add a D3DXEffect slot
|
|
m_DXEffect.PushBack( NULL );
|
|
|
|
///// Also add a ShaderDescriptor slot
|
|
ShaderDescriptor::Shader* shaderDescriptorForThisRenderContext = new ShaderDescriptor::Shader;
|
|
m_ShaderDescriptor.PushBack( shaderDescriptorForThisRenderContext );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RCKShader::_RemoveRenderContextSlot( int iRCIndex )
|
|
{
|
|
//--- Remove dxEffect for this rcIndex
|
|
XArray<ID3DXEffect*>& dxEffectArray = m_DXEffect;
|
|
dxEffectArray.RemoveAt( iRCIndex );
|
|
|
|
//--- Remove also the ShaderDescriptor
|
|
delete m_ShaderDescriptor[iRCIndex];
|
|
m_ShaderDescriptor.RemoveAt( iRCIndex );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Registering
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CKSTRING RCKShader::GetClassName()
|
|
{
|
|
return "Shader";
|
|
}
|
|
|
|
|
|
#if DIRECT3D_VERSION<0x0900
|
|
|
|
char* FourCC2String(DWORD fcc)
|
|
{
|
|
static char ret[5];
|
|
char *tmp = (char*)&fcc;
|
|
|
|
ret[0] = tmp[0] ? tmp[0] : '\0';
|
|
ret[1] = tmp[1] ? tmp[1] : '\0';
|
|
ret[2] = tmp[2] ? tmp[2] : '\0';
|
|
ret[3] = tmp[3] ? tmp[3] : '\0';
|
|
|
|
ret[4] = '\0';
|
|
return ret;
|
|
};
|
|
|
|
#endif
|