Coverage Report

Created: 2025-07-11 06:36

/src/ogre/OgreMain/include/OgrePass.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
-----------------------------------------------------------------------------
3
This source file is part of OGRE
4
(Object-oriented Graphics Rendering Engine)
5
For the latest info, see http://www.ogre3d.org
6
7
Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9
Permission is hereby granted, free of charge, to any person obtaining a copy
10
of this software and associated documentation files (the "Software"), to deal
11
in the Software without restriction, including without limitation the rights
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
copies of the Software, and to permit persons to whom the Software is
14
furnished to do so, subject to the following conditions:
15
16
The above copyright notice and this permission notice shall be included in
17
all copies or substantial portions of the Software.
18
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
THE SOFTWARE.
26
-----------------------------------------------------------------------------
27
*/
28
#ifndef __Pass_H__
29
#define __Pass_H__
30
31
#include "OgrePrerequisites.h"
32
#include "OgreColourValue.h"
33
#include "OgreCommon.h"
34
#include "OgreLight.h"
35
#include "OgreTextureUnitState.h"
36
#include "OgreUserObjectBindings.h"
37
#include "OgreHeaderPrefix.h"
38
39
namespace Ogre {
40
41
    /** \addtogroup Core
42
     *  @{
43
     */
44
    /** \addtogroup Materials
45
     *  @{
46
     */
47
    /// Categorisation of passes for the purpose of additive lighting
48
    enum IlluminationStage : uint8
49
    {
50
        /// Part of the rendering which occurs without any kind of direct lighting
51
        IS_AMBIENT,
52
        /// Part of the rendering which occurs per light
53
        IS_PER_LIGHT,
54
        /// Post-lighting rendering
55
        IS_DECAL,
56
        /// Not determined
57
        IS_UNKNOWN
58
    };
59
60
    /** Class defining a single pass of a Technique (of a Material): a single rendering call.
61
62
        If a pass does not explicitly use a vertex or fragment shader, %Ogre will calculate
63
        lighting based on the [Direct3D Light Model](https://docs.microsoft.com/en-us/windows/win32/direct3d9/mathematics-of-lighting) as:
64
65
        If at least one shader is used, the pass is considered *programmable* and the lighting is
66
        up to the shader.
67
68
        Rendering can be repeated with many passes for more complex effects.
69
70
        @copydetails setLightingEnabled
71
72
        @par Lighting disabled
73
74
        $$ passBase = C $$
75
76
        where \f$C = (1, 1, 1)\f$ or a tracked vertex attribute if #TVC_DIFFUSE is set.
77
78
        @par Lighting enabled
79
80
        \f[ passBase = G_a \cdot C_a + \sum^N_i ( C_d \cdot L^{(i)}_d +  C_s \cdot L^{(i)}_s ) + C_e \f]
81
82
        where
83
        - \f$G_a\f$ is the ambient colour defined by the SceneManager
84
        - \f$C_a\f$ is the pass ambient colour
85
        - \f$C_e\f$ is the pass self-illumination colour or a tracked vertex attribute
86
        - \f$N\f$ is the number of lights considered during light iteration
87
        - \f$C_d\f$ is the pass diffuse colour or a tracked vertex attribute
88
        - \f$C_s\f$ is the pass specular colour or a tracked vertex attribute
89
        - \f$L_d^{(i)}\f$ is the (attenuated) diffuse colour of the i-th Light
90
        - \f$L_s^{(i)}\f$ is the (attenuated) specular colour of the i-th Light
91
92
        @par Programmable passes
93
94
        Programmable passes are complex to define, because they require custom
95
        programs and you have to set all constant inputs to the programs (like
96
        the position of lights, any base material colours you wish to use etc), but
97
        they do give you much total flexibility over the algorithms used to render your
98
        pass, and you can create some effects which are impossible with a fixed-function pass.
99
        On the other hand, you can define a fixed-function pass in very little time, and
100
        you can use a range of fixed-function effects like environment mapping very
101
        easily, plus your pass will be more likely to be compatible with older hardware.
102
        There are pros and cons to both, just remember that if you use a programmable
103
        pass to create some great effects, allow more time for definition and testing.
104
    */
105
    class _OgreExport Pass : public PassAlloc
106
    {
107
    public:
108
        /** Definition of a functor for calculating the hashcode of a Pass.
109
110
            The hashcode of a Pass is used to sort Passes for rendering, in order
111
            to reduce the number of render state changes. Each Pass represents a
112
            single unique set of states, but by ordering them, state changes can
113
            be minimised between passes. An implementation of this functor should
114
            order passes so that the elements that you want to keep constant are
115
            sorted next to each other.
116
117
            Hash format is 32-bit, divided as follows (high to low bits)
118
            bits   purpose
119
             4     Pass index (i.e. max 16 passes!).
120
            28     Pass contents
121
122
            @note the high bits returned by this function will get overwritten
123
124
            @see Pass::setHashFunc
125
        */
126
        struct HashFunc
127
        {
128
            virtual uint32 operator()(const Pass* p) const = 0;
129
            /// Need virtual destructor in case subclasses use it
130
0
            virtual ~HashFunc() {}
131
        };
132
133
        typedef std::vector<TextureUnitState*> TextureUnitStates;
134
    private:
135
        Technique* mParent;
136
        String mName; /// Optional name for the pass
137
        uint32 mHash; /// Pass hash
138
        //-------------------------------------------------------------------------
139
        // Colour properties, only applicable in fixed-function passes
140
        ColourValue mAmbient;
141
        ColourValue mDiffuse;
142
        ColourValue mSpecular;
143
        ColourValue mEmissive;
144
        float mShininess;
145
        TrackVertexColourType mTracking;
146
        //-------------------------------------------------------------------------
147
        ColourBlendState mBlendState;
148
149
        /// Needs to be dirtied when next loaded
150
        bool mHashDirtyQueued : 1;
151
        // Depth buffer settings
152
        bool mDepthCheck : 1;
153
        bool mDepthWrite : 1;
154
        bool mAlphaToCoverageEnabled : 1;
155
        /// Transparent depth sorting
156
        bool mTransparentSorting : 1;
157
        /// Transparent depth sorting forced
158
        bool mTransparentSortingForced : 1;
159
        /// Lighting enabled?
160
        bool mLightingEnabled : 1;
161
        /// Run this pass once per light?
162
        bool mIteratePerLight : 1;
163
        /// Should it only be run for a certain light type?
164
        bool mRunOnlyForOneLightType : 1;
165
        bool mPolygonModeOverrideable : 1;
166
        bool mFogOverride : 1;
167
        /// Is this pass queued for deletion?
168
        bool mQueuedForDeletion : 1;
169
        /// Scissoring for the light?
170
        bool mLightScissoring : 1;
171
        /// User clip planes for light?
172
        bool mLightClipPlanes : 1;
173
        bool mPointSpritesEnabled : 1;
174
        bool mPointAttenuationEnabled : 1;
175
        mutable bool mContentTypeLookupBuilt : 1;
176
177
        uchar mAlphaRejectVal;
178
179
        float mDepthBiasConstant;
180
        float mDepthBiasSlopeScale;
181
        float mDepthBiasPerIteration;
182
183
        CompareFunction mDepthFunc;
184
        // Alpha reject settings
185
        CompareFunction mAlphaRejectFunc;
186
187
        //-------------------------------------------------------------------------
188
189
        //-------------------------------------------------------------------------
190
        // Culling mode
191
        CullingMode mCullMode;
192
        ManualCullingMode mManualCullMode;
193
        //-------------------------------------------------------------------------
194
195
        /// Max simultaneous lights
196
        unsigned short mMaxSimultaneousLights;
197
        /// Starting light index
198
        unsigned short mStartLight;
199
        /// Iterate per how many lights?
200
        unsigned short mLightsPerIteration;
201
202
        ushort mIndex; /// Pass index
203
204
        /// With a specific light mask?
205
        uint32 mLightMask;
206
207
        //-------------------------------------------------------------------------
208
        // Fog
209
        ColourValue mFogColour;
210
        float mFogStart;
211
        float mFogEnd;
212
        float mFogDensity;
213
        //-------------------------------------------------------------------------
214
        /// line width
215
        float mLineWidth;
216
        /// Storage of texture unit states
217
        TextureUnitStates mTextureUnitStates;
218
219
        // TU Content type lookups
220
        typedef std::vector<unsigned short> ContentTypeLookup;
221
        mutable ContentTypeLookup mShadowContentTypeLookup;
222
223
        std::unique_ptr<GpuProgramUsage> mProgramUsage[GPT_PIPELINE_COUNT];
224
        /// Number of pass iterations to perform
225
        size_t mPassIterationCount;
226
        /// Point size, applies when not using per-vertex point size
227
        float mPointMinSize;
228
        float mPointMaxSize;
229
        /// Size, Constant, linear, quadratic coeffs
230
        Vector4f mPointAttenution;
231
232
        /// User objects binding.
233
        UserObjectBindings      mUserObjectBindings;
234
235
        /// Shading options
236
        ShadeOptions mShadeOptions;
237
        /// Polygon mode
238
        PolygonMode mPolygonMode;
239
        /// Illumination stage?
240
        IlluminationStage mIlluminationStage;
241
242
        Light::LightTypes mOnlyLightType;
243
        FogMode mFogMode;
244
245
    public:
246
        typedef std::set<Pass*> PassSet;
247
    private:
248
        /// List of Passes whose hashes need recalculating
249
        static PassSet msDirtyHashList;
250
        /// The place where passes go to die
251
        static PassSet msPassGraveyard;
252
        /// The Pass hash functor
253
        static HashFunc* msHashFunc;
254
    public:
255
        OGRE_STATIC_MUTEX(msDirtyHashListMutex);
256
        OGRE_STATIC_MUTEX(msPassGraveyardMutex);
257
        OGRE_MUTEX(mTexUnitChangeMutex);
258
        OGRE_MUTEX(mGpuProgramChangeMutex);
259
        /// Default constructor
260
        Pass(Technique* parent, unsigned short index);
261
        /// Copy constructor
262
        Pass(Technique* parent, unsigned short index, const Pass& oth );
263
264
        ~Pass();
265
266
        /// Operator = overload
267
        Pass& operator=(const Pass& oth);
268
269
        size_t calculateSize(void) const;
270
271
        /// Gets the index of this Pass in the parent Technique
272
0
        unsigned short getIndex(void) const { return mIndex; }
273
        /** Set the name of the pass
274
275
           The name of the pass is optional.  Its useful in material scripts where a material could inherit
276
           from another material and only want to modify a particular pass.
277
        */
278
0
        void setName(const String& name) { mName = name; }
279
        /// Get the name of the pass
280
0
        const String& getName(void) const { return mName; }
281
282
        /// @name Surface properties
283
        /// @{
284
        /** Sets the ambient colour reflectance properties of this pass.
285
286
        This property determines how much ambient light (directionless global light) is
287
        reflected. The default is full white, meaning objects are completely globally
288
        illuminated. Reduce this if you want to see diffuse or specular light effects, or change
289
        the blend of colours to make the object have a base colour other than white.
290
291
        It is also possible to make the ambient reflectance track the vertex colour as defined in
292
        the mesh instead of the colour values.
293
        @note
294
        This setting has no effect if dynamic lighting is disabled (see
295
        Ogre::Pass::setLightingEnabled), or, if any texture layer has a Ogre::LBO_REPLACE
296
        attribute.
297
        */
298
        void setAmbient(float red, float green, float blue);
299
300
        /// @overload
301
0
        void setAmbient(const ColourValue& ambient) { mAmbient = ambient; }
302
303
        /** Sets the diffuse colour reflectance properties of this pass.
304
305
        This property determines how much diffuse light (light from instances
306
        of the Light class in the scene) is reflected. The default is full white, meaning objects
307
        reflect the maximum white light they can from Light objects.
308
309
        It is also possible to make the diffuse reflectance track the vertex colour as defined in
310
        the mesh instead of the colour values.
311
        @note
312
        This setting has no effect if dynamic lighting is disabled (see
313
        Ogre::Pass::setLightingEnabled), or, if any texture layer has a Ogre::LBO_REPLACE
314
        attribute.
315
        */
316
        void setDiffuse(float red, float green, float blue, float alpha);
317
318
        /// @overload
319
0
        void setDiffuse(const ColourValue& diffuse) { mDiffuse = diffuse; }
320
321
        /** Sets the specular colour reflectance properties of this pass.
322
323
        This property determines how much specular light (highlights from instances of the Light
324
        class in the scene) is reflected. The default is to reflect no specular light.
325
326
        It is also possible to make the specular reflectance track the vertex colour as defined in
327
        the mesh instead of the colour values.
328
        @note
329
        The size of the specular highlights is determined by the separate 'shininess' property.
330
        @note
331
        This setting has no effect if dynamic lighting is disabled (see
332
        Ogre::Pass::setLightingEnabled), or, if any texture layer has a Ogre::LBO_REPLACE
333
        attribute.
334
        */
335
        void setSpecular(float red, float green, float blue, float alpha);
336
337
        /// @overload
338
0
        void setSpecular(const ColourValue& specular) { mSpecular = specular; }
339
340
        /** Sets the shininess of the pass, affecting the size of specular highlights.
341
342
        The higher the value of the shininess parameter, the sharper the highlight i.e. the radius
343
        is smaller. Beware of using shininess values in the range of 0 to 1 since this causes the
344
        the specular colour to be applied to the whole surface that has the material applied to it.
345
        When the viewing angle to the surface changes, ugly flickering will also occur when
346
        shininess is in the range of 0 to 1. Shininess values between 1 and 128 work best in both
347
        DirectX and OpenGL renderers.
348
        @note
349
        This setting has no effect if dynamic lighting is disabled (see
350
        Ogre::Pass::setLightingEnabled), or, if any texture layer has a Ogre::LBO_REPLACE
351
        attribute.
352
        */
353
0
        void setShininess(float val) {  mShininess = val; }
354
355
        /** Sets the amount of self-illumination an object has.
356
357
        If an object is self-illuminating, it does not need external sources to light it, ambient or
358
        otherwise. It's like the object has it's own personal ambient light. This property is rarely useful since
359
        you can already specify per-pass ambient light, but is here for completeness.
360
361
        It is also possible to make the emissive reflectance track the vertex colour as defined in
362
        the mesh instead of the colour values.
363
        @note
364
        This setting has no effect if dynamic lighting is disabled (see
365
        Ogre::Pass::setLightingEnabled), or, if any texture layer has a Ogre::LBO_REPLACE
366
        attribute.
367
        */
368
        void setSelfIllumination(float red, float green, float blue);
369
370
        /// @overload
371
0
        void setSelfIllumination(const ColourValue& selfIllum) { mEmissive = selfIllum; }
372
373
        /// @copydoc setSelfIllumination
374
0
        void setEmissive(float red, float green, float blue) { setSelfIllumination(red, green, blue); }
375
        /// @overload
376
0
        void setEmissive(const ColourValue& emissive) { setSelfIllumination(emissive); }
377
378
        /** Sets which material properties follow the vertex colour
379
         */
380
0
        void setVertexColourTracking(TrackVertexColourType tracking) { mTracking = tracking; }
381
382
        /** Gets the ambient colour reflectance of the pass.
383
         */
384
0
        const ColourValue& getAmbient(void) const { return mAmbient; }
385
386
        /** Gets the diffuse colour reflectance of the pass.
387
         */
388
0
        const ColourValue& getDiffuse(void) const { return mDiffuse; }
389
390
        /** Gets the specular colour reflectance of the pass.
391
         */
392
0
        const ColourValue& getSpecular(void) const { return mSpecular; }
393
394
        /** Gets the self illumination colour of the pass.
395
         */
396
0
        const ColourValue& getSelfIllumination(void) const { return mEmissive; }
397
398
        /** Gets the self illumination colour of the pass.
399
            @see
400
            getSelfIllumination
401
        */
402
0
        const ColourValue& getEmissive(void) const { return getSelfIllumination(); }
403
404
        /** Gets the 'shininess' property of the pass (affects specular highlights).
405
         */
406
0
        float getShininess(void) const { return mShininess; }
407
408
        /** Gets which material properties follow the vertex colour
409
         */
410
0
        TrackVertexColourType getVertexColourTracking(void) const {  return mTracking; }
411
412
        /** Sets whether or not dynamic lighting is enabled.
413
414
            Turning dynamic lighting off makes any ambient, diffuse, specular, emissive and shading
415
            properties for this pass redundant.
416
            If lighting is turned off, all objects rendered using the pass will be fully lit.
417
            When lighting is turned on, objects are lit according
418
            to their vertex normals for diffuse and specular light, and globally for ambient and
419
            emissive.
420
        */
421
0
        void setLightingEnabled(bool enabled) { mLightingEnabled = enabled; }
422
423
        /** Returns whether or not dynamic lighting is enabled.
424
         */
425
0
        bool getLightingEnabled(void) const { return mLightingEnabled; }
426
        /// @}
427
428
        /**
429
         * set the line width for this pass
430
         *
431
         * This property determines what width is used to render lines.
432
         * @note some drivers only support a value of 1.0 here
433
         */
434
0
        void setLineWidth(float width) { mLineWidth = width; }
435
0
        float getLineWidth() const { return mLineWidth; }
436
437
        /// @name Point Sprites
438
        /// @{
439
        /** Gets the point size of the pass.
440
441
            This property determines what point size is used to render a point
442
            list.
443
        */
444
0
        float getPointSize(void) const { return mPointAttenution[0]; }
445
446
        /** Sets the point size of this pass.
447
448
            This setting allows you to change the size of points when rendering
449
            a point list, or a list of point sprites. The interpretation of this
450
            command depends on the Ogre::Pass::setPointAttenuation option - if it
451
            is off (the default), the point size is in screen pixels, if it is on,
452
            it expressed as normalised screen coordinates (1.0 is the height of
453
            the screen) when the point is at the origin.
454
            @note
455
            Some drivers have an upper limit on the size of points they support - this can even vary
456
            between APIs on the same card! Don't rely on point sizes that cause the point sprites to
457
            get very large on screen, since they may get clamped on some cards. Upper sizes can range
458
            from 64 to 256 pixels.
459
        */
460
0
        void setPointSize(float ps) { mPointAttenution[0] = ps; }
461
462
        /** Sets whether points will be rendered as textured quads or plain dots
463
464
            This setting specifies whether or not hardware point sprite rendering is enabled for
465
            this pass. Enabling it means that a point list is rendered as a list of quads rather than
466
            a list of dots. It is very useful to use this option if you are using a BillboardSet and
467
            only need to use point oriented billboards which are all of the same size. You can also
468
            use it for any other point list render.
469
        */
470
0
        void setPointSpritesEnabled(bool enabled) { mPointSpritesEnabled = enabled; }
471
472
        /** Returns whether point sprites are enabled when rendering a
473
            point list.
474
        */
475
0
        bool getPointSpritesEnabled(void) const {  return mPointSpritesEnabled; }
476
477
        /** Sets how points are attenuated with distance.
478
479
            When performing point rendering or point sprite rendering,
480
            point size can be attenuated with distance. The equation for
481
            doing this is:
482
            
483
            \f[ S_a = V_h \cdot S \cdot \frac{1}{\sqrt{constant + linear \cdot d + quadratic \cdot d^2}} \f]
484
485
            Where
486
            - \f$d\f$ is the distance from the camera to the point
487
            - \f$S\f$ is the point size parameter
488
            - \f$V_h\f$ is the viewport height in pixels
489
490
            For example, to disable distance attenuation (constant screensize)
491
            you would set constant to 1, and linear and quadratic to 0. A
492
            standard perspective attenuation would be 0, 1, 0 respectively.
493
494
            The resulting size is clamped to the minimum and maximum point
495
            size.
496
        @param enabled Whether point attenuation is enabled
497
        @param constant, linear, quadratic Parameters to the attenuation
498
            function defined above
499
        */
500
        void setPointAttenuation(bool enabled, float constant = 0.0f, float linear = 1.0f, float quadratic = 0.0f);
501
502
        /** Returns whether points are attenuated with distance. */
503
0
        bool isPointAttenuationEnabled(void) const { return mPointAttenuationEnabled; }
504
505
        /** Returns the constant coefficient of point attenuation. */
506
0
        float getPointAttenuationConstant(void) const { return mPointAttenution[1]; }
507
        /** Returns the linear coefficient of point attenuation. */
508
0
        float getPointAttenuationLinear(void) const { return mPointAttenution[2]; }
509
        /** Returns the quadratic coefficient of point attenuation. */
510
0
        float getPointAttenuationQuadratic(void) const { return mPointAttenution[3]; }
511
512
        /// get all point attenuation params as (size, constant, linear, quadratic)
513
0
        const Vector4f& getPointAttenuation() const { return mPointAttenution; }
514
515
        /** Set the minimum point size, when point attenuation is in use. */
516
        void setPointMinSize(Real min);
517
        /** Get the minimum point size, when point attenuation is in use. */
518
        Real getPointMinSize(void) const;
519
        /** Set the maximum point size, when point attenuation is in use.
520
            @remarks Setting this to 0 indicates the max size supported by the card.
521
        */
522
        void setPointMaxSize(Real max);
523
        /** Get the maximum point size, when point attenuation is in use.
524
            @remarks 0 indicates the max size supported by the card.
525
        */
526
        Real getPointMaxSize(void) const;
527
        /// @}
528
529
        typedef VectorIterator<TextureUnitStates> TextureUnitStateIterator;
530
        typedef ConstVectorIterator<TextureUnitStates> ConstTextureUnitStateIterator;
531
        /// @name Texture Units
532
        /// @{
533
        /** Inserts a new TextureUnitState object into the Pass.
534
535
            This unit is is added on top of all previous units.
536
            @param textureName
537
            The basic name of the texture e.g. brickwall.jpg, stonefloor.png
538
            @param texCoordSet
539
            The index of the texture coordinate set to use.
540
            @note
541
            Applies to both fixed-function and programmable passes.
542
        */
543
        TextureUnitState* createTextureUnitState( const String& textureName, unsigned short texCoordSet = 0);
544
        /// @overload
545
        TextureUnitState* createTextureUnitState(void);
546
547
        /** Adds the passed in TextureUnitState, to the existing Pass.
548
            @param
549
            state The Texture Unit State to be attached to this pass.  It must not be attached to another pass.
550
            @note
551
            Throws an exception if the TextureUnitState is attached to another Pass.*/
552
        void addTextureUnitState(TextureUnitState* state);
553
        /** Retrieves a const pointer to a texture unit state.
554
         */
555
0
        TextureUnitState* getTextureUnitState(size_t index) const { return mTextureUnitStates.at(index); }
556
        /** Retrieves the Texture Unit State matching name.
557
            Returns 0 if name match is not found.
558
        */
559
        TextureUnitState* getTextureUnitState(const String& name) const;
560
561
562
        /**  Retrieve the index of the Texture Unit State in the pass.
563
             @param
564
             state The Texture Unit State this is attached to this pass.
565
             @note
566
             Throws an exception if the state is not attached to the pass.
567
             @deprecated use getTextureUnitStates()
568
        */
569
        unsigned short getTextureUnitStateIndex(const TextureUnitState* state) const;
570
571
        /** Get an iterator over the TextureUnitStates contained in this Pass.
572
         * @deprecated use getTextureUnitStates() */
573
        OGRE_DEPRECATED TextureUnitStateIterator getTextureUnitStateIterator(void);
574
575
        /** Get an iterator over the TextureUnitStates contained in this Pass.
576
         * @deprecated use getTextureUnitStates() */
577
        OGRE_DEPRECATED ConstTextureUnitStateIterator getTextureUnitStateIterator(void) const;
578
579
        /** Get the TextureUnitStates contained in this Pass. */
580
0
        const TextureUnitStates& getTextureUnitStates() const { return mTextureUnitStates; }
581
582
        /** Removes the indexed texture unit state from this pass.
583
584
            Note that removing a texture which is not the topmost will have a larger performance impact.
585
        */
586
        void removeTextureUnitState(unsigned short index);
587
588
        /** Removes all texture unit settings.
589
         */
590
        void removeAllTextureUnitStates(void);
591
592
        /** Returns the number of texture unit settings */
593
0
        size_t getNumTextureUnitStates(void) const { return mTextureUnitStates.size(); }
594
595
        /** Gets the 'nth' texture which references the given content type.
596
597
            If the 'nth' texture unit which references the content type doesn't
598
            exist, then this method returns an arbitrary high-value outside the
599
            valid range to index texture units.
600
        */
601
        unsigned short _getTextureUnitWithContentTypeIndex(
602
            TextureUnitState::ContentType contentType, unsigned short index) const;
603
604
        /** Set texture filtering for every texture unit
605
            @note
606
            This property actually exists on the TextureUnitState class
607
            For simplicity, this method allows you to set these properties for
608
            every current TeextureUnitState, If you need more precision, retrieve the
609
            TextureUnitState instance and set the property there.
610
            @see TextureUnitState::setTextureFiltering
611
        */
612
        void setTextureFiltering(TextureFilterOptions filterType);
613
        /** Sets the anisotropy level to be used for all textures.
614
            @note
615
            This property has been moved to the TextureUnitState class, which is accessible via the
616
            Technique and Pass. For simplicity, this method allows you to set these properties for
617
            every current TeextureUnitState, If you need more precision, retrieve the Technique,
618
            Pass and TextureUnitState instances and set the property there.
619
            @see TextureUnitState::setTextureAnisotropy
620
        */
621
        void setTextureAnisotropy(unsigned int maxAniso);
622
        /// @}
623
624
        /// @name Scene Blending
625
        /// @{
626
        /** Sets the kind of blending this pass has with the existing contents of the scene.
627
628
            Whereas the texture blending operations seen in the TextureUnitState class are concerned with
629
            blending between texture layers, this blending is about combining the output of the Pass
630
            as a whole with the existing contents of the rendering target. This blending therefore allows
631
            object transparency and other special effects. If all passes in a technique have a scene
632
            blend, then the whole technique is considered to be transparent.
633
634
            This method allows you to select one of a number of predefined blending types. If you require more
635
            control than this, use the alternative version of this method which allows you to specify source and
636
            destination blend factors.
637
            @note
638
            This method is applicable for both the fixed-function and programmable pipelines.
639
            @param
640
            sbt One of the predefined SceneBlendType blending types
641
        */
642
        void setSceneBlending( const SceneBlendType sbt );
643
644
        /** Sets the kind of blending this pass has with the existing contents of the scene, separately for color and alpha channels
645
646
            This method allows you to select one of a number of predefined blending types. If you require more
647
            control than this, use the alternative version of this method which allows you to specify source and
648
            destination blend factors.
649
650
            @param
651
            sbt One of the predefined SceneBlendType blending types for the color channel
652
            @param
653
            sbta One of the predefined SceneBlendType blending types for the alpha channel
654
        */
655
        void setSeparateSceneBlending( const SceneBlendType sbt, const SceneBlendType sbta );
656
657
        /** Allows very fine control of blending this Pass with the existing contents of the scene.
658
659
            This version of the method allows complete control over the blending operation, by specifying the
660
            source and destination blending factors.
661
662
            @copydetails Ogre::ColourBlendState
663
664
            @param
665
            sourceFactor The source factor in the above calculation, i.e. multiplied by the output of the %Pass.
666
            @param
667
            destFactor The destination factor in the above calculation, i.e. multiplied by the Frame Buffer contents.
668
        */
669
        void setSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor);
670
671
        /** Allows very fine control of blending this Pass with the existing contents of the scene.
672
            @copydetails Ogre::Pass::setSceneBlending( const SceneBlendFactor, const SceneBlendFactor)
673
            @param
674
            sourceFactorAlpha The alpha source factor in the above calculation, i.e. multiplied by the output of the %Pass.
675
            @param
676
            destFactorAlpha The alpha destination factor in the above calculation, i.e. multiplied by the Frame Buffer alpha.
677
        */
678
        void setSeparateSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor, const SceneBlendFactor sourceFactorAlpha, const SceneBlendFactor destFactorAlpha );
