#include "stdafx.h" #include "RTView.h" #include "CKRasterizer.h" //#include "RCKRenderContext.h" #define CombineRTViews_GUID CKGUID(0x43ac0870,0x44fc02ed) //----------------------------------------------------------------------------- void ComputeViewRectFromCameraRatio( VxRect& oViewRect, CKCamera& iCam, VxRect& iWindowRect ) { if( !&iCam ) return; int camWidth, camHeight; iCam.GetAspectRatio( camWidth, camHeight ); float camRatio = (float)camHeight / (float)camWidth; int pixelHeight = (int)(iWindowRect.GetWidth() * camRatio + 0.5f); float homogeneousHeight = pixelHeight / iWindowRect.GetHeight(); oViewRect.SetCorners( 0.0f, 0.5f-homogeneousHeight*0.5f, 1.0f, 0.5f+homogeneousHeight*0.5f ); } //----------------------------------------------------------------------------- void ConvertToFullSizeIfInvalid( RTView& rtview, CKRenderContext* rc=NULL, BOOL homogen=FALSE ) { if( rtview.rect.GetWidth()<=0 || rtview.rect.GetHeight()<=0 ){ rtview.rect.left = 0.0f; rtview.rect.top = 0.0f; if( rtview.tex ){ rtview.rect.right = (float)rtview.tex->GetWidth(); rtview.rect.bottom = (float)rtview.tex->GetHeight(); } else if ( rc ){ rtview.rect.right = (float)rc->GetWidth(); rtview.rect.bottom = (float)rc->GetHeight(); } else { rtview.rect.right = 0.0f; rtview.rect.bottom = 0.0f; } } else if( homogen ){ if( rtview.tex ){ rtview.rect.left *= rtview.tex->GetWidth(); rtview.rect.right *= rtview.tex->GetWidth(); rtview.rect.top *= rtview.tex->GetHeight(); rtview.rect.bottom *= rtview.tex->GetHeight(); } else if ( rc ){ rtview.rect.left *= rc->GetWidth(); rtview.rect.right *= rc->GetWidth(); rtview.rect.top *= rc->GetHeight(); rtview.rect.bottom *= rc->GetHeight(); } } } #ifndef NO_CG_SHADERS //----------------------------------------------------------------------------- enum { PARAM_DEST_VIEW = 0, PARAM_RENDEROPTIONS, PARAM_BGCOLOR, PARAM_SHADER, PARAM_SHADER_TECHNIQUE, PARAM_VIEW0 }; //----------------------------------------------------------------------------- enum { LOCAL_COMPID = 0, LOCAL_FXPARAMS, LOCAL_INPUTVIEWCOUNT, LOCAL_HOMOGENEOUSVIEW, LOCAL_BUILDPARAMS, LOCAL_OUTPUTVIEWCOUNT, LOCAL_ADJUSTD3DTEXCOORD }; #define MAXRT_COUNT 4 //----------------------------------------------------------------------------- class innerCombineRTView { public: innerCombineRTView() { ropt = 0; lastTick = 0xFFFFFFFF; } XArray fxparams; CKDWORD ropt; CKDWORD lastTick; }; //----------------------------------------------------------------------------- void FillVertex( VxDrawPrimitiveData* dpdata, const int viewCount, const float x, const float y, const float& tx, const float& ty ) { int rectOffset = sizeof(VxRect)/sizeof(float); *dpdata->Positions++ = VxVector4(x, y, 1, 1); *dpdata->TexCoord++ = VxUV(tx, ty); for( int a=1 ; aTexCoords[a-1]++ = VxUV( *(&tx + rectOffset), *(&ty + rectOffset) ); } } //----------------------------------------------------------------------------- CKParameterLocal* FindParameterByNameAndType( const XArray& params, char* paramName, CKGUID paramType ); //----------------------------------------------------------------------------- void FillShaderParameters( CKBehavior* beh, int firstParamIndex, XArray& params ); //----------------------------------------------------------------------------- CKParameterIn* FindBBParamByNameAndType( CKBehavior* beh, int firstParamIndex, char* paramName, CKGUID paramType ); //----------------------------------------------------------------------------- void BuildShaderExposedParams( CKBehavior* beh, int firstParamIndex, XArray& params ); //----------------------------------------------------------------------------- int GetCurrentOutViewCount( CKBehavior* beh ) { int viewCount=1; while( 1 ){ CKParameterIn* pin = beh->GetInputParameter( PARAM_DEST_VIEW + viewCount ); if( !pin || pin->GetGUID()!=CKPGUID_TEXTURE ) break; ++viewCount; } return viewCount; } //----------------------------------------------------------------------------- int GetCurrentViewCount( CKBehavior* beh ) { int viewCount=0; int decal = GetCurrentOutViewCount(beh)-1; while( 1 ){ CKParameterIn* pin = beh->GetInputParameter(decal + PARAM_VIEW0 + viewCount ); if( !pin || pin->GetGUID()!=CKPGUID_RTVIEW ) break; ++viewCount; } return viewCount; } /***********************************************/ // PostProcess Callback // Set render options here. /***********************************************/ void CombineRTViewsPostProcess( void *arg ) { CKBehavior* beh = (CKBehavior*)arg; CKContext *ctx = beh->GetCKContext(); CKRenderContext* rc = ctx->GetRenderManager()->GetRenderContext(0); if( !rc ) return; CKRasterizerContext* rstc = rc->GetRasterizerContext(); if( !rstc ) return; //--- Get Inner Struct innerCombineRTView* icrtv = NULL; beh->GetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); if( !icrtv ){ icrtv = new innerCombineRTView(); beh->SetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); } int decal = GetCurrentOutViewCount(beh)-1; //--- Store previous rendering options and apply user's ones. ///// ... only if tick count is different for this beh (it can be call twice, ///// and if so, we don't want to overide the first stored rendering options) CKTimeManager* timeMan = ctx->GetTimeManager(); CKDWORD lastTick = timeMan->GetMainTickCount(); if( icrtv->lastTick != lastTick ){ //--- definitly store previous rendering options icrtv->ropt = rc->GetCurrentRenderOptions(); icrtv->lastTick = lastTick; } CKDWORD ropt = icrtv->ropt; beh->GetInputParameterValue(decal+PARAM_RENDEROPTIONS, &ropt ); //--- Get Dest RT View. CKParameterIn* pin = beh->GetInputParameter( PARAM_DEST_VIEW ); if( !pin ) return; CKParameter* realPin = pin->GetRealSource(); if( !realPin ) return; RTView destRTView( realPin ); ///// If Dest RT View is a texture then force upload to Video Memory if( destRTView.tex && !destRTView.tex->IsInVideoMemory() ) destRTView.tex->EnsureVideoMemory(rc); //--- View Rect is homogeneous ? BOOL homogen = FALSE; beh->GetLocalParameterValue( LOCAL_HOMOGENEOUSVIEW, &homogen ); //--- Check Rect size CKCamera* cam = rc->GetAttachedCamera(); if( cam && (ropt&CK_RENDER_USECAMERARATIO) ){ homogen = TRUE; VxRect windowRect; rc->GetWindowRect( windowRect ); ComputeViewRectFromCameraRatio( destRTView.rect, *cam, windowRect ); } ConvertToFullSizeIfInvalid( destRTView, rc, homogen ); //--- Get Background Color VxColor bgColor(0, 0, 0, 0); beh->GetInputParameterValue(decal+PARAM_BGCOLOR, &bgColor ); //--- Get Shader Name CKShaderManager* shaderMan = (CKShaderManager*)ctx->GetManagerByGuid( ShaderManagerGUID ); const char* shaderName = (char*)beh->GetInputParameterReadDataPtr(decal+PARAM_SHADER ); if( !shaderName ) return; CKShader* shader = shaderMan->GetShaderByName( shaderName ); if( !shader ) return; //--- Get Technique Name XString techName = (char*)beh->GetInputParameterReadDataPtr(decal+PARAM_SHADER_TECHNIQUE ); int techIndex = -1; if( !shader->GetTechIndexByName( techName, techIndex ) ) return; if( !shader->FindNextValidTechnique( techIndex ) ) return; //--- Get Views XArray view; XArray rect; CKTexture* lastTexture = NULL; CKRST_RSTFAMILY driverFamily = rc->GetRasterizerContext()->m_Driver->m_2DCaps.Family; float textureOffset = 0.f; if (driverFamily == CKRST_DIRECTX) { // Auto adjust texcoords for D3D if desired CKBOOL autoAdjustTexCoord = 1; beh->GetLocalParameterValue(LOCAL_ADJUSTD3DTEXCOORD, &autoAdjustTexCoord); if (autoAdjustTexCoord) { textureOffset = 0.5f; // ensure proper sampling of texel center in D3D } } ///// Note: We don't parse RT Views pIns with a for() loop ///// just to be back-compatible (and thus we don't read viewCount from setting). const int viewCount = GetCurrentViewCount( beh ); int a; for( a=0 ; aGetInputParameter( decal + PARAM_VIEW0 + a ); RTView rtview( pin->GetRealSource() ); lastTexture = rtview.tex; //--- Check Rect size if( cam && (ropt&CK_RENDER_USECAMERARATIO) ){ VxRect texRect( 0, 0, 256, 256 ); if( rtview.tex ) texRect.SetCorners(0.0f,0.0f,(float)rtview.tex->GetWidth(), (float)rtview.tex->GetHeight() ); ComputeViewRectFromCameraRatio( rtview.rect, *cam, texRect ); } ConvertToFullSizeIfInvalid( rtview, NULL, homogen ); view.PushBack( rtview ); rect.PushBack( view[a].GetRectangleTexCoords(textureOffset) ); } //--- Set Texture Stages for( a=0 ; am_PseudoChannelTexture[a] = view[a].tex; } //--- Fill Next RTViews with the last One (could be NULL, but ///// we must use the last one for backcompatibilty reasons). for( a=viewCount ; am_PseudoChannelTexture[a] = lastTexture; } //--- Get Compilation ID int compID = 0; beh->GetLocalParameterValue( LOCAL_COMPID, &compID ); //--- Get Parameters shader->LinkParameters( compID, icrtv->fxparams ); FillShaderParameters( beh, PARAM_VIEW0+viewCount, icrtv->fxparams ); //--- Rendering Initializations rc->SetUpdate2DProjEnableFlag(TRUE /*FALSE*/); // Do not update 2D views when SetRenderTarget will be called // (We don't render them, this will save some CPU) ///// Set Destination RTView VxRect oldRect; rc->GetViewRect( oldRect ); if( destRTView.tex ){ #ifdef _XBOX destRTView.tex->EnsureVideoMemory(rc); #endif rc->SetRenderTarget( destRTView.tex ); } int currentOutRTCount = GetCurrentOutViewCount(beh); if(currentOutRTCount>1){ int rtIndex = 1; for(int i=PARAM_DEST_VIEW+1;iGetInputParameterObject(i); rc->SetRenderTarget(tex, rtIndex++); } } rc->SetViewRect( destRTView.rect ); rstc->m_CurrentFrame |= 0x80000000; // Ro: Did not know why this value was set , but it is now // used in ckDx9Rasterizer to avoid Device Reset so don't remove... rstc->BeginScene(); rstc->m_CurrentFrame &= ~0x80000000; shaderMan->BeginShaders(rc); ///// Clear Destination RTView with background color and no BACKTOFRONT VxColor oldbg = rc->GetBackgroundMaterial()->GetDiffuse(); rc->GetBackgroundMaterial()->SetDiffuse( bgColor ); rc->Clear( (CK_RENDER_FLAGS)(ropt&(~CK_RENDER_DOBACKTOFRONT)) ); rc->GetBackgroundMaterial()->SetDiffuse(oldbg); //--- Impede zread and zwrite rc->SetState( VXRENDERSTATE_ZWRITEENABLE, FALSE ); rc->SetState( VXRENDERSTATE_ZENABLE, FALSE ); //--- Start Rendering of Final Rectangle ///// If we render to the screen the real rendering will occur later ///// (called by CUIK for example), and we don't want the buffers ///// to be cleared if we cleared them already (it would override our rendering !). if( !destRTView.tex ){ ropt &= ~CK_RENDER_CLEARZ & ~CK_RENDER_CLEARBACK & ~CK_RENDER_CLEARSTENCIL; } ///// Set Render Options rc->SetCurrentRenderOptions( ropt ); ///// Set Technique shader->SetTechnique( techName ); ///// Render Final Rectangle with Passes #if (DIRECT3D_VERSION<0x0900) && !defined(macintosh) const DWORD DPF = (CKRST_DP_STAGES0 << (viewCount-1)); #else const DWORD DPF = CKRST_DP_TRANSFORM | (CKRST_DP_STAGES0 << (viewCount-1)); #endif VxDrawPrimitiveData* dpdata = rc->GetDrawPrimitiveStructure((CKRST_DPFLAGS)DPF, 4); VxDrawPrimitiveData dpdataTmp; ///// Set PASSCOUNT semantic int passCount = shader->Begin(rc); shaderMan->m_CurrentPassCount = passCount; //--- Set Automatics Values shader->SetParameters( icrtv->fxparams ); rc->SetValuesOfUsedAutomatics( *shader, NULL, NULL, NULL ); for( a=0 ; am_CurrentPassIndex = a; shader->ExecutePerPassMeanings( NULL, NULL, NULL, rc ); shader->BeginPass(a,rc); memcpy( &dpdataTmp, dpdata, sizeof(VxDrawPrimitiveData) ); VxRect fillRect = rect[0]; if (!destRTView.tex || driverFamily != CKRST_OPENGL) { FillVertex( &dpdataTmp, viewCount,-1, 1, fillRect.left, fillRect.top ); FillVertex( &dpdataTmp, viewCount, 1, 1, fillRect.right, fillRect.top ); FillVertex( &dpdataTmp, viewCount,-1,-1, fillRect.left, fillRect.bottom ); FillVertex( &dpdataTmp, viewCount, 1,-1, fillRect.right, fillRect.bottom ); } else { // Special case for OpenGL + Render targets // When a texture is bound as a render target, the rasterization is inverted on the y axis // This require to change the projection matrix (inversion on y axis to compensate), but also invert the winding. // This is handled automatically by the OpenGL rasterizer context. // Unfortunately, previously written post process shaders ignore the WorldViewProjection matrix // and just do a pass through with vertex coordinates. As a result the quad y coords are flipped and winding // is inverted -> nothing is drawn. We just compensate by drawing the quad upside down. FillVertex( &dpdataTmp, viewCount,-1, -1, fillRect.left, fillRect.top ); FillVertex( &dpdataTmp, viewCount, 1, -1, fillRect.right, fillRect.top ); FillVertex( &dpdataTmp, viewCount,-1, 1, fillRect.left, fillRect.bottom ); FillVertex( &dpdataTmp, viewCount, 1, 1, fillRect.right, fillRect.bottom ); } //--- Draw Rectangle rc->DrawPrimitive( VX_TRIANGLESTRIP, (WORD*)NULL, 0, dpdata ); shader->EndPass(rc); } //--- End Rendering of Final Rectangle shader->End(rc); shaderMan->EndShaders(rc); rstc->EndScene(); //--- Restore some other stuff if( destRTView.tex ){ rc->SetRenderTarget( NULL ); } if(currentOutRTCount>1){ int rtIndex = 0; for(int i=1;iSetRenderTarget(NULL,i); } } rc->SetUpdate2DProjEnableFlag(TRUE); // Allow agin to update 2D views extent rc->SetViewRect( oldRect ); //--- Restore zread and zwrite rc->SetState( VXRENDERSTATE_ZWRITEENABLE, TRUE ); rc->SetState( VXRENDERSTATE_ZENABLE, TRUE ); //--- Save the locals beh->SetLocalParameterValue( LOCAL_COMPID, &compID ); } /***********************************************/ // PreProcess Callback // Restore render context options here /***********************************************/ void CombineRTViewsPreProcess( void *arg ) { CKBehavior* beh = (CKBehavior*)arg; CKContext *ctx = beh->GetCKContext(); CKRenderContext* rc = ctx->GetRenderManager()->GetRenderContext(0); if( !rc ) return; //--- Get inner Struct innerCombineRTView* icrtv = NULL; beh->GetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); if( !icrtv ) return; //--- Restore previous rendering options rc->SetCurrentRenderOptions( icrtv->ropt ); } /***********************************************/ // Reset render options /***********************************************/ void ResetRenderOptions( CKBehavior* beh ) { CKContext *ctx = beh->GetCKContext(); CKRenderContext* rc = ctx->GetRenderManager()->GetRenderContext(0); if( !rc ) return; //--- Reset rendering options CKShaderManager* shaderMan = (CKShaderManager*)ctx->GetManagerByGuid( ShaderManagerGUID ); if( shaderMan ){ if( shaderMan->m_RenderOptionsBeforePlay != CK_RENDER_USECURRENTSETTINGS ){ CKDWORD useCameraRatio = shaderMan->m_RenderOptionsBeforePlay & CK_RENDER_USECAMERARATIO; rc->SetCurrentRenderOptions( (CK_RENDER_DEFAULTSETTINGS & ~CK_RENDER_USECAMERARATIO) | useCameraRatio ); if( !useCameraRatio ){ VxRect windowRect; rc->GetWindowRect( windowRect ); Vx2DVector zero(0,0); Vx2DVector size = windowRect.GetSize(); VxRect r(zero,size) ; rc->SetViewRect( r ); } } } } /***********************************************/ // MAIN /***********************************************/ int CombineRTViews(const CKBehaviorContext& behcontext) { //--- Standard Behavioral Initialization CKBehavior* beh = behcontext.Behavior; CKContext *ctx = behcontext.Context; beh->ActivateInput(0, FALSE); beh->ActivateOutput(0); CKRenderContext* rc = behcontext.CurrentRenderContext; if( !rc ) CKBR_BEHAVIORERROR; //--- Get the Shader Manager CKShaderManager* shaderMan = (CKShaderManager*)ctx->GetManagerByGuid( ShaderManagerGUID ); if( !shaderMan || !shaderMan->IsSupported() ){ ctx->OutputToConsole("Shader Manager not supported."); return CKBR_BEHAVIORERROR; } //--- Get Dest RT View. CKParameterIn* pin = beh->GetInputParameter( PARAM_DEST_VIEW ); if( !pin ) return CKBR_PARAMETERERROR; CKParameter* realPin = pin->GetRealSource(); if( !realPin ) return CKBR_PARAMETERERROR; RTView destRTView( realPin ); //--- If we write in a texture then execute both callback now ! if( destRTView.tex ){ CombineRTViewsPostProcess( (void*)beh ); CombineRTViewsPreProcess( (void*)beh ); //--- Otherwise, it's the final post-processing, let render context callthem } else { //--- Before Transparent Object ? CKBOOL beforeTransparent = FALSE; shaderMan->AddTemporaryPostProcessCallBack( CombineRTViewsPostProcess, (void*)beh ); shaderMan->AddTemporaryPreProcessCallBack( CombineRTViewsPreProcess, (void*)beh ); } return CKBR_OK; } /***********************************************/ // CALLBACK /***********************************************/ CKERROR CombineRTViewsCallback(const CKBehaviorContext& behcontext) { CKBehavior* beh = behcontext.Behavior; switch( behcontext.CallbackMessage ){ case CKM_BEHAVIORDELETE: case CKM_BEHAVIORDETACH: { //--- Restore render options ResetRenderOptions( beh ); //CombineRTViewsPreProcess( (void*)beh ); //--- Init pfxParams innerCombineRTView* icrtv = NULL; beh->GetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); delete icrtv; icrtv = NULL; beh->SetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); } break; case CKM_BEHAVIORLOAD: case CKM_BEHAVIORATTACH: { //--- Init compID int compID = 0; beh->SetLocalParameterValue( LOCAL_COMPID, &compID ); //--- Init pfxParams innerCombineRTView* icrtv = NULL; beh->SetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); if(!beh->GetLocalParameter(LOCAL_OUTPUTVIEWCOUNT)){ beh->CreateLocalParameter("Output RT View Count",CKPGUID_INT); int one = 1; beh->SetLocalParameterValue(LOCAL_OUTPUTVIEWCOUNT,&one); } if(!beh->GetLocalParameter(LOCAL_ADJUSTD3DTEXCOORD)){ beh->CreateLocalParameter("Adjust D3D Tex Coord",CKPGUID_BOOL); CKBOOL vtrue = 1; beh->SetLocalParameterValue(LOCAL_ADJUSTD3DTEXCOORD,&vtrue); } } break; case CKM_BEHAVIORRESET: { //--- Reset render options ResetRenderOptions( beh ); } break; case CKM_BEHAVIORPAUSE: { if( behcontext.Context->IsInInterfaceMode() ){ //--- Reset render options ResetRenderOptions( beh ); } } break; case CKM_BEHAVIORSETTINGSEDITED: { //--- Get Wanted Input View Count int wantedViewCount = 1; beh->GetLocalParameterValue( LOCAL_INPUTVIEWCOUNT, &wantedViewCount ); int decal = GetCurrentOutViewCount(beh)-1; //--- Get Previous View Count int currentViewCount = GetCurrentViewCount( beh ); if( currentViewCount != wantedViewCount ){ //--- Limit View Count if( wantedViewCount<1 ) wantedViewCount = 1; if( wantedViewCount>8 ) wantedViewCount = 8; beh->SetLocalParameterValue( LOCAL_INPUTVIEWCOUNT, &wantedViewCount ); //--- Destroy pIns beyond "View Current" int lastPinIndex = beh->GetInputParameterCount(); while( --lastPinIndex > (decal+PARAM_VIEW0+wantedViewCount-1) ){ if(beh->GetInputParameter(lastPinIndex)->GetGUID() == CKPGUID_RTVIEW){ CKDestroyObject( beh->RemoveInputParameter(lastPinIndex) ); currentViewCount--; } } //--- Create missing view pIns char pInName[8]; for( int a=currentViewCount ; aCreateCKParameterIn(pInName,CKPGUID_RTVIEW); //beh->InsertInputParameter(++lastPinIndex,pin); beh->InsertInputParameter(decal+PARAM_VIEW0+a,pin); } } //--- Get Wanted Output View Count int wantedOutViewCount = 1; beh->GetLocalParameterValue( LOCAL_OUTPUTVIEWCOUNT, &wantedOutViewCount ); //--- Get Previous View Count int currentOutViewCount = GetCurrentOutViewCount( beh ); if( currentOutViewCount != wantedOutViewCount){ //--- Limit View Count if( wantedOutViewCount<1 ) wantedOutViewCount = 1; if( wantedOutViewCount>MAXRT_COUNT ) wantedOutViewCount = MAXRT_COUNT; beh->SetLocalParameterValue( LOCAL_OUTPUTVIEWCOUNT, &wantedOutViewCount); //--- Destroy pIns beyond "View Current" for(int i=1;iGetInputParameter(i); if(pin->GetGUID() == CKPGUID_TEXTURE) if(i>=wantedOutViewCount){ CKDestroyObject( beh->RemoveInputParameter(i) ); --decal; } else { i++; } else break; } //--- Create missing view pIns char pInName[16]; for( int a=currentOutViewCount ; aInsertInputParameter(PARAM_DEST_VIEW+a,behcontext.Context->CreateCKParameterIn(pInName, CKPGUID_TEXTURE)); ++decal; } } //--- Build Exposed Parameters BOOL buildExposedParams = FALSE; beh->GetLocalParameterValue( LOCAL_BUILDPARAMS, &buildExposedParams ); if( buildExposedParams ){ //--- Reset buildExposedParams Flag buildExposedParams = FALSE; beh->SetLocalParameterValue( LOCAL_BUILDPARAMS, &buildExposedParams ); //--- Get Shader CKContext* ctx = behcontext.Context; CKShaderManager* shaderMan = (CKShaderManager*)ctx->GetManagerByGuid( ShaderManagerGUID ); const char* shaderName = (char*)beh->GetInputParameterReadDataPtr(decal+PARAM_SHADER ); if( !shaderName ) return CKBR_PARAMETERERROR; CKShader* shader = shaderMan->GetShaderByName( shaderName ); if( !shader ) return CKBR_PARAMETERERROR; //--- Get Compilation ID int compID = 0; beh->GetLocalParameterValue( LOCAL_COMPID, &compID ); //--- Get Inner Struct innerCombineRTView* icrtv = NULL; beh->GetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); if( !icrtv ){ icrtv = new innerCombineRTView(); beh->SetLocalParameterValue( LOCAL_FXPARAMS, &icrtv ); } //--- Build Shader Local Parameter Array shader->LinkParameters( compID, icrtv->fxparams ); //--- Create and Destroy pIns int firstParamIndex = decal+PARAM_VIEW0+wantedViewCount; BuildShaderExposedParams( beh, firstParamIndex, icrtv->fxparams ); } } break; } return CKBR_OK; } /***********************************************/ // PROTO /***********************************************/ CKERROR CreateCombineRTViewsProto(CKBehaviorPrototype **pproto) { CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Combine RT Views"); if(!proto) return CKERR_OUTOFMEMORY; proto->DeclareInput("In"); proto->DeclareOutput("Out"); proto->DeclareInParameter("Dest RT View", CKPGUID_RTVIEW); proto->DeclareInParameter("Render Options", CKPGUID_RENDEROPTIONS, "Foreground Sprites,Buffer Swapping,Disable 3D Only,Clear ZBuffer,Buffer Swapping"); proto->DeclareInParameter("Background Color", CKPGUID_COLOR); proto->DeclareInParameter("Shader", CKPGUID_SHADER ); proto->DeclareInParameter("Technique", CKPGUID_TECHNIQUE ); proto->DeclareInParameter("View 0", CKPGUID_RTVIEW); proto->DeclareLocalParameter(NULL, CKPGUID_INT); // CompID proto->DeclareLocalParameter(NULL, CKPGUID_POINTER);// pFxParams and inner struct proto->DeclareSetting("Input RT View Count", CKPGUID_INT, "1"); proto->DeclareSetting("Viewports are Homogeneous",CKPGUID_BOOL, "FALSE"); proto->DeclareSetting("Build Exposed Params",CKPGUID_BOOL, "FALSE"); proto->DeclareSetting("Output RT View Count", CKPGUID_INT, "1"); proto->DeclareSetting("Adjust D3D Tex Coord", CKPGUID_BOOL, "TRUE"); proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL); proto->SetFunction(CombineRTViews); proto->SetBehaviorFlags((CK_BEHAVIOR_FLAGS) (CKBEHAVIOR_INTERNALLYCREATEDINPUTPARAMS | CKBEHAVIOR_VARIABLEPARAMETERINPUTS)); proto->SetBehaviorCallbackFct( CombineRTViewsCallback, CKCB_BEHAVIORATTACH | CKCB_BEHAVIORLOAD | CKCB_BEHAVIORSETTINGSEDITED | CKCB_BEHAVIORDELETE | CKCB_BEHAVIORDETACH | CKCB_BEHAVIORPAUSE | CKCB_BEHAVIORRESUME | CKCB_BEHAVIORRESET ); *pproto = proto; return CK_OK; } /***********************************************/ // DECLARATION /***********************************************/ CKObjectDeclaration *FillBehaviorCombineRTViews() { CKObjectDeclaration *od = CreateCKObjectDeclaration("Combine RT Views"); od->SetDescription("Renders a 2D rectangle into a RT View using a Shader to combine up to 8 RT Views."); od->SetCategory("Shaders/Rendering"); od->SetType(CKDLL_BEHAVIORPROTOTYPE); od->SetGuid(CombineRTViews_GUID); od->SetAuthorGuid(VIRTOOLS_GUID); od->SetAuthorName("Virtools"); od->SetVersion(0x00010000); od->SetCreationFunction(CreateCombineRTViewsProto); od->SetCompatibleClassId(CKCID_BEOBJECT); return od; } #endif