/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### // ## ############### Shark 3D Engine (www.shark3d.com) // ########## # # # // ######## Copyright (c) 1996-2006 Spinor GmbH. // ######### # # # All rights reserved. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// //@cpp #include "gtp_shader_cubetexfilter.h" #include "../../interf/eng_gfxvar.h" #include "../../util/eng_util_gfxutil.h" #include "../../util/eng_util_gfxparamutil.h" #include "../../util/eng_util_shaderutil.h" #include "../../util/eng_util_shaderitemjob.h" #include "../../../drv/interf/drv_vartypes.h" #include "../../../drv/util/drv_util_varutil.h" #include "../../../drv/util/drv_util_gfxutil.h" #include "../../../drv/util/drv_util_paintprim.h" #include "../../../util/snk/util_snk_extractutil.h" /////////////////////////////////////////////////////////////////////////////// /*@{ @declare{shadercomp.class}{eng_shader_special.filter}{} This component performs some iterative texture filtering. @p The component takes none, one or multiple source textures as input, see @sident{comp}{eng_shader_special.filter.src_array}. Then it passes them to a shaderprogram, see @sident{comp}{eng_shader_special.filter.shaderprog_ident}. Then it writes the result to none, one or multiple @em{destination} textures, see @sident{comp}{eng_shader_special.filter.dest_array}. @p If the destination textures have already been allocated they are used "as is", but only if they all have the same size. Otherwise temporary textures will fetched. Their size is the maximum of the source textures scaled by @sident{comp}{eng_shader_special.filter.width_scale} and @sident{comp}{eng_shader_special.filter.height_scale}. If necessary the destination texture size is @em{snapped} to a value acceptable to the graphics card. @p @}*/ /////////////////////////////////////////////////////////////////////////////// S3D_UTIL_RTTI_TABLE_DEFINE_BEGIN(gtp_Shader_CubeTexFilter) S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CEngShader) S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompUtilUniqueBase) S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompSetup) S3D_UTIL_RTTI_TABLE_DEFINE_END gtp_Shader_CubeTexFilter::gtp_Shader_CubeTexFilter() { } void gtp_Shader_CubeTexFilter::SetupInit( s3d_CUtilMsgHandler *MsgHandler, s3d_CUtilStr_cr Info, s3d_CCompSuppl *FetchSuppl, s3d_CUtilSnkChunk *Param) { m_Data = S3D_SYS_NEW gtp_Shader_CubeTexFilterData; s3d_CUtilSnkExtract SnkExtract; SnkExtract.Assign(MsgHandler, Param); m_Data->m_Info = SnkExtract.GetInfo(); /*@{ @declare{shadercomp.param}{eng_shader_special.filter.env}{$ [str]} See @ident{comp}{eng_shader_std.group.env}. @}*/ s3d_CUtilStr EnvIdent, EnvInfo; SnkExtract.ExtractStr(EnvInfo, EnvIdent, "env", true); m_ShaderEnv = s3d_CompSupplObjT( MsgHandler, EnvInfo, FetchSuppl, EnvIdent, S3D_GENERAL_INTEROP_INTERF); if(!m_ShaderEnv) return; /*@{ @declare{shadercomp.param} {eng_shader_special.filter.methods}{$ [str] .. [str]} See @ref{prog_man.shader.methods}. @}*/ s3d_CUtilSnkExtractUtil::ExtractAtomSortedArray( m_Data->m_MethodArray, m_ShaderEnv->m_AtomMgr, SnkExtract, "methods", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.rank}{$ [str]} Rank of the shader in the rendering sequence. @}*/ SnkExtract.ExtractInt(m_Data->m_RankInfo, m_Data->m_Rank, "rank", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.iter_start}{$ [int]} Iteration start value. @}*/ m_Data->m_IterStart = SnkExtract.ExtractInt("iter_start", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.iter_end}{$ [int]} Iteration end value. @}*/ m_Data->m_IterEnd = SnkExtract.ExtractInt("iter_end", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.iter_step}{$ [int]} Iteration step. If the step is positive, then the step is added to the start value until the value is larger than the end. If the step is negative, then the step is added to the start value until the value is smaller than the end. If the step is zero, the iteration is only executed once for the start value. @}*/ m_Data->m_IterStep = SnkExtract.ExtractInt("iter_step", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.iter_width_scale}{$ [float]} Scale the image by this scale each iteration. The last iteration @}*/ m_Data->m_IterWidthScale = SnkExtract.ExtractFloat( "iter_width_scale", false); if(m_Data->m_IterWidthScale <= 0) m_Data->m_IterWidthScale = 1; /*@{ @declare{shadercomp.param} {eng_shader_special.filter.iter_height_scale}{$ [float]} Scale the image by this scale each iteration. The last iteration @}*/ m_Data->m_IterHeightScale = SnkExtract.ExtractFloat("iter_height_scale", false); if(m_Data->m_IterHeightScale <= 0) m_Data->m_IterHeightScale = 1; m_Data->m_DestProp = 0; /*@{ @declare{shadercomp.param} {eng_shader_special.filter.destprop_antialias}{$ [bool]} Render the filtering with antialiasing. @}*/ if(SnkExtract.ExtractBool("destprop_antialias", true)) m_Data->m_DestProp |= s3d_CDrvGfxEng::DestProp_Antialias; /*@{ @declare{shadercomp.param} {eng_shader_special.filter.width_scale}{$ [float]} Requested final horizontal scaling factor. @}*/ m_Data->m_WidthScale = SnkExtract.ExtractFloat("width_scale", false); if(m_Data->m_WidthScale <= 0) m_Data->m_WidthScale = 1; /*@{ @declare{shadercomp.param} {eng_shader_special.filter.height_scale}{$ [float]} Requested final vertical scaling factor. @}*/ m_Data->m_HeightScale = SnkExtract.ExtractFloat("height_scale", false); if(m_Data->m_HeightScale <= 0) m_Data->m_HeightScale = 1; /*@{ @declare{shadercomp.param} {eng_shader_special.filter.passinfo_var}{$ [str]} This variable is a name for the float4-vector containing information about the iteration. The first component of the vector contains the current iteration number, The second the total number of iterations. The remaining components are unused. @}*/ s3d_CUtilSnkExtractUtil::ExtractAtom( m_Data->m_TaskInfoVarInfo, m_Data->m_TaskInfoVarAtom, m_ShaderEnv->m_AtomMgr, SnkExtract, "passinfo_var", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.shaderprog_ident}{$ [str]} Shader program used for the smoothing iterations. @}*/ SnkExtract.ExtractStr( m_Data->m_ProgInfo, m_Data->m_ProgIdent, "shaderprog_ident", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.shaderprog_param_array} {$ [chunk] .. [chunk]} Defines which variables are passed to the shader program. See @ident{comp}{} for details. @}*/ s3d_CUtilSnkChunkArray ProgParamChunkArray; SnkExtract.ExtractChunkArray( m_Data->m_ProgParamInfo, ProgParamChunkArray, "shaderprog_param_array", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.src_array}{$ [str]..[str]} @}*/ s3d_CUtilSnkExtractUtil::ExtractAtomArray( m_Data->m_SrcVarInfo, m_Data->m_SrcVarAtomArray, m_ShaderEnv->m_AtomMgr, SnkExtract, "src_array", true); /*@{ @declare{shadercomp.param} {eng_shader_special.filter.dest_array}{$ [chunk]..[chunk]} See @ident{comp}{}. @}*/ s3d_CUtilSnkChunkArray DestChunkArray; SnkExtract.ExtractChunkArray(DestChunkArray, "dest_array", true); m_Data->m_UpdateInterval = SnkExtract.ExtractInt("update_interval", true, 1); m_Data->m_StartFrame = SnkExtract.ExtractInt("start_frame", true, 0); m_Data->m_UpdateAllFace = SnkExtract.ExtractBool("update_all_face", true, true); SnkExtract.CheckForUnknown(); int ExtraTexProp = 0; int ExtraSampMode = 0; m_Data->m_Dest.Init(m_ShaderEnv, ExtraTexProp, ExtraSampMode, DestChunkArray); s3d_CEngUtilGfxParamUtil::EvalMapProg( MsgHandler, m_Data->m_ProgParamInfo, m_ShaderEnv->m_AtomMgr, ProgParamChunkArray, m_Data->m_ProgParamMapArray); } void gtp_Shader_CubeTexFilter::SetupDone() { } s3d_CUtilStr gtp_Shader_CubeTexFilter::GetInfo() { return m_Data->m_Info; } void gtp_Shader_CubeTexFilter::RegisterNotif(s3d_CUtilNotifRecip *Recip) { } s3d_CEngShaderGfxPtr gtp_Shader_CubeTexFilter::FindShaderGfx( s3d_CUtilNotifGather *NotifGather, s3d_CEngGfxCtx *GfxCtx) { if(!m_ShaderEnv) return 0; gtp_Shader_CubeTexFilterGfxPtr ShaderGfx; gtp_Shader_CubeTexFilterGfxTree::CNode *Pos = s3d_UtilTreeSortedGetStart(m_ShaderGfxTree, GfxCtx); if(s3d_UtilTreeIsEqualAt(Pos, GfxCtx)) ShaderGfx = Pos->m_Data.m_Val; else { ShaderGfx = S3D_SYS_NEW gtp_Shader_CubeTexFilterGfx( m_ShaderEnv, NotifGather, GfxCtx, m_Data); gtp_Shader_CubeTexFilterGfxTree::CNode *Node = ShaderGfx->GetNode(); m_ShaderGfxTree.InsertBefore(Pos, Node); } return ShaderGfx.Get(); } /////////////////////////////////////////////////////////////////////////////// gtp_Shader_CubeTexFilterGfx::gtp_Shader_CubeTexFilterGfx( s3d_CEngShaderEnv *ShaderEnv, s3d_CUtilNotifGather *NotifGather, s3d_CEngGfxCtx *GfxCtx, gtp_Shader_CubeTexFilterData *Data) { m_Node.m_Data.m_Key = GfxCtx; m_Node.m_Data.m_Val = this; m_ShaderEnv = ShaderEnv; m_Data = Data; m_FilterDestGfx.Init(ShaderEnv, GfxCtx); s3d_CEngGfxProgMgr *GfxProgMgr = ShaderEnv->m_GfxProgMgr; if(GfxProgMgr) m_GfxProg = GfxProgMgr->CreateGfxProg( Data->m_ProgInfo, GfxCtx, NotifGather, Data->m_ProgIdent); } gtp_Shader_CubeTexFilterGfxTree::CNode *gtp_Shader_CubeTexFilterGfx::GetNode() { return &m_Node; } void gtp_Shader_CubeTexFilterGfx::RegisterNotif( s3d_CUtilNotifRecip *Recip) { } void gtp_Shader_CubeTexFilterGfx::ExtractGfx() { m_Node.Extract(); } bool gtp_Shader_CubeTexFilterGfx::IsValid() { if(m_GfxProg && !m_GfxProg->IsValid()) return false; return true; } void gtp_Shader_CubeTexFilterGfx::LinkCollect( s3d_CUtilAtomSet &VarAtomSet) { s3d_CDrvUtilVarUtil::LinkCollect( VarAtomSet, m_Data->m_TaskInfoVarAtom); s3d_CDrvUtilVarUtil::LinkCollectArray( VarAtomSet, m_Data->m_SrcVarAtomArray); m_FilterDestGfx.LinkCollect(VarAtomSet, m_Data->m_Dest); s3d_CDrvUtilVarUtil::LinkCollectExport( VarAtomSet, m_Data->m_ProgParamMapArray); } void gtp_Shader_CubeTexFilterGfx::LinkAppoint( s3d_CDrvVarDecl *VarDecl) { s3d_CDrvUtilVarUtil::LinkAppoint( m_TaskInfoVarSlot.m_Val, VarDecl, m_Data->m_TaskInfoVarAtom); s3d_CDrvUtilVarUtil::LinkAppointArray( m_SrcVarSlotArray, VarDecl, m_Data->m_SrcVarAtomArray); m_FilterDestGfx.LinkAppoint(VarDecl, m_Data->m_Dest); s3d_CDrvUtilVarUtil::LinkAppointExport( m_ShaderEnv->m_MsgHandler, m_Data->m_ProgParamInfo, m_ProgParamDecl, VarDecl, m_Data->m_ProgParamMapArray); } s3d_CEngShaderInstPtr gtp_Shader_CubeTexFilterGfx::CreateShaderInst( s3d_CEngShaderHead *Head) { s3d_CEngGfxCtx *GfxCtx = m_Node.m_Data.m_Key; return S3D_SYS_NEW gtp_Shader_CubeTexFilterInst( m_ShaderEnv, GfxCtx, this, m_GfxProg); } /////////////////////////////////////////////////////////////////////////////// gtp_Shader_CubeTexFilterInst::gtp_Shader_CubeTexFilterInst( s3d_CEngShaderEnv *ShaderEnv, s3d_CEngGfxCtx *GfxCtx, gtp_Shader_CubeTexFilterGfx *ShaderGfx, s3d_CEngGfxProg *GfxProg) { m_FrameCount = 0; m_ShaderEnv = ShaderEnv; m_GfxCtx = GfxCtx; m_ShaderGfx = ShaderGfx; m_GfxProg = GfxProg; } void gtp_Shader_CubeTexFilterInst::RegisterNotif( s3d_CUtilNotifRecip *Recip) { } void gtp_Shader_CubeTexFilterInst::SetShaderCtx( s3d_CEngShaderCtx *ShaderCtx) { } void gtp_Shader_CubeTexFilterInst::SetGfxState( s3d_CEngGfxState *GfxState) { } void gtp_Shader_CubeTexFilterInst::SetPos(s3d_CEngPos *Pos) { } void gtp_Shader_CubeTexFilterInst::SetModel(s3d_CEngModel *Model) { } void gtp_Shader_CubeTexFilterInst::ArrangeCollect( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray &ScopeArray) { } void gtp_Shader_CubeTexFilterInst::ArrangeInit( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { } void gtp_Shader_CubeTexFilterInst::ArrangePerform( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { } void gtp_Shader_CubeTexFilterInst::ArrangeFeedback( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScopeArray_cr ScopeArray) { } void gtp_Shader_CubeTexFilterInst::ArrangeGather( s3d_CEngShaderExecArray &ExecArray) { gtp_Shader_CubeTexFilterData *Data = m_ShaderGfx->m_Data; s3d_CEngUtilShaderUtil::ArrangeGather( ExecArray, Data->m_MethodArray, this); } void gtp_Shader_CubeTexFilterInst::ShaderExecPerform( s3d_CEngShaderScope *Scope, s3d_CUtilAtom *Method, s3d_CEngGfxTaskArray &TaskArray) { gtp_Shader_CubeTexFilterData *Data = m_ShaderGfx->m_Data; bool doRender = true; if(Data->m_UpdateInterval > 1) { if(m_FrameCount == Data->m_UpdateInterval) m_FrameCount = 0; m_FrameCount++; if(!(m_FrameCount % Data->m_UpdateInterval == 1)) doRender = false; } if(Data->m_UpdateInterval < 0) doRender = false; if(Data->m_UpdateInterval == 0) { Data->m_UpdateInterval = -1; Data->m_UpdateAllFace = true; } int Rank = Data->m_Rank; if(Rank == 0) return; if(doRender) { s3d_CEngGfxElemJob *GfxElemJob = new(m_ShaderEnv->m_MemPool) s3d_CEngUtilShaderItemJob( Scope, 0, this, >p_Shader_CubeTexFilterInst::GfxElemJobExec); s3d_CEngGfxTaskOrder KeyOrder = 0; s3d_CEngUtilGfxUtil::AppendTask( m_ShaderEnv->m_MemPool, TaskArray, Rank, KeyOrder, GfxElemJob); } } void *gtp_Shader_CubeTexFilterInst::GfxElemJobExec( s3d_CEngShaderScope *Scope, void *GfxMark) { gtp_Shader_CubeTexFilterGfx *ShaderGfx = m_ShaderGfx; const gtp_Shader_CubeTexFilterData *Data = ShaderGfx->m_Data; s3d_CDrvGfxEng *GfxEng = m_GfxCtx->m_GfxEng; if(!GfxEng) return GfxMark; s3d_CEngUtilShaderDestGfx *FilterDestGfx = &ShaderGfx->m_FilterDestGfx; s3d_CEngGfxVarTexChanArray FilterSrcTexArray; FetchSrcArray( m_ShaderEnv->m_MemPool, Scope, Data->m_SrcVarInfo.GetChars(), FilterSrcTexArray, ShaderGfx->m_SrcVarSlotArray); int RawBaseWidth = 0; int RawBaseHeight = 0; CalcSrcTexSize( m_ShaderEnv->m_MemPool, Scope, GfxEng, RawBaseWidth, RawBaseHeight, FilterSrcTexArray); int DestProp = 0; if(!FilterDestGfx->GetSnapTexPropWidthHeight( m_ShaderEnv, Scope, Data->m_Dest, RawBaseWidth, RawBaseHeight, DestProp)) return GfxMark; float BaseWidth = RawBaseWidth * Data->m_WidthScale; float BaseHeight = RawBaseHeight * Data->m_HeightScale; if(BaseWidth <= 0) return GfxMark; if(BaseHeight <= 0) return GfxMark; int IterStart = Data->m_IterStart; int IterEnd = Data->m_IterEnd; int IterStep = Data->m_IterStep; if(IterStep > 0) { float CurWidth = BaseWidth; float CurHeight = BaseHeight; int Iter; for(Iter = IterStart; Iter <= IterEnd; Iter += IterStep) { CurWidth /= Data->m_IterWidthScale; CurHeight /= Data->m_IterHeightScale; } for(Iter = IterStart; Iter <= IterEnd; Iter += IterStep) { CurWidth *= Data->m_IterWidthScale; CurHeight *= Data->m_IterHeightScale; Iteration(Scope, Iter, DestProp, CurWidth, CurHeight); } } else if(IterStep < 0) { float CurWidth = BaseWidth; float CurHeight = BaseHeight; int Iter; for(Iter = IterStart; Iter >= IterEnd; Iter += IterStep) { CurWidth /= Data->m_IterWidthScale; CurHeight /= Data->m_IterHeightScale; } for(Iter = IterStart; Iter >= IterEnd; Iter += IterStep) { CurWidth *= Data->m_IterWidthScale; CurHeight *= Data->m_IterHeightScale; Iteration(Scope, Iter, DestProp, CurWidth, CurHeight); } } else Iteration(Scope, IterStart, DestProp, BaseWidth, BaseHeight); return 0; } void gtp_Shader_CubeTexFilterInst::Iteration( s3d_CEngShaderScope *Scope, int Iter, int DestProp, float WantWidth, float WantHeight) { gtp_Shader_CubeTexFilterGfx *ShaderGfx = m_ShaderGfx; gtp_Shader_CubeTexFilterData *Data = ShaderGfx->m_Data; s3d_CEngUtilShaderDestGfx *FilterDestGfx = &ShaderGfx->m_FilterDestGfx; if(!Scope) return; s3d_CEngGfxPortion *Portion = Scope->m_Portion; if(!Portion) return; s3d_CEngGfxCycle *Cycle = Portion->m_Cycle; if(!Cycle) return; s3d_CUtilMemPool *MemPool = m_ShaderEnv->m_MemPool; s3d_CDrvVarVec4f *TaskInfoVar = new(MemPool) s3d_CDrvVarVec4f; TaskInfoVar->m_Val = 0; TaskInfoVar->m_Val.m_x = s3d_SysFloatOfInt(Iter); s3d_DrvVarSet(Scope->m_VarBlk, ShaderGfx->m_TaskInfoVarSlot, TaskInfoVar); if(!s3d_CEngUtilGfxUtil::VerifyGfxClosed( m_ShaderEnv->m_MsgHandler, Data->m_RankInfo.GetChars(), Portion->m_Cycle)) { Data->m_Rank = 0; // Avoid the error being reported each frame return; } s3d_CDrvGfxEng *GfxEng = m_GfxCtx->m_GfxEng; if(!GfxEng) return; s3d_CEngGfxVarTexChanArray FilterSrcTexArray; FetchSrcArray( MemPool, Scope, Data->m_SrcVarInfo.GetChars(), FilterSrcTexArray, ShaderGfx->m_SrcVarSlotArray); int DestWidth = s3d_SysIntOfFloatNearest(WantWidth); int DestHeight = s3d_SysIntOfFloatNearest(WantHeight); int DestDepth = 1; int DestSnap = s3d_CDrvGfxEng::TexSnap_PreferUp; GfxEng->SnapTexSize(DestWidth, DestHeight, DestDepth, DestProp, DestSnap); s3d_CEngUtilShaderDestJob *DestJob = FilterDestGfx->CreateJob( m_ShaderEnv, Scope, Data->m_Dest, DestWidth, DestHeight); if(!DestJob) return; s3d_CSysIntps nSrcTex = FilterSrcTexArray.GetCnt(); int nSamp = GfxEng->GetSampCnt(); if(nSrcTex > nSamp) { s3d_CUtilMsg e; e.m_Code = "eng/shader/eng_shader_special_filter.too_many_tex"; e.m_StdTempl = "Too many textures specified. " "Max textures allowed '[1]'."; e.AddInfo(Data->m_Info); e.AddInfo(s3d_CUtilStrUtil::StrOfInt(nSamp)); s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e); return; } // Filter: GfxEng->SetTransfIdentity(s3d_CDrvGfxEng::TransfChan_View, 0); GfxEng->SetTransfIdentity(s3d_CDrvGfxEng::TransfChan_Proj, 0); GfxEng->SetPaintMode(s3d_CDrvGfxEng::PaintMode_Fill); GfxEng->SetCullMode(s3d_CDrvGfxEng::CullMode_None); GfxEng->SetDepthTest(s3d_CDrvGfxEng::TestMode_Always); GfxEng->SetDepthWrite(false); GfxEng->SetDepthBias(0, 0); GfxEng->SetStencilMode( 0, 0, s3d_CDrvGfxEng::TestMode_Always, s3d_CDrvGfxEng::TestMode_Always, 0, s3d_CDrvGfxEng::StencilOp_Keep, s3d_CDrvGfxEng::StencilOp_Keep, s3d_CDrvGfxEng::StencilOp_Keep, s3d_CDrvGfxEng::StencilOp_Keep, s3d_CDrvGfxEng::StencilOp_Keep, s3d_CDrvGfxEng::StencilOp_Keep); GfxEng->SetFogNone(); GfxEng->SetBlendMode( s3d_CDrvGfxEng::BlendFac_One, s3d_CDrvGfxEng::BlendFac_Zero, s3d_CDrvGfxEng::BlendOp_SrcPlusDest, s3d_CDrvGfxEng::BlendFac_One, s3d_CDrvGfxEng::BlendFac_Zero, s3d_CDrvGfxEng::BlendOp_SrcPlusDest); GfxEng->SetAlphaTest(s3d_CDrvGfxEng::TestMode_Always, 0); GfxEng->DisableLighting(); GfxEng->SetColorAlpha(1); GfxEng->SetSampTexElseNone(int(nSrcTex)); s3d_CDrvGfxProg *DrvProg = 0; if(m_GfxProg) DrvProg = m_GfxProg->GetDrvProg(); s3d_CDrvGfxParam GfxParam; GfxParam.m_Blk.m_Decl = ShaderGfx->m_ProgParamDecl; GfxParam.m_Blk.m_Data = Scope->m_VarBlk.m_Data; s3d_CUtilMemPoolFrm MemPoolFrm(MemPool); s3d_CDrvUtilPaintTri PaintTri( Data->m_Info.GetChars(), MemPool, GfxEng, DrvProg); s3d_CDrvGfxClearParam ClearParam; s3d_CDrvGfxDest *Dest = DestJob->m_DrvGfxDestArray.GetPtrRaw(); s3d_CSysIntps nDestTex = DestJob->m_DrvGfxDestArray.GetCnt(); static const int CubeFaceMap[] = { s3d_CDrvGfxEng::TexPart_CubePosX, s3d_CDrvGfxEng::TexPart_CubeNegX, s3d_CDrvGfxEng::TexPart_CubePosY, s3d_CDrvGfxEng::TexPart_CubeNegY, s3d_CDrvGfxEng::TexPart_CubePosZ, s3d_CDrvGfxEng::TexPart_CubeNegZ, }; for(int iFace = 0; iFace < 6; iFace++) { if(!Data->m_UpdateAllFace) { iFace = m_CurrentFace; m_CurrentFace = (++m_CurrentFace) % 6; } for(int j = 0; j < nDestTex; j++) Dest[j].m_Part = CubeFaceMap[iFace]; GfxEng->BeginRenderTex(Data->m_DestProp, ClearParam, DestWidth, DestHeight, nDestTex, Dest); GfxEng->SetViewRect(1); int iSamp; for(iSamp = 0; iSamp < nSrcTex; iSamp++) { const s3d_CEngGfxVarTexChan *SrcTexChanVar = FilterSrcTexArray[iSamp]; s3d_CDrvGfxTex *DrvTex = 0; if(SrcTexChanVar) DrvTex = SrcTexChanVar->m_Val.m_FixedDrvTex; GfxEng->SetSampTex(iSamp, DrvTex); GfxEng->SetSampMode(iSamp, SrcTexChanVar->m_Val.m_FixedSampMode); } PaintTri.AddQuadAligned( s3d_CUtilVec2f(-1, -1), s3d_CUtilVec2f(0, 0), s3d_CUtilVec2f(1, 1), s3d_CUtilVec2f(1, 1), (float)iFace, 1); PaintTri.Perform(GfxParam); GfxEng->EndRender(); } FilterDestGfx->FinishJob( m_ShaderEnv, Scope, Data->m_Dest, DestJob); } void gtp_Shader_CubeTexFilterInst::FetchSrcArray( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScope *Scope, const s3d_CSysChar *Info, s3d_CEngGfxVarTexChanArray &SrcTexArray, s3d_CDrvVarSlotArray &SrcVarSlotArray) { s3d_CSysIntps nTex = SrcVarSlotArray.GetCnt(); SrcTexArray.SetCnt(MemPool, nTex); s3d_CSysIntps iTex; for(iTex = 0; iTex < nTex; iTex++) { s3d_CEngGfxVarTexChan *TexChanVar = s3d_EngGfxVarFetchWaryTexChan( m_ShaderEnv->m_MsgHandler, Info, Scope->m_VarBlk, SrcVarSlotArray.RefAt(iTex)); SrcTexArray.SetAt(iTex, TexChanVar); } } void gtp_Shader_CubeTexFilterInst::CalcSrcTexSize( s3d_CUtilMemPool *MemPool, s3d_CEngShaderScope *Scope, s3d_CDrvGfxEng *GfxEng, int &Width, int &Height, s3d_CEngGfxVarTexChanArray &FilterSrcTexArray) { Width = 0; Height = 0; s3d_CSysIntps nSrcTex = FilterSrcTexArray.GetCnt(); s3d_CSysIntps iSrcTex; for(iSrcTex = 0; iSrcTex < nSrcTex; iSrcTex++) { s3d_CEngGfxVarTexChan *SrcTexChan = FilterSrcTexArray[iSrcTex]; if(!SrcTexChan) continue; s3d_CDrvGfxTex *SrcDrvTex = SrcTexChan->m_Val.m_FixedDrvTex; if(!SrcDrvTex) continue; int SrcTexWidth, SrcTexHeight, SrcTexDepth; SrcDrvTex->GetSize(SrcTexWidth, SrcTexHeight, SrcTexDepth); if(Width < SrcTexWidth) Width = SrcTexWidth; if(Height < SrcTexHeight) Height = SrcTexHeight; } } ///////////////////////////////////////////////////////////////////////////////