679
680
        /// Retrieves the complete blend state of this pass
681
0
        const ColourBlendState& getBlendState() const { return mBlendState; }
682
683
        /** Retrieves the source blending factor for the material
684
         */
685
0
        SceneBlendFactor getSourceBlendFactor() const { return mBlendState.sourceFactor; }
686
687
        /** Retrieves the destination blending factor for the material
688
         */
689
0
        SceneBlendFactor getDestBlendFactor() const { return mBlendState.destFactor; }
690
691
        /** Retrieves the alpha source blending factor for the material
692
         */
693
0
        SceneBlendFactor getSourceBlendFactorAlpha() const { return mBlendState.sourceFactorAlpha; }
694
695
        /** Retrieves the alpha destination blending factor for the material
696
         */
697
0
        SceneBlendFactor getDestBlendFactorAlpha() const { return mBlendState.destFactorAlpha; }
698
699
        /** Sets the specific operation used to blend source and destination pixels together.
700
701
            @see Ogre::ColourBlendState
702
            @param op The blending operation mode to use for this pass
703
        */
704
        void setSceneBlendingOperation(SceneBlendOperation op);
705
706
        /** Sets the specific operation used to blend source and destination pixels together.
707
708
            This function allows more control over blending since it allows you to select different blending
709
            modes for the color and alpha channels
710
711
            @copydetails Pass::setSceneBlendingOperation
712
            @param alphaOp The blending operation mode to use for alpha channels in this pass
713
        */
