source: GTP/trunk/App/Demos/Illum/Shark3D/version164x12u/IllumDemo/src/gtp_shader/gtp_shader_cubetexfilter.cpp @ 2196

Revision 2196, 24.7 KB checked in by szirmay, 17 years ago (diff)
Line 
1///////////////////////////////////////////////////////////////////////////////
2//
3//      ##  ######
4//       ######  ###
5//  ## ###############        Shark 3D Engine (www.shark3d.com)
6//   ########## # # #
7//    ########                Copyright (c) 1996-2006 Spinor GmbH.
8//   ######### # # #          All rights reserved.
9//  ##   ##########
10//      ##
11//
12///////////////////////////////////////////////////////////////////////////////
13
14//@cpp
15
16#include "gtp_shader_cubetexfilter.h"
17#include "../../interf/eng_gfxvar.h"
18#include "../../util/eng_util_gfxutil.h"
19#include "../../util/eng_util_gfxparamutil.h"
20#include "../../util/eng_util_shaderutil.h"
21#include "../../util/eng_util_shaderitemjob.h"
22#include "../../../drv/interf/drv_vartypes.h"
23#include "../../../drv/util/drv_util_varutil.h"
24#include "../../../drv/util/drv_util_gfxutil.h"
25#include "../../../drv/util/drv_util_paintprim.h"
26#include "../../../util/snk/util_snk_extractutil.h"
27
28///////////////////////////////////////////////////////////////////////////////
29/*@{
30
31@declare{shadercomp.class}{eng_shader_special.filter}{}
32
33This component performs some iterative texture filtering.
34@p
35
36The component takes none, one or multiple source textures as input,
37see @sident{comp}{eng_shader_special.filter.src_array}.
38Then it passes them to a shaderprogram,
39see @sident{comp}{eng_shader_special.filter.shaderprog_ident}.
40Then it writes the result to none, one or multiple @em{destination} textures,
41see @sident{comp}{eng_shader_special.filter.dest_array}.
42@p
43
44If the destination textures have already been allocated
45they are used "as is", but only if they all have the same size.
46Otherwise temporary textures will fetched.
47Their size is the maximum of the source textures scaled by
48@sident{comp}{eng_shader_special.filter.width_scale} and
49@sident{comp}{eng_shader_special.filter.height_scale}.
50If necessary the destination texture size is @em{snapped}
51to a value acceptable to the graphics card.
52@p
53
54@}*/
55///////////////////////////////////////////////////////////////////////////////
56
57S3D_UTIL_RTTI_TABLE_DEFINE_BEGIN(gtp_Shader_CubeTexFilter)
58S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CEngShader)
59S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompUtilUniqueBase)
60S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompSetup)
61S3D_UTIL_RTTI_TABLE_DEFINE_END
62
63gtp_Shader_CubeTexFilter::gtp_Shader_CubeTexFilter()
64{
65}
66
67void gtp_Shader_CubeTexFilter::SetupInit(
68        s3d_CUtilMsgHandler *MsgHandler, s3d_CUtilStr_cr Info,
69        s3d_CCompSuppl *FetchSuppl, s3d_CUtilSnkChunk *Param)
70{
71    m_Data = S3D_SYS_NEW gtp_Shader_CubeTexFilterData;
72
73    s3d_CUtilSnkExtract SnkExtract;
74    SnkExtract.Assign(MsgHandler, Param);
75    m_Data->m_Info = SnkExtract.GetInfo();
76   
77    /*@{ @declare{shadercomp.param}{eng_shader_special.filter.env}{$ [str]}
78        See @ident{comp}{eng_shader_std.group.env}.
79    @}*/
80    s3d_CUtilStr EnvIdent, EnvInfo;
81    SnkExtract.ExtractStr(EnvInfo, EnvIdent, "env", true);
82
83    m_ShaderEnv = s3d_CompSupplObjT<s3d_CEngShaderEnv>(
84            MsgHandler, EnvInfo, FetchSuppl,
85            EnvIdent, S3D_GENERAL_INTEROP_INTERF);
86    if(!m_ShaderEnv)
87        return;
88
89    /*@{ @declare{shadercomp.param}
90            {eng_shader_special.filter.methods}{$ [str] .. [str]}
91        See @ref{prog_man.shader.methods}.
92    @}*/
93    s3d_CUtilSnkExtractUtil::ExtractAtomSortedArray(
94            m_Data->m_MethodArray, m_ShaderEnv->m_AtomMgr,
95            SnkExtract, "methods", true);
96
97    /*@{ @declare{shadercomp.param}
98            {eng_shader_special.filter.rank}{$ [str]}
99       Rank of the shader in the rendering sequence.
100    @}*/
101    SnkExtract.ExtractInt(m_Data->m_RankInfo, m_Data->m_Rank, "rank", true);
102   
103    /*@{ @declare{shadercomp.param}
104            {eng_shader_special.filter.iter_start}{$ [int]}
105        Iteration start value.
106    @}*/
107    m_Data->m_IterStart = SnkExtract.ExtractInt("iter_start", true);
108
109    /*@{ @declare{shadercomp.param}
110            {eng_shader_special.filter.iter_end}{$ [int]}
111        Iteration end value.
112    @}*/
113    m_Data->m_IterEnd = SnkExtract.ExtractInt("iter_end", true);
114
115    /*@{ @declare{shadercomp.param}
116            {eng_shader_special.filter.iter_step}{$ [int]}
117        Iteration step.
118        If the step is positive, then the step is added to the start value
119        until the value is larger than the end.
120        If the step is negative, then the step is added to the start value
121        until the value is smaller than the end.
122        If the step is zero, the iteration is only executed once
123        for the start value.
124    @}*/
125    m_Data->m_IterStep = SnkExtract.ExtractInt("iter_step", true);
126
127    /*@{ @declare{shadercomp.param}
128            {eng_shader_special.filter.iter_width_scale}{$ [float]}
129        Scale the image by this scale each iteration.
130        The last iteration
131    @}*/
132    m_Data->m_IterWidthScale = SnkExtract.ExtractFloat(
133            "iter_width_scale", false);
134    if(m_Data->m_IterWidthScale <= 0)
135        m_Data->m_IterWidthScale = 1;
136
137    /*@{ @declare{shadercomp.param}
138            {eng_shader_special.filter.iter_height_scale}{$ [float]}
139        Scale the image by this scale each iteration.
140        The last iteration
141    @}*/
142    m_Data->m_IterHeightScale
143            = SnkExtract.ExtractFloat("iter_height_scale", false);
144    if(m_Data->m_IterHeightScale <= 0)
145        m_Data->m_IterHeightScale = 1;
146
147    m_Data->m_DestProp = 0;
148
149    /*@{ @declare{shadercomp.param}
150            {eng_shader_special.filter.destprop_antialias}{$ [bool]}
151        Render the filtering with antialiasing.
152    @}*/
153    if(SnkExtract.ExtractBool("destprop_antialias", true))
154        m_Data->m_DestProp |= s3d_CDrvGfxEng::DestProp_Antialias;
155
156    /*@{ @declare{shadercomp.param}
157            {eng_shader_special.filter.width_scale}{$ [float]}
158       Requested final horizontal scaling factor.
159    @}*/
160    m_Data->m_WidthScale = SnkExtract.ExtractFloat("width_scale", false);
161    if(m_Data->m_WidthScale <= 0)
162        m_Data->m_WidthScale = 1;
163
164    /*@{ @declare{shadercomp.param}
165            {eng_shader_special.filter.height_scale}{$ [float]}
166       Requested final vertical scaling factor.
167    @}*/
168    m_Data->m_HeightScale = SnkExtract.ExtractFloat("height_scale", false);
169    if(m_Data->m_HeightScale <= 0)
170        m_Data->m_HeightScale = 1;
171
172    /*@{ @declare{shadercomp.param}
173            {eng_shader_special.filter.passinfo_var}{$ [str]}
174       This variable is a name for the float4-vector
175       containing information about the iteration.
176       The first component of the vector contains the current iteration number,
177       The second the total number of iterations.
178       The remaining components are unused.
179    @}*/
180    s3d_CUtilSnkExtractUtil::ExtractAtom(
181            m_Data->m_TaskInfoVarInfo, m_Data->m_TaskInfoVarAtom,
182            m_ShaderEnv->m_AtomMgr, SnkExtract, "passinfo_var", true);
183
184    /*@{ @declare{shadercomp.param}
185            {eng_shader_special.filter.shaderprog_ident}{$ [str]}
186       Shader program used for the smoothing iterations.
187    @}*/
188    SnkExtract.ExtractStr(
189            m_Data->m_ProgInfo, m_Data->m_ProgIdent,
190            "shaderprog_ident", true);
191
192    /*@{ @declare{shadercomp.param}
193            {eng_shader_special.filter.shaderprog_param_array}
194            {$ [chunk] .. [chunk]}
195       Defines which variables are passed to the shader program.
196       See @ident{comp}{<shaderprog.map_prog_array>} for details.
197    @}*/
198    s3d_CUtilSnkChunkArray ProgParamChunkArray;
199    SnkExtract.ExtractChunkArray(
200            m_Data->m_ProgParamInfo, ProgParamChunkArray,
201            "shaderprog_param_array", true);
202   
203    /*@{ @declare{shadercomp.param}
204            {eng_shader_special.filter.src_array}{$ [str]..[str]}
205    @}*/
206    s3d_CUtilSnkExtractUtil::ExtractAtomArray(
207            m_Data->m_SrcVarInfo, m_Data->m_SrcVarAtomArray,
208            m_ShaderEnv->m_AtomMgr, SnkExtract, "src_array", true);
209   
210    /*@{ @declare{shadercomp.param}
211            {eng_shader_special.filter.dest_array}{$ [chunk]..[chunk]}
212        See @ident{comp}{<dest_array>}.
213    @}*/
214    s3d_CUtilSnkChunkArray DestChunkArray;
215    SnkExtract.ExtractChunkArray(DestChunkArray, "dest_array", true);
216
217        m_Data->m_UpdateInterval = SnkExtract.ExtractInt("update_interval", true, 1);
218        m_Data->m_StartFrame = SnkExtract.ExtractInt("start_frame", true, 0);
219    m_Data->m_UpdateAllFace = SnkExtract.ExtractBool("update_all_face", true, true);
220       
221    SnkExtract.CheckForUnknown();
222
223    int ExtraTexProp = 0;
224    int ExtraSampMode = 0;
225    m_Data->m_Dest.Init(m_ShaderEnv, ExtraTexProp,
226            ExtraSampMode, DestChunkArray);
227
228    s3d_CEngUtilGfxParamUtil::EvalMapProg(
229            MsgHandler, m_Data->m_ProgParamInfo,
230            m_ShaderEnv->m_AtomMgr, ProgParamChunkArray,
231            m_Data->m_ProgParamMapArray);
232}
233
234void gtp_Shader_CubeTexFilter::SetupDone()
235{
236}
237
238s3d_CUtilStr gtp_Shader_CubeTexFilter::GetInfo()
239{
240    return m_Data->m_Info;
241}
242
243void gtp_Shader_CubeTexFilter::RegisterNotif(s3d_CUtilNotifRecip *Recip)
244{
245}
246
247s3d_CEngShaderGfxPtr gtp_Shader_CubeTexFilter::FindShaderGfx(
248        s3d_CUtilNotifGather *NotifGather, s3d_CEngGfxCtx *GfxCtx)
249{
250    if(!m_ShaderEnv)
251        return 0;
252
253    gtp_Shader_CubeTexFilterGfxPtr ShaderGfx;
254    gtp_Shader_CubeTexFilterGfxTree::CNode *Pos
255            = s3d_UtilTreeSortedGetStart(m_ShaderGfxTree, GfxCtx);
256    if(s3d_UtilTreeIsEqualAt(Pos, GfxCtx))
257        ShaderGfx = Pos->m_Data.m_Val;
258    else
259    {
260        ShaderGfx = S3D_SYS_NEW gtp_Shader_CubeTexFilterGfx(
261                m_ShaderEnv, NotifGather, GfxCtx, m_Data);
262        gtp_Shader_CubeTexFilterGfxTree::CNode *Node
263                = ShaderGfx->GetNode();
264        m_ShaderGfxTree.InsertBefore(Pos, Node);
265    }
266    return ShaderGfx.Get();
267}
268
269///////////////////////////////////////////////////////////////////////////////
270
271gtp_Shader_CubeTexFilterGfx::gtp_Shader_CubeTexFilterGfx(
272        s3d_CEngShaderEnv *ShaderEnv, s3d_CUtilNotifGather *NotifGather,
273        s3d_CEngGfxCtx *GfxCtx,
274        gtp_Shader_CubeTexFilterData *Data)
275{
276    m_Node.m_Data.m_Key = GfxCtx;
277    m_Node.m_Data.m_Val = this;
278    m_ShaderEnv = ShaderEnv;
279    m_Data = Data;
280
281    m_FilterDestGfx.Init(ShaderEnv, GfxCtx);
282
283    s3d_CEngGfxProgMgr *GfxProgMgr = ShaderEnv->m_GfxProgMgr;
284    if(GfxProgMgr)
285        m_GfxProg = GfxProgMgr->CreateGfxProg(
286                Data->m_ProgInfo, GfxCtx, NotifGather,
287                Data->m_ProgIdent);
288}
289
290gtp_Shader_CubeTexFilterGfxTree::CNode
291        *gtp_Shader_CubeTexFilterGfx::GetNode()
292{
293    return &m_Node;
294}
295
296void gtp_Shader_CubeTexFilterGfx::RegisterNotif(
297        s3d_CUtilNotifRecip *Recip)
298{
299}
300
301void gtp_Shader_CubeTexFilterGfx::ExtractGfx()
302{
303    m_Node.Extract();
304}
305
306bool gtp_Shader_CubeTexFilterGfx::IsValid()
307{
308    if(m_GfxProg && !m_GfxProg->IsValid())
309        return false;
310    return true;
311}
312
313void gtp_Shader_CubeTexFilterGfx::LinkCollect(
314        s3d_CUtilAtomSet &VarAtomSet)
315{
316    s3d_CDrvUtilVarUtil::LinkCollect(
317            VarAtomSet, m_Data->m_TaskInfoVarAtom);
318    s3d_CDrvUtilVarUtil::LinkCollectArray(
319            VarAtomSet, m_Data->m_SrcVarAtomArray);
320
321    m_FilterDestGfx.LinkCollect(VarAtomSet, m_Data->m_Dest);
322
323    s3d_CDrvUtilVarUtil::LinkCollectExport(
324            VarAtomSet, m_Data->m_ProgParamMapArray);
325}
326
327void gtp_Shader_CubeTexFilterGfx::LinkAppoint(
328        s3d_CDrvVarDecl *VarDecl)
329{
330    s3d_CDrvUtilVarUtil::LinkAppoint(
331            m_TaskInfoVarSlot.m_Val,
332            VarDecl, m_Data->m_TaskInfoVarAtom);
333    s3d_CDrvUtilVarUtil::LinkAppointArray(
334            m_SrcVarSlotArray,
335            VarDecl, m_Data->m_SrcVarAtomArray);
336   
337    m_FilterDestGfx.LinkAppoint(VarDecl, m_Data->m_Dest);
338
339    s3d_CDrvUtilVarUtil::LinkAppointExport(
340            m_ShaderEnv->m_MsgHandler, m_Data->m_ProgParamInfo,
341            m_ProgParamDecl, VarDecl,
342            m_Data->m_ProgParamMapArray);
343}
344
345s3d_CEngShaderInstPtr gtp_Shader_CubeTexFilterGfx::CreateShaderInst(
346        s3d_CEngShaderHead *Head)
347{
348    s3d_CEngGfxCtx *GfxCtx = m_Node.m_Data.m_Key;
349    return S3D_SYS_NEW gtp_Shader_CubeTexFilterInst(
350            m_ShaderEnv, GfxCtx, this, m_GfxProg);
351}
352
353///////////////////////////////////////////////////////////////////////////////
354
355gtp_Shader_CubeTexFilterInst::gtp_Shader_CubeTexFilterInst(
356        s3d_CEngShaderEnv *ShaderEnv,
357        s3d_CEngGfxCtx *GfxCtx,
358        gtp_Shader_CubeTexFilterGfx *ShaderGfx,
359        s3d_CEngGfxProg *GfxProg)
360{
361    m_FrameCount = 0;
362        m_ShaderEnv = ShaderEnv;
363    m_GfxCtx = GfxCtx;
364    m_ShaderGfx = ShaderGfx;
365    m_GfxProg = GfxProg;
366}
367
368void gtp_Shader_CubeTexFilterInst::RegisterNotif(
369        s3d_CUtilNotifRecip *Recip)
370{
371}
372
373void gtp_Shader_CubeTexFilterInst::SetShaderCtx(
374        s3d_CEngShaderCtx *ShaderCtx)
375{
376}
377
378void gtp_Shader_CubeTexFilterInst::SetGfxState(
379        s3d_CEngGfxState *GfxState)
380{
381}
382
383void gtp_Shader_CubeTexFilterInst::SetPos(s3d_CEngPos *Pos)
384{
385}
386
387void gtp_Shader_CubeTexFilterInst::SetModel(s3d_CEngModel *Model)
388{
389}
390
391void gtp_Shader_CubeTexFilterInst::ArrangeCollect(
392        s3d_CUtilMemPool *MemPool,
393        s3d_CEngShaderScopeArray &ScopeArray)
394{
395}
396
397void gtp_Shader_CubeTexFilterInst::ArrangeInit(
398        s3d_CUtilMemPool *MemPool,
399        s3d_CEngShaderScopeArray_cr ScopeArray)
400{
401}
402
403void gtp_Shader_CubeTexFilterInst::ArrangePerform(
404        s3d_CUtilMemPool *MemPool,
405        s3d_CEngShaderScopeArray_cr ScopeArray)
406{
407}
408
409void gtp_Shader_CubeTexFilterInst::ArrangeFeedback(
410        s3d_CUtilMemPool *MemPool,
411        s3d_CEngShaderScopeArray_cr ScopeArray)
412{
413}
414
415void gtp_Shader_CubeTexFilterInst::ArrangeGather(
416        s3d_CEngShaderExecArray &ExecArray)
417{
418    gtp_Shader_CubeTexFilterData *Data = m_ShaderGfx->m_Data;
419
420    s3d_CEngUtilShaderUtil::ArrangeGather(
421            ExecArray, Data->m_MethodArray, this);
422}
423
424void gtp_Shader_CubeTexFilterInst::ShaderExecPerform(
425        s3d_CEngShaderScope *Scope,
426        s3d_CUtilAtom *Method,
427        s3d_CEngGfxTaskArray &TaskArray)
428{
429    gtp_Shader_CubeTexFilterData *Data = m_ShaderGfx->m_Data;
430
431        bool doRender = true;
432        if(Data->m_UpdateInterval > 1)
433        {
434                if(m_FrameCount == Data->m_UpdateInterval)
435                        m_FrameCount = 0;
436                m_FrameCount++;
437                if(!(m_FrameCount % Data->m_UpdateInterval == 1))       
438                        doRender = false;
439        }
440        if(Data->m_UpdateInterval < 0)
441                doRender = false;
442        if(Data->m_UpdateInterval == 0)
443        {
444                Data->m_UpdateInterval = -1;
445            Data->m_UpdateAllFace = true;
446        }
447
448    int Rank = Data->m_Rank;
449    if(Rank == 0)
450        return;
451       
452        if(doRender)
453        {
454                s3d_CEngGfxElemJob *GfxElemJob = new(m_ShaderEnv->m_MemPool)
455                                s3d_CEngUtilShaderItemJob<gtp_Shader_CubeTexFilterInst>(
456                                Scope, 0,
457                                this, &gtp_Shader_CubeTexFilterInst::GfxElemJobExec);
458
459                s3d_CEngGfxTaskOrder KeyOrder = 0;
460                s3d_CEngUtilGfxUtil::AppendTask(
461                                m_ShaderEnv->m_MemPool, TaskArray, Rank, KeyOrder, GfxElemJob);
462        }
463}
464
465void *gtp_Shader_CubeTexFilterInst::GfxElemJobExec(
466        s3d_CEngShaderScope *Scope,
467        void *GfxMark)
468{
469    gtp_Shader_CubeTexFilterGfx *ShaderGfx = m_ShaderGfx;
470    const gtp_Shader_CubeTexFilterData *Data = ShaderGfx->m_Data;
471
472    s3d_CDrvGfxEng *GfxEng = m_GfxCtx->m_GfxEng;
473    if(!GfxEng)
474        return GfxMark;
475
476    s3d_CEngUtilShaderDestGfx *FilterDestGfx = &ShaderGfx->m_FilterDestGfx;
477
478    s3d_CEngGfxVarTexChanArray FilterSrcTexArray;
479    FetchSrcArray(
480            m_ShaderEnv->m_MemPool, Scope, Data->m_SrcVarInfo.GetChars(),
481            FilterSrcTexArray, ShaderGfx->m_SrcVarSlotArray);
482
483    int RawBaseWidth = 0;
484    int RawBaseHeight = 0;
485    CalcSrcTexSize(
486            m_ShaderEnv->m_MemPool, Scope, GfxEng,
487            RawBaseWidth, RawBaseHeight, FilterSrcTexArray);
488   
489    int DestProp = 0;
490    if(!FilterDestGfx->GetSnapTexPropWidthHeight(
491                m_ShaderEnv, Scope, Data->m_Dest,
492                RawBaseWidth, RawBaseHeight, DestProp))
493        return GfxMark;
494
495    float BaseWidth = RawBaseWidth * Data->m_WidthScale;
496    float BaseHeight = RawBaseHeight * Data->m_HeightScale;
497    if(BaseWidth <= 0)
498        return GfxMark;
499    if(BaseHeight <= 0)
500        return GfxMark;
501
502    int IterStart = Data->m_IterStart;
503    int IterEnd = Data->m_IterEnd;
504    int IterStep = Data->m_IterStep;
505    if(IterStep > 0)
506    {
507        float CurWidth = BaseWidth;
508        float CurHeight = BaseHeight;
509        int Iter;
510        for(Iter = IterStart; Iter <= IterEnd; Iter += IterStep)
511        {
512            CurWidth /= Data->m_IterWidthScale;
513            CurHeight /= Data->m_IterHeightScale;
514        }
515        for(Iter = IterStart; Iter <= IterEnd; Iter += IterStep)
516        {
517            CurWidth *= Data->m_IterWidthScale;
518            CurHeight *= Data->m_IterHeightScale;
519            Iteration(Scope, Iter, DestProp, CurWidth, CurHeight);
520        }
521    }
522    else if(IterStep < 0)
523    {
524        float CurWidth = BaseWidth;
525        float CurHeight = BaseHeight;
526        int Iter;
527        for(Iter = IterStart; Iter >= IterEnd; Iter += IterStep)
528        {
529            CurWidth /= Data->m_IterWidthScale;
530            CurHeight /= Data->m_IterHeightScale;
531        }
532        for(Iter = IterStart; Iter >= IterEnd; Iter += IterStep)
533        {
534            CurWidth *= Data->m_IterWidthScale;
535            CurHeight *= Data->m_IterHeightScale;
536            Iteration(Scope, Iter, DestProp, CurWidth, CurHeight);
537        }
538    }
539    else
540        Iteration(Scope, IterStart, DestProp, BaseWidth, BaseHeight);
541
542    return 0;
543}
544
545void gtp_Shader_CubeTexFilterInst::Iteration(
546        s3d_CEngShaderScope *Scope, int Iter,
547        int DestProp, float WantWidth, float WantHeight)
548{
549    gtp_Shader_CubeTexFilterGfx *ShaderGfx = m_ShaderGfx;
550    gtp_Shader_CubeTexFilterData *Data = ShaderGfx->m_Data;
551    s3d_CEngUtilShaderDestGfx *FilterDestGfx = &ShaderGfx->m_FilterDestGfx;
552
553    if(!Scope)
554        return;
555
556    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
557    if(!Portion)
558        return;
559    s3d_CEngGfxCycle *Cycle = Portion->m_Cycle;
560    if(!Cycle)
561        return;
562
563    s3d_CUtilMemPool *MemPool = m_ShaderEnv->m_MemPool;
564
565    s3d_CDrvVarVec4f *TaskInfoVar = new(MemPool) s3d_CDrvVarVec4f;
566    TaskInfoVar->m_Val = 0;
567    TaskInfoVar->m_Val.m_x = s3d_SysFloatOfInt<float>(Iter);
568    s3d_DrvVarSet(Scope->m_VarBlk, ShaderGfx->m_TaskInfoVarSlot, TaskInfoVar);
569
570    if(!s3d_CEngUtilGfxUtil::VerifyGfxClosed(
571            m_ShaderEnv->m_MsgHandler, Data->m_RankInfo.GetChars(),
572            Portion->m_Cycle))
573    {
574        Data->m_Rank = 0; // Avoid the error being reported each frame
575        return;
576    }
577
578    s3d_CDrvGfxEng *GfxEng = m_GfxCtx->m_GfxEng;
579    if(!GfxEng)
580        return;
581
582    s3d_CEngGfxVarTexChanArray FilterSrcTexArray;
583    FetchSrcArray(
584            MemPool, Scope, Data->m_SrcVarInfo.GetChars(),
585            FilterSrcTexArray, ShaderGfx->m_SrcVarSlotArray);
586
587    int DestWidth = s3d_SysIntOfFloatNearest(WantWidth);
588    int DestHeight = s3d_SysIntOfFloatNearest(WantHeight);
589    int DestDepth = 1;
590    int DestSnap = s3d_CDrvGfxEng::TexSnap_PreferUp;
591    GfxEng->SnapTexSize(DestWidth, DestHeight, DestDepth, DestProp, DestSnap);
592
593    s3d_CEngUtilShaderDestJob *DestJob = FilterDestGfx->CreateJob(
594                m_ShaderEnv, Scope, Data->m_Dest, DestWidth, DestHeight);
595    if(!DestJob)
596        return;
597
598    s3d_CSysIntps nSrcTex = FilterSrcTexArray.GetCnt();
599    int nSamp = GfxEng->GetSampCnt();
600   
601    if(nSrcTex > nSamp)
602    {
603        s3d_CUtilMsg e;
604        e.m_Code = "eng/shader/eng_shader_special_filter.too_many_tex";
605        e.m_StdTempl = "Too many textures specified. "
606                       "Max textures allowed '[1]'.";
607        e.AddInfo(Data->m_Info);
608        e.AddInfo(s3d_CUtilStrUtil::StrOfInt(nSamp));
609        s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
610        return;
611    }
612
613    // Filter:
614
615    GfxEng->SetTransfIdentity(s3d_CDrvGfxEng::TransfChan_View, 0);
616    GfxEng->SetTransfIdentity(s3d_CDrvGfxEng::TransfChan_Proj, 0);
617    GfxEng->SetPaintMode(s3d_CDrvGfxEng::PaintMode_Fill);
618    GfxEng->SetCullMode(s3d_CDrvGfxEng::CullMode_None);
619    GfxEng->SetDepthTest(s3d_CDrvGfxEng::TestMode_Always);
620    GfxEng->SetDepthWrite(false);
621    GfxEng->SetDepthBias(0, 0);
622    GfxEng->SetStencilMode(
623            0,
624            0,
625            s3d_CDrvGfxEng::TestMode_Always,
626            s3d_CDrvGfxEng::TestMode_Always,
627            0,
628            s3d_CDrvGfxEng::StencilOp_Keep,
629            s3d_CDrvGfxEng::StencilOp_Keep,
630            s3d_CDrvGfxEng::StencilOp_Keep,
631            s3d_CDrvGfxEng::StencilOp_Keep,
632            s3d_CDrvGfxEng::StencilOp_Keep,
633            s3d_CDrvGfxEng::StencilOp_Keep);
634    GfxEng->SetFogNone();
635    GfxEng->SetBlendMode(
636            s3d_CDrvGfxEng::BlendFac_One,
637            s3d_CDrvGfxEng::BlendFac_Zero,
638            s3d_CDrvGfxEng::BlendOp_SrcPlusDest,
639            s3d_CDrvGfxEng::BlendFac_One,
640            s3d_CDrvGfxEng::BlendFac_Zero,
641            s3d_CDrvGfxEng::BlendOp_SrcPlusDest);
642    GfxEng->SetAlphaTest(s3d_CDrvGfxEng::TestMode_Always, 0);
643    GfxEng->DisableLighting();
644    GfxEng->SetColorAlpha(1);
645
646    GfxEng->SetSampTexElseNone(int(nSrcTex));
647
648    s3d_CDrvGfxProg *DrvProg = 0;
649    if(m_GfxProg)
650        DrvProg = m_GfxProg->GetDrvProg();
651
652    s3d_CDrvGfxParam GfxParam;
653    GfxParam.m_Blk.m_Decl = ShaderGfx->m_ProgParamDecl;
654    GfxParam.m_Blk.m_Data = Scope->m_VarBlk.m_Data;
655
656    s3d_CUtilMemPoolFrm MemPoolFrm(MemPool);
657    s3d_CDrvUtilPaintTri PaintTri(
658            Data->m_Info.GetChars(), MemPool, GfxEng, DrvProg);
659
660    s3d_CDrvGfxClearParam ClearParam;
661    s3d_CDrvGfxDest *Dest = DestJob->m_DrvGfxDestArray.GetPtrRaw();
662    s3d_CSysIntps nDestTex = DestJob->m_DrvGfxDestArray.GetCnt();
663   
664        static const int CubeFaceMap[] =
665    {
666        s3d_CDrvGfxEng::TexPart_CubePosX, s3d_CDrvGfxEng::TexPart_CubeNegX,
667        s3d_CDrvGfxEng::TexPart_CubePosY, s3d_CDrvGfxEng::TexPart_CubeNegY,   
668        s3d_CDrvGfxEng::TexPart_CubePosZ, s3d_CDrvGfxEng::TexPart_CubeNegZ,
669    };
670
671        for(int iFace = 0; iFace < 6; iFace++) 
672        {
673                if(!Data->m_UpdateAllFace)
674                {
675                        iFace = m_CurrentFace;
676                        m_CurrentFace = (++m_CurrentFace) % 6;
677                }
678
679                for(int j = 0; j < nDestTex; j++)
680                  Dest[j].m_Part = CubeFaceMap[iFace];
681
682                GfxEng->BeginRenderTex(Data->m_DestProp, ClearParam,
683                                DestWidth, DestHeight, nDestTex, Dest);
684                GfxEng->SetViewRect(1);
685   
686                int iSamp;
687                for(iSamp = 0; iSamp < nSrcTex; iSamp++)
688                {
689                        const s3d_CEngGfxVarTexChan *SrcTexChanVar =
690                                        FilterSrcTexArray[iSamp];
691                        s3d_CDrvGfxTex *DrvTex = 0;
692                        if(SrcTexChanVar)
693                                DrvTex = SrcTexChanVar->m_Val.m_FixedDrvTex;
694                        GfxEng->SetSampTex(iSamp, DrvTex);
695                        GfxEng->SetSampMode(iSamp, SrcTexChanVar->m_Val.m_FixedSampMode);
696                }
697                       
698                PaintTri.AddQuadAligned(
699            s3d_CUtilVec2f(-1, -1),
700            s3d_CUtilVec2f(0, 0),
701            s3d_CUtilVec2f(1, 1),
702            s3d_CUtilVec2f(1, 1),
703            (float)iFace, 1);
704
705                PaintTri.Perform(GfxParam);
706
707                GfxEng->EndRender();           
708        }
709
710    FilterDestGfx->FinishJob(
711            m_ShaderEnv, Scope, Data->m_Dest, DestJob);
712}
713
714void gtp_Shader_CubeTexFilterInst::FetchSrcArray(
715        s3d_CUtilMemPool *MemPool, s3d_CEngShaderScope *Scope,
716        const s3d_CSysChar *Info,
717        s3d_CEngGfxVarTexChanArray &SrcTexArray,
718        s3d_CDrvVarSlotArray &SrcVarSlotArray)
719{
720    s3d_CSysIntps nTex = SrcVarSlotArray.GetCnt();
721    SrcTexArray.SetCnt(MemPool, nTex);
722    s3d_CSysIntps iTex;
723    for(iTex = 0; iTex < nTex; iTex++)
724    {
725        s3d_CEngGfxVarTexChan *TexChanVar =
726                s3d_EngGfxVarFetchWaryTexChan(
727                    m_ShaderEnv->m_MsgHandler, Info, Scope->m_VarBlk,
728                    SrcVarSlotArray.RefAt(iTex));       
729        SrcTexArray.SetAt(iTex, TexChanVar);
730    }
731}
732
733void gtp_Shader_CubeTexFilterInst::CalcSrcTexSize(
734        s3d_CUtilMemPool *MemPool, s3d_CEngShaderScope *Scope,
735        s3d_CDrvGfxEng *GfxEng, int &Width, int &Height,
736        s3d_CEngGfxVarTexChanArray &FilterSrcTexArray)
737{
738    Width = 0;
739    Height = 0;
740
741    s3d_CSysIntps nSrcTex = FilterSrcTexArray.GetCnt();
742    s3d_CSysIntps iSrcTex;
743    for(iSrcTex = 0; iSrcTex < nSrcTex; iSrcTex++)
744    {
745        s3d_CEngGfxVarTexChan *SrcTexChan = FilterSrcTexArray[iSrcTex];
746        if(!SrcTexChan)
747            continue;
748        s3d_CDrvGfxTex *SrcDrvTex = SrcTexChan->m_Val.m_FixedDrvTex;
749        if(!SrcDrvTex)
750            continue;
751
752        int SrcTexWidth, SrcTexHeight, SrcTexDepth;
753        SrcDrvTex->GetSize(SrcTexWidth, SrcTexHeight, SrcTexDepth);
754
755        if(Width < SrcTexWidth)
756            Width = SrcTexWidth;
757        if(Height < SrcTexHeight)
758            Height = SrcTexHeight;
759    }
760}
761
762///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.