deargui-vpl/ref/virtools/Samples/Behaviors/Shader/Sources/RCKShader.cpp

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( &params[exposedMeaningIndex], &params[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