714
        void setSeparateSceneBlendingOperation(SceneBlendOperation op, SceneBlendOperation alphaOp);
715
716
        /** Returns the current blending operation */
717
0
        SceneBlendOperation getSceneBlendingOperation() const { return mBlendState.operation; }
718
719
        /** Returns the current alpha blending operation */
720
0
        SceneBlendOperation getSceneBlendingOperationAlpha() const {  return mBlendState.alphaOperation; }
721
722
        /** Sets whether or not colour buffer writing is enabled for this %Pass.
723
724
            If colour writing is off no visible pixels are written to the screen during this pass.
725
            You might think this is useless, but if you render with colour writing off, and with very
726
            minimal other settings, you can use this pass to initialise the depth buffer before
727
            subsequently rendering other passes which fill in the colour data. This can give you
728
            significant performance boosts on some newer cards, especially when using complex
729
            fragment programs, because if the depth check fails then the fragment program is never
730
            run.
731
        */
732
        void setColourWriteEnabled(bool enabled);
733
        /** Determines if colour buffer writing is enabled for this pass i.e. when at least one
734
            colour channel is enabled for writing.
735
         */
736
        bool getColourWriteEnabled(void) const;
737
738
        /// Sets which colour buffer channels are enabled for writing for this Pass
739
        void setColourWriteEnabled(bool red, bool green, bool blue, bool alpha);
