source: GTP/trunk/App/Demos/Geom/Shark3D/src/shader_paintmesh_clod/eng_shader_std_paintmesh_clod.cpp @ 2236

Revision 2236, 65.2 KB checked in by gumbau, 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 "eng_shader_std_paintmesh_clod.h"
17#include "eng/interf/eng_gfxstruct.h"
18#include "eng/interf/eng_mesh.h"
19#include "eng/interf/eng_gfxvar.h"
20#include "eng/util/eng_util_gfxutil.h"
21#include "eng/util/eng_util_gfxparamutil.h"
22#include "eng/util/eng_util_shaderutil.h"
23#include "eng/util/eng_util_shaderitemjob.h"
24#include "eng/util/eng_util_gfxinsputil.h"
25#include "sys/core/sys_activity.h"
26#include "drv/interf/drv_vartypes.h"
27#include "drv/util/drv_util_varutil.h"
28#include "util/math/util_geo_types.h"
29#include "util/snk/util_snk_extractutil.h"
30#include "util/cont/util_arrayalgo.h"
31#include "util/pattern/util_wildcard.h"
32
33// GAMETOOLS
34#include "../drv_d3d9_eng.h"
35//#include "GeoLodStripsLibrary.h"
36#include "GeoLodLibraryDLL.h"
37
38///////////////////////////////////////////////////////////////////////////////
39/*@{
40
41@declare{shadercomp.class}{eng_shader_std.paintmesh}{}
42
43This component renders a mesh.
44See also @ref{prog_man.shader.paintmesh}.
45@p
46
47@}*/
48///////////////////////////////////////////////////////////////////////////////
49
50S3D_UTIL_RTTI_TABLE_DEFINE_BEGIN(s3d_CEngShaderStdPaintMesh)
51S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CEngShader)
52S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompUtilUniqueBase)
53S3D_UTIL_RTTI_TABLE_DEFINE_BASE(s3d_CCompSetup)
54S3D_UTIL_RTTI_TABLE_DEFINE_END
55
56s3d_CEngShaderStdPaintMesh::s3d_CEngShaderStdPaintMesh()
57{
58}
59
60void s3d_CEngShaderStdPaintMesh::SetupInit(
61        s3d_CUtilMsgHandler *MsgHandler, s3d_CUtilStr_cr Info,
62        s3d_CCompSuppl *FetchSuppl, s3d_CUtilSnkChunk *Param)
63{
64    m_Data = S3D_SYS_NEW s3d_CEngShaderStdPaintMeshData;
65
66    s3d_CUtilSnkExtract SnkExtract;
67    SnkExtract.Assign(MsgHandler, Param);
68    m_Data->m_Info = SnkExtract.GetInfo();
69
70    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.env}{$ [str]}
71        See @ident{comp}{eng_shader_std.group.env}.
72    @}*/
73    s3d_CUtilStr EnvIdent, EnvInfo;
74    SnkExtract.ExtractStr(EnvInfo, EnvIdent, "env", true);
75
76    m_ShaderEnv = s3d_CompSupplObjT<s3d_CEngShaderEnv>(
77            MsgHandler, EnvInfo, FetchSuppl,
78            EnvIdent, S3D_GENERAL_INTEROP_INTERF);
79    if(!m_ShaderEnv)
80        return;
81
82    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.methods}
83            {$ [str] .. [str]}
84        See @ref{prog_man.shader.methods}.
85    @}*/
86    s3d_CUtilSnkExtractUtil::ExtractAtomSortedArray(
87            m_Data->m_MethodArray, m_ShaderEnv->m_AtomMgr,
88            SnkExtract, "methods", true);
89
90    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.rank}
91            {$ [int]}
92        Rank of the shader in the rendering sequence.
93        Shaders having a smaller rank are rendered first.
94        @p
95
96        A @em{positive} rank is used for normal rendering,
97        a @em{negative} for rendering into a texture.
98        Shaders with rank @em{0} are disabled.
99        @p
100
101        Theoretically, you can use any rank numbers you want.
102        However, it is strongly recommended to use the standard rank numbers
103        listed in @ref{prog_ref.gfxelem_ranks}.
104        @p
105    @}*/
106    m_Data->m_Rank = SnkExtract.ExtractInt("rank", true);
107
108    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.back_to_front}
109            {$ [bool]}
110        Set rank-internal rendering order to "back to front". Default is 0.
111        If neither @ident{comp}{eng_shader_std.paintmesh.back_to_front}
112        nor @ident{comp}{eng_shader_std.paintmesh.front_to_back} is set,
113        the objects are grouped by models.
114    @}*/
115    m_Data->m_BackToFront = SnkExtract.ExtractBool("back_to_front", false);
116
117    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.front_to_back}
118            {$ [bool]}
119        Set rank-internal rendering order to "front to back". Default is 0.
120        See also @ident{comp}{eng_shader_std.paintmesh.back_to_front}.
121    @}*/
122    m_Data->m_FrontToBack = SnkExtract.ExtractBool("front_to_back", false);
123
124    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.paint_mode}
125            {$ [str]}
126        @skeyword{paint mode}
127        @table
128        {
129            { @bold{Parameter value} }
130            { @bold{Description} }
131        }
132        {
133            { @code{fill} }
134            { Filled }
135        }
136        {
137            { @code{line} }
138            { Wireframe }
139        }
140        {
141            { @code{point} }
142            { Points }
143        }
144        Default is "fill".
145    @}*/
146    s3d_CUtilStr PaintModeStr, PaintModeInfo;
147    SnkExtract.ExtractStr(PaintModeInfo, PaintModeStr, "paint_mode", false);
148    m_Data->m_PaintMode = s3d_CEngUtilGfxParamUtil::ParsePaintMode(
149            MsgHandler, PaintModeInfo, PaintModeStr,
150            s3d_CDrvGfxEng::PaintMode_Fill);
151
152    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.paint_ext}
153            {$ [float]}
154        If @ident{comp}{eng_shader_std.paintmesh.paint_mode} is "line",
155        this is the width of the lines.
156        if @ident{comp}{eng_shader_std.paintmesh.paint_mode} is "point",
157        this is the size of the points.
158    @}*/
159    m_Data->m_PaintExt = SnkExtract.ExtractFloat("paint_ext", false);
160
161    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.cull_mode}
162            {$ [str]}
163        @skeyword{cull mode}
164        Define the cull mode for this pass.
165        Default is "back".
166        @table
167        {
168            { @bold{Parameter value} }
169            { @bold{Description} }
170        }
171        {
172            { @code{none} }
173            { Render both sides. }
174        }
175        {
176            { @code{back} }
177            { Cull back side, render the front side only. }
178        }
179        {
180            { @code{front} }
181            { Call front side, render the back side only. }
182        }
183    @}*/
184    s3d_CUtilStr CullModeStr, CullModeInfo;
185    SnkExtract.ExtractStr(CullModeInfo, CullModeStr, "cull_mode", true);
186    m_Data->m_CullMode = s3d_CEngUtilGfxParamUtil::ParseCullMode(
187            MsgHandler, CullModeInfo, CullModeStr,
188            s3d_CDrvGfxEng::CullMode_None);
189
190    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.depth_test}
191            {$ [str]}
192        @skeyword{test mode}
193        Depth test mode.
194        @table
195        {
196            { @bold{Parameter value} }
197            { @bold{Description} }
198        }
199        {
200            { @code{never} }
201            { false }
202        }
203        {
204            { @code{equal} }
205            { x == y }
206        }
207        {
208            { @code{less} }
209            { x < y }
210        }
211        {
212            { @code{less_equal} }
213            { x <= y }
214        }
215        {
216            { @code{greater} }
217            { x > y }
218        }
219        {
220            { @code{greater_equal} }
221            { x >= y }
222        }
223        {
224            { @code{not_equal} }
225            { x != y }
226        }
227        {
228            { @code{always}}
229            { true }
230        }
231        Default is "less_equal".
232    @}*/
233    s3d_CUtilStr DepthTestStr, DepthTestInfo;
234    SnkExtract.ExtractStr(DepthTestInfo, DepthTestStr, "depth_test", true);
235    m_Data->m_DepthTest = s3d_CEngUtilGfxParamUtil::ParseTestMode(
236            MsgHandler, DepthTestInfo, DepthTestStr,
237            s3d_CDrvGfxEng::TestMode_Always);
238
239    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.depth_write}
240            {$ [bool]}
241        Enabled updating the depth buffer.
242        Default is 1.
243    @}*/
244    m_Data->m_DepthWrite = SnkExtract.ExtractBool("depth_write", true);
245
246    /*@{ @declare{shadercomp.param}
247            {eng_shader_std.paintmesh.depth_bias_overlay}
248            {$ [float]}
249        A non-zero values adds an offset to the depth value
250        which compensates rounding errors of the depth values
251        of non-identical but coplanar polygons.
252        This also respects polygon shifts on the screen
253        due to the slope of the polygon and a limited sub-pixel accuracy.
254        Per convention, a difference of +/- 1.0 means
255        that polygons are drawn before / after the other polygons.
256        In other words, to draw polygons before other polygons,
257        use a depth bias which is 1.0 more than the depth bias
258        of the other polygons.
259        Because of this, normally the depth bias is an integer,
260        and non-integer depth bias are only useful
261        for platform-specific fine-tuning.
262    @}*/
263    m_Data->m_DepthBiasOverlay = SnkExtract.ExtractFloat(
264            "depth_bias_overlay", false);
265
266    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.depth_bias_offs}
267            {$ [float]}
268        Assume that @code{delta_depth} is the half maximal difference
269        of the depth values of the neighboring eight pixels
270        and the depth of the pixel itself due to the polygon slope.
271        Then a non-zero @code{depth_bias_offs}
272        adds @code{delta_depth * depth_bias_offs}
273        to the depth values generated by the polygon.
274        This means, if a second polygon is shifted by a half pixel
275        along the x or y screen axis,
276        then a value of @code{depth_bias_offs = 1} compensates the change
277        of the depth values.
278        Note that when only resolving coplanar polyons,
279        you don't have to use this value,
280        but only @ident{comp}{eng_shader_std.paintmesh.depth_bias_overlay}.
281    @}*/
282    m_Data->m_DepthBiasOffs = SnkExtract.ExtractFloat(
283            "depth_bias_offs", false);
284
285    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.fog_enabled}
286            {$ [bool]}
287        @skeyword{fog}.
288    @}*/
289    m_Data->m_FogEnabled = SnkExtract.ExtractBool(
290            "fog_enabled", false);
291
292    /*@{ @declare{shadercomp.param}
293            {eng_shader_std.paintmesh.fog_black}{$ [bool]}
294        @skeyword{fog}
295        Uses black as fog color instead of the real fog color.
296        Should be used for additive rendering passes.
297        Default is 0.
298    @}*/
299    m_Data->m_FogBlack = SnkExtract.ExtractBool("fog_black", false);
300
301    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.blend_col_src_fac}
302            {$ [str]}
303        @skeyword{blend}
304        @skeyword{alpha}
305
306        Define the source factor for blending the RGB component.
307        Default for this parameter is "one".
308        @ident{comp}{eng_shader_std.paintmesh.blend_col_op} defines
309        how the final color is calculated.
310        See also @ident{comp}{eng_shader_std.paintmesh.blend_col_dest_fac}.
311        See also @ref{prog_man.shader.blending}.
312        @p
313
314        The blending modes described in the following
315        are standard Direct3D/OpenGL blending modes.
316        See the Direct3D or OpenGL documentation or reference
317        for details about blending.
318        @p
319
320        @table
321        {
322            { @bold{Parameter value} }
323            { @bold{Description} }
324        }
325        {
326            { @code{zero} }
327            { @code{factor = 0} }
328        }
329        {
330            { @code{one} }
331            { @code{factor = 1} }
332        }
333        {
334            { @code{src_alpha} }
335            { @code{factor = src_alpha} }
336        }
337        {
338            { @code{inv_src_alpha} }
339            { @code{factor = 1 - src_alpha} }
340        }
341        {
342            { @code{src_col} }
343            { @code{factor = src_color} }
344        }
345        {
346            { @code{inv_src_col} }
347            { @code{factor = 1 - src_color} }
348        }
349        {
350            { @code{dest_alpha} }
351            { @code{factor = dest_alpha} }
352        }
353        {
354            { @code{inv_dest_alpha} }
355            { @code{factor = 1 - dest_alpha} }
356        }
357        {
358            { @code{dest_col} }
359            { @code{factor = dest_color} }
360        }
361        {
362            { @code{inv_dest_col} }
363            { @code{factor = 1 - dest_color} }
364        }
365        @p
366    @}*/
367    s3d_CUtilStr BlendColSrcFac, BlendColSrcFacInfo;
368    SnkExtract.ExtractStr(
369            BlendColSrcFacInfo, BlendColSrcFac,
370            "blend_col_src_fac", false);
371    m_Data->m_BlendColSrcFac = s3d_CEngUtilGfxParamUtil::ParseBlendFac(
372            MsgHandler, BlendColSrcFacInfo, BlendColSrcFac,
373            s3d_CDrvGfxEng::BlendFac_One);
374
375    /*@{ @declare{shadercomp.param}
376            {eng_shader_std.paintmesh.blend_col_dest_fac}
377            {$ [str]}
378
379        Define the destination factor for blending the RGB component.
380        Default for this parameter is "zero".
381        @ident{comp}{eng_shader_std.paintmesh.blend_col_op} defines
382        how the final color is calculated.
383        See also @ident{comp}{eng_shader_std.paintmesh.blend_col_src_fac}.
384        See also @ref{prog_man.shader.blending}.
385        @p
386
387        The possible values are the same
388        as for @ident{comp}{eng_shader_std.paintmesh.blend_col_src_fac}.
389        @p
390    @}*/
391    s3d_CUtilStr BlendColDestFac, BlendColDestFacInfo;
392    SnkExtract.ExtractStr(
393            BlendColDestFacInfo, BlendColDestFac,
394            "blend_col_dest_fac", false);
395    m_Data->m_BlendColDestFac = s3d_CEngUtilGfxParamUtil::ParseBlendFac(
396            MsgHandler, BlendColDestFacInfo, BlendColDestFac,
397            s3d_CDrvGfxEng::BlendFac_Zero);
398
399    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.blend_col_op}
400            {$ [str]}
401        @skeyword{blend}
402        @skeyword{alpha}
403
404        Define the blend mode operation for the RGB component.
405        Default for this parameter is "src_plus_dest".
406        See also @ident{comp}{eng_shader_std.paintmesh.blend_col_src_fac}
407        and @ident{comp}{eng_shader_std.paintmesh.blend_col_op}.
408        See also @ref{prog_man.shader.blending}.
409        The final color is calculated in the following way:
410        The blending modes described in the following
411        are standard Direct3D blending modes.
412        So see an Direct3D documentation or reference for details
413        about blending.
414        In the following table, @code{src_interm} and @code{dest_interm}
415        are defined in the following way,
416        using a component-wise multiplication.
417        @listing
418        {
419            src_interm = src_col * @$
420                @sident{comp}{eng_shader_std.paintmesh.blend_col_src_fac}
421            dest_interm = dest_col * @$
422                @sident{comp}{eng_shader_std.paintmesh.blend_col_dest_fac}
423        }
424        @p
425
426        @table
427        {
428            { @bold{Parameter value} }
429            { @bold{Operation} }
430        }
431        {
432            { @code{src_plus_dest} }
433            { @code{src_interm + dest_interm} }
434        }
435        {
436            { @code{src_minus_dest} }
437            { @code{src_interm - dest_interm} }
438        }
439        {
440            { @code{dest_minus_src} }
441            { @code{dest_interm - src_interm} }
442        }
443        {
444            { @code{min_src_dest} }
445            { @code{min(src_interm, dest_interm)} }
446        }
447        {
448            { @code{max_src_dest} }
449            { @code{max(src_interm, dest_interm)} }
450        }
451        @p
452    @}*/
453    s3d_CUtilStr BlendColOp, BlendColOpInfo;
454    SnkExtract.ExtractStr(
455            BlendColOpInfo, BlendColOp,
456            "blend_col_op", false);
457    m_Data->m_BlendColOp = s3d_CEngUtilGfxParamUtil::ParseBlendOp(
458            MsgHandler, BlendColOpInfo, BlendColOp,
459            s3d_CDrvGfxEng::BlendOp_SrcPlusDest);
460
461    /*@{ @declare{shadercomp.param}
462            {eng_shader_std.paintmesh.blend_alpha_src_fac}
463            {$ [str]}
464        Define the source blend mode parameter for the alpha component.
465        See @ident{comp}{eng_shader_std.paintmesh.blend_col_src_fac}.
466        The default is
467        @ident{comp}{eng_shader_std.paintmesh.blend_col_src_fac}.
468        @p
469    @}*/
470    s3d_CUtilStr BlendAlphaSrcFac, BlendAlphaSrcFacInfo;
471    SnkExtract.ExtractStr(
472            BlendAlphaSrcFacInfo, BlendAlphaSrcFac,
473            "blend_alpha_src_fac", false);
474    m_Data->m_BlendAlphaSrcFac = s3d_CEngUtilGfxParamUtil::ParseBlendFac(
475            MsgHandler, BlendAlphaSrcFacInfo, BlendAlphaSrcFac,
476            m_Data->m_BlendColSrcFac);
477
478    /*@{ @declare{shadercomp.param}
479            {eng_shader_std.paintmesh.blend_alpha_dest_fac}
480            {$ [str]}
481        Define the destination blend mode parameter for the alpha component.
482        See @ident{comp}{eng_shader_std.paintmesh.blend_col_dest_fac}.
483        The default is
484        @ident{comp}{eng_shader_std.paintmesh.blend_col_dest_fac}.
485    @}*/
486    s3d_CUtilStr BlendAlphaDestFac, BlendAlphaDestFacInfo;
487    SnkExtract.ExtractStr(
488            BlendAlphaDestFacInfo, BlendAlphaDestFac,
489            "blend_alpha_dest_fac", false);
490    m_Data->m_BlendAlphaDestFac = s3d_CEngUtilGfxParamUtil::ParseBlendFac(
491            MsgHandler, BlendAlphaDestFacInfo, BlendAlphaDestFac,
492            m_Data->m_BlendColDestFac);
493
494    /*@{ @declare{shadercomp.param}
495            {eng_shader_std.paintmesh.blend_alpha_op}
496            {$ [str]}
497        Define the blend mode operation for the alpha component.
498        See @ident{comp}{eng_shader_std.paintmesh.blend_col_op}.
499        The default is
500        @ident{comp}{eng_shader_std.paintmesh.blend_col_op}.
501        The final alpha value is calculated in the same way
502        as described in @ident{comp}{eng_shader_std.paintmesh.blend_col_op},
503        but with the following values:
504        @listing
505        {
506            src_interm = src_alpha * @$
507                @sident{comp}{eng_shader_std.paintmesh.blend_alpha_src_fac}
508            dest_interm = dest_alpha * @$
509                @sident{comp}{eng_shader_std.paintmesh.blend_alpha_dest_fac}
510        }
511        @p
512
513    @}*/
514    s3d_CUtilStr BlendAlphaOp, BlendAlphaOpInfo;
515    SnkExtract.ExtractStr(
516            BlendAlphaOpInfo, BlendAlphaOp,
517            "blend_alpha_op", false);
518    m_Data->m_BlendAlphaOp = s3d_CEngUtilGfxParamUtil::ParseBlendFac(
519            MsgHandler, BlendAlphaOpInfo, BlendAlphaOp,
520            m_Data->m_BlendColOp);
521
522    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.color}{$ [rgb]}
523        Constant color. Default is 1.
524    @}*/
525    m_Data->m_Color = s3d_CUtilSnkExtractUtil::ExtractVec3f(
526            SnkExtract, "color", false, 1);
527
528    /*@{ @declare{shadercomp.param}
529            {eng_shader_std.paintmesh.color_var}{$ [float]}
530        Instead of using the color value @ident{comp}
531        {eng_shader_std.paintmesh.color},
532        use the paramer from this slot. @p
533        You can add such parameters
534        by a @ident{comp}{eng_shader_std.animgen} or
535        @ident{comp}{eng_shader_std.animactu}.
536    @}*/
537    s3d_CUtilSnkExtractUtil::ExtractAtom(
538            m_Data->m_ColorVarInfo, m_Data->m_ColorVarAtom,
539            m_ShaderEnv->m_AtomMgr, SnkExtract, "color_var", false);
540
541    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.alpha}{$ [float]}
542        Basis alpha value.
543    @}*/
544    m_Data->m_Alpha = SnkExtract.ExtractFloat("alpha", false, 1);
545
546    /*@{ @declare{shadercomp.param}
547            {eng_shader_std.paintmesh.alpha_var}{$ [float]}
548        Instead of using the alpha value @ident{comp}
549        {eng_shader_std.paintmesh.alpha},
550        use the paramer from this slot. @p
551        You can add such parameters
552        by a @ident{comp}{eng_shader_std.animgen} or
553        @ident{comp}{eng_shader_std.animactu}.
554    @}*/
555    s3d_CUtilSnkExtractUtil::ExtractAtom(
556            m_Data->m_AlphaVarInfo, m_Data->m_AlphaVarAtom,
557            m_ShaderEnv->m_AtomMgr, SnkExtract, "alpha_var", false);
558
559    /*@{ @declare{shadercomp.param}
560            {eng_shader_std.paintmesh.coloralpha_attr_var}{$ [int]}
561        Instead of using the color value @ident{comp}
562        {eng_shader_std.paintmesh.color},
563        use the variable from this slot. @p
564        You can add such variables
565        by a @ident{comp}{eng_shader_std.animgen} or
566        @ident{comp}{eng_shader_std.animactu}.
567    @}*/
568    s3d_CUtilSnkExtractUtil::ExtractAtom(
569            m_Data->m_ColorVarInfo, m_Data->m_ColorVarAtom,
570            m_ShaderEnv->m_AtomMgr, SnkExtract, "coloralpha_attr_var", false);
571
572    /*@{ @declare{shadercomp.param}
573            {eng_shader_std.paintmesh.alpha_test}{$ [str]}
574        Alpha test mode.
575        It accepts the same values
576        as @ident{comp}{eng_shader_std.paintmesh.depth_test}.
577        The current fragment alpha value is tested against
578        @ident{comp}
579        {eng_shader_std.paintmesh.alpha_ref} using this test mode.
580        Default is "always".
581    @}*/
582    s3d_CUtilStr AlphaTestStr, AlphaTestInfo;
583    SnkExtract.ExtractStr(AlphaTestInfo, AlphaTestStr, "alpha_test", false);
584    m_Data->m_AlphaTestMode = s3d_CEngUtilGfxParamUtil::ParseTestMode(
585            MsgHandler, AlphaTestInfo, AlphaTestStr,
586            s3d_CDrvGfxEng::TestMode_Always);
587
588    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.alpha_ref}
589            {$ [float]}
590        A reference value for alpha testing.
591        See also @ident{comp}{eng_shader_std.paintmesh.alpha_test}.
592        When using alpha keying 0.5 is a typical treshold value.
593    @}*/
594    m_Data->m_AlphaRef = SnkExtract.ExtractFloat("alpha_ref", false, 0);
595
596    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.lightarray_var}
597            {$ [str]}
598        Variable containing driver lights.
599    @}*/
600    s3d_CUtilSnkExtractUtil::ExtractAtom(
601            m_Data->m_LightArrayVarInfo, m_Data->m_LightArrayVarAtom,
602            m_ShaderEnv->m_AtomMgr, SnkExtract, "lightarray_var", false);
603
604    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.mtl}{$ [chunk]}
605        If this chunk exists, @keyword{vertex lighting} is performed
606        according the parameters, see @ident{comp}
607        {<shadercomp.mtl>}.
608        If this chunk does not exists, no lighting is performed.
609    @}*/
610    s3d_CUtilSnkChunkPtr MtlCfg
611                = SnkExtract.ExtractChunk("mtl", false);
612    m_Data->m_Mtl = s3d_CEngUtilLightUtil::CreateMtl(
613            MsgHandler, MtlCfg);
614
615    /*@{ @declare{shadercomp.param}
616            {eng_shader_std.paintmesh.use_vertex_bone_wgh}
617            {$ [bool]}
618        Use the vertex normals imported with the the mesh.
619    @}*/
620    m_Data->m_UseVertexBoneWgh =
621            SnkExtract.ExtractBool("use_vertex_bone_wgh", false);
622
623    /*@{ @declare{shadercomp.param}
624            {eng_shader_std.paintmesh.use_vertex_bone_subscr}{$ [bool]}
625        Use the vertex normals imported with the the mesh.
626    @}*/
627    m_Data->m_UseVertexBoneSubscr =
628            SnkExtract.ExtractBool("use_vertex_bone_subscr", false);
629
630    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.use_vertex_point}
631            {$ [bool]}
632        Use the vertex normals imported with the the mesh.
633    @}*/
634    m_Data->m_UseVertexPoint =
635            SnkExtract.ExtractBool("use_vertex_point", false);
636
637    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.use_vertex_normal}
638            {$ [bool]}
639        Use the vertex normals imported with the the mesh.
640    @}*/
641    m_Data->m_UseVertexNormal =
642            SnkExtract.ExtractBool("use_vertex_normal", false);
643
644    /*@{ @declare{shadercomp.param}
645            {eng_shader_std.paintmesh.use_vertex_coloralpha}
646            {$ [bool]}
647        Use the precalculated vertex colors imported with the the mesh.
648        Important! When using mesh vertex colors,
649        you cannot animate the alpha channel any more
650        since the vertex colors include the alpha component.
651    @}*/
652    m_Data->m_UseVertexColorAlpha =
653            SnkExtract.ExtractBool("use_vertex_coloralpha", false);
654
655    /*@{ @declare{shadercomp.param}
656            {eng_shader_std.paintmesh.shaderprog_ident}{$ [str]}
657        Define an optional shader program.
658    @}*/
659    SnkExtract.ExtractStr(
660            m_Data->m_ProgInfo, m_Data->m_ProgIdent,
661            "shaderprog_ident", true);
662
663    /*@{ @declare{shadercomp.param}
664            {eng_shader_std.paintmesh.shaderprog_param_array}
665            {$ [chunk] .. [chunk]}
666        Defines which variables are passed to the shader program.
667        See @ident{comp}{<shaderprog.map_prog_array>} for details.
668    @}*/
669    s3d_CUtilSnkChunkArray ProgParamChunkArray;
670    SnkExtract.ExtractChunkArray(
671            m_Data->m_ProgParamInfo, ProgParamChunkArray,
672            "shaderprog_param_array", true);
673
674    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.texchan_var_array}
675            {$ [str] .. [str]}
676        Array of texture channels used for rendering.
677        See also @ref{prog_man.shader.texture_channels}.
678        See also @ident{comp}{eng_shader_std.modelmesh} and
679        @ident{comp}{eng_shader_std.directtexchan}
680        as examples on how to assign a texture channel to a variable. @p
681    @}*/
682    s3d_CUtilSnkExtractUtil::ExtractAtomArray(
683            m_Data->m_TexChanVarInfo, m_Data->m_TexChanVarAtomArray,
684            m_ShaderEnv->m_AtomMgr,
685            SnkExtract, "texchan_var_array", true);
686
687    /*@{ @declare{shadercomp.param}
688            {eng_shader_std.paintmesh.tex_attr_var_array}
689            {$ [str] .. [str]}
690        Each entry in this array binds the texture attributes/coordinates
691        (as referenced by the supplied variable) to the slot corresponding to
692        the entry's position within the array.
693        You can then directly access these values from within your vertex
694        shader code.
695        Depending on the used shader language,
696        these values are either stored
697        in the shader code variables
698        @code{gl_MultiTexCoordx} (OpenGL GLSL)
699        or in your input structure's
700        @code{TEXCOORDx} members (DirectX HLSL). @p
701
702        @subsection{Example}
703
704        @code{tex_attr_var_array "attr0" "tangentu" "tangentv"} @p
705        will bind the texture attributes/coordinates referenced by variable
706        @code{"attr0"} to @code{gl_MultiTexCoord0/TEXCOORD0},
707        the ones referenced by variable @code{"tangentu"} to
708        @code{gl_MultiTexCoord1/TEXCOORD1} and the ones referenced
709        by variable @code{"tangentv"}
710        to @code{gl_MultiTexCoord2/TEXCOORD2}. @p
711    @}*/
712    s3d_CUtilSnkExtractUtil::ExtractAtomArray(
713            m_Data->m_AttrVarInfo, m_Data->m_AttrVarAtomArray,
714            m_ShaderEnv->m_AtomMgr,
715            SnkExtract, "tex_attr_var_array", true);
716
717    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.attrmat_var_array}
718            {$ [str] .. [str]}
719        Array of names of the variables containing the mapping coordinates
720        of the multi-texturing layers.
721    @}*/
722    s3d_CUtilSnkExtractUtil::ExtractAtomArray(
723            m_Data->m_AttrMatVarInfo, m_Data->m_AttrMatVarAtomArray,
724            m_ShaderEnv->m_AtomMgr,
725            SnkExtract, "attrmat_var_array", true);
726
727    /*@{ @declare{shadercomp.param}{eng_shader_std.paintmesh.mesh_var}{$ [str]}
728        Name of the variable containing the mesh which is rendered.
729    @}*/
730    s3d_CUtilSnkExtractUtil::ExtractAtom(
731            m_Data->m_MeshVarInfo, m_Data->m_MeshVarAtom,
732            m_ShaderEnv->m_AtomMgr, SnkExtract, "mesh_var", true);
733
734    /*@{ @declare{shadercomp.param}
735            {eng_shader_std.paintmesh.insp_ident}{$ [str]}
736        Identifier triggering a simple wireframe inspection rendering mode.
737        For more sophisticated wireframe rendering,
738        use @ident{comp}{eng_shader_std.modeswitch}.
739    @}*/
740    m_Data->m_InspAtom = s3d_CUtilSnkExtractUtil::ExtractAtom(
741            m_ShaderEnv->m_AtomMgr, SnkExtract, "insp_ident", false);
742
743        // GAMETOOLS: load the name of the .mesh file with the LOD data
744    SnkExtract.ExtractStr(
745            m_Data->m_LODMeshFileInfo, m_Data->m_LODMeshFileIdent,
746            "lodmesh", true);
747
748
749    SnkExtract.CheckForUnknown();
750
751    s3d_CEngUtilGfxParamUtil::EvalMapProg(
752            MsgHandler, m_Data->m_ProgParamInfo,
753            m_ShaderEnv->m_AtomMgr, ProgParamChunkArray,
754            m_Data->m_ProgParamMapArray);
755
756    m_Data->m_Dyn = false;
757    if(m_Data->m_ColorVarAtom)
758        m_Data->m_Dyn = true;
759    if(m_Data->m_AlphaVarAtom)
760        m_Data->m_Dyn = true;
761
762    if(m_Data->m_ProgIdent.IsEmpty())
763    {
764        s3d_CSysIntps TexChanCnt = m_Data->m_TexChanVarAtomArray.GetCnt();
765
766        if(TexChanCnt != m_Data->m_AttrVarAtomArray.GetCnt()
767                || TexChanCnt != m_Data->m_AttrMatVarAtomArray.GetCnt())
768        {
769            s3d_CUtilMsg e;
770            e.m_Code = "eng/shader/std"
771                    "/eng_shader_std_paintmesh.texcnt_mismatch";
772            e.m_StdTempl = " Sizes of texchan_var_array, tex_attr_var_array "
773                    "and attrmat_var_array differ. "
774                    "When no shaderprogram is used the array sizes "
775                    "must be equal.";
776            e.AddInfo(m_Data->m_Info);
777            s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
778        }
779    }
780}
781
782void s3d_CEngShaderStdPaintMesh::SetupDone()
783{
784}
785
786s3d_CUtilStr s3d_CEngShaderStdPaintMesh::GetInfo()
787{
788    return m_Data->m_Info;
789}
790
791void s3d_CEngShaderStdPaintMesh::RegisterNotif(s3d_CUtilNotifRecip *Recip)
792{
793}
794
795s3d_CEngShaderGfxPtr s3d_CEngShaderStdPaintMesh::FindShaderGfx(
796        s3d_CUtilNotifGather *NotifGather,
797        s3d_CEngGfxCtx *GfxCtx)
798{
799    if(!m_ShaderEnv)
800        return 0;
801
802    s3d_CEngShaderStdPaintMeshGfxPtr ShaderGfx;
803    s3d_CEngShaderStdPaintMeshGfxTree::CNode *Pos
804            = s3d_UtilTreeSortedGetStart(m_ShaderGfxTree, GfxCtx);
805    if(s3d_UtilTreeIsEqualAt(Pos, GfxCtx))
806        ShaderGfx = Pos->m_Data.m_Val;
807    else
808    {
809        ShaderGfx = S3D_SYS_NEW s3d_CEngShaderStdPaintMeshGfx(
810                m_ShaderEnv, NotifGather, GfxCtx, m_Data);
811        s3d_CEngShaderStdPaintMeshGfxTree::CNode *Node
812                = ShaderGfx->GetNode();
813        m_ShaderGfxTree.InsertBefore(Pos, Node);
814    }
815    return ShaderGfx.Get();
816}
817
818///////////////////////////////////////////////////////////////////////////////
819
820s3d_CEngShaderStdPaintMeshGfx::s3d_CEngShaderStdPaintMeshGfx(
821        s3d_CEngShaderEnv *ShaderEnv, s3d_CUtilNotifGather *NotifGather,
822        s3d_CEngGfxCtx *GfxCtx, s3d_CEngShaderStdPaintMeshData *Data)
823{
824    m_Node.m_Data.m_Key = GfxCtx;
825    m_Node.m_Data.m_Val = this;
826    m_ShaderEnv = ShaderEnv;
827    m_Data = Data;
828
829    s3d_CEngGfxProgMgr *GfxProgMgr = ShaderEnv->m_GfxProgMgr;
830    if(GfxProgMgr)
831        m_GfxProg = GfxProgMgr->CreateGfxProg(
832                                m_Data->m_ProgInfo, GfxCtx,
833                                NotifGather, m_Data->m_ProgIdent);
834}
835
836s3d_CEngShaderStdPaintMeshGfxTree::CNode
837        *s3d_CEngShaderStdPaintMeshGfx::GetNode()
838{
839    return &m_Node;
840}
841
842void s3d_CEngShaderStdPaintMeshGfx::RegisterNotif(s3d_CUtilNotifRecip *Recip)
843{
844}
845
846void s3d_CEngShaderStdPaintMeshGfx::ExtractGfx()
847{
848    m_Node.Extract();
849}
850
851bool s3d_CEngShaderStdPaintMeshGfx::IsValid()
852{
853    if(m_GfxProg && !m_GfxProg->IsValid())
854        return false;
855
856    s3d_CEngGfxCtx *GfxCtx = m_Node.m_Data.m_Key;
857    s3d_CDrvGfxEng *GfxEng = GfxCtx->m_GfxEng;
858    int GfxEngSampCnt = GfxEng->GetSampCnt();
859    if(GfxEngSampCnt < m_Data->m_TexChanVarAtomArray.GetCnt())
860        return false;
861
862    return true;
863}
864
865void s3d_CEngShaderStdPaintMeshGfx::LinkCollect(
866        s3d_CUtilAtomSet &VarAtomSet)
867{
868    s3d_CDrvUtilVarUtil::LinkCollect(
869            VarAtomSet, m_Data->m_ColorVarAtom);
870    s3d_CDrvUtilVarUtil::LinkCollect(
871            VarAtomSet, m_Data->m_AlphaVarAtom);
872    s3d_CDrvUtilVarUtil::LinkCollect(
873            VarAtomSet, m_Data->m_LightArrayVarAtom);
874    s3d_CDrvUtilVarUtil::LinkCollect(
875            VarAtomSet, m_Data->m_MeshVarAtom);
876    s3d_CDrvUtilVarUtil::LinkCollectExport(
877            VarAtomSet, m_Data->m_ProgParamMapArray);
878    s3d_CDrvUtilVarUtil::LinkCollectArray(
879            VarAtomSet, m_Data->m_TexChanVarAtomArray);
880    s3d_CDrvUtilVarUtil::LinkCollectArray(
881            VarAtomSet, m_Data->m_AttrVarAtomArray);
882    s3d_CDrvUtilVarUtil::LinkCollectArray(
883            VarAtomSet, m_Data->m_AttrMatVarAtomArray);
884}
885
886void s3d_CEngShaderStdPaintMeshGfx::LinkAppoint(
887        s3d_CDrvVarDecl *VarDecl)
888{
889    s3d_CDrvUtilVarUtil::LinkAppoint(
890            m_ColorVarSlot.m_Val,
891            VarDecl, m_Data->m_ColorVarAtom);
892    s3d_CDrvUtilVarUtil::LinkAppoint(
893            m_AlphaVarSlot.m_Val,
894            VarDecl, m_Data->m_AlphaVarAtom);
895    s3d_CDrvUtilVarUtil::LinkAppoint(
896            m_LightArrayVarSlot.m_Val,
897            VarDecl, m_Data->m_LightArrayVarAtom);
898    s3d_CDrvUtilVarUtil::LinkAppoint(
899            m_MeshVarSlot.m_Val,
900            VarDecl, m_Data->m_MeshVarAtom);
901    s3d_CDrvUtilVarUtil::LinkAppointExport(
902            m_ShaderEnv->m_MsgHandler, m_Data->m_ProgParamInfo,
903            m_ProgParamDecl, VarDecl,
904            m_Data->m_ProgParamMapArray);
905    s3d_CDrvUtilVarUtil::LinkAppointArray(
906            m_TexChanVarSlotArray,
907            VarDecl, m_Data->m_TexChanVarAtomArray);
908    s3d_CDrvUtilVarUtil::LinkAppointArray(
909            m_AttrVarSlotArray,
910            VarDecl, m_Data->m_AttrVarAtomArray);
911    s3d_CDrvUtilVarUtil::LinkAppointArray(
912            m_AttrMatVarSlotArray,
913            VarDecl, m_Data->m_AttrMatVarAtomArray);
914}
915
916s3d_CEngShaderInstPtr s3d_CEngShaderStdPaintMeshGfx::CreateShaderInst(
917        s3d_CEngShaderHead *Head)
918{
919    s3d_CEngGfxCtx *GfxCtx = m_Node.m_Data.m_Key;
920    return S3D_SYS_NEW s3d_CEngShaderStdPaintMeshInst(
921            m_ShaderEnv, GfxCtx, Head, this, m_GfxProg);
922}
923
924///////////////////////////////////////////////////////////////////////////////
925
926s3d_CEngShaderStdPaintMeshInst::s3d_CEngShaderStdPaintMeshInst(
927        s3d_CEngShaderEnv *ShaderEnv,
928        s3d_CEngGfxCtx *GfxCtx, s3d_CEngShaderHead *Head,
929        s3d_CEngShaderStdPaintMeshGfx *ShaderGfx, s3d_CEngGfxProg *GfxProg)
930{
931    m_ShaderEnv = ShaderEnv;
932    m_GfxCtx = GfxCtx;
933    m_ShaderGfx = ShaderGfx;
934    m_ProgGfx = GfxProg;
935
936        geoIndexData = 0;
937        lodStrips = 0;
938}
939
940void s3d_CEngShaderStdPaintMeshInst::RegisterNotif(
941        s3d_CUtilNotifRecip *Recip)
942{
943}
944
945void s3d_CEngShaderStdPaintMeshInst::SetShaderCtx(
946        s3d_CEngShaderCtx *ShaderCtx)
947{
948}
949
950void s3d_CEngShaderStdPaintMeshInst::SetGfxState(s3d_CEngGfxState *GfxState)
951{
952        theGfxState=GfxState;
953}
954
955void s3d_CEngShaderStdPaintMeshInst::SetPos(s3d_CEngPos *Pos)
956{
957}
958
959
960class CustomIndexData : public Geometry::IndexData
961{
962private:
963/*      Ogre::Mesh *targetMesh;
964        Ogre::HardwareIndexBufferSharedPtr ibuf;
965        Ogre::RenderOperation mRenderOp;
966        unsigned long* pIdx;*/
967        void* pIdx;
968public:
969        CustomIndexData(/*Ogre::Mesh *ogremesh*/):Geometry::IndexData(){
970                batch = NULL;
971                pIdx = 0;
972/*              targetMesh=ogremesh;
973                pIdx=NULL;*/
974        }
975        virtual ~CustomIndexData(void){}
976
977        virtual void Begin(unsigned int submeshid, unsigned int indexcount){
978                assert(submeshid==0);
979               
980                if (batch)  // esto no deberia estar: el batch nunca deberia ser nulo, debe cogese desde el constructor
981                {
982                        // the first time (maximum capacity) the buffer is gone to bhe locked must be created
983        /*              if (pIdx16 == 0 && batch->m_IdxBufObj->m_Fmt == D3DFMT_INDEX16)
984                                pIdx16 = new unsigned short int[indexcount];
985                        if (pIdx32 == 0 && batch->m_IdxBufObj->m_Fmt == D3DFMT_INDEX32)
986                                pIdx32 = new unsigned long int[indexcount];*/
987
988                        batch->m_IdxBufObj->m_IdxCnt = indexcount;
989                        batch->m_IdxBufObj->m_PacketArray[submeshid].m_IdxCnt = batch->m_IdxBufObj->m_IdxCnt;
990                        batch->m_IdxBufObj->m_PacketArray[submeshid].m_PrimCnt = batch->m_IdxBufObj->m_PacketArray[submeshid].m_IdxCnt - 2;
991
992                        LPDIRECT3DINDEXBUFFER9 indexBuffer = batch->m_IdxBufObj->m_IdxBuf;
993                        HRESULT hres = indexBuffer->Lock(0,0,&pIdx,0);
994                        assert(!FAILED(hres));
995                }
996/*              targetMesh->getSubMesh(submeshid)->_getRenderOperation(mRenderOp,0);
997                ibuf = mRenderOp.indexData->indexBuffer;
998                mRenderOp.indexData->indexCount = indexcount;
999                pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));*/
1000        }
1001        virtual void SetIndex(unsigned int i, unsigned int index){             
1002                if (batch) // esto no deberia estar: el batch nunca deberia ser nulo, debe cogese desde el constructor
1003                {
1004                        if (batch->m_IdxBufObj->m_Fmt == D3DFMT_INDEX16)
1005                        {
1006                                unsigned short int* pIdx16 = (unsigned short int*)pIdx;
1007                                pIdx16[i] = (unsigned short)index;
1008                        }
1009                        if (batch->m_IdxBufObj->m_Fmt == D3DFMT_INDEX32)
1010                        {
1011                                unsigned long int* pIdx32 = (unsigned long int*)pIdx;
1012                                pIdx32[i] = (unsigned short)index;
1013                        }
1014                }
1015/*              pIdx[i] = index; //lodStripsLib->dataRetrievalInterface->GetIndex(k+offset);*/
1016        }
1017        virtual void End(){
1018                if (batch) // esto no deberia estar: el batch nunca deberia ser nulo, debe cogese desde el constructor
1019                {
1020                        LPDIRECT3DINDEXBUFFER9 indexBuffer = batch->m_IdxBufObj->m_IdxBuf;
1021                        HRESULT hres = indexBuffer->Unlock();
1022                        assert(!FAILED(hres));
1023                }
1024        }
1025        virtual void BorrowIndexData(const Geometry::IndexData *){}
1026
1027        // must be assigned externally when it's about to being used (before the gotoLod) and batch==0
1028        // TODO: it should be better to pass this batch through the constructor
1029        s3d_CDrvD3d9Batch *batch;
1030};
1031
1032
1033void s3d_CEngShaderStdPaintMeshInst::SetModel(s3d_CEngModel *Model)
1034{
1035        if (Model)
1036        {
1037                s3d_CSharkMeshLoader *lodmodel = (s3d_CSharkMeshLoader *)Model;
1038                const Geometry::LodStripsLibraryData *lodData = lodmodel->GetLodStripsData();
1039                geoIndexData = new CustomIndexData();
1040                lodStrips = new Geometry::LodStripsLibrary(lodData,lodmodel->GetGeoMesh(),geoIndexData);
1041        }
1042}
1043
1044void s3d_CEngShaderStdPaintMeshInst::ArrangeCollect(
1045        s3d_CUtilMemPool *MemPool,
1046        s3d_CEngShaderScopeArray &ScopeArray)
1047{
1048}
1049
1050void s3d_CEngShaderStdPaintMeshInst::ArrangeInit(
1051        s3d_CUtilMemPool *MemPool,
1052        s3d_CEngShaderScopeArray_cr ScopeArray)
1053{
1054        // GAMETOOLS: load the .mesh file and create an instance to a LodStripsObject
1055        Geometry::GeoMeshLoader loader;
1056        Geometry::Mesh *dummyMesh = loader.load((char*)m_ShaderGfx->m_Data->m_LODMeshFileIdent.GetChars());
1057}
1058
1059void s3d_CEngShaderStdPaintMeshInst::ArrangePerform(
1060        s3d_CUtilMemPool *MemPool,
1061        s3d_CEngShaderScopeArray_cr ScopeArray)
1062{
1063    s3d_CEngShaderStdPaintMeshGfx *ShaderGfx = m_ShaderGfx;
1064    s3d_CEngShaderStdPaintMeshData *Data = ShaderGfx->m_Data;
1065    s3d_CUtilMemPoolFrm MemPoolFrm(MemPool);
1066    s3d_CEngGfxBatchMgr *BatchMgr = m_ShaderEnv->m_GfxBatchMgr;
1067
1068    m_BatchArray.Reset();
1069
1070    s3d_CSysIntps nScope = ScopeArray.GetCnt();
1071    s3d_CSysIntps iScope;
1072    for(iScope = 0; iScope < nScope; iScope++)
1073    {
1074        s3d_CEngShaderScope *Scope = ScopeArray[iScope];
1075
1076        s3d_CEngGfxVarMesh *MeshVar
1077            = s3d_EngGfxVarGetMesh(
1078                m_ShaderEnv->m_MsgHandler, Data->m_MeshVarInfo.GetChars(),
1079                Scope->m_VarBlk, m_ShaderGfx->m_MeshVarSlot);
1080        if(!MeshVar)
1081            continue;
1082
1083        s3d_CEngMeshData *MeshData = MeshVar->m_Val.m_MeshCompos.m_MeshData;
1084        s3d_CDrvSig *MeshSig = MeshVar->m_Val.m_MeshCompos.m_MeshSig;
1085
1086        bool Complete = false;
1087        if(MeshData && MeshSig)
1088        {
1089            s3d_CDrvGfxCharge *ChargeArray
1090                    = CreateChargeArray(MemPool, Scope, MeshData, true);
1091
1092            Complete = true;
1093            bool HasBatch = false;
1094            s3d_CEngGfxBatchArray BatchArray;
1095            s3d_CSysIntps nFamily = MeshData->m_Topol.m_FamilyCnt;
1096            s3d_CSysIntps iFamily;
1097            for(iFamily = 0; iFamily < nFamily; iFamily++)
1098            {
1099                s3d_CDrvGfxCharge *Charge = 0;
1100                if(ChargeArray)
1101                    Charge = &ChargeArray[iFamily];
1102                s3d_CEngGfxBatchPtr Batch =
1103                        BatchMgr->CreateBatch(m_GfxCtx, Charge);
1104                BatchArray.InsertBack(Batch);
1105                if(Batch)
1106                {
1107                    HasBatch = true;
1108                    if(!Batch->IsComplete())
1109                        Complete = false;
1110                }
1111                else
1112                    Complete = false;
1113            }
1114
1115            if(HasBatch)
1116            {
1117                s3d_CEngShaderStdPaintMeshBatchKeyEntry BatchEntry;
1118                BatchEntry.m_Key = MeshSig;
1119                BatchEntry.m_Val.m_BatchArray = BatchArray;
1120                BatchEntry.m_Val.m_Complete = Complete;
1121                m_BatchArray.InsertBack(BatchEntry);               
1122            }
1123        }
1124
1125        if(!Complete)
1126        {
1127            MeshVar->m_Val.m_NeedMeshData = true;
1128
1129            s3d_CSysIntps nAttr = ShaderGfx->m_AttrVarSlotArray.GetCnt();
1130            s3d_CSysIntps iAttr;
1131            for(iAttr = 0; iAttr < nAttr; iAttr++)
1132            {
1133                s3d_CDrvVarSlot &AttrVarSlot
1134                        = ShaderGfx->m_AttrVarSlotArray.RefAt(iAttr);
1135                s3d_CEngGfxVarAttr *AttrVar = s3d_EngGfxVarGetAttr(
1136                        m_ShaderEnv->m_MsgHandler,
1137                                Data->m_AttrVarInfo.GetChars(),
1138                        Scope->m_VarBlk, AttrVarSlot);
1139                if(AttrVar)
1140                    AttrVar->m_Val.m_NeedBankData = true;
1141            }
1142        }
1143    }
1144
1145    s3d_UtilArraySortDefault(m_BatchArray);
1146}
1147
1148void s3d_CEngShaderStdPaintMeshInst::ArrangeFeedback(
1149        s3d_CUtilMemPool *MemPool,
1150        s3d_CEngShaderScopeArray_cr ScopeArray)
1151{
1152}
1153
1154void s3d_CEngShaderStdPaintMeshInst::ArrangeGather(
1155        s3d_CEngShaderExecArray &ExecArray)
1156{
1157    s3d_CEngShaderStdPaintMeshData *Data = m_ShaderGfx->m_Data;
1158
1159    s3d_CEngUtilShaderUtil::ArrangeGather(
1160            ExecArray, Data->m_MethodArray, this);
1161}
1162
1163void s3d_CEngShaderStdPaintMeshInst::ShaderExecPerform(
1164        s3d_CEngShaderScope *Scope,
1165        s3d_CUtilAtom *Method,
1166        s3d_CEngGfxTaskArray &TaskArray)
1167{
1168    s3d_CEngShaderStdPaintMeshGfx *ShaderGfx = m_ShaderGfx;
1169    s3d_CEngShaderStdPaintMeshData *Data = ShaderGfx->m_Data;
1170
1171    int Rank = Data->m_Rank;
1172    if(Rank == 0)
1173        return;
1174
1175    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
1176    if(!Portion)
1177        return;
1178
1179    s3d_CEngGfxVarMesh *MeshVar
1180        = s3d_EngGfxVarFetchWaryMesh(
1181            m_ShaderEnv->m_MsgHandler, Data->m_Info.GetChars(),
1182            Scope->m_VarBlk, ShaderGfx->m_MeshVarSlot.m_Val);
1183    if(!MeshVar)
1184        return;
1185
1186        ////////////////////////////////////////////
1187        // GAMETOOLS: change indices and index count
1188
1189        // GET the Batch!
1190    s3d_CEngShaderStdPaintMeshBatch *MeshBatch = 0;
1191    s3d_CDrvSig *MeshSig = MeshVar->m_Val.m_MeshCompos.m_MeshSig;
1192    if(MeshSig)
1193    {
1194        s3d_CSysIntps BatchIdx
1195                = s3d_UtilArraySortedGetEqual(m_BatchArray, MeshSig);
1196        if(BatchIdx >= 0)
1197        {
1198            s3d_CEngShaderStdPaintMeshBatchKeyEntry *BatchEntry
1199                    = &m_BatchArray.RefAt(BatchIdx);
1200            MeshBatch = &BatchEntry->m_Val;
1201        }
1202    }
1203
1204    s3d_CSysIntps FamilyCnt = 0;
1205    s3d_CDrvGfxCharge *ChargeArray = 0;
1206    const s3d_CEngGfxBatchArray *BatchArray = 0;
1207    if(MeshBatch)
1208    {
1209        BatchArray = &MeshBatch->m_BatchArray;
1210        FamilyCnt = MeshBatch->m_BatchArray.GetCnt();
1211    }
1212
1213        // modify the batch!
1214        // GAMETOOLS
1215        S3D_SYS_ASSERT(theGfxState);
1216
1217    s3d_CDrvGfxEng *engine = theGfxState->GetGfxEng();
1218        s3d_CDrvD3d9GfxEngCLOD *engineLOD = s3d_UtilRttiCastSilent<s3d_CDrvD3d9GfxEngCLOD>(engine);
1219
1220        S3D_SYS_ASSERT(engineLOD);
1221        if (engineLOD)
1222        {
1223                const int BatchCnt = BatchArray->GetCnt();
1224                for (int i=0; i<BatchCnt; i++)
1225                {
1226                        s3d_CEngGfxBatch * batch = BatchArray->GetAt(i);
1227//                      HAY QUE VER COMO CONSEGUIR ACCEDER A MI CLASE MODEL DESDE AQUI PARA SABER SI HAY QUE USAR STRIPS O NO
1228//                      OTRA SOLUCION ES ASUMIR SIEMPRE STRIPS SI SE USA ESTE SHADER COMPONENT
1229//                      s3d_CSharkMeshLoader *gtmodel = s3d_UtilRttiCastSilent<s3d_CSharkMeshLoader>(current_model);
1230                        assert(lodStrips);
1231                        assert(geoIndexData);
1232
1233                        s3d_CDrvD3d9Batch *BatchImpl = s3d_UtilRecogCastSilent<s3d_CDrvD3d9Batch>(batch->GetDrvBatch());
1234                        if(!BatchImpl)
1235                        {
1236                                S3D_SYS_ASSERT(0);
1237                                return;
1238                        }
1239
1240                        CustomIndexData *customIndexData = (CustomIndexData*)geoIndexData;
1241
1242                        if (customIndexData->batch==0)
1243                                customIndexData->batch = (s3d_CDrvD3d9Batch*)batch->GetDrvBatch();
1244
1245                        s3d_CUtilMat4x4f auxViewMat
1246                                = s3d_CUtilGeof::GetMapOfTransf3(MeshVar->m_Val.m_ViewTransf);
1247
1248                        s3d_CUtilMat4x4f viewInv = auxViewMat.GetInv();
1249                        s3d_CUtilVec3f campos(viewInv.m_xw,viewInv.m_yw,viewInv.m_zw);
1250
1251                        static float previous_lodfactor = 1.0;
1252                        float distance = campos.GetLen();
1253                        float dist_max = 4;
1254                        float dist_min = 0.2;
1255
1256                        float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min);
1257
1258                        if (lodfactor<0.0f)
1259                                lodfactor=0.0f;
1260                        if (lodfactor>1.0f)
1261                                lodfactor=1.0f;
1262
1263                        lodfactor = 1.0f - lodfactor;
1264
1265/*                      static float ii = 0.0f;
1266                        lodfactor = sinf(ii+=0.1f)*0.5f + 0.5f;*/
1267
1268                        if (fabsf(previous_lodfactor-lodfactor)>0.01f)
1269                        {
1270                                lodStrips->GoToLod(lodfactor);
1271                                previous_lodfactor = lodfactor;
1272                        }
1273
1274                        BatchImpl->m_IdxBufObj->m_PacketArray[0].m_PrimCnt = BatchImpl->m_IdxBufObj->m_PacketArray[0].m_IdxCnt - 2;                     
1275                        BatchImpl->m_IdxBufObj->m_D3dPrim = D3DPT_TRIANGLESTRIP;
1276                }
1277        }
1278
1279        ////////////////////////////////////////////
1280
1281    s3d_CEngGfxTaskOrder KeyOrder = s3d_CEngUtilGfxUtil::GetOrderOfMesh(
1282            Portion->m_Cam,
1283            Data->m_BackToFront, Data->m_FrontToBack,
1284            &MeshVar->m_Val);
1285
1286    s3d_CEngGfxElemJob *GfxElemJob = new(m_ShaderEnv->m_MemPool)
1287            s3d_CEngUtilShaderItemJob<s3d_CEngShaderStdPaintMeshInst>(
1288            Scope, 0,
1289            this, &s3d_CEngShaderStdPaintMeshInst::GfxElemJobExec);
1290
1291    s3d_CEngUtilGfxUtil::AppendTask(
1292            Portion->m_MemPool, TaskArray, Rank, KeyOrder, GfxElemJob);
1293}
1294
1295void *s3d_CEngShaderStdPaintMeshInst::GfxElemJobExec(
1296        s3d_CEngShaderScope *Scope,
1297        void *GfxMark)
1298{
1299    S3D_SYS_ACTIVITY_SOFTFRM(
1300            "s3d_CEngShaderStdPaintMeshInst::GfxElemJobExec");
1301
1302    s3d_CEngShaderStdPaintMeshGfx *ShaderGfx = m_ShaderGfx;
1303    s3d_CEngShaderStdPaintMeshData *Data = ShaderGfx->m_Data;
1304
1305    if(!Scope)
1306        return GfxMark;
1307    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
1308    if(!Portion)
1309        return GfxMark;
1310    s3d_CEngGfxCycle *Cycle = Portion->m_Cycle;
1311    if(!Cycle)
1312        return GfxMark;
1313    s3d_CEngGfxRun *Run = Cycle->m_Run;
1314    if(!Run)
1315        return GfxMark;
1316    s3d_CDrvGfxEng *GfxEng = Run->m_GfxEng;
1317    if(!GfxEng)
1318        return GfxMark;
1319
1320    if(!s3d_CEngUtilGfxUtil::VerifyGfxOpen(
1321            m_ShaderEnv->m_MsgHandler, Data->m_Info.GetChars(), Cycle))
1322    {
1323        Data->m_Rank = 0; // Avoid the error being reported each frame
1324        return GfxMark;
1325    }
1326
1327    s3d_CEngGfxVarMesh *MeshVar
1328        = s3d_EngGfxVarFetchWaryMesh(
1329            m_ShaderEnv->m_MsgHandler, Data->m_MeshVarInfo.GetChars(),
1330            Scope->m_VarBlk, ShaderGfx->m_MeshVarSlot.m_Val);
1331    if(!MeshVar)
1332        return GfxMark;
1333
1334    const s3d_CEngMeshData *MeshData = MeshVar->m_Val.m_MeshCompos.m_MeshData;
1335
1336    GfxEng->SetViewRect(
1337        Cycle->m_CurViewAdapt.Concat(Portion->m_Cam.m_ViewPane));
1338    GfxEng->SetViewDepthRange(
1339        Portion->m_Cam.m_ViewDepthStart, Portion->m_Cam.m_ViewDepthEnd);
1340
1341    s3d_CUtilMat4x4f ViewMat
1342            = s3d_CUtilGeof::GetMapOfTransf3(MeshVar->m_Val.m_ViewTransf);
1343    GfxEng->SetTransf(s3d_CDrvGfxEng::TransfChan_View, 0, ViewMat);
1344    GfxEng->SetTransf(
1345            s3d_CDrvGfxEng::TransfChan_Proj, 0, MeshVar->m_Val.m_Proj);
1346
1347    s3d_CSysIntps nBone = MeshVar->m_Val.m_BoneViewTransfCnt;
1348    s3d_CUtilTranslQuatf *BoneViewTransfArray =
1349            MeshVar->m_Val.m_BoneViewTransfArray;
1350    s3d_CSysIntps iBone;
1351    for(iBone = 0; iBone < nBone; iBone++)
1352    {
1353        s3d_CUtilMat4x4f DrvMat
1354            = s3d_CUtilGeof::GetMapOfTransf3(BoneViewTransfArray[iBone]);
1355        GfxEng->SetTransf(s3d_CDrvGfxEng::TransfChan_Bone, int(iBone), DrvMat);
1356    }
1357
1358    void *KinGfxMark = Data;
1359    if(GfxMark != KinGfxMark)
1360        ExecStatic(Scope, GfxEng);
1361
1362    s3d_CUtilVec3f Color = Data->m_Color;
1363    float Alpha = Data->m_Alpha;
1364    if(Data->m_Dyn)
1365        ExecDyn(Scope, GfxEng, Color, Alpha);
1366
1367    if(Data->m_Mtl)
1368        ExecLighting(Scope, GfxEng, Alpha);
1369
1370    s3d_CSysIntps nAttrMat = ShaderGfx->m_AttrMatVarSlotArray.GetCnt();
1371    int iAttrMat;
1372    for(iAttrMat = 0; iAttrMat < nAttrMat; iAttrMat++)
1373    {
1374        s3d_CDrvVarSlot &AttrMatVarSlot
1375                = ShaderGfx->m_AttrMatVarSlotArray.RefAt(iAttrMat);
1376        s3d_CDrvVarMat4x4f *AttrMatVar
1377            = s3d_DrvVarFetchWaryMat4x4f(
1378                m_ShaderEnv->m_MsgHandler,
1379                        Data->m_AttrMatVarInfo.GetChars(),
1380                Scope->m_VarBlk, AttrMatVarSlot);
1381
1382        s3d_CUtilMat4x4f Transf = 1;
1383        if(AttrMatVar)
1384            Transf = AttrMatVar->m_Val;
1385        if(Transf != 1)
1386            GfxEng->SetTransf(
1387                    s3d_CDrvGfxEng::TransfChan_Gen, iAttrMat, Transf);
1388        else
1389            GfxEng->SetTransfIdentity(
1390                    s3d_CDrvGfxEng::TransfChan_Gen, iAttrMat);
1391    }
1392
1393    int nTexChan = m_ShaderGfx->m_TexChanVarSlotArray.GetCntInt();
1394    s3d_CEngTexChan *TexChanArray
1395        = new(Portion->m_MemPool) s3d_CEngTexChan[nTexChan];
1396    int iTexChan;
1397    for(iTexChan = 0; iTexChan < nTexChan; iTexChan++)
1398    {
1399        s3d_CDrvVarSlot &TexChanVarSlot
1400                = m_ShaderGfx->m_TexChanVarSlotArray.RefAt(iTexChan);
1401        s3d_CEngGfxVarTexChan *TexChanVar
1402            = s3d_EngGfxVarFetchWaryTexChan(
1403                m_ShaderEnv->m_MsgHandler,
1404                        Data->m_TexChanVarInfo.GetChars(),
1405                Scope->m_VarBlk, TexChanVarSlot);
1406
1407        s3d_CEngTexChan *TexChan = &TexChanArray[iTexChan];
1408        if(TexChanVar)
1409            *TexChan = TexChanVar->m_Val;
1410        else
1411            TexChan->Reset();
1412    }
1413
1414    s3d_CEngShaderStdPaintMeshBatch *MeshBatch = 0;
1415    s3d_CDrvSig *MeshSig = MeshVar->m_Val.m_MeshCompos.m_MeshSig;
1416    if(MeshSig)
1417    {
1418        s3d_CSysIntps BatchIdx
1419                = s3d_UtilArraySortedGetEqual(m_BatchArray, MeshSig);
1420        if(BatchIdx >= 0)
1421        {
1422            s3d_CEngShaderStdPaintMeshBatchKeyEntry *BatchEntry
1423                    = &m_BatchArray.RefAt(BatchIdx);
1424            MeshBatch = &BatchEntry->m_Val;
1425        }
1426    }
1427
1428    s3d_CDrvGfxParam GfxParam;
1429    GfxParam.m_Blk.m_Decl = ShaderGfx->m_ProgParamDecl;
1430    GfxParam.m_Blk.m_Data = Scope->m_VarBlk.m_Data;
1431
1432    s3d_CSysIntps FamilyCnt = 0;
1433    s3d_CDrvGfxCharge *ChargeArray = 0;
1434    if(!MeshBatch || !MeshBatch->m_Complete)
1435    {
1436        ChargeArray = CreateChargeArray(
1437                Portion->m_MemPool, Scope, MeshData, false);
1438        if(MeshData)
1439            FamilyCnt = MeshData->m_Topol.m_FamilyCnt;
1440    }
1441    const s3d_CEngGfxBatchArray *BatchArray = 0;
1442    if(MeshBatch)
1443    {
1444        BatchArray = &MeshBatch->m_BatchArray;
1445        FamilyCnt = MeshBatch->m_BatchArray.GetCnt();
1446    }
1447    s3d_CEngUtilGfxUtil::PaintChargeArray(
1448            GfxEng, FamilyCnt,
1449            ChargeArray, BatchArray, nTexChan, TexChanArray,
1450            GfxParam);
1451
1452    return KinGfxMark;
1453}
1454
1455s3d_CDrvGfxCharge *s3d_CEngShaderStdPaintMeshInst::CreateChargeArray(
1456        s3d_CUtilMemPool *MemPool, s3d_CEngShaderScope *Scope,
1457        const s3d_CEngMeshData *MeshData, bool Quiet)
1458{
1459    s3d_CEngShaderStdPaintMeshGfx *ShaderGfx = m_ShaderGfx;
1460    s3d_CEngShaderStdPaintMeshData *Data = ShaderGfx->m_Data;
1461
1462    if(!Scope)
1463        return 0;
1464    if(!MeshData)
1465        return 0;
1466
1467    if(!m_GfxCtx)
1468        return 0;
1469    s3d_CDrvGfxEng *GfxEng = m_GfxCtx->m_GfxEng;
1470    if(!GfxEng)
1471        return 0;
1472
1473    s3d_CSysIntps nAttr = ShaderGfx->m_AttrVarSlotArray.GetCnt();
1474    s3d_CSysIntps MaxAttrCnt = 6 + nAttr;
1475    s3d_CDrvGfxAttr *AttrArray
1476            = new(MemPool) s3d_CDrvGfxAttr[MaxAttrCnt];
1477
1478    s3d_CDrvGfxAttr *Attr = AttrArray;
1479
1480    if(Data->m_UseVertexBoneWgh && MeshData->m_Topol.m_BoneCnt > 0)
1481    {
1482        s3d_CDrvBank *Bank = MeshData->m_BoneWghAttr.m_Bank;
1483        if(!Bank)
1484            ErrorNoBoneWghBank(Data->m_Info, MeshData);
1485
1486        Attr->m_BankDyn = MeshData->m_BoneWghAttr.m_BankDyn;
1487        Attr->m_BankSig = MeshData->m_BoneWghAttr.m_BankSig;
1488        Attr->m_Bank = Bank;
1489        Attr->m_Chan = s3d_CDrvGfxEng::AttrChan_BoneWgh;
1490        Attr->m_Slot = 0;
1491        Attr++;
1492    }
1493    if(Data->m_UseVertexBoneSubscr && MeshData->m_Topol.m_UseSubscr)
1494    {
1495        s3d_CDrvBank *Bank = MeshData->m_BoneSubscrAttr.m_Bank;
1496        if(!Bank)
1497            ErrorNoBoneSubscrBank(Data->m_Info, MeshData);
1498
1499        Attr->m_BankDyn = MeshData->m_BoneSubscrAttr.m_BankDyn;
1500        Attr->m_BankSig = MeshData->m_BoneSubscrAttr.m_BankSig;
1501        Attr->m_Bank = Bank;
1502        Attr->m_Chan = s3d_CDrvGfxEng::AttrChan_BoneSubscr;
1503        Attr->m_Slot = 0;
1504        Attr++;
1505    }
1506    if(Data->m_UseVertexPoint)
1507    {
1508        s3d_CDrvBank *Bank = MeshData->m_PointAttr.m_Bank;
1509        if(!Bank)
1510            ErrorNoPointBank(Data->m_Info, MeshData);
1511
1512        Attr->m_BankDyn = MeshData->m_PointAttr.m_BankDyn;
1513        Attr->m_BankSig = MeshData->m_PointAttr.m_BankSig;
1514        Attr->m_Bank = Bank;
1515        Attr->m_Chan = s3d_CDrvGfxEng::AttrChan_Point;
1516        Attr->m_Slot = 0;
1517        Attr++;
1518    }
1519    if(Data->m_UseVertexNormal)
1520    {
1521        s3d_CDrvBank *Bank = MeshData->m_NormalAttr.m_Bank;
1522        if(!Bank)
1523            ErrorNoNormalBank(Data->m_Info, MeshData);
1524
1525        Attr->m_BankDyn = MeshData->m_NormalAttr.m_BankDyn;
1526        Attr->m_BankSig = MeshData->m_NormalAttr.m_BankSig;
1527        Attr->m_Bank = Bank;
1528        Attr->m_Chan = s3d_CDrvGfxEng::AttrChan_Normal;
1529        Attr->m_Slot = 0;
1530        Attr++;
1531    }
1532
1533    if(Data->m_UseVertexColorAlpha)
1534    {
1535        s3d_CDrvBank *Bank = MeshData->m_ColorAlphaAttr.m_Bank;
1536        if(!Bank)
1537            ErrorNoColorAlphaBank(Data->m_Info, MeshData);
1538
1539        Attr->m_BankDyn = MeshData->m_ColorAlphaAttr.m_BankDyn;
1540        Attr->m_BankSig = MeshData->m_ColorAlphaAttr.m_BankSig;
1541        Attr->m_Bank = Bank;
1542        Attr->m_Chan = s3d_CDrvGfxEng::AttrChan_ColorAlpha;
1543        Attr->m_Slot = 0;
1544        Attr++;
1545    }
1546
1547    s3d_CSysIntps iAttr;
1548    for(iAttr = 0; iAttr < nAttr; iAttr++)
1549    {
1550        s3d_CDrvVarSlot &AttrVarSlot
1551                = ShaderGfx->m_AttrVarSlotArray.RefAt(iAttr);
1552        s3d_CEngGfxVarAttr *AttrVar = 0;
1553        if(Quiet)
1554        {
1555            AttrVar = s3d_EngGfxVarGetAttr(
1556                m_ShaderEnv->m_MsgHandler, Data->m_AttrVarInfo.GetChars(),
1557                Scope->m_VarBlk, AttrVarSlot);
1558        }
1559        else
1560        {
1561            AttrVar = s3d_EngGfxVarFetchWaryAttr(
1562                m_ShaderEnv->m_MsgHandler, Data->m_AttrVarInfo.GetChars(),
1563                Scope->m_VarBlk, AttrVarSlot);
1564        }
1565
1566        if(AttrVar)
1567        {
1568            Attr->m_BankDyn = AttrVar->m_Val.m_MeshAttr.m_BankDyn;
1569            Attr->m_BankSig = AttrVar->m_Val.m_MeshAttr.m_BankSig;
1570            Attr->m_Bank = AttrVar->m_Val.m_MeshAttr.m_Bank;
1571        }
1572        Attr->m_Chan = s3d_CDrvGfxEng::AttrChan_Generic;
1573        Attr->m_Slot = int(iAttr);
1574        Attr++;
1575    }
1576
1577    s3d_CSysIntps AttrCnt = s3d_CSysIntps(Attr - AttrArray);
1578    S3D_SYS_ASSERT(AttrCnt <= MaxAttrCnt);
1579
1580    s3d_CDrvGfxProg *DrvProg = 0;
1581    if(m_ProgGfx)
1582        DrvProg = m_ProgGfx->GetDrvProg();
1583
1584    s3d_CDrvGfxCharge *ChargeArray
1585        = s3d_CEngUtilGfxUtil::CreateChargeArrayOfFamilyArray(
1586                MemPool, Data->m_Info.GetChars(),
1587                MeshData->m_Info, MeshData->m_Desc,
1588                DrvProg, MeshData->m_Topol, AttrCnt, AttrArray);
1589
1590    return ChargeArray;
1591}
1592
1593void s3d_CEngShaderStdPaintMeshInst::ExecStatic(
1594        s3d_CEngShaderScope *Scope, s3d_CDrvGfxEng *GfxEng)
1595{
1596    if(!Scope)
1597        return;
1598    if(!GfxEng)
1599        return;
1600    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
1601    if(!Portion)
1602        return;
1603
1604    s3d_CEngShaderStdPaintMeshGfx *ShaderGfx = m_ShaderGfx;
1605    s3d_CEngShaderStdPaintMeshData *Data = ShaderGfx->m_Data;
1606
1607    bool DoInsp = s3d_CEngUtilGfxUtil::IsModeFlagDefined(
1608            Portion->m_Cam, Data->m_InspAtom);
1609
1610    int PaintMode = Data->m_PaintMode;
1611    if(DoInsp)
1612    {
1613        if(PaintMode == s3d_CDrvGfxEng::PaintMode_Fill)
1614            PaintMode = s3d_CDrvGfxEng::PaintMode_Line;
1615    }
1616    GfxEng->SetPaintMode(PaintMode);
1617    if(PaintMode != 0)
1618        GfxEng->SetPaintExt(Data->m_PaintExt);
1619
1620    int CullMode = s3d_CEngUtilGfxUtil::CalcCullMode(
1621                    Data->m_CullMode, Portion->m_Cam.m_Reverse);
1622    GfxEng->SetCullMode(CullMode);
1623    GfxEng->SetDepthTest(Data->m_DepthTest);
1624    GfxEng->SetDepthWrite(Data->m_DepthWrite);
1625    GfxEng->SetDepthBias(
1626            Portion->m_Cam.m_DepthBiasOverlay + Data->m_DepthBiasOverlay,
1627            Portion->m_Cam.m_DepthBiasOffs + Data->m_DepthBiasOffs);
1628    GfxEng->SetStencilMode(
1629            Portion->m_Cam.m_StencilTestMask,
1630            Portion->m_Cam.m_StencilTestRef,
1631            Portion->m_Cam.m_StencilTestMode,
1632            Portion->m_Cam.m_StencilTestMode,
1633            0,
1634            s3d_CDrvGfxEng::StencilOp_Keep,
1635            s3d_CDrvGfxEng::StencilOp_Keep,
1636            s3d_CDrvGfxEng::StencilOp_Keep,
1637            s3d_CDrvGfxEng::StencilOp_Keep,
1638            s3d_CDrvGfxEng::StencilOp_Keep,
1639            s3d_CDrvGfxEng::StencilOp_Keep);
1640    s3d_CEngUtilGfxUtil::SetFog(GfxEng,
1641            Portion->m_Cam.m_FogDensity, Portion->m_Cam.m_FogColor,
1642            Data->m_FogEnabled, Data->m_FogBlack);
1643    GfxEng->SetBlendMode(
1644            Data->m_BlendColSrcFac,
1645            Data->m_BlendColDestFac,
1646            Data->m_BlendColOp,
1647            Data->m_BlendAlphaSrcFac,
1648            Data->m_BlendAlphaDestFac,
1649            Data->m_BlendAlphaOp);
1650    GfxEng->SetAlphaTest(
1651            Data->m_AlphaTestMode, Data->m_AlphaRef);
1652    GfxEng->SetColorAlpha(s3d_CUtilVec4f(
1653            Data->m_Color, Data->m_Alpha));
1654
1655    int nSamp = ShaderGfx->m_TexChanVarSlotArray.GetCntInt();
1656    GfxEng->SetSampTexElseNone(nSamp);
1657
1658    if(!Data->m_Mtl)
1659        GfxEng->DisableLighting();
1660}
1661
1662void s3d_CEngShaderStdPaintMeshInst::ExecDyn(
1663        s3d_CEngShaderScope *Scope, s3d_CDrvGfxEng *GfxEng,
1664        s3d_CUtilVec3f &Color, float &Alpha)
1665{
1666    if(!Scope)
1667        return;
1668    if(!GfxEng)
1669        return;
1670    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
1671    if(!Portion)
1672        return;
1673
1674    s3d_CEngShaderStdPaintMeshGfx *ShaderGfx = m_ShaderGfx;
1675    s3d_CEngShaderStdPaintMeshData *Data = ShaderGfx->m_Data;
1676
1677    s3d_CDrvVarVec4f *ColorVar
1678        = s3d_DrvVarFetchWaryVec4f(
1679            m_ShaderEnv->m_MsgHandler, Data->m_ColorVarInfo.GetChars(),
1680            Scope->m_VarBlk, ShaderGfx->m_ColorVarSlot.m_Val);
1681    if(ColorVar)
1682    {
1683        Color.m_x = ColorVar->m_Val.m_x;
1684        Color.m_y = ColorVar->m_Val.m_y;
1685        Color.m_z = ColorVar->m_Val.m_z;
1686    }
1687
1688    s3d_CDrvVarVec4f *AlphaVar
1689        = s3d_DrvVarFetchWaryVec4f(
1690            m_ShaderEnv->m_MsgHandler, Data->m_AlphaVarInfo.GetChars(),
1691            Scope->m_VarBlk, ShaderGfx->m_AlphaVarSlot.m_Val);
1692    if(AlphaVar)
1693        Alpha = AlphaVar->m_Val.m_w;
1694
1695    GfxEng->SetColorAlpha(s3d_CUtilVec4f(Color, Alpha));
1696}
1697
1698void s3d_CEngShaderStdPaintMeshInst::ExecLighting(
1699        s3d_CEngShaderScope *Scope, s3d_CDrvGfxEng *GfxEng,
1700        float Alpha)
1701{
1702    if(!Scope)
1703        return;
1704    if(!GfxEng)
1705        return;
1706    s3d_CEngGfxPortion *Portion = Scope->m_Portion;
1707    if(!Portion)
1708        return;
1709
1710    s3d_CEngShaderStdPaintMeshGfx *ShaderGfx = m_ShaderGfx;
1711    s3d_CEngShaderStdPaintMeshData *Data = ShaderGfx->m_Data;
1712
1713    bool DoInsp = s3d_CEngUtilGfxUtil::IsModeFlagDefined(
1714            Portion->m_Cam, Data->m_InspAtom);
1715
1716    s3d_CEngUtilMtl *Mtl = Data->m_Mtl;
1717    if(DoInsp)
1718        Mtl = 0;
1719
1720    if(Mtl)
1721    {
1722        s3d_CEngGfxVarLightArray *LightArrayVar
1723            = s3d_EngGfxVarFetchWaryLightArray(
1724                m_ShaderEnv->m_MsgHandler,
1725                        Data->m_LightArrayVarInfo.GetChars(),
1726                Scope->m_VarBlk, ShaderGfx->m_LightArrayVarSlot.m_Val);
1727        s3d_CDrvGfxLight **LightArray = 0;
1728        s3d_CSysIntps nLight = 0;
1729        if(LightArrayVar)
1730        {
1731            LightArray = LightArrayVar->m_Val.GetPtrRaw();
1732            nLight =  LightArrayVar->m_Val.GetCnt();
1733        }
1734        GfxEng->SetLightArray(nLight, LightArray);
1735        GfxEng->SetMtl(
1736                    Mtl->m_Ambient, Mtl->m_Diffuse,
1737                    Mtl->m_Specular, Mtl->m_Emissive,
1738                    Mtl->m_SpecExp, Alpha);
1739    }
1740    else
1741        GfxEng->DisableLighting();
1742}
1743
1744void s3d_CEngShaderStdPaintMeshInst::ErrorNoBoneWghBank(
1745        s3d_CUtilStr_cr Info, const s3d_CEngMeshData *MeshData)
1746{
1747    if(!m_ShaderEnv)
1748        return;
1749    if(!MeshData)
1750        return;
1751
1752    s3d_CUtilMsg e;
1753    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1754            "no_bonewgh_bank";
1755    e.m_StdTempl = "Mesh \"[1]\" of object \"[2]\" "
1756                "has no bone weights. ";
1757    e.AddInfo(Info);
1758    e.AddInfo(MeshData->m_Info);
1759    e.AddInfo(MeshData->m_Desc);
1760    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1761
1762    e.Reset();
1763    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1764            "no_bonewgh_bank_sic";
1765    e.m_StdTempl = "Sic: This mesh of object \"[2]\" used by shader \"[1]\" "
1766                "has no bone weights. ";
1767    e.AddInfo(MeshData->m_Info);
1768    e.AddInfo(Info);
1769    e.AddInfo(MeshData->m_Desc);
1770    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1771}
1772
1773void s3d_CEngShaderStdPaintMeshInst::ErrorNoBoneSubscrBank(
1774        s3d_CUtilStr_cr Info, const s3d_CEngMeshData *MeshData)
1775{
1776    if(!m_ShaderEnv)
1777        return;
1778    if(!MeshData)
1779        return;
1780
1781    s3d_CUtilMsg e;
1782    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1783            "no_bonesubscr_bank";
1784    e.m_StdTempl = "Mesh \"[1]\" of object \"[2]\" "
1785                "has no bone subscripts. ";
1786    e.AddInfo(Info);
1787    e.AddInfo(MeshData->m_Info);
1788    e.AddInfo(MeshData->m_Desc);
1789    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1790
1791    e.Reset();
1792    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1793            "no_bonesubscr_bank_sic";
1794    e.m_StdTempl = "Sic: This mesh of object \"[2]\" used by shader \"[1]\" "
1795                "has no bone subscripts. ";
1796    e.AddInfo(MeshData->m_Info);
1797    e.AddInfo(Info);
1798    e.AddInfo(MeshData->m_Desc);
1799    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1800}
1801
1802void s3d_CEngShaderStdPaintMeshInst::ErrorNoPointBank(
1803        s3d_CUtilStr_cr Info, const s3d_CEngMeshData *MeshData)
1804{
1805    if(!m_ShaderEnv)
1806        return;
1807    if(!MeshData)
1808        return;
1809
1810    s3d_CUtilMsg e;
1811    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1812            "no_point_bank";
1813    e.m_StdTempl = "Mesh \"[1]\" of object \"[2]\" "
1814                "has no point data. ";
1815    e.AddInfo(Info);
1816    e.AddInfo(MeshData->m_Info);
1817    e.AddInfo(MeshData->m_Desc);
1818    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1819
1820    e.Reset();
1821    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1822            "no_point_bank_sic";
1823    e.m_StdTempl = "Sic: This mesh of object \"[2]\" used by shader \"[1]\" "
1824                "has no point data. ";
1825    e.AddInfo(MeshData->m_Info);
1826    e.AddInfo(Info);
1827    e.AddInfo(MeshData->m_Desc);
1828    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1829}
1830
1831void s3d_CEngShaderStdPaintMeshInst::ErrorNoNormalBank(
1832        s3d_CUtilStr_cr Info, const s3d_CEngMeshData *MeshData)
1833{
1834    if(!m_ShaderEnv)
1835        return;
1836    if(!MeshData)
1837        return;
1838
1839    s3d_CUtilMsg e;
1840    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1841            "no_normal_bank";
1842    e.m_StdTempl = "Mesh \"[1]\" of object \"[2]\" "
1843                "has no normal data. ";
1844    e.AddInfo(Info);
1845    e.AddInfo(MeshData->m_Info);
1846    e.AddInfo(MeshData->m_Desc);
1847    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1848
1849    e.Reset();
1850    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1851            "no_normal_bank_sic";
1852    e.m_StdTempl = "Sic: This mesh of object \"[2]\" used by shader \"[1]\" "
1853                "has no normal data. ";
1854    e.AddInfo(MeshData->m_Info);
1855    e.AddInfo(Info);
1856    e.AddInfo(MeshData->m_Desc);
1857    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1858}
1859
1860void s3d_CEngShaderStdPaintMeshInst::ErrorNoColorAlphaBank(
1861        s3d_CUtilStr_cr Info, const s3d_CEngMeshData *MeshData)
1862{
1863    if(!m_ShaderEnv)
1864        return;
1865    if(!MeshData)
1866        return;
1867
1868    s3d_CUtilMsg e;
1869    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1870            "no_coloralpha_bank";
1871    e.m_StdTempl = "Mesh \"[1]\" of object \"[2]\" "
1872                "has no color and alpha data. ";
1873    e.AddInfo(Info);
1874    e.AddInfo(MeshData->m_Info);
1875    e.AddInfo(MeshData->m_Desc);
1876    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1877
1878    e.Reset();
1879    e.m_Code = "eng/shader/std/eng_shader_std_paintmesh."
1880            "no_coloralpha_bank_sic";
1881    e.m_StdTempl = "Sic: This mesh of object \"[2]\" used by shader \"[1]\" "
1882                "has no color and alpha data. ";
1883    e.AddInfo(MeshData->m_Info);
1884    e.AddInfo(Info);
1885    e.AddInfo(MeshData->m_Desc);
1886    s3d_UtilMsgReportError(m_ShaderEnv->m_MsgHandler, e);
1887}
1888
1889///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.