source: GTP/trunk/App/Demos/Geom/OgreStuff/include/OgreManualObject.h @ 1812

Revision 1812, 15.7 KB checked in by gumbau, 18 years ago (diff)
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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25
26#ifndef __OgreManualObject_H__
27#define __OgreManualObject_H__
28
29#include "OgrePrerequisites.h"
30#include "OgreMovableObject.h"
31#include "OgreRenderable.h"
32#include "OgreResourceGroupManager.h"
33
34
35namespace Ogre
36{
37        /** Class providing a much simplified interface to generating manual
38                objects with custom geometry.
39        @remarks
40                Building one-off geometry objects manually usually requires getting
41                down and dirty with the vertex buffer and vertex declaration API,
42                which some people find a steep learning curve. This class gives you
43                a simpler interface specifically for the purpose of building a one-off
44                3D object simply and quickly. Note that if you intend to instance your
45                object you will still need to become familiar with the Mesh class.
46        @par
47                This class draws heavily on the interface for OpenGL
48                immediate-mode (glBegin, glVertex, glNormal etc), since this
49                is generally well-liked by people. There are a couple of differences
50                in the results though - internally this class still builds hardware
51                buffers which can be re-used, so you can render the resulting object
52                multiple times without re-issuing all the same commands again.
53                Secondly, the rendering is not immediate, it is still queued just like
54                all OGRE objects. This makes this object more efficient than the
55                equivalent GL immediate-mode commands, so it's feasible to use it for
56                large objects if you really want to.
57        @par
58                To construct some geometry with this object:
59                  -# If you know roughly how many vertices (and indices, if you use them)
60                     you're going to submit, call estimateVertexCount and estimateIndexCount.
61                         This is not essential but will make the process more efficient by saving
62                         memory reallocations.
63                  -# Call begin() to begin entering data
64                  -# For each vertex, call position(), normal(), textureCoord(), colour()
65                     to define your vertex data. Note that each time you call position()
66                         you start a new vertex. Note that the first vertex defines the
67                         components of the vertex - you can't add more after that. For example
68                         if you didn't call normal() in the first vertex, you cannot call it
69                         in any others. You ought to call the same combination of methods per
70                         vertex.
71                  -# If you want to define triangles (or lines/points) by indexing into the vertex list,
72                         you can call index() as many times as you need to define them.
73                         If you don't do this, the class will assume you want triangles drawn
74                         directly as defined by the vertex list, ie non-indexed geometry. Note
75                         that stencil shadows are only supported on indexed geometry, and that
76                         indexed geometry is a little faster; so you should try to use it.
77                  -# Call end() to finish entering data.
78                  -# Optionally repeat the begin-end cycle if you want more geometry
79                        using different rendering operation types, or different materials
80            After calling end(), the class will organise the data for that section
81                internally and make it ready to render with. Like any other
82                MovableObject you should attach the object to a SceneNode to make it
83                visible. Other aspects like the relative render order can be controlled
84                using standard MovableObject methods like setRenderQueueGroup.
85        @par
86                Note that like all OGRE geometry, triangles should be specified in
87                anti-clockwise winding order (whether you're doing it with just
88                vertices, or using indexes too). That is to say that the front of the
89                face is the one where the vertices are listed in anti-clockwise order.
90        */
91        class _OgreExport ManualObject : public MovableObject
92        {
93        public:
94                ManualObject(const String& name);
95                virtual ~ManualObject();
96
97                /** Completely clear the contents of the object.
98                @remarks
99                        This class is not designed for dynamic vertex data, since the
100                        translation it has to perform is not suitable for frame-by-frame
101                        updates. However if you do want to modify the contents from time
102                        to time you can do so by clearing and re-specifying the data.
103                */
104                virtual void clear(void);
105               
106                /** Estimate the number of vertices ahead of time.
107                @remarks
108                        Calling this helps to avoid memory reallocation when you define
109                        vertices.
110                */
111                virtual void estimateVertexCount(size_t vcount);
112
113                /** Estimate the number of vertices ahead of time.
114                @remarks
115                        Calling this helps to avoid memory reallocation when you define
116                        indices.
117                */
118                virtual void estimateIndexCount(size_t icount);
119
120                /** Start defining a part of the object.
121                @remarks
122                        Each time you call this method, you start a new section of the
123                        object with its own material and potentially its own type of
124                        rendering operation (triangles, points or lines for example).
125                @param materialName The name of the material to render this part of the
126                        object with.
127                @param opType The type of operation to use to render.
128                */
129                virtual void begin(const String& materialName,
130                        RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);
131                /** Add a vertex position, starting a new vertex at the same time.
132                @remarks A vertex position is slightly special among the other vertex data
133                        methods like normal() and textureCoord(), since calling it indicates
134                        the start of a new vertex. All other vertex data methods you call
135                        after this are assumed to be adding more information (like normals or
136                        texture coordinates) to the last vertex started with position().
137                */
138                virtual void position(const Vector3& pos);
139                /// @copydoc ManualObject::position(const Vector3&)
140                virtual void position(Real x, Real y, Real z);
141
142                /** Add a vertex normal to the current vertex.
143                @remarks
144                        Vertex normals are most often used for dynamic lighting, and
145                        their components should be normalised.
146                */
147                virtual void normal(const Vector3& norm);
148                /// @copydoc ManualObject::normal(const Vector3&)
149                virtual void normal(Real x, Real y, Real z);
150
151                /** Add a texture coordinate to the current vertex.
152                @remarks
153                        You can call this method multiple times between position() calls
154                        to add multiple texture coordinates to a vertex. Each one can have
155                        between 1 and 3 dimensions, depending on your needs, although 2 is
156                        most common. There are several versions of this method for the
157                        variations in number of dimensions.
158                */
159                virtual void textureCoord(Real u);
160                /// @copydoc ManualObject::textureCoord(Real)
161                virtual void textureCoord(Real u, Real v);
162                /// @copydoc ManualObject::textureCoord(Real)
163                virtual void textureCoord(Real u, Real v, Real w);
164                /// @copydoc ManualObject::textureCoord(Real)
165                virtual void textureCoord(const Vector2& uv);
166                /// @copydoc ManualObject::textureCoord(Real)
167                virtual void textureCoord(const Vector3& uvw);
168
169                /** Add a vertex colour to a vertex.
170                */
171                virtual void colour(const ColourValue& col);
172                /** Add a vertex colour to a vertex.
173                @param r,g,b,a Colour components expressed as floating point numbers from 0-1
174                */
175                virtual void colour(Real r, Real g, Real b, Real a = 1.0f);
176
177                /** Add a vertex index to construct faces / lines / points via indexing
178                        rather than just by a simple list of vertices.
179                @remarks
180                        You will have to call this 3 times for each face for a triangle list,
181                        or use the alternative 3-parameter version. Other operation types
182                        require different numbers of indexes, @see RenderOperation::OperationType.
183                @note
184                        32-bit indexes are not supported on all cards which is why this
185                        class only allows 16-bit indexes, for simplicity and ease of use.
186                @param idx A vertex index from 0 to 65535.
187                */
188                virtual void index(uint16 idx);
189                /** Add a set of 3 vertex indices to construct a triangle; this is a
190                        shortcut to calling index() 3 times. It is only valid for triangle
191                        lists.
192                @note
193                        32-bit indexes are not supported on all cards which is why this
194                        class only allows 16-bit indexes, for simplicity and ease of use.
195                @param i1, i2, i3 3 vertex indices from 0 to 65535 defining a face.
196                */
197                virtual void triangle(uint16 i1, uint16 i2, uint16 i3);
198                /** Add a set of 4 vertex indices to construct a quad (out of 2
199                        triangles); this is a shortcut to calling index() 6 times,
200                        or triangle() twice. It's only valid for triangle list operations.
201                @note
202                        32-bit indexes are not supported on all cards which is why this
203                        class only allows 16-bit indexes, for simplicity and ease of use.
204                @param i1, i2, i3 3 vertex indices from 0 to 65535 defining a face.
205                */
206                virtual void quad(uint16 i1, uint16 i2, uint16 i3, uint16 i4);
207
208                /** Finish defining the object and compile the final renderable version. */
209                virtual void end(void);
210
211                /** Convert this object to a Mesh.
212                @remarks
213                        After you've finished building this object, you may convert it to
214                        a Mesh if you want in order to be able to create many instances of
215                        it in the world (via Entity). This is optional, since this instance
216                        can be directly attached to a SceneNode itself, but of course only
217                        one instance of it can exist that way.
218                @note Only objects which use indexed geometry may be converted to a mesh.
219                @param meshName The name to give the mesh
220                @param groupName The resource group to create the mesh in
221                */
222                virtual MeshPtr convertToMesh(const String& meshName,
223                        const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
224
225                // MovableObject overrides
226
227                /** @copydoc MovableObject::getMovableType. */
228                const String& getMovableType(void) const;
229                /** @copydoc MovableObject::getBoundingBox. */
230                const AxisAlignedBox& getBoundingBox(void) const;
231                /** @copydoc MovableObject::getBoundingRadius. */
232                Real getBoundingRadius(void) const;
233                /** @copydoc MovableObject::_updateRenderQueue. */
234                void _updateRenderQueue(RenderQueue* queue);
235                /** Implement this method to enable stencil shadows. */
236                EdgeData* getEdgeList(void);
237                /** Implement this method to enable stencil shadows. */
238                ShadowRenderableListIterator getShadowVolumeRenderableIterator(
239                        ShadowTechnique shadowTechnique, const Light* light,
240                        HardwareIndexBufferSharedPtr* indexBuffer,
241                        bool extrudeVertices, Real extrusionDist, unsigned long flags = 0);
242
243
244                /// Built, renderable section of geometry
245                class _OgreExport ManualObjectSection : public Renderable
246                {
247                protected:
248                        ManualObject* mParent;
249                        String mMaterialName;
250                        mutable MaterialPtr mMaterial;
251                        RenderOperation mRenderOperation;
252                       
253                public:
254                        ManualObjectSection(ManualObject* parent, const String& materialName,
255                                RenderOperation::OperationType opType);
256                        virtual ~ManualObjectSection();
257                       
258                        /// Retrieve render operation for manipulation
259                        RenderOperation* getRenderOperation(void);
260                        /// Retrieve the material name in use
261                        const String& getMaterialName(void) const { return mMaterialName; }
262                       
263                        // Renderable overrides
264                        /** @copydoc Renderable::getMaterial. */
265                        const MaterialPtr& getMaterial(void) const;
266                        /** @copydoc Renderable::getRenderOperation. */
267                        void getRenderOperation(RenderOperation& op);
268                        /** @copydoc Renderable::getWorldTransforms. */
269                        void getWorldTransforms(Matrix4* xform) const;
270                        /** @copydoc Renderable::getWorldOrientation. */
271                        const Quaternion& getWorldOrientation(void) const;
272                        /** @copydoc Renderable::getWorldPosition. */
273                        const Vector3& getWorldPosition(void) const;
274                        /** @copydoc Renderable::getSquaredViewDepth. */
275                        Real getSquaredViewDepth(const Ogre::Camera *) const;
276                        /** @copydoc Renderable::getLights. */
277                        const LightList &getLights(void) const;
278                                       
279                };
280                /** Nested class to allow shadows. */
281                class _OgreExport ManualObjectSectionShadowRenderable : public ShadowRenderable
282                {
283                protected:
284                        ManualObject* mParent;
285                        // Shared link to position buffer
286                        HardwareVertexBufferSharedPtr mPositionBuffer;
287                        // Shared link to w-coord buffer (optional)
288                        HardwareVertexBufferSharedPtr mWBuffer;
289
290                public:
291                        ManualObjectSectionShadowRenderable(ManualObject* parent,
292                                HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData,
293                                bool createSeparateLightCap, bool isLightCap = false);
294                        ~ManualObjectSectionShadowRenderable();
295                        /// Overridden from ShadowRenderable
296                        void getWorldTransforms(Matrix4* xform) const;
297                        /// Overridden from ShadowRenderable
298                        const Quaternion& getWorldOrientation(void) const;
299                        /// Overridden from ShadowRenderable
300                        const Vector3& getWorldPosition(void) const;
301                        HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
302                        HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
303
304                };
305
306                typedef std::vector<ManualObjectSection*> SectionList;
307               
308        protected:
309                /// List of subsections
310                SectionList mSectionList;
311                /// Current section
312                ManualObjectSection* mCurrentSection;
313                /// Temporary vertex structure
314                struct TempVertex
315                {
316                        Vector3 position;
317                        Vector3 normal;
318                        Vector3 texCoord[OGRE_MAX_TEXTURE_COORD_SETS];
319                        ushort texCoordDims[OGRE_MAX_TEXTURE_COORD_SETS];
320                        ColourValue colour;
321                };
322                /// Temp storage
323                TempVertex mTempVertex;
324                /// First vertex indicator
325                bool mFirstVertex;
326                /// Temp vertex data to copy?
327                bool mTempVertexPending;
328                /// System-memory buffer whilst we establish the size required
329                char* mTempVertexBuffer;
330                /// System memory allocation size, in bytes
331                size_t mTempVertexSize;
332                /// System-memory buffer whilst we establish the size required
333                uint16* mTempIndexBuffer;
334                /// System memory allocation size, in bytes
335                size_t mTempIndexSize;
336                /// Current declaration vertex size
337                size_t mDeclSize;
338                /// Current texture coordinate
339                ushort mTexCoordIndex;
340                /// Bounding box
341                AxisAlignedBox mAABB;
342                /// Bounding sphere
343                Real mRadius;
344                /// Any indexed geoemtry on any sections?
345                bool mAnyIndexed;
346                /// Edge list, used if stencil shadow casting is enabled
347                EdgeData* mEdgeList;
348                /// List of shadow renderables
349                ShadowRenderableList mShadowRenderables;
350
351
352                /// Delete temp buffers and reset init counts
353                virtual void resetTempAreas(void);
354                /// Resize the temp vertex buffer?
355                virtual void resizeTempVertexBufferIfNeeded(size_t numVerts);
356                /// Resize the temp index buffer?
357                virtual void resizeTempIndexBufferIfNeeded(size_t numInds);
358
359                /// Copy current temp vertex into buffer
360                virtual void copyTempVertexToBuffer(void);
361
362        };
363
364
365        /** Factory object for creating ManualObject instances */
366        class _OgreExport ManualObjectFactory : public MovableObjectFactory
367        {
368        protected:
369                MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params);
370        public:
371                ManualObjectFactory() {}
372                ~ManualObjectFactory() {}
373
374                static String FACTORY_TYPE_NAME;
375
376                const String& getType(void) const;
377                void destroyInstance( MovableObject* obj); 
378
379        };
380}
381
382#endif
383
Note: See TracBrowser for help on using the repository browser.