740
        /// Determines which colour buffer channels are enabled for writing for this pass.
741
        void getColourWriteEnabled(bool& red, bool& green, bool& blue, bool& alpha) const;
742
        /// @}
743
744
        /** Returns true if this pass has some element of transparency. */
745
        bool isTransparent(void) const;
746
747
        /// @name Depth Testing
748
        /// @{
749
        /** Sets whether or not this pass renders with depth-buffer checking on or not.
750
751
            If depth-buffer checking is on, whenever a pixel is about to be written to the frame buffer
752
            the depth buffer is checked to see if the pixel is in front of all other pixels written at that
753
            point. If not, the pixel is not written.
754
755
            If depth checking is off, pixels are written no matter what has been rendered before.
756
            Also see setDepthFunction for more advanced depth check configuration.
757
            @see Ogre::CompareFunction
758
        */
759
0
        void setDepthCheckEnabled(bool enabled) {  mDepthCheck = enabled; }
760
761
        /** Returns whether or not this pass renders with depth-buffer checking on or not.
762
        */
763
0
        bool getDepthCheckEnabled(void) const { return mDepthCheck; }
764
765
        /** Sets whether or not this pass renders with depth-buffer writing on or not.
766
767
            If depth-buffer writing is on, whenever a pixel is written to the frame buffer
768
            the depth buffer is updated with the depth value of that new pixel, thus affecting future
769
            rendering operations if future pixels are behind this one.
770
771
            If depth writing is off, pixels are written without updating the depth buffer Depth writing should
772
            normally be on but can be turned off when rendering static backgrounds or when rendering a collection
773
            of transparent objects at the end of a scene so that they overlap each other correctly.
774
        */
775
0
        void setDepthWriteEnabled(bool enabled) { mDepthWrite = enabled; }
776
777
        /** Returns whether or not this pass renders with depth-buffer writing on or not.
778
        */
779
0
        bool getDepthWriteEnabled(void) const { return mDepthWrite; }
780
781
        /** Sets the function used to compare depth values when depth checking is on.
782
783
            If depth checking is enabled (see setDepthCheckEnabled) a comparison occurs between the depth
784
            value of the pixel to be written and the current contents of the buffer. This comparison is
785
            normally Ogre::CMPF_LESS_EQUAL.
786
        */
787
0
        void setDepthFunction( CompareFunction func ) {  mDepthFunc = func; }
788
        /** Returns the function used to compare depth values when depth checking is on.
789
            @see
790
            setDepthFunction
791
        */
792
0
        CompareFunction getDepthFunction(void) const {  return mDepthFunc; }
793
794
        /** Sets the depth bias to be used for this material.
795
796
            When polygons are coplanar, you can get problems with 'depth fighting' where
797
            the pixels from the two polys compete for the same screen pixel. This is particularly
798
            a problem for decals (polys attached to another surface to represent details such as
799
            bulletholes etc.).
800
801
            A way to combat this problem is to use a depth bias to adjust the depth buffer value
802
            used for the decal such that it is slightly higher than the true value, ensuring that
803
            the decal appears on top. There are two aspects to the biasing, a constant
804
            bias value and a slope-relative biasing value, which varies according to the
805
            maximum depth slope relative to the camera, ie:
806
807
            $$finalBias = maxSlope * slopeScaleBias + constantBias$$
808
809
            Slope scale biasing is relative to the angle of the polygon to the camera, which makes
810
            for a more appropriate bias value, but this is ignored on some older hardware. Constant
811
            biasing is expressed as a factor of the minimum depth value, so a value of 1 will nudge
812
            the depth by one ’notch’ if you will.
813
            @param constantBias The constant bias value
814
            @param slopeScaleBias The slope-relative bias value
815
        */
816
        void setDepthBias(float constantBias, float slopeScaleBias = 0.0f);
817
818
        /** Retrieves the const depth bias value as set by setDepthBias. */
819
0
        float getDepthBiasConstant(void) const { return mDepthBiasConstant; }
820
        /** Retrieves the slope-scale depth bias value as set by setDepthBias. */
821
0
        float getDepthBiasSlopeScale(void) const { return mDepthBiasSlopeScale; }
822
        /** Sets a factor which derives an additional depth bias from the number
823
            of times a pass is iterated.
824
825
            The Final depth bias will be the constant depth bias as set through
826
            setDepthBias, plus this value times the iteration number.
827
        */
828
0
        void setIterationDepthBias(float biasPerIteration) { mDepthBiasPerIteration = biasPerIteration; }
829
        /** Gets a factor which derives an additional depth bias from the number
830
            of times a pass is iterated.
831
        */
832
0
        float getIterationDepthBias() const { return mDepthBiasPerIteration; }
833
        /// @}
