Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreShadowCaster.h @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 10.7 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#ifndef __ShadowCaster_H__
30#define __ShadowCaster_H__
31
32#include "OgrePrerequisites.h"
33#include "OgreRenderable.h"
34
35
36namespace Ogre {
37
38
39    /** Class which represents the renderable aspects of a set of shadow volume faces.
40    @remarks
41        Note that for casters comprised of more than one set of vertex buffers (e.g. SubMeshes each
42        using their own geometry), it will take more than one ShadowRenderable to render the
43        shadow volume. Therefore for shadow caster geometry, it is best to stick to one set of
44        vertex buffers (not necessarily one buffer, but the positions for the entire geometry
45        should come from one buffer if possible)
46    */
47    class _OgreExport ShadowRenderable : public Renderable
48    {
49    protected:
50        MaterialPtr mMaterial;
51        RenderOperation mRenderOp;
52        ShadowRenderable* mLightCap; // used only if isLightCapSeparate == true
53    public:
54        ShadowRenderable() : mMaterial(), mLightCap(0) {}
55        virtual ~ShadowRenderable() { delete mLightCap; }
56        /** Set the material to be used by the shadow, should be set by the caller
57          before adding to a render queue
58        */
59        void setMaterial(const MaterialPtr& mat) { mMaterial = mat; }
60        /// Overridden from Renderable
61        const MaterialPtr& getMaterial(void) const { return mMaterial; }
62        /// Overridden from Renderable
63        void getRenderOperation(RenderOperation& op) { op = mRenderOp; }
64        /// Get the internal render operation for set up
65        RenderOperation* getRenderOperationForUpdate(void) {return &mRenderOp;}
66        /// Overridden from Renderable
67        void getWorldTransforms(Matrix4* xform) const = 0;
68        /// Overridden from Renderable
69        const Quaternion& getWorldOrientation(void) const = 0;
70        /// Overridden from Renderable
71        const Vector3& getWorldPosition(void) const = 0;
72        /// Overridden from Renderable
73        Real getSquaredViewDepth(const Camera*) const{ return 0; /* not used */}
74        /// Overridden from Renderable
75        const LightList& getLights(void) const;
76        /** Does this renderable require a separate light cap?
77        @remarks
78            If possible, the light cap (when required) should be contained in the
79            usual geometry of the shadow renderable. However, if for some reason
80            the normal depth function (less than) could cause artefacts, then a
81            separate light cap with a depth function of 'always fail' can be used
82            instead. The primary example of this is when there are floating point
83            inaccuracies caused by calculating the shadow geometry separately from
84            the real geometry.
85        */
86        bool isLightCapSeparate(void) const { return mLightCap != 0; }
87
88        /// Get the light cap version of this renderable
89        ShadowRenderable* getLightCapRenderable(void) { return mLightCap; }
90        /// Should this ShadowRenderable be treated as visible?
91        virtual bool isVisible(void) const { return true; }
92
93    };
94
95    /** A set of flags that can be used to influence ShadowRenderable creation. */
96    enum ShadowRenderableFlags
97    {
98        /// For shadow volume techniques only, generate a light cap on the volume
99        SRF_INCLUDE_LIGHT_CAP = 0x00000001,
100        /// For shadow volume techniques only, generate a dark cap on the volume
101        SRF_INCLUDE_DARK_CAP  = 0x00000002,
102        /// For shadow volume techniques only, indicates volume is extruded to infinity
103        SRF_EXTRUDE_TO_INFINITY  = 0x00000004
104    };
105
106    /** This class defines the interface that must be implemented by shadow casters.
107    */
108    class _OgreExport ShadowCaster
109    {
110    public:
111        virtual ~ShadowCaster() { }
112        /** Returns whether or not this object currently casts a shadow. */
113        virtual bool getCastShadows(void) const = 0;
114
115        /** Returns details of the edges which might be used to determine a silhouette. */
116        virtual EdgeData* getEdgeList(void) = 0;
117                /** Returns whether the object has a valid edge list. */
118                virtual bool hasEdgeList(void) = 0;
119
120        /** Get the world bounding box of the caster. */
121        virtual const AxisAlignedBox& getWorldBoundingBox(bool derive = false) const = 0;
122        /** Gets the world space bounding box of the light cap */
123        virtual const AxisAlignedBox& getLightCapBounds(void) const = 0;
124        /** Gets the world space bounding box of the dark cap, as extruded using the light provided */
125        virtual const AxisAlignedBox& getDarkCapBounds(const Light& light, Real dirLightExtrusionDist) const = 0;
126
127        typedef std::vector<ShadowRenderable*> ShadowRenderableList;
128        typedef VectorIterator<ShadowRenderableList> ShadowRenderableListIterator;
129
130        /** Gets an iterator over the renderables required to render the shadow volume.
131        @remarks
132            Shadowable geometry should ideally be designed such that there is only one
133            ShadowRenderable required to render the the shadow; however this is not a necessary
134            limitation and it can be exceeded if required.
135        @param shadowTechnique The technique being used to generate the shadow
136        @param light The light to generate the shadow from
137        @param indexBuffer The index buffer to build the renderables into,
138            the current contents are assumed to be disposable.
139        @param extrudeVertices If true, this means this class should extrude
140            the vertices of the back of the volume in software. If false, it
141            will not be done (a vertex program is assumed).
142        @param extrusionDistance The distance to extrude the shadow volume
143        @param flags Technique-specific flags, see ShadowRenderableFlags
144        */
145        virtual ShadowRenderableListIterator getShadowVolumeRenderableIterator(
146            ShadowTechnique shadowTechnique, const Light* light, 
147            HardwareIndexBufferSharedPtr* indexBuffer, 
148            bool extrudeVertices, Real extrusionDistance, unsigned long flags = 0 ) = 0;
149
150        /** Utility method for extruding vertices based on a light.
151        @remarks
152            Unfortunately, because D3D cannot handle homogenous (4D) position
153            coordinates in the fixed-function pipeline (GL can, but we have to
154            be cross-API), when we extrude in software we cannot extrude to
155            infinity the way we do in the vertex program (by setting w to
156            0.0f). Therefore we extrude by a fixed distance, which may cause
157            some problems with larger scenes. Luckily better hardware (ie
158            vertex programs) can fix this.
159        @param vertexBuffer The vertex buffer containing ONLY xyz position
160        values, which must be originalVertexCount * 2 * 3 floats long.
161        @param originalVertexCount The count of the original number of
162        vertices, ie the number in the mesh, not counting the doubling
163        which has already been done (by VertexData::prepareForShadowVolume)
164        to provide the extruded area of the buffer.
165        @param lightPos 4D light position in object space, when w=0.0f this
166        represents a directional light
167        @param extrudeDist The distance to extrude
168        */
169        static void extrudeVertices(const HardwareVertexBufferSharedPtr& vertexBuffer, 
170            size_t originalVertexCount, const Vector4& lightPos, Real extrudeDist);
171        /** Get the distance to extrude for a point/spot light */
172        virtual Real getPointExtrusionDistance(const Light* l) const = 0;
173    protected:
174        /// Helper moethod for calculating extrusion distance
175        Real getExtrusionDistance(const Vector3& objectPos, const Light* light) const;
176        /** Tells the caster to perform the tasks necessary to update the
177            edge data's light listing. Can be overridden if the subclass needs
178            to do additional things.
179        @param edgeData The edge information to update
180        @param lightPos 4D vector representing the light, a directional light
181            has w=0.0
182       */
183        virtual void updateEdgeListLightFacing(EdgeData* edgeData, 
184            const Vector4& lightPos);
185
186        /** Generates the indexes required to render a shadow volume into the
187            index buffer which is passed in, and updates shadow renderables
188            to use it.
189        @param edgeData The edge information to use
190        @param indexBuffer The buffer into which to write data into; current
191            contents are assumed to be discardable.
192        @param light The light, mainly for type info as silhouette calculations
193            should already have been done in updateEdgeListLightFacing
194        @param shadowRenderables A list of shadow renderables which has
195            already been constructed but will need populating with details of
196            the index ranges to be used.
197        @param flags Additional controller flags, see ShadowRenderableFlags
198        */
199        virtual void generateShadowVolume(EdgeData* edgeData, 
200            const HardwareIndexBufferSharedPtr& indexBuffer, const Light* light,
201            ShadowRenderableList& shadowRenderables, unsigned long flags);
202        /** Utility method for extruding a bounding box.
203        @param box Original bounding box, will be updated in-place
204        @param lightPos 4D light position in object space, when w=0.0f this
205        represents a directional light
206        @param extrudeDist The distance to extrude
207        */
208        virtual void extrudeBounds(AxisAlignedBox& box, const Vector4& lightPos, 
209            Real extrudeDist) const;
210
211
212    };
213}
214
215#endif
Note: See TracBrowser for help on using the repository browser.