Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

=update

File size: 21.2 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
30#ifndef __OgreManualObject_H__
31#define __OgreManualObject_H__
32
33#include "OgrePrerequisites.h"
34#include "OgreMovableObject.h"
35#include "OgreRenderable.h"
36#include "OgreResourceGroupManager.h"
37
38
39namespace Ogre
40{
41        /** Class providing a much simplified interface to generating manual
42                objects with custom geometry.
43        @remarks
44                Building one-off geometry objects manually usually requires getting
45                down and dirty with the vertex buffer and vertex declaration API,
46                which some people find a steep learning curve. This class gives you
47                a simpler interface specifically for the purpose of building a
48                3D object simply and quickly. Note that if you intend to instance your
49                object you will still need to become familiar with the Mesh class.
50        @par
51                This class draws heavily on the interface for OpenGL
52                immediate-mode (glBegin, glVertex, glNormal etc), since this
53                is generally well-liked by people. There are a couple of differences
54                in the results though - internally this class still builds hardware
55                buffers which can be re-used, so you can render the resulting object
56                multiple times without re-issuing all the same commands again.
57                Secondly, the rendering is not immediate, it is still queued just like
58                all OGRE objects. This makes this object more efficient than the
59                equivalent GL immediate-mode commands, so it's feasible to use it for
60                large objects if you really want to.
61        @par
62                To construct some geometry with this object:
63                  -# If you know roughly how many vertices (and indices, if you use them)
64                     you're going to submit, call estimateVertexCount and estimateIndexCount.
65                         This is not essential but will make the process more efficient by saving
66                         memory reallocations.
67                  -# Call begin() to begin entering data
68                  -# For each vertex, call position(), normal(), textureCoord(), colour()
69                     to define your vertex data. Note that each time you call position()
70                         you start a new vertex. Note that the first vertex defines the
71                         components of the vertex - you can't add more after that. For example
72                         if you didn't call normal() in the first vertex, you cannot call it
73                         in any others. You ought to call the same combination of methods per
74                         vertex.
75                  -# If you want to define triangles (or lines/points) by indexing into the vertex list,
76                         you can call index() as many times as you need to define them.
77                         If you don't do this, the class will assume you want triangles drawn
78                         directly as defined by the vertex list, ie non-indexed geometry. Note
79                         that stencil shadows are only supported on indexed geometry, and that
80                         indexed geometry is a little faster; so you should try to use it.
81                  -# Call end() to finish entering data.
82                  -# Optionally repeat the begin-end cycle if you want more geometry
83                        using different rendering operation types, or different materials
84            After calling end(), the class will organise the data for that section
85                internally and make it ready to render with. Like any other
86                MovableObject you should attach the object to a SceneNode to make it
87                visible. Other aspects like the relative render order can be controlled
88                using standard MovableObject methods like setRenderQueueGroup.
89        @par
90                You can also use beginUpdate() to alter the geometry later on if you wish.
91                If you do this, you should call setDynamic(true) before your first call
92                to begin(), and also consider using estimateVertexCount / estimateIndexCount
93                if your geometry is going to be growing, to avoid buffer recreation during
94                growth.
95        @par
96                Note that like all OGRE geometry, triangles should be specified in
97                anti-clockwise winding order (whether you're doing it with just
98                vertices, or using indexes too). That is to say that the front of the
99                face is the one where the vertices are listed in anti-clockwise order.
100        */
101        class _OgreExport ManualObject : public MovableObject
102        {
103        public:
104                ManualObject(const String& name);
105                virtual ~ManualObject();
106
107                //pre-declare ManualObjectSection
108                class ManualObjectSection;
109
110                /** Completely clear the contents of the object.
111                @remarks
112                        Clearing the contents of this object and rebuilding from scratch
113                        is not the optimal way to manage dynamic vertex data, since the
114                        buffers are recreated. If you want to keep the same structure but
115                        update the content within that structure, use beginUpdate() instead
116                        of clear() begin(). However if you do want to modify the structure
117                        from time to time you can do so by clearing and re-specifying the data.
118                */
119                virtual void clear(void);
120               
121                /** Estimate the number of vertices ahead of time.
122                @remarks
123                        Calling this helps to avoid memory reallocation when you define
124                        vertices. Also very handy when using beginUpdate() to manage dynamic
125                        data - you can make the vertex buffers a little larger than their
126                        initial needs to allow for growth later with this method.
127                */
128                virtual void estimateVertexCount(size_t vcount);
129
130                /** Estimate the number of indices ahead of time.
131                @remarks
132                        Calling this helps to avoid memory reallocation when you define
133                        indices. Also very handy when using beginUpdate() to manage dynamic
134                        data - you can make the index buffer a little larger than the
135                        initial need to allow for growth later with this method.
136                */
137                virtual void estimateIndexCount(size_t icount);
138
139                /** Start defining a part of the object.
140                @remarks
141                        Each time you call this method, you start a new section of the
142                        object with its own material and potentially its own type of
143                        rendering operation (triangles, points or lines for example).
144                @param materialName The name of the material to render this part of the
145                        object with.
146                @param opType The type of operation to use to render.
147                */
148                virtual void begin(const String& materialName, 
149                        RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);
150
151                /** Use before defining gometry to indicate that you intend to update the
152                        geometry regularly and want the internal structure to reflect that.
153                */
154                virtual void setDynamic(bool dyn) { mDynamic = dyn; }
155                /** Gets whether this object is marked as dynamic */
156                virtual bool getDynamic() const { return mDynamic; }
157
158                /** Start the definition of an update to a part of the object.
159                @remarks
160                        Using this method, you can update an existing section of the object
161                        efficiently. You do not have the option of changing the operation type
162                        obviously, since it must match the one that was used before.
163                @note If your sections are changing size, particularly growing, use
164                        estimateVertexCount and estimateIndexCount to pre-size the buffers a little
165                        larger than the initial needs to avoid buffer reconstruction.
166                @param sectionIndex The index of the section you want to update. The first
167                        call to begin() would have created section 0, the second section 1, etc.
168                */
169                virtual void beginUpdate(size_t sectionIndex);
170                /** Add a vertex position, starting a new vertex at the same time.
171                @remarks A vertex position is slightly special among the other vertex data
172                        methods like normal() and textureCoord(), since calling it indicates
173                        the start of a new vertex. All other vertex data methods you call
174                        after this are assumed to be adding more information (like normals or
175                        texture coordinates) to the last vertex started with position().
176                */
177                virtual void position(const Vector3& pos);
178                /// @copydoc ManualObject::position(const Vector3&)
179                virtual void position(Real x, Real y, Real z);
180
181                /** Add a vertex normal to the current vertex.
182                @remarks
183                        Vertex normals are most often used for dynamic lighting, and
184                        their components should be normalised.
185                */
186                virtual void normal(const Vector3& norm);
187                /// @copydoc ManualObject::normal(const Vector3&)
188                virtual void normal(Real x, Real y, Real z);
189
190                /** Add a texture coordinate to the current vertex.
191                @remarks
192                        You can call this method multiple times between position() calls
193                        to add multiple texture coordinates to a vertex. Each one can have
194                        between 1 and 3 dimensions, depending on your needs, although 2 is
195                        most common. There are several versions of this method for the
196                        variations in number of dimensions.
197                */
198                virtual void textureCoord(Real u);
199                /// @copydoc ManualObject::textureCoord(Real)
200                virtual void textureCoord(Real u, Real v);
201                /// @copydoc ManualObject::textureCoord(Real)
202                virtual void textureCoord(Real u, Real v, Real w);
203                /// @copydoc ManualObject::textureCoord(Real)
204                virtual void textureCoord(const Vector2& uv);
205                /// @copydoc ManualObject::textureCoord(Real)
206                virtual void textureCoord(const Vector3& uvw);
207
208                /** Add a vertex colour to a vertex.
209                */
210                virtual void colour(const ColourValue& col);
211                /** Add a vertex colour to a vertex.
212                @param r,g,b,a Colour components expressed as floating point numbers from 0-1
213                */
214                virtual void colour(Real r, Real g, Real b, Real a = 1.0f);
215
216                /** Add a vertex index to construct faces / lines / points via indexing
217                        rather than just by a simple list of vertices.
218                @remarks
219                        You will have to call this 3 times for each face for a triangle list,
220                        or use the alternative 3-parameter version. Other operation types
221                        require different numbers of indexes, @see RenderOperation::OperationType.
222                @note
223                        32-bit indexes are not supported on all cards which is why this
224                        class only allows 16-bit indexes, for simplicity and ease of use.
225                @param idx A vertex index from 0 to 65535.
226                */
227                virtual void index(uint16 idx);
228                /** Add a set of 3 vertex indices to construct a triangle; this is a
229                        shortcut to calling index() 3 times. It is only valid for triangle
230                        lists.
231                @note
232                        32-bit indexes are not supported on all cards which is why this
233                        class only allows 16-bit indexes, for simplicity and ease of use.
234                @param i1, i2, i3 3 vertex indices from 0 to 65535 defining a face.
235                */
236                virtual void triangle(uint16 i1, uint16 i2, uint16 i3);
237                /** Add a set of 4 vertex indices to construct a quad (out of 2
238                        triangles); this is a shortcut to calling index() 6 times,
239                        or triangle() twice. It's only valid for triangle list operations.
240                @note
241                        32-bit indexes are not supported on all cards which is why this
242                        class only allows 16-bit indexes, for simplicity and ease of use.
243                @param i1, i2, i3 3 vertex indices from 0 to 65535 defining a face.
244                */
245                virtual void quad(uint16 i1, uint16 i2, uint16 i3, uint16 i4);
246
247                /** Finish defining the object and compile the final renderable version.
248                @note
249                        Will return a pointer to the finished section or NULL if the section was discarded (i.e. has zero vertices/indices).
250                */
251                virtual ManualObjectSection* end(void);
252
253                /** Alter the material for a subsection of this object after it has been
254                        specified.
255                @remarks
256                        You specify the material to use on a section of this object during the
257                        call to begin(), however if you want to change the material afterwards
258                        you can do so by calling this method.
259                @param subIndex The index of the subsection to alter
260                @param name The name of the new material to use
261                */
262                virtual void setMaterialName(size_t subindex, const String& name);
263
264                /** Convert this object to a Mesh.
265                @remarks
266                        After you've finished building this object, you may convert it to
267                        a Mesh if you want in order to be able to create many instances of
268                        it in the world (via Entity). This is optional, since this instance
269                        can be directly attached to a SceneNode itself, but of course only
270                        one instance of it can exist that way.
271                @note Only objects which use indexed geometry may be converted to a mesh.
272                @param meshName The name to give the mesh
273                @param groupName The resource group to create the mesh in
274                */
275                virtual MeshPtr convertToMesh(const String& meshName, 
276                        const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
277
278                /** Sets whether or not to use an 'identity' projection.
279                @remarks
280                        Usually ManualObjects will use a projection matrix as determined
281                        by the active camera. However, if they want they can cancel this out
282                        and use an identity projection, which effectively projects in 2D using
283                        a {-1, 1} view space. Useful for overlay rendering. Normally you don't
284                        need to change this. The default is false.
285                @see ManualObject::getUseIdentityProjection
286                */
287                void setUseIdentityProjection(bool useIdentityProjection);
288
289                /** Returns whether or not to use an 'identity' projection.
290                @remarks
291                        Usually ManualObjects will use a projection matrix as determined
292                        by the active camera. However, if they want they can cancel this out
293                        and use an identity projection, which effectively projects in 2D using
294                        a {-1, 1} view space. Useful for overlay rendering. Normally you don't
295                        need to change this.
296                @see ManualObject::setUseIdentityProjection
297                */
298                bool getUseIdentityProjection(void) const { return mUseIdentityProjection; }
299
300                /** Sets whether or not to use an 'identity' view.
301                @remarks
302                        Usually ManualObjects will use a view matrix as determined
303                        by the active camera. However, if they want they can cancel this out
304                        and use an identity matrix, which means all geometry is assumed
305                        to be relative to camera space already. Useful for overlay rendering.
306                        Normally you don't need to change this. The default is false.
307                @see ManualObject::getUseIdentityView
308                */
309                void setUseIdentityView(bool useIdentityView);
310
311                /** Returns whether or not to use an 'identity' view.
312                @remarks
313                        Usually ManualObjects will use a view matrix as determined
314                        by the active camera. However, if they want they can cancel this out
315                        and use an identity matrix, which means all geometry is assumed
316                        to be relative to camera space already. Useful for overlay rendering.
317                        Normally you don't need to change this.
318                @see ManualObject::setUseIdentityView
319                */
320                bool getUseIdentityView(void) const { return mUseIdentityView; }
321
322                /** Sets the bounding box.
323                        @remarks Call this after having finished creating sections to modify the
324                                bounding box. E.g. if you're using ManualObject to create 2D overlays
325                                you can call things function to set an infinite bounding box so that
326                                the object always stays visible when attached.
327                        @see ManualObject::setUseIdentityProjection, ManualObject::setUseIdentityView,
328                                AxisAlignedBox::setInfinite */
329                void setBoundingBox(const AxisAlignedBox& box) { mAABB = box; }
330
331                /** Gets a pointer to a ManualObjectSection, ie a part of a ManualObject.
332                */
333                ManualObjectSection* getSection(unsigned int index) const;
334
335                /** Retrieves the number of ManualObjectSection objects making up this ManualObject.
336                */
337                unsigned int getNumSections(void) const;
338
339                // MovableObject overrides
340
341                /** @copydoc MovableObject::getMovableType. */
342                const String& getMovableType(void) const;
343                /** @copydoc MovableObject::getBoundingBox. */
344                const AxisAlignedBox& getBoundingBox(void) const;
345                /** @copydoc MovableObject::getBoundingRadius. */
346                Real getBoundingRadius(void) const;
347                /** @copydoc MovableObject::_updateRenderQueue. */
348                void _updateRenderQueue(RenderQueue* queue);
349                /** Implement this method to enable stencil shadows. */
350                EdgeData* getEdgeList(void);
351                /** Overridden member from ShadowCaster. */
352                bool hasEdgeList(void);
353                /** Implement this method to enable stencil shadows. */
354                ShadowRenderableListIterator getShadowVolumeRenderableIterator(
355                        ShadowTechnique shadowTechnique, const Light* light, 
356                        HardwareIndexBufferSharedPtr* indexBuffer, 
357                        bool extrudeVertices, Real extrusionDist, unsigned long flags = 0);
358
359
360                /// Built, renderable section of geometry
361                class _OgreExport ManualObjectSection : public Renderable
362                {
363                protected:
364                        ManualObject* mParent;
365                        String mMaterialName;
366                        mutable MaterialPtr mMaterial;
367                        RenderOperation mRenderOperation;
368                       
369                public:
370                        ManualObjectSection(ManualObject* parent, const String& materialName,
371                                RenderOperation::OperationType opType);
372                        virtual ~ManualObjectSection();
373                       
374                        /// Retrieve render operation for manipulation
375                        RenderOperation* getRenderOperation(void);
376                        /// Retrieve the material name in use
377                        const String& getMaterialName(void) const { return mMaterialName; }
378                        /// update the material name in use
379                        void setMaterialName(const String& name);
380                       
381                        // Renderable overrides
382                        /** @copydoc Renderable::getMaterial. */
383                        const MaterialPtr& getMaterial(void) const;
384                        /** @copydoc Renderable::getRenderOperation. */
385                        void getRenderOperation(RenderOperation& op);
386                        /** @copydoc Renderable::getWorldTransforms. */
387                        void getWorldTransforms(Matrix4* xform) const;
388                        /** @copydoc Renderable::getWorldOrientation. */
389                        const Quaternion& getWorldOrientation(void) const;
390                        /** @copydoc Renderable::getWorldPosition. */
391                        const Vector3& getWorldPosition(void) const;
392                        /** @copydoc Renderable::getSquaredViewDepth. */
393                        Real getSquaredViewDepth(const Ogre::Camera *) const;
394                        /** @copydoc Renderable::getLights. */
395                        const LightList &getLights(void) const;
396                                       
397                };
398                /** Nested class to allow shadows. */
399                class _OgreExport ManualObjectSectionShadowRenderable : public ShadowRenderable
400                {
401                protected:
402                        ManualObject* mParent;
403                        // Shared link to position buffer
404                        HardwareVertexBufferSharedPtr mPositionBuffer;
405                        // Shared link to w-coord buffer (optional)
406                        HardwareVertexBufferSharedPtr mWBuffer;
407
408                public:
409                        ManualObjectSectionShadowRenderable(ManualObject* parent, 
410                                HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData, 
411                                bool createSeparateLightCap, bool isLightCap = false);
412                        ~ManualObjectSectionShadowRenderable();
413                        /// Overridden from ShadowRenderable
414                        void getWorldTransforms(Matrix4* xform) const;
415                        /// Overridden from ShadowRenderable
416                        const Quaternion& getWorldOrientation(void) const;
417                        /// Overridden from ShadowRenderable
418                        const Vector3& getWorldPosition(void) const;
419                        HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
420                        HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
421
422                };
423
424                typedef std::vector<ManualObjectSection*> SectionList;
425               
426        protected:
427                /// Dynamic?
428                bool mDynamic;
429                /// List of subsections
430                SectionList mSectionList;
431                /// Current section
432                ManualObjectSection* mCurrentSection;
433                /// Are we updating?
434                bool mCurrentUpdating;
435                /// Temporary vertex structure
436                struct TempVertex
437                {
438                        Vector3 position;
439                        Vector3 normal;
440                        Vector3 texCoord[OGRE_MAX_TEXTURE_COORD_SETS];
441                        ushort texCoordDims[OGRE_MAX_TEXTURE_COORD_SETS];
442                        ColourValue colour;
443                };
444                /// Temp storage
445                TempVertex mTempVertex;
446                /// First vertex indicator
447                bool mFirstVertex;
448                /// Temp vertex data to copy?
449                bool mTempVertexPending;
450                /// System-memory buffer whilst we establish the size required
451                char* mTempVertexBuffer;
452                /// System memory allocation size, in bytes
453                size_t mTempVertexSize;
454                /// System-memory buffer whilst we establish the size required
455                uint16* mTempIndexBuffer;
456                /// System memory allocation size, in bytes
457                size_t mTempIndexSize;
458                /// Current declaration vertex size
459                size_t mDeclSize;
460                /// Estimated vertex count
461                size_t mEstVertexCount;
462                /// Estimated index count
463                size_t mEstIndexCount;
464                /// Current texture coordinate
465                ushort mTexCoordIndex;
466                /// Bounding box
467                AxisAlignedBox mAABB;
468                /// Bounding sphere
469                Real mRadius;
470                /// Any indexed geoemtry on any sections?
471                bool mAnyIndexed;
472                /// Edge list, used if stencil shadow casting is enabled
473                EdgeData* mEdgeList;
474                /// List of shadow renderables
475                ShadowRenderableList mShadowRenderables;
476                /// Whether to use identity projection for sections
477                bool mUseIdentityProjection;
478                /// Whether to use identity view for sections
479                bool mUseIdentityView;
480
481
482                /// Delete temp buffers and reset init counts
483                virtual void resetTempAreas(void);
484                /// Resize the temp vertex buffer?
485                virtual void resizeTempVertexBufferIfNeeded(size_t numVerts);
486                /// Resize the temp index buffer?
487                virtual void resizeTempIndexBufferIfNeeded(size_t numInds);
488
489                /// Copy current temp vertex into buffer
490                virtual void copyTempVertexToBuffer(void);
491
492        };
493
494
495        /** Factory object for creating ManualObject instances */
496        class _OgreExport ManualObjectFactory : public MovableObjectFactory
497        {
498        protected:
499                MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params);
500        public:
501                ManualObjectFactory() {}
502                ~ManualObjectFactory() {}
503
504                static String FACTORY_TYPE_NAME;
505
506                const String& getType(void) const;
507                void destroyInstance( MovableObject* obj); 
508
509        };
510}
511
512#endif
513
Note: See TracBrowser for help on using the repository browser.