834
835
        /** Sets the culling mode for this pass based on the 'vertex winding'.
836
            A typical way for the rendering engine to cull triangles is based on the 'vertex winding' of
837
            triangles. Vertex winding refers to the direction in which the vertices are passed or indexed
838
            to in the rendering operation as viewed from the camera, and will either be clockwise or
839
            anticlockwise (that's 'counterclockwise' for you Americans out there ;) The default is
840
            Ogre::CULL_CLOCKWISE i.e. that only triangles whose vertices are passed/indexed in anticlockwise order
841
            are rendered - this is a common approach and is used in 3D studio models for example. You can
842
            alter this culling mode if you wish but it is not advised unless you know what you are doing.
843
844
            You may wish to use the Ogre::CULL_NONE option for mesh data that you cull yourself where the vertex
845
            winding is uncertain or for creating 2-sided passes.
846
        */
847
0
        void setCullingMode( CullingMode mode ) { mCullMode = mode; }
848
849
        /** Returns the culling mode for geometry rendered with this pass. See setCullingMode for more information.
850
         */
851
0
        CullingMode getCullingMode(void) const { return mCullMode; }
852
853
        /** Sets the manual culling mode, performed by CPU rather than hardware.
854
855
            In some situations you want to use manual culling of triangles rather than sending the
856
            triangles to the hardware and letting it cull them. This setting only takes effect on
857
            SceneManager's that use it (since it is best used on large groups of planar world geometry rather
858
            than on movable geometry since this would be expensive), but if used can cull geometry before it is
859
            sent to the hardware.
860
861
            In this case the culling is based on whether the ’back’ or ’front’ of the triangle is facing the
862
            camera - this definition is based on the face normal (a vector which sticks out of the front side of
863
            the polygon perpendicular to the face). Since %Ogre expects face normals to be on anticlockwise side
864
            of the face, Ogre::MANUAL_CULL_BACK is the software equivalent of Ogre::CULL_CLOCKWISE setting,
865
            which is why they are both the default. The naming is different to reflect the way the culling is
866
            done though, since most of the time face normals are pre-calculated and they don’t have to be the
867
            way %Ogre expects - you could set Ogre::CULL_NONE and completely cull in software based on your
868
            own face normals, if you have the right SceneManager which uses them.
869
        */
870
        void setManualCullingMode( ManualCullingMode mode );
871
872
        /** Retrieves the manual culling mode for this pass
873
            @see
874
            setManualCullingMode
875
        */
876
        ManualCullingMode getManualCullingMode(void) const;
877
878
        /** Sets the type of light shading required
879
880
            When dynamic lighting is turned on, the effect is to generate colour values at each
881
            vertex. Whether these values are interpolated across the face (and how) depends on this
882
            setting. The default shading method is Ogre::SO_GOURAUD.
883
        */
884
0
        void setShadingMode( ShadeOptions mode ) { mShadeOptions = mode; }
885
886
        /** Returns the type of light shading to be used.
887
         */
888
0
        ShadeOptions getShadingMode(void) const { return mShadeOptions; }
889
890
        /** Sets the type of polygon rendering required
891
            
892
            Sets how polygons should be rasterised, i.e. whether they should be filled in, or just drawn as lines or points.
893
            The default shading method is Ogre::PM_SOLID.
894
        */
895
0
        void setPolygonMode( PolygonMode mode ) { mPolygonMode = mode; }
896
897
        /** Returns the type of light shading to be used.
898
         */
899
0
        PolygonMode getPolygonMode(void) const { return mPolygonMode; }
900
901
        /** Sets whether the PolygonMode set on this pass can be downgraded by the camera
902
903
         @param override If set to false, this pass will always be rendered at its own chosen polygon mode no matter what the
904
         camera says. The default is true.
905
        */
906
0
        void setPolygonModeOverrideable(bool override) { mPolygonModeOverrideable = override; }
907
908
        /** Gets whether this renderable's chosen detail level can be
909
            overridden (downgraded) by the camera setting.
910
        */
911
0
        bool getPolygonModeOverrideable(void) const { return mPolygonModeOverrideable; }
912
913
        /// @name Fogging
914
        /// @{
915
        /** Sets the fogging mode applied to this pass.
916
917
            Fogging is an effect that is applied as polys are rendered. Sometimes, you want
918
            fog to be applied to an entire scene. Other times, you want it to be applied to a few
919
            polygons only. This pass-level specification of fog parameters lets you easily manage
920
            both.
921
            @par
922
            The SceneManager class also has a setFog method which applies scene-level fog. This method
923
            lets you change the fog behaviour for this pass compared to the standard scene-level fog.
924
            @param
925
            overrideScene If true, you authorise this pass to override the scene's fog params with it's own settings.
926
            If you specify false, so other parameters are necessary, and this is the default behaviour for passes.
927
            @param
928
            mode Only applicable if overrideScene is true. You can disable fog which is turned on for the
929
            rest of the scene by specifying FOG_NONE. Otherwise, set a pass-specific fog mode as
930
            defined in the enum FogMode.
931
            @param
932
            colour The colour of the fog. Either set this to the same as your viewport background colour,
933
            or to blend in with a skydome or skybox.
934
            @param
935
            expDensity The density of the fog in FOG_EXP or FOG_EXP2 mode, as a value between 0 and 1.
936
            The default is 0.001.
937
            @param
938
            linearStart Distance in world units at which linear fog starts to encroach.
939
            Only applicable if mode is FOG_LINEAR.
940
            @param
941
            linearEnd Distance in world units at which linear fog becomes completely opaque.
942
            Only applicable if mode is FOG_LINEAR.
943
        */
944
        void setFog(
945
            bool overrideScene,
946
            FogMode mode = FOG_NONE,
947
            const ColourValue& colour = ColourValue::White,
948
            float expDensity = 0.001f, float linearStart = 0.0f, float linearEnd = 1.0f );
949
950
        /** Returns true if this pass is to override the scene fog settings.
951
         */
952
0
        bool getFogOverride(void) const { return mFogOverride; }
953
954
        /** Returns the fog mode for this pass.
955
            @note
956
            Only valid if getFogOverride is true.
957
        */
958
0
        FogMode getFogMode(void) const { return mFogMode; }
959
960
        /** Returns the fog colour for the scene.
961
         */
962
0
        const ColourValue& getFogColour(void) const { return mFogColour; }
963
964
        /** Returns the fog start distance for this pass.
965
            @note
966
            Only valid if getFogOverride is true.
967
        */
968
0
        float getFogStart(void) const { return mFogStart; }
969
970
        /** Returns the fog end distance for this pass.
971
            @note
972
            Only valid if getFogOverride is true.
973
        */
974
0
        float getFogEnd(void) const { return mFogEnd; }
975
976
        /** Returns the fog density for this pass.
977
            @note
978
            Only valid if getFogOverride is true.
979
        */
980
0
        float getFogDensity(void) const { return mFogDensity; }
981
        /// @}
982
983
        /// @name Alpha Rejection
984
        /// @{
985
        /** Sets the way the pass will have use alpha to totally reject pixels from the pipeline.
986
987
            The default is CMPF_ALWAYS_PASS i.e. alpha is not used to reject pixels.
988
            @param func The comparison which must pass for the pixel to be written.
989
            @param value 1 byte value against which alpha values will be tested(0-255)
990
            @param alphaToCoverageEnabled Whether to use alpha to coverage with MSAA.
991
                   This option applies in both the fixed function and the programmable pipeline.
992
        */
993
        void setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverageEnabled = false);
994
995
        /** Sets the alpha reject function. @see setAlphaRejectSettings for more information.
996
         */
997
0
        void setAlphaRejectFunction(CompareFunction func) { mAlphaRejectFunc = func; }
998
999
        /** Gets the alpha reject value. @see setAlphaRejectSettings for more information.
1000
         */
1001
0
        void setAlphaRejectValue(unsigned char val) { mAlphaRejectVal = val; }
1002
1003
        /** Gets the alpha reject function. @see setAlphaRejectSettings for more information.
1004
         */
1005
0
        CompareFunction getAlphaRejectFunction(void) const { return mAlphaRejectFunc; }
1006
1007
        /** Gets the alpha reject value. @see setAlphaRejectSettings for more information.
1008
         */
1009
0
        unsigned char getAlphaRejectValue(void) const { return mAlphaRejectVal; }
1010
1011
        /** Sets whether to use alpha to coverage (A2C) when blending alpha rejected values.
1012
1013
            Alpha to coverage performs multisampling on the edges of alpha-rejected
1014
            textures to produce a smoother result. It is only supported when multisampling
1015
            is already enabled on the render target, and when the hardware supports
1016
            alpha to coverage (see RenderSystemCapabilities).
1017
            The common use for alpha to coverage is foliage rendering and chain-link fence style
1018
            textures.
1019
        */
1020
0
        void setAlphaToCoverageEnabled(bool enabled) { mAlphaToCoverageEnabled = enabled; }
1021
1022
        /** Gets whether to use alpha to coverage (A2C) when blending alpha rejected values.
1023
         */
1024
0
        bool isAlphaToCoverageEnabled() const { return mAlphaToCoverageEnabled; }
1025
        /// @}
