1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_STATEATTRIBUTE
15#define OSG_STATEATTRIBUTE 1
16
17#include <osg/Export>
18#include <osg/Object>
19#include <osg/Callback>
20#include <osg/Shader>
21#include <osg/GL>
22
23#include <typeinfo>
24#include <utility>
25#include <vector>
26
27// define for the GL_EXT_secondary_color extension, GL_COLOR_SUM is OpenGL
28// mode to be used to enable and disable the second color.
29#ifndef GL_COLOR_SUM
30#define GL_COLOR_SUM    0x8458
31#endif
32
33namespace osg {
34
35
36// forward declare NodeVisitor, State & StateSet
37class NodeVisitor;
38class State;
39class ShaderComposer;
40class StateSet;
41class Texture;
42
43/** META_StateAttribute macro define the standard clone, isSameKindAs,
44  * className and getType methods.
45  * Use when subclassing from Object to make it more convenient to define
46  * the standard pure virtual methods which are required for all Object
47  * subclasses.*/
48#define META_StateAttribute(library,name,type) \
49        virtual osg::Object* cloneType() const { return new name(); } \
50        virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \
51        virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const name *>(obj)!=NULL; } \
52        virtual const char* libraryName() const { return #library; } \
53        virtual const char* className() const { return #name; } \
54        virtual Type getType() const { return type; }
55
56/** COMPARE_StateAttribute_Types macro is a helper for implementing the StateAtribute::compare(..) method.*/
57#define COMPARE_StateAttribute_Types(TYPE,rhs_attribute) \
58            if (this==&rhs_attribute) return 0;\
59            const std::type_info* type_lhs = &typeid(*this);\
60            const std::type_info* type_rhs = &typeid(rhs_attribute);\
61            if (type_lhs->before(*type_rhs)) return -1;\
62            if (*type_lhs != *type_rhs) return 1;\
63            const TYPE& rhs = static_cast<const TYPE&>(rhs_attribute);
64
65
66/** COMPARE_StateAttribute_Parameter macro is a helper for implementing the StatateAtribute::compare(..) method.
67  * Macro assumes that variable rhs has been correctly defined by preceding code
68  * macro.*/
69#define COMPARE_StateAttribute_Parameter(parameter) \
70        if (parameter<rhs.parameter) return -1; \
71        if (rhs.parameter<parameter) return 1;
72
73
74/** Base class for state attributes.
75*/
76class OSG_EXPORT StateAttribute : public Object
77{
78    public :
79
80        /** GLMode is the value used in glEnable/glDisable(mode) */
81        typedef GLenum          GLMode;
82        /** GLModeValue is used to specify whether a mode is enabled (ON) or disabled (OFF).
83          * GLMoveValue is also used to specify the override behavior of modes from parent to children.
84          * See enum Value description for more details.*/
85        typedef unsigned int    GLModeValue;
86        /** Override is used to specify the override behavior of StateAttributes
87          * from parent to children.
88          * See enum Value description for more details.*/
89        typedef unsigned int    OverrideValue;
90
91        /** list values which can be used to set either GLModeValues or OverrideValues.
92          * When using in conjunction with GLModeValues, all Values have meaning.
93          * When using in conjunction with StateAttribute OverrideValue only
94          * OFF,OVERRIDE and INHERIT are meaningful.
95          * However, they are useful when using GLModeValue
96          * and OverrideValue in conjunction with each other as when using
97          * StateSet::setAttributeAndModes(..).*/
98        enum Values
99        {
100            /** means that associated GLMode and Override is disabled.*/
101            OFF          = 0x0,
102            /** means that associated GLMode is enabled and Override is disabled.*/
103            ON           = 0x1,
104            /** Overriding of GLMode's or StateAttributes is enabled, so that state below it is overridden.*/
105            OVERRIDE     = 0x2,
106            /** Protecting of GLMode's or StateAttributes is enabled, so that state from above cannot override this and below state.*/
107            PROTECTED    = 0x4,
108            /** means that GLMode or StateAttribute should be inherited from above.*/
109            INHERIT      = 0x8
110        };
111
112        /** Type identifier to differentiate between different state types. */
113        // typedef unsigned int Type;
114
115        /** Values of StateAttribute::Type used to aid identification
116          * of different StateAttribute subclasses. Each subclass defines
117          * its own value in the virtual Type getType() method.  When
118          * extending the osg's StateAttribute's simply define your
119          * own Type value which is unique, using the StateAttribute::Type
120          * enum as a guide of what values to use.  If your new subclass
121          * needs to override a standard StateAttribute then simply use
122          * that type's value. */
123        enum Type
124        {
125            TEXTURE,
126
127            POLYGONMODE,
128            POLYGONOFFSET,
129            MATERIAL,
130            ALPHAFUNC,
131            ANTIALIAS,
132            COLORTABLE,
133            CULLFACE,
134            FOG,
135            FRONTFACE,
136
137            LIGHT,
138
139            POINT,
140            LINEWIDTH,
141            LINESTIPPLE,
142            POLYGONSTIPPLE,
143            SHADEMODEL,
144            TEXENV,
145            TEXENVFILTER,
146            TEXGEN,
147            TEXMAT,
148            LIGHTMODEL,
149            BLENDFUNC,
150            BLENDEQUATION,
151            LOGICOP,
152            STENCIL,
153            COLORMASK,
154            DEPTH,
155            VIEWPORT,
156            SCISSOR,
157            BLENDCOLOR,
158            MULTISAMPLE,
159            CLIPPLANE,
160            COLORMATRIX,
161            VERTEXPROGRAM,
162            FRAGMENTPROGRAM,
163            POINTSPRITE,
164            PROGRAM,
165            CLAMPCOLOR,
166            HINT,
167            SAMPLEMASKI,
168            PRIMITIVERESTARTINDEX,
169            CLIPCONTROL,
170
171            /// osgFX namespace
172            VALIDATOR,
173            VIEWMATRIXEXTRACTOR,
174
175            /// osgNV namespace
176            OSGNV_PARAMETER_BLOCK,
177
178            // osgNVExt namespace
179            OSGNVEXT_TEXTURE_SHADER,
180            OSGNVEXT_VERTEX_PROGRAM,
181            OSGNVEXT_REGISTER_COMBINERS,
182
183            /// osgNVCg namespace
184            OSGNVCG_PROGRAM,
185
186            // osgNVSlang namespace
187            OSGNVSLANG_PROGRAM,
188
189            // osgNVParse
190            OSGNVPARSE_PROGRAM_PARSER,
191
192            UNIFORMBUFFERBINDING,
193            TRANSFORMFEEDBACKBUFFERBINDING,
194
195            ATOMICCOUNTERBUFFERBINDING,
196
197            PATCH_PARAMETER,
198
199            FRAME_BUFFER_OBJECT,
200
201            VERTEX_ATTRIB_DIVISOR,
202
203            SHADERSTORAGEBUFFERBINDING,
204
205            CAPABILITY = 100
206        };
207
208        /** Simple pairing between an attribute type and the member within that attribute type group.*/
209        typedef std::pair<Type,unsigned int> TypeMemberPair;
210
211        StateAttribute();
212
213        StateAttribute(const StateAttribute& sa,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
214            Object(sa,copyop),
215            _shaderComponent(sa._shaderComponent),
216            _updateCallback(copyop(sa._updateCallback.get())),
217            _eventCallback(copyop(sa._eventCallback.get()))
218            {}
219
220
221        /** Clone the type of an attribute, with Object* return type.
222            Must be defined by derived classes.*/
223        virtual Object* cloneType() const = 0;
224
225        /** Clone an attribute, with Object* return type.
226            Must be defined by derived classes.*/
227        virtual Object* clone(const CopyOp&) const = 0;
228
229        /** Return true if this and obj are of the same kind of object.*/
230        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const StateAttribute*>(obj)!=NULL; }
231
232        /** Return the name of the attribute's library.*/
233        virtual const char* libraryName() const { return "osg"; }
234
235        /** Return the name of the attribute's class type.*/
236        virtual const char* className() const { return "StateAttribute"; }
237
238
239        /** Convert 'this' into a StateAttribute pointer if Object is a StateAttribute, otherwise return 0.
240          * Equivalent to dynamic_cast<StateAttribute*>(this).*/
241        virtual StateAttribute* asStateAttribute() { return this; }
242
243        /** convert 'const this' into a const StateAttribute pointer if Object is a StateAttribute, otherwise return 0.
244          * Equivalent to dynamic_cast<const StateAttribute*>(this).*/
245        virtual const StateAttribute* asStateAttribute() const { return this; }
246
247        /** Fast alternative to dynamic_cast<> for determining if state attribute is a Texture.*/
248        virtual Texture* asTexture() { return 0; }
249
250        /** Fast alternative to dynamic_cast<> for determining if state attribute is a Texture.*/
251        virtual const Texture* asTexture() const { return 0; }
252
253
254        /** Return the Type identifier of the attribute's class type.*/
255        virtual Type getType() const = 0;
256
257        /** Return the member identifier within the attribute's class type. Used for light number/clip plane number etc.*/
258        virtual unsigned int getMember() const { return 0; }
259
260        /** Return the TypeMemberPair that uniquely identifies this type member.*/
261        inline TypeMemberPair getTypeMemberPair() const { return TypeMemberPair(getType(),getMember()); }
262
263        /** Return true if StateAttribute is a type which controls texturing and needs to be issued w.r.t to specific texture unit.*/
264        virtual bool isTextureAttribute() const { return false; }
265
266        /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
267        virtual int compare(const StateAttribute& sa) const = 0;
268
269        bool operator <  (const StateAttribute& rhs) const { return compare(rhs)<0; }
270        bool operator == (const StateAttribute& rhs) const { return compare(rhs)==0; }
271        bool operator != (const StateAttribute& rhs) const { return compare(rhs)!=0; }
272
273
274        /** A vector of osg::StateSet pointers which is used to store the parent(s) of this StateAttribute.*/
275        typedef std::vector<StateSet*> ParentList;
276
277        /** Get the parent list of this StateAttribute. */
278        inline const ParentList& getParents() const { return _parents; }
279
280        inline StateSet* getParent(unsigned int i)  { return _parents[i]; }
281        /**
282         * Get a single const parent of this StateAttribute.
283         * @param i index of the parent to get.
284         * @return the parent i.
285         */
286        inline const StateSet* getParent(unsigned int i) const  { return _parents[i]; }
287
288        /**
289         * Get the number of parents of this StateAttribute.
290         * @return the number of parents of this StateAttribute.
291         */
292        inline unsigned int getNumParents() const { return static_cast<unsigned int>(_parents.size()); }
293
294        void setShaderComponent(ShaderComponent* sc) { _shaderComponent = sc; }
295        ShaderComponent* getShaderComponent() { return _shaderComponent.get(); }
296        const ShaderComponent* getShaderComponent() const { return _shaderComponent.get(); }
297
298        struct ModeUsage
299        {
300            virtual ~ModeUsage() {}
301            virtual void usesMode(GLMode mode) = 0;
302            virtual void usesTextureMode(GLMode mode) = 0;
303        };
304
305        /** Return the modes associated with this StateAttribute.*/
306        virtual bool getModeUsage(ModeUsage&) const
307        {
308            // default to no GLMode's associated with use of the StateAttribute.
309            return false;
310        }
311
312        /** Check the modes associated with this StateAttribute are supported by current OpenGL drivers,
313          * and if not set the associated mode in osg::State to be black listed/invalid.
314          * Return true if all associated modes are valid.*/
315        virtual bool checkValidityOfAssociatedModes(osg::State&) const
316        {
317            // default to no black listed GLMode's associated with use of the StateAttribute.
318            return true;
319        }
320
321        // provide callback for backwards compatibility.
322        typedef osg::StateAttributeCallback Callback;
323
324        /** Set the UpdateCallback which allows users to attach customize the updating of an object during the update traversal.*/
325        void setUpdateCallback(StateAttributeCallback* uc);
326
327        /** Get the non const UpdateCallback.*/
328        StateAttributeCallback* getUpdateCallback() { return _updateCallback.get(); }
329
330        /** Get the const UpdateCallback.*/
331        const StateAttributeCallback* getUpdateCallback() const { return _updateCallback.get(); }
332
333
334        /** Set the EventCallback which allows users to attach customize the updating of an object during the Event traversal.*/
335        void setEventCallback(StateAttributeCallback* ec);
336
337        /** Get the non const EventCallback.*/
338        StateAttributeCallback* getEventCallback() { return _eventCallback.get(); }
339
340        /** Get the const EventCallback.*/
341        const StateAttributeCallback* getEventCallback() const { return _eventCallback.get(); }
342
343
344        /** apply the OpenGL state attributes.
345          * The render info for the current OpenGL context is passed
346          * in to allow the StateAttribute to obtain details on the
347          * the current context and state.
348          */
349        virtual void apply(State&) const {}
350
351        /** Default to nothing to compile - all state is applied immediately. */
352        virtual void compileGLObjects(State&) const {}
353
354        /** Resize any per context GLObject buffers to specified size. */
355        virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/) {}
356
357        /** Release OpenGL objects in specified graphics context if State
358            object is passed, otherwise release OpenGL objects for all graphics context if
359            State object pointer NULL.*/
360        virtual void releaseGLObjects(State* =0) const {}
361
362
363    protected:
364
365        virtual ~StateAttribute() {}
366
367        void addParent(osg::StateSet* object);
368        void removeParent(osg::StateSet* object);
369
370        ParentList _parents;
371        friend class osg::StateSet;
372
373        ref_ptr<ShaderComponent>          _shaderComponent;
374
375        ref_ptr<StateAttributeCallback>   _updateCallback;
376        ref_ptr<StateAttributeCallback>   _eventCallback;
377};
378
379}
380
381#endif
382