1026
1027
        /** Sets whether or not transparent sorting is enabled.
1028
            @param enabled
1029
            If false depth sorting of this material will be disabled.
1030
1031
            By default all transparent materials are sorted such that renderables furthest
1032
            away from the camera are rendered first. This is usually the desired behaviour
1033
            but in certain cases this depth sorting may be unnecessary and undesirable. If
1034
            for example it is necessary to ensure the rendering order does not change from
1035
            one frame to the next.
1036
            @note
1037
            This will have no effect on non-transparent materials.
1038
        */
1039
0
        void setTransparentSortingEnabled(bool enabled) { mTransparentSorting = enabled; }
1040
1041
        /** Returns whether or not transparent sorting is enabled.
1042
         */
1043
0
        bool getTransparentSortingEnabled(void) const { return mTransparentSorting; }
1044
1045
        /** Sets whether or not transparent sorting is forced.
1046
            @param enabled
1047
            If true depth sorting of this material will be depend only on the value of
1048
            getTransparentSortingEnabled().
1049
1050
            By default even if transparent sorting is enabled, depth sorting will only be
1051
            performed when the material is transparent and depth write/check are disabled.
1052
            This function disables these extra conditions.
1053
        */
1054
0
        void setTransparentSortingForced(bool enabled) {  mTransparentSortingForced = enabled; }
1055
1056
        /** Returns whether or not transparent sorting is forced.
1057
         */
1058
0
        bool getTransparentSortingForced(void) const { return mTransparentSortingForced; }
1059
1060
        /// @name Light Iteration
1061
        /// @{
1062
        /** Sets the maximum number of lights to be used by this pass.
1063
1064
            During rendering, if lighting is enabled (or if the pass uses an automatic
1065
            program parameter based on a light) the engine will request the nearest lights
1066
            to the object being rendered in order to work out which ones to use. This
1067
            parameter sets the limit on the number of lights which should apply to objects
1068
            rendered with this pass.
1069
        */
1070
0
        void setMaxSimultaneousLights(unsigned short maxLights) { mMaxSimultaneousLights = maxLights; }
1071
        /** Gets the maximum number of lights to be used by this pass. */
1072
0
        unsigned short getMaxSimultaneousLights(void) const { return mMaxSimultaneousLights; }
1073
1074
        /** Sets the light index that this pass will start at in the light list.
1075
1076
            Normally the lights passed to a pass will start from the beginning
1077
            of the light list for this object. This option allows you to make this
1078
            pass start from a higher light index, for example if one of your earlier
1079
            passes could deal with lights 0-3, and this pass dealt with lights 4+.
1080
            This option also has an interaction with pass iteration, in that
1081
            if you choose to iterate this pass per light too, the iteration will
1082
            only begin from light 4.
1083
        */
1084
0
        void setStartLight(unsigned short startLight) { mStartLight = startLight; }
1085
        /** Gets the light index that this pass will start at in the light list. */
1086
0
        unsigned short getStartLight(void) const { return mStartLight; }
1087
1088
        /** Sets the light mask which can be matched to specific light flags to be handled by this pass */
1089
0
        void setLightMask(uint32 mask) { mLightMask = mask; }
1090
        /** Gets the light mask controlling which lights are used for this pass */
1091
0
        uint32 getLightMask() const { return mLightMask; }
1092
1093
        /** Sets whether or not this pass should iterate per light or number of
1094
            lights which can affect the object being rendered.
1095
1096
            The default behaviour for a pass (when this option is 'false'), is
1097
            for a pass to be rendered only once (or the number of times set in
1098
            setPassIterationCount), with all the lights which could
1099
            affect this object set at the same time (up to the maximum lights
1100
            allowed in the render system, which is typically 8).
1101
            @par
1102
            Setting this option to 'true' changes this behaviour, such that
1103
            instead of trying to issue render this pass once per object, it
1104
            is run <b>per light</b>, or for a group of 'n' lights each time
1105
            which can affect this object, the number of
1106
            times set in setPassIterationCount (default is once). In
1107
            this case, only light index 0 is ever used, and is a different light
1108
            every time the pass is issued, up to the total number of lights
1109
            which is affecting this object. This has 2 advantages:
1110
            <ul><li>There is no limit on the number of lights which can be
1111
            supported</li>
1112
            <li>It's easier to write vertex / fragment programs for this because
1113
            a single program can be used for any number of lights</li>
1114
            </ul>
1115
            However, this technique is more expensive, and typically you
1116
            will want an additional ambient pass, because if no lights are
1117
            affecting the object it will not be rendered at all, which will look
1118
            odd even if ambient light is zero (imagine if there are lit objects
1119
            behind it - the objects silhouette would not show up). Therefore,
1120
            use this option with care, and you would be well advised to provide
1121
            a less expensive fallback technique for use in the distance.
1122
            @note
1123
            The number of times this pass runs is still limited by the maximum
1124
            number of lights allowed as set in setMaxSimultaneousLights, so
1125
            you will never get more passes than this. Also, the iteration is
1126
            started from the 'start light' as set in Pass::setStartLight, and
1127
            the number of passes is the number of lights to iterate over divided
1128
            by the number of lights per iteration (default 1, set by
1129
            setLightCountPerIteration).
1130
            @param enabled Whether this feature is enabled
1131
            @param onlyForOneLightType If true, the pass will only be run for a single type
1132
            of light, other light types will be ignored.
1133
            @param lightType The single light type which will be considered for this pass
1134
        */
1135
        void setIteratePerLight(bool enabled,
1136
                                bool onlyForOneLightType = true, Light::LightTypes lightType = Light::LT_POINT);
1137
1138
        /** Does this pass run once for every light in range? */
1139
0
        bool getIteratePerLight(void) const { return mIteratePerLight; }
1140
        /** Does this pass run only for a single light type (if getIteratePerLight is true). */
1141
0
        bool getRunOnlyForOneLightType(void) const { return mRunOnlyForOneLightType; }
1142
        /** Gets the single light type this pass runs for if  getIteratePerLight and
1143
            getRunOnlyForOneLightType are both true. */
1144
0
        Light::LightTypes getOnlyLightType() const { return mOnlyLightType; }
1145
1146
        /** If light iteration is enabled, determine the number of lights per
1147
            iteration.
1148
1149
            The default for this setting is 1, so if you enable light iteration
1150
            (Pass::setIteratePerLight), the pass is rendered once per light. If
1151
            you set this value higher, the passes will occur once per 'n' lights.
1152
            The start of the iteration is set by Pass::setStartLight and the end
1153
            by Pass::setMaxSimultaneousLights.
1154
        */
1155
0
        void setLightCountPerIteration(unsigned short c) { mLightsPerIteration = c; }
1156
        /** If light iteration is enabled, determine the number of lights per
1157
            iteration.
1158
        */
1159
0
        unsigned short getLightCountPerIteration(void) const { return mLightsPerIteration; }
1160
        /// @}
1161
1162
        /// Gets the parent Technique
1163
0
        Technique* getParent(void) const { return mParent; }
1164
1165
        /// Gets the resource group of the ultimate parent Material
1166
        const String& getResourceGroup(void) const;
1167
1168
        /// @name Gpu Programs
1169
        /// @{
1170
1171
        /// Returns true if this pass is programmable i.e. includes either a vertex or fragment program.
1172
        bool isProgrammable(void) const
1173
0
        {
1174
0
            for (const auto& u : mProgramUsage)
1175
0
                if (u) return true;
1176
0
            return false;
1177
0
        }
1178
        /// Returns true if this pass uses a programmable vertex pipeline
1179
0
        bool hasVertexProgram(void) const { return hasGpuProgram(GPT_VERTEX_PROGRAM); }
1180
        /// Returns true if this pass uses a programmable fragment pipeline
1181
0
        bool hasFragmentProgram(void) const { return hasGpuProgram(GPT_FRAGMENT_PROGRAM); }
1182
        /// Returns true if this pass uses a programmable geometry pipeline
1183
0
        bool hasGeometryProgram(void) const { return hasGpuProgram(GPT_GEOMETRY_PROGRAM); }
1184
        /// Returns true if this pass uses a programmable tessellation control pipeline
1185
0
        bool hasTessellationHullProgram(void) const { return hasGpuProgram(GPT_HULL_PROGRAM); }
1186
        /// Returns true if this pass uses a programmable tessellation control pipeline
1187
0
        bool hasTessellationDomainProgram(void) const { return hasGpuProgram(GPT_DOMAIN_PROGRAM); }
1188
        /// Returns true if this pass uses a programmable compute pipeline
1189
0
        bool hasComputeProgram(void) const { return hasGpuProgram(GPT_COMPUTE_PROGRAM); }
1190
        /// Gets the Gpu program used by this pass, only available after _load()
1191
        const GpuProgramPtr& getGpuProgram(GpuProgramType programType) const;
1192
        /// @overload
1193
0
        const GpuProgramPtr& getVertexProgram(void) const { return getGpuProgram(GPT_VERTEX_PROGRAM); }
1194
        /// @overload
1195
0
        const GpuProgramPtr& getFragmentProgram(void) const { return getGpuProgram(GPT_FRAGMENT_PROGRAM); }
1196
        /// @overload
1197
0
        const GpuProgramPtr& getGeometryProgram(void) const { return getGpuProgram(GPT_GEOMETRY_PROGRAM); }
1198
        /// @overload
1199
0
        const GpuProgramPtr& getTessellationHullProgram(void) const { return getGpuProgram(GPT_HULL_PROGRAM); }
1200
        /// @overload
1201
0
        const GpuProgramPtr& getTessellationDomainProgram(void) const { return getGpuProgram(GPT_DOMAIN_PROGRAM); }
1202
        /// @overload
1203
0
        const GpuProgramPtr& getComputeProgram(void) const { return getGpuProgram(GPT_COMPUTE_PROGRAM); }
1204
1205
        bool hasGpuProgram(GpuProgramType programType) const;
1206
1207
        /** Sets the details of the program to use.
1208
1209
            Only applicable to programmable passes, this sets the details of
1210
            the program to use in this pass. The program will not be
1211
            loaded until the parent Material is loaded.
1212
            @param prog The program. If this parameter is @c NULL, any program of the type in this pass is disabled.
1213
            @param type The type of program
1214
            @param resetParams
1215
            If true, this will create a fresh set of parameters from the
1216
            new program being linked, so if you had previously set parameters
1217
            you will have to set them again. If you set this to false, you must
1218
            be absolutely sure that the parameters match perfectly, and in the
1219
            case of named parameters refers to the indexes underlying them,
1220
            not just the names.
1221
        */
1222
        void setGpuProgram(GpuProgramType type, const GpuProgramPtr& prog, bool resetParams = true);
1223
        /// @overload
1224
        void setGpuProgram(GpuProgramType type, const String& name, bool resetParams = true);
1225
        /// @overload
1226
        void setFragmentProgram(const String& name, bool resetParams = true);
1227
        /// @overload
1228
        void setGeometryProgram(const String& name, bool resetParams = true);
1229
        /// @overload
1230
        void setTessellationDomainProgram(const String& name, bool resetParams = true);
1231
        /// @overload
1232
        void setTessellationHullProgram(const String& name, bool resetParams = true);
1233
        /// @overload
1234
        void setVertexProgram(const String& name, bool resetParams = true);
1235
        /// @overload
1236
        void setComputeProgram(const String& name, bool resetParams = true);
1237
1238
        /** Gets the name of the program used by this pass. */
1239
        const String& getGpuProgramName(GpuProgramType type) const;
1240
        /// @overload
1241
0
        const String& getFragmentProgramName(void) const { return getGpuProgramName(GPT_FRAGMENT_PROGRAM); }
1242
        /// @overload
1243
0
        const String& getGeometryProgramName(void) const { return getGpuProgramName(GPT_GEOMETRY_PROGRAM); }
1244
        /// @overload
1245
0
        const String& getTessellationDomainProgramName(void) const { return getGpuProgramName(GPT_DOMAIN_PROGRAM); }
1246
        /// @overload
1247
0
        const String& getTessellationHullProgramName(void) const { return getGpuProgramName(GPT_HULL_PROGRAM); }
1248
        /// @overload
1249
0
        const String& getVertexProgramName(void) const { return getGpuProgramName(GPT_VERTEX_PROGRAM); }
1250
        /// @overload
1251
0
        const String& getComputeProgramName(void) const { return getGpuProgramName(GPT_COMPUTE_PROGRAM); }
1252
1253
        /** Sets the Gpu program parameters.
1254
1255
            Only applicable to programmable passes, and this particular call is
1256
            designed for low-level programs; use the named parameter methods
1257
            for setting high-level program parameters.
1258
        */
1259
        void setGpuProgramParameters(GpuProgramType type, const GpuProgramParametersSharedPtr& params);
1260
        /// @overload
1261
        void setVertexProgramParameters(GpuProgramParametersSharedPtr params);
1262
        /// @overload
1263
        void setFragmentProgramParameters(GpuProgramParametersSharedPtr params);
1264
        /// @overload
1265
        void setGeometryProgramParameters(GpuProgramParametersSharedPtr params);
1266
        /// @overload
1267
        void setTessellationHullProgramParameters(GpuProgramParametersSharedPtr params);
1268
        /// @overload
1269
        void setTessellationDomainProgramParameters(GpuProgramParametersSharedPtr params);
1270
        /// @overload
1271
        void setComputeProgramParameters(GpuProgramParametersSharedPtr params);
1272
1273
        /** Gets the Gpu program parameters used by this pass. */
1274
        const GpuProgramParametersSharedPtr& getGpuProgramParameters(GpuProgramType type) const;
1275
        /// @overload
1276
        GpuProgramParametersSharedPtr getVertexProgramParameters(void) const;
1277
        /// @overload
1278
        GpuProgramParametersSharedPtr getFragmentProgramParameters(void) const;
1279
        /// @overload
1280
        GpuProgramParametersSharedPtr getGeometryProgramParameters(void) const;
1281
        /// @overload
1282
        GpuProgramParametersSharedPtr getTessellationHullProgramParameters(void) const;
1283
        /// @overload
1284
        GpuProgramParametersSharedPtr getTessellationDomainProgramParameters(void) const;
1285
        /// @overload
1286
        GpuProgramParametersSharedPtr getComputeProgramParameters(void) const;
1287
        /// @}
1288
1289
        /** Splits this Pass to one which can be handled in the number of
1290
            texture units specified.
1291
1292
            Only works on non-programmable passes, programmable passes cannot be
1293
            split, it's up to the author to ensure that there is a fallback Technique
1294
            for less capable cards.
1295
            @param numUnits The target number of texture units
1296
            @return A new Pass which contains the remaining units, and a scene_blend
1297
            setting appropriate to approximate the multitexture. This Pass will be
1298
            attached to the parent Technique of this Pass.
1299
        */
1300
        Pass* _split(unsigned short numUnits);
1301
1302
        /** Internal method to adjust pass index. */
1303
        void _notifyIndex(unsigned short index);
1304
1305
        /** Internal method for preparing to load this pass. */
1306
        void _prepare(void);
1307
        /** Internal method for undoing the load preparartion for this pass. */
1308
        void _unprepare(void);
1309
        /** Internal method for loading this pass. */
1310
        void _load(void);
1311
        /** Internal method for unloading this pass. */
1312
        void _unload(void);
1313
        /// Is this loaded?
1314
        bool isLoaded(void) const;
1315
1316
        /** Gets the 'hash' of this pass, ie a precomputed number to use for sorting
1317
1318
            This hash is used to sort passes, and for this reason the pass is hashed
1319
            using firstly its index (so that all passes are rendered in order), then
1320
            by the textures which it's TextureUnitState instances are using.
1321
        */
1322
0
        uint32 getHash(void) const { return mHash; }
1323
        /// Mark the hash as dirty
1324
        void _dirtyHash(void);
1325
        /** Internal method for recalculating the hash.
1326
1327
            Do not call this unless you are sure the old hash is not still being
1328
            used by anything. If in doubt, call _dirtyHash if you want to force
1329
            recalculation of the has next time.
1330
        */
1331
        void _recalculateHash(void);
1332
        /** Tells the pass that it needs recompilation. */
1333
        void _notifyNeedsRecompile(void);
1334
1335
        /** Update automatic parameters.
1336
            @param source The source of the parameters
1337
            @param variabilityMask A mask of GpuParamVariability which identifies which autos will need updating
1338
        */
1339
        void _updateAutoParams(const AutoParamDataSource* source, uint16 variabilityMask) const;
1340
1341
        /** Static method to retrieve all the Passes which need their
1342
            hash values recalculated.
1343
        */
1344
        static const PassSet& getDirtyHashList(void)
1345
0
        { return msDirtyHashList; }
1346
        /** Static method to retrieve all the Passes which are pending deletion.
1347
         */
1348
        static const PassSet& getPassGraveyard(void)
1349
0
        { return msPassGraveyard; }
1350
        /** Static method to reset the list of passes which need their hash
1351
            values recalculated.
1352
1353
            For performance, the dirty list is not updated progressively as
1354
            the hashes are recalculated, instead we expect the processor of the
1355
            dirty hash list to clear the list when they are done.
1356
        */
1357
        static void clearDirtyHashList(void);
1358
1359
        /** Process all dirty and pending deletion passes. */
1360
        static void processPendingPassUpdates(void);
1361
1362
        /** Queue this pass for deletion when appropriate. */
1363
        void queueForDeletion(void);
1364
1365
        /** Returns whether this pass is ambient only.
1366
         */
1367
        bool isAmbientOnly(void) const;
1368
1369
        /** set the number of iterations that this pass
1370
            should perform when doing fast multi pass operation.
1371
1372
            Only applicable for programmable passes.
1373
            @param count number of iterations to perform fast multi pass operations.
1374
            A value greater than 1 will cause the pass to be executed count number of
1375
            times without changing the render state.  This is very useful for passes
1376
            that use programmable shaders that have to iterate more than once but don't
1377
            need a render state change.  Using multi pass can dramatically speed up rendering
1378
            for materials that do things like fur, blur.
1379
            A value of 1 turns off multi pass operation and the pass does
1380
            the normal pass operation.
1381
        */
1382
0
        void setPassIterationCount(const size_t count) { mPassIterationCount = count; }
1383
1384
        /** Gets the pass iteration count value.
1385
         */
1386
0
        size_t getPassIterationCount(void) const { return mPassIterationCount; }
1387
1388
        /** Sets whether or not this pass will be clipped by a scissor rectangle
1389
            encompassing the lights that are being used in it.
1390
1391
            In order to cut down on fillrate when you have a number of fixed-range
1392
            lights in the scene, you can enable this option to request that
1393
            during rendering, only the region of the screen which is covered by
1394
            the lights is rendered. This region is the screen-space rectangle
1395
            covering the union of the spheres making up the light ranges. Directional
1396
            lights are ignored for this.
1397
1398
            This is only likely to be useful for multipass additive lighting
1399
            algorithms, where the scene has already been 'seeded' with an ambient
1400
            pass and this pass is just adding light in affected areas.
1401
1402
            When using Ogre::SHADOWTYPE_STENCIL_ADDITIVE or Ogre::SHADOWTYPE_TEXTURE_ADDITIVE,
1403
            this option is implicitly used for all per-light passes and does
1404
            not need to be specified. If you are not using shadows or are using
1405
            a modulative or @ref Integrated-Texture-Shadows then this could be useful.
1406
1407
        */
1408
0
        void setLightScissoringEnabled(bool enabled) { mLightScissoring = enabled; }
1409
        /** Gets whether or not this pass will be clipped by a scissor rectangle
1410
            encompassing the lights that are being used in it.
1411
        */
1412
0
        bool getLightScissoringEnabled() const { return mLightScissoring; }
1413
1414
        /** Sets whether or not this pass will be clipped by user clips planes
1415
            bounding the area covered by the light.
1416
1417
            This option will only function if there is a single non-directional light being used in
1418
            this pass. If there is more than one light, or only directional lights, then no clipping
1419
            will occur. If there are no lights at all then the objects won’t be rendered at all.
1420
1421
            In order to cut down on the geometry set up to render this pass
1422
            when you have a single fixed-range light being rendered through it,
1423
            you can enable this option to request that during triangle setup,
1424
            clip planes are defined to bound the range of the light. In the case
1425
            of a point light these planes form a cube, and in the case of
1426
            a spotlight they form a pyramid. Directional lights are never clipped.
1427
1428
            This option is only likely to be useful for multipass additive lighting
1429
            algorithms, where the scene has already been 'seeded' with an ambient
1430
            pass and this pass is just adding light in affected areas. In addition,
1431
            it will only be honoured if there is exactly one non-directional light
1432
            being used in this pass. Also, these clip planes override any user clip
1433
            planes set on Camera.
1434
1435
            When using Ogre::SHADOWTYPE_STENCIL_ADDITIVE or Ogre::SHADOWTYPE_TEXTURE_ADDITIVE,
1436
            this option is automatically used for all per-light passes if you
1437
            enable Ogre::SceneManager::setShadowUseLightClipPlanes and does
1438
            not need to be specified. It is disabled by default since clip planes have
1439
            a cost of their own which may not always exceed the benefits they give you.
1440
            Generally the smaller your lights are the more chance you’ll see a benefit rather than
1441
            a penalty from clipping.
1442
1443
            @note Only has an effect with the fixed-function pipeline. Exceptions:
1444
            - with D3D9, clip planes are even available when shaders are used
1445
            - with GL1, shaders must write to gl_ClipVertex
1446
        */
1447
0
        void setLightClipPlanesEnabled(bool enabled) { mLightClipPlanes = enabled; }
1448
        /** Gets whether or not this pass will be clipped by user clips planes
1449
            bounding the area covered by the light.
1450
        */
1451
0
        bool getLightClipPlanesEnabled() const { return mLightClipPlanes; }
1452
1453
        /** Manually set which illumination stage this pass is a member of.
1454
1455
            When using an additive lighting mode (Ogre::SHADOWTYPE_STENCIL_ADDITIVE or
1456
            Ogre::SHADOWTYPE_TEXTURE_ADDITIVE), the scene is rendered in 3 discrete
1457
            stages, ambient (or pre-lighting), per-light (once per light, with
1458
            shadowing) and decal (or post-lighting). Usually OGRE figures out how
1459
            to categorise your passes automatically, but there are some effects you
1460
            cannot achieve without manually controlling the illumination. For example
1461
            specular effects are muted by the typical sequence because all textures
1462
            are saved until the Ogre::IS_DECAL stage which mutes the specular effect.
1463
            Instead, you could do texturing within the per-light stage if it's
1464
            possible for your material and thus add the specular on after the
1465
            decal texturing, and have no post-light rendering.
1466
1467
            If you assign an illumination stage to a pass you have to assign it
1468
            to all passes in the technique otherwise it will be ignored. Also note
1469
            that whilst you can have more than one pass in each group, they cannot
1470
            alternate, ie all ambient passes will be before all per-light passes,
1471
            which will also be before all decal passes. Within their categories
1472
            the passes will retain their ordering though.
1473
        */
1474
0
        void setIlluminationStage(IlluminationStage is) { mIlluminationStage = is; }
1475
        /// Get the manually assigned illumination stage, if any
1476
0
        IlluminationStage getIlluminationStage() const { return mIlluminationStage; }
1477
        /** There are some default hash functions used to order passes so that
1478
            render state changes are minimised, this enumerates them.
1479
        */
1480
        enum BuiltinHashFunction
1481
        {
1482
            /** Try to minimise the number of texture changes. */
1483
            MIN_TEXTURE_CHANGE,
1484
            /** Try to minimise the number of GPU program changes.
1485
                @note Only really useful if you use GPU programs for all of your
1486
                materials.
1487
            */
1488
            MIN_GPU_PROGRAM_CHANGE
1489
        };
1490
        /** Sets one of the default hash functions to be used.
1491
1492
            You absolutely must not change the hash function whilst any Pass instances
1493
            exist in the render queue. The only time you can do this is either
1494
            before you render anything, or directly after you manuall call
1495
            RenderQueue::clear(true) to completely destroy the queue structures.
1496
            The default is MIN_GPU_PROGRAM_CHANGE.
1497
            @note
1498
            You can also implement your own hash function, see the alternate version
1499
            of this method.
1500
            @see HashFunc
1501
        */
1502
        static void setHashFunction(BuiltinHashFunction builtin);
1503
1504
        /** Set the hash function used for all passes.
1505
1506
            You absolutely must not change the hash function whilst any Pass instances
1507
            exist in the render queue. The only time you can do this is either
1508
            before you render anything, or directly after you manuall call
1509
            RenderQueue::clear(true) to completely destroy the queue structures.
1510
            @note
1511
            You can also use one of the built-in hash functions, see the alternate version
1512
            of this method. The default is MIN_GPU_PROGRAM_CHANGE.
1513
            @see HashFunc
1514
        */
1515
0
        static void setHashFunction(HashFunc* hashFunc) { msHashFunc = hashFunc; }
1516
1517
        /** Get the hash function used for all passes.
1518
         */
1519
0
        static HashFunc* getHashFunction(void) { return msHashFunc; }
1520
1521
        /** Get the builtin hash function.
1522
         */
1523
        static HashFunc* getBuiltinHashFunction(BuiltinHashFunction builtin);
1524
1525
        /// @copydoc UserObjectBindings
1526
0
        UserObjectBindings&     getUserObjectBindings() { return mUserObjectBindings; }
1527
1528
        /// @overload
1529
0
        const UserObjectBindings& getUserObjectBindings() const { return mUserObjectBindings; }
1530
     private:
1531
        std::unique_ptr<GpuProgramUsage>& getProgramUsage(GpuProgramType programType);
1532
        const std::unique_ptr<GpuProgramUsage>& getProgramUsage(GpuProgramType programType) const;
1533
    };
1534
1535
    /** Struct recording a pass which can be used for a specific illumination stage.
1536
1537
        This structure is used to record categorised passes which fit into a
1538
        number of distinct illumination phases - ambient, diffuse / specular
1539
        (per-light) and decal (post-lighting texturing).
1540
        An original pass may fit into one of these categories already, or it
1541
        may require splitting into its component parts in order to be categorised
1542
        properly.
1543
    */
1544
    struct IlluminationPass : public PassAlloc
1545
    {
1546
        IlluminationStage stage;
1547
        /// The pass to use in this stage
1548
        Pass* pass;
1549
        /// Whether this pass is one which should be deleted itself
1550
        bool destroyOnShutdown;
1551
        /// The original pass which spawned this one
1552
        Pass* originalPass;
1553
1554
0
        IlluminationPass() {}
1555
    };
1556
1557
    typedef std::vector<IlluminationPass*> IlluminationPassList;
1558
1559
    /** @} */
1560
    /** @} */
1561
1562
}
1563
1564
#include "OgreHeaderSuffix.h"
1565
1566
#endif