PixelLightAPI  .
VertexBuffer.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: VertexBuffer.h                                 *
00003  *
00004  *  Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/)
00005  *
00006  *  This file is part of PixelLight.
00007  *
00008  *  PixelLight is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU Lesser General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  PixelLight is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  *  GNU Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public License
00019  *  along with PixelLight. If not, see <http://www.gnu.org/licenses/>.
00020 \*********************************************************/
00021 
00022 
00023 #ifndef __PLRENDERER_VERTEXBUFFER_H__
00024 #define __PLRENDERER_VERTEXBUFFER_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include <PLCore/Container/Array.h>
00032 #include <PLGraphics/Color/Color4.h>
00033 #include "PLRenderer/Renderer/Buffer.h"
00034 
00035 
00036 //[-------------------------------------------------------]
00037 //[ Forward declarations                                  ]
00038 //[-------------------------------------------------------]
00039 namespace PLMath {
00040     class Vector3;
00041 }
00042 namespace PLRenderer {
00043     class IndexBuffer;
00044 }
00045 
00046 
00047 //[-------------------------------------------------------]
00048 //[ Namespace                                             ]
00049 //[-------------------------------------------------------]
00050 namespace PLRenderer {
00051 
00052 
00053 //[-------------------------------------------------------]
00054 //[ Classes                                               ]
00055 //[-------------------------------------------------------]
00056 /**
00057 *  @brief
00058 *    Renderer vertex buffer (VBO) resource
00059 *
00060 *  @note
00061 *    - If for instance fog coordinates (Capabilities::bVertexBufferFogCoord) are not supported by the
00062 *      GPU, this data is ignored for rendering but can still be used inside your vertex buffer
00063 */
00064 class VertexBuffer : public Buffer {
00065 
00066 
00067     //[-------------------------------------------------------]
00068     //[ Public definitions                                    ]
00069     //[-------------------------------------------------------]
00070     public:
00071         /**
00072         *  @brief
00073         *    Vertex attribute semantic
00074         *
00075         *  @note
00076         *    - Defines input vertex data to the pipeline, on legacy hardware, this should be defined in this order (performance)
00077         */
00078         enum ESemantic {
00079             Position     =  0,  /**< Position data (1 channel) */
00080             BlendWeight  =  1,  /**< Blend weight data (1 channel) */
00081             Normal       =  2,  /**< Normal data (1 channel, only Float3/Half3 allowed due to restrictions of legacy APIs!) */
00082             Color        =  3,  /**< Color data (2 channels, only RGBA allowed, second channel requires Capabilities::bVertexBufferSecondaryColor) */
00083             FogCoord     =  4,  /**< Fog coordinate data (1 channel, only Float1 allowed, requires FixedFunctions::Capabilities::bVertexBufferFogCoord) */
00084             PointSize    =  5,  /**< Point sprite size data (1 channel, only Float1 allowed! Known as "PSize", but this name may conflict with OS definitions) */
00085             BlendIndices =  6,  /**< Blend indices data (1 channel) */
00086             TexCoord     =  7,  /**< Texture coordinate data (n channels) */
00087             Tangent      =  8,  /**< Tangent data (1 channel, only Float3/Half3 allowed due to restrictions of legacy APIs!) */
00088             Binormal     =  9   /**< Binormal (also referred to as bitangent) data (1 channel, only Float3/Half3 allowed due to restrictions of legacy APIs!) */
00089         };
00090         static const PLCore::uint8 NumOfSemantics      = 10;    /**< Number of vertex attribute semantics */
00091         static const PLCore::uint8 MaxPipelineChannels = 16;    /**< Maximum possible number of channels */
00092 
00093         /**
00094         *  @brief
00095         *    Vertex attribute types
00096         */
00097         enum EType {
00098             RGBA   = 0, /**< Color (legacy API dependent storage which is no longer required when using modern shader based API's, do always use GetColor() and SetColor()!) */
00099             Float1 = 1, /**< Float 1 (one component per element, 32 bit floating point per component) */
00100             Float2 = 2, /**< Float 2 (two components per element, 32 bit floating point per component) */
00101             Float3 = 3, /**< Float 3 (three components per element, 32 bit floating point per component) */
00102             Float4 = 4, /**< Float 4 (four components per element, 32 bit floating point per component) */
00103             Short2 = 5, /**< Short 2 (two components per element, 16 bit integer per component) */
00104             Short4 = 6, /**< Short 4 (four components per element, 16 bit integer per component) */
00105             Half1  = 7, /**< Half 1 (one component per element, 16 bit floating point per component, may not be supported by each API, be careful with this data type because not every GPU driver is optimized for it) */
00106             Half2  = 8, /**< Half 2 (two components per element, 16 bit floating point per component, may not be supported by each API, be careful with this data type because not every GPU driver is optimized for it) */
00107             Half3  = 9, /**< Half 3 (three components per element, 16 bit floating point per component, may not be supported by each API, be careful with this data type because not every GPU driver is optimized for it) */
00108             Half4  = 10 /**< Half 4 (four components per element, 16 bit floating point per component, may not be supported by each API, be careful with this data type because not every GPU driver is optimized for it) */
00109         };
00110 
00111 
00112     //[-------------------------------------------------------]
00113     //[ Public structures                                     ]
00114     //[-------------------------------------------------------]
00115     public:
00116         /**
00117         *  @brief
00118         *    Defines input vertex attribute to the pipeline
00119         */
00120         struct Attribute {
00121             ESemantic      nSemantic;       /**< Any member of the vertex attribute semantic enumeration type */
00122             PLCore::uint32 nChannel;        /**< Pipeline channel (see ESemantic) */
00123             EType          nType;           /**< Any member of the EType enumeration type */
00124             PLCore::uint32 nOffset;         /**< Offset of the vertex attribute */
00125             // API dependent
00126             PLCore::uint32 nSizeAPI;        /**< Size of the vertex attribute */
00127             PLCore::uint32 nTypeAPI;        /**< API dependent vertex type */
00128             PLCore::uint32 nComponentsAPI;  /**< Number of vertex type components */
00129         };
00130 
00131 
00132     //[-------------------------------------------------------]
00133     //[ Public functions                                      ]
00134     //[-------------------------------------------------------]
00135     public:
00136         /**
00137         *  @brief
00138         *    Destructor
00139         */
00140         PLRENDERER_API virtual ~VertexBuffer();
00141 
00142         /**
00143         *  @brief
00144         *    Returns the number of vertex attributes
00145         *
00146         *  @return
00147         *    Number of vertex attributes
00148         */
00149         inline PLCore::uint32 GetNumOfVertexAttributes() const;
00150 
00151         /**
00152         *  @brief
00153         *    Clears the vertex attributes
00154         *
00155         *  @return
00156         *    'true' if all went fine, else 'false'
00157         *
00158         *  @note
00159         *    - This is only possible if the vertex buffer is not allocated (see Allocate())
00160         *    - The virtual buffer function Clear() only clears the buffer itself,
00161         *      ClearVertexAttributes() clears the vertex attributes definition
00162         */
00163         PLRENDERER_API bool ClearVertexAttributes();
00164 
00165         /**
00166         *  @brief
00167         *    Adds vertex attribute
00168         *
00169         *  @param[in] nSemantic
00170         *    Any member of the vertex attribute semantic enumeration type
00171         *  @param[in] nChannel
00172         *    Pipeline channel (see ESemantic, maximum see MaxPipelineChannels)
00173         *  @param[in] nType
00174         *    Any member of the EType enumeration type
00175         *
00176         *  @return
00177         *    'true' if all went fine, else 'false' (maybe this vertex attribute is already there or the requested type is not supported)
00178         *
00179         *  @note
00180         *    - You shouldn't change the vertex attribute after the vertex buffer was
00181         *      allocated using the Allocate()-function! (performance!)
00182         *    - It the buffer is still locked, it's forced to be unlocked immediately if all went fine
00183         */
00184         PLRENDERER_API bool AddVertexAttribute(ESemantic nSemantic, PLCore::uint32 nChannel, EType nType);
00185 
00186         /**
00187         *  @brief
00188         *    Returns a vertex attribute
00189         *
00190         *  @param[in] nIndex
00191         *    Index of the vertex attribute which should be returned
00192         *
00193         *  @return
00194         *    The requested vertex attribute, a null pointer on error
00195         */
00196         inline const Attribute *GetVertexAttribute(PLCore::uint32 nIndex = 0) const;
00197 
00198         /**
00199         *  @brief
00200         *    Returns the first found vertex attribute with the requested semantic
00201         *
00202         *  @param[in] nSemantic
00203         *    Vertex attribute semantic
00204         *  @param[in] nChannel
00205         *    Pipeline channel (see ESemantic, maximum see MaxPipelineChannels)
00206         *
00207         *  @return
00208         *    The first found vertex attribute with the requested semantic, a null pointer on error
00209         */
00210         PLRENDERER_API const Attribute *GetVertexAttribute(ESemantic nSemantic, PLCore::uint32 nChannel = 0) const;
00211 
00212         /**
00213         *  @brief
00214         *    Returns the vertex size (in bytes)
00215         *
00216         *  @return
00217         *    Vertex size (in bytes)
00218         */
00219         inline PLCore::uint32 GetVertexSize() const;
00220 
00221         /**
00222         *  @brief
00223         *    Copy operator
00224         *
00225         *  @param[in] cSource
00226         *    Source to copy from
00227         *
00228         *  @return
00229         *    Reference to this object
00230         */
00231         PLRENDERER_API VertexBuffer &operator =(const VertexBuffer &cSource);
00232 
00233         //[-------------------------------------------------------]
00234         //[ Tool functions                                        ]
00235         //[-------------------------------------------------------]
00236         /**
00237         *  @brief
00238         *    Fills the data of a vertex buffer attribute into four given generic floating point components
00239         *
00240         *  @param[in]  nIndex
00241         *    Vertex index
00242         *  @param[in]  nSemantic
00243         *    Any member of the vertex attribute semantic enumeration type
00244         *  @param[in]  nChannel
00245         *    Pipeline channel (see ESemantic)
00246         *  @param[out] fX
00247         *    On success, receives the first component, set to null on error
00248         *  @param[out] fY
00249         *    On success, receives the second component, set to null on error or when the component does not exist
00250         *  @param[out] fZ
00251         *    On success, receives the third component, set to null on error or when the component does not exist
00252         *  @param[out] fW
00253         *    On success, receives the fourth component, set to null on error or when the component does not exist
00254         *
00255         *  @return
00256         *    'true' if all went fine, else 'false'
00257         *
00258         *  @note
00259         *    - Performance warning: This is only a comfort method and there's a notable overhead
00260         *      due to the required multiple checks, access the data directly if you need maximum possible performance
00261         *    - Unavailable components are ignored, e.g. when setting "Float1" the given "fY", "fZ" and "fW" will be ignored
00262         *    - See GetData() in Buffer
00263         *    - This function will give you the correct offset of the requested
00264         *      vertex attribute
00265         *    - When manipulating color data you should use GetColor() and SetColor()!
00266         */
00267         PLRENDERER_API bool GetFloat(PLCore::uint32 nIndex, PLCore::uint32 nSemantic, PLCore::uint32 nChannel, float &fX, float &fY, float &fZ, float &fW);
00268 
00269         /**
00270         *  @brief
00271         *    Sets the data of a vertex buffer attribute by using four given generic floating point components
00272         *
00273         *  @param[in] nIndex
00274         *    Vertex index
00275         *  @param[in] nSemantic
00276         *    Any member of the vertex attribute semantic enumeration type
00277         *  @param[in] nChannel
00278         *    Pipeline channel (see ESemantic)
00279         *  @param[in] fX
00280         *    First component
00281         *  @param[in] fY
00282         *    Second component
00283         *  @param[in] fZ
00284         *    Third component
00285         *  @param[in] fW
00286         *    Fourth component
00287         *
00288         *  @return
00289         *    'true' if all went fine, else 'false'
00290         *
00291         *  @note
00292         *    - Performance warning: This is only a comfort method and there's a notable overhead
00293         *      due to the required multiple checks, access the data directly if you need maximum possible performance
00294         *    - Unavailable components are ignored, e.g. when setting "Float1" the given "fY", "fZ" and "fW" will be ignored
00295         *    - See GetData() in Buffer
00296         *    - This function will give you the correct offset of the requested
00297         *      vertex attribute
00298         *    - When manipulating color data you should use GetColor() and SetColor()!
00299         */
00300         PLRENDERER_API bool SetFloat(PLCore::uint32 nIndex, PLCore::uint32 nSemantic, PLCore::uint32 nChannel, float fX, float fY = 0.0f, float fZ = 0.0f, float fW = 0.0f);
00301 
00302         /**
00303         *  @brief
00304         *    Returns the vertex buffer bounding box
00305         *
00306         *  @param[out] vMinPos
00307         *    Will receive the minimum bounding box position
00308         *  @param[out] vMaxPos
00309         *    Will receive the maximum bounding box position
00310         *  @param[in]  pIndexBuffer
00311         *    Optional index buffer to take only a set of vertices into account, set to a null pointer if not used
00312         */
00313         PLRENDERER_API void CalculateBoundingBox(PLMath::Vector3 &vMinPos, PLMath::Vector3 &vMaxPos, PLRenderer::IndexBuffer *pIndexBuffer = nullptr);
00314 
00315         /**
00316         *  @brief
00317         *    Returns the vertex buffer bounding sphere
00318         *
00319         *  @param[out] vPos
00320         *    Will receive the bounding sphere position
00321         *  @param[out] fRadius
00322         *    Will receive the bounding sphere radius
00323         *  @param[in]  pIndexBuffer
00324         *    Optional index buffer to take only a set of vertices into account, set to a null pointer if not used
00325         */
00326         PLRENDERER_API void CalculateBoundingSphere(PLMath::Vector3 &vPos, float &fRadius, PLRenderer::IndexBuffer *pIndexBuffer = nullptr);
00327 
00328 
00329     //[-------------------------------------------------------]
00330     //[ Public virtual VertexBuffer functions                 ]
00331     //[-------------------------------------------------------]
00332     public:
00333         /**
00334         *  @brief
00335         *    Returns the data of a vertex buffer attribute
00336         *
00337         *  @param[in] nIndex
00338         *    Vertex index
00339         *  @param[in] nSemantic
00340         *    Any member of the vertex attribute semantic enumeration type
00341         *  @param[in] nChannel
00342         *    Pipeline channel (see ESemantic)
00343         *
00344         *  @return
00345         *    The data of the locked vertex buffer, a null pointer on error
00346         *
00347         *  @note
00348         *    - See GetData() in Buffer
00349         *    - This function will give you the correct offset of the requested
00350         *      vertex attribute
00351         *    - When manipulating color data you should use GetColor() and SetColor()!
00352         */
00353         virtual void *GetData(PLCore::uint32 nIndex, PLCore::uint32 nSemantic, PLCore::uint32 nChannel = 0) = 0;
00354 
00355         /**
00356         *  @brief
00357         *    Returns the RGBA color of a vertex
00358         *
00359         *  @param[in] nIndex
00360         *    Vertex index
00361         *  @param[in] nChannel
00362         *    Pipeline channel (see ESemantic)
00363         *
00364         *  @return
00365         *    The RGBA color of a vertex
00366         *
00367         *  @note
00368         *    - Because the different APIs will store the colors in different formats
00369         *      you should always use this offered color functions which are API
00370         *      independent!
00371         */
00372         virtual PLGraphics::Color4 GetColor(PLCore::uint32 nIndex, PLCore::uint32 nChannel = 0) = 0;
00373 
00374         /**
00375         *  @brief
00376         *    Set the RGBA color of a vertex
00377         *
00378         *  @param[in] nIndex
00379         *    Vertex index
00380         *  @param[in] cColor
00381         *    Color to set
00382         *  @param[in] nChannel
00383         *    Pipeline channel (see ESemantic)
00384         *
00385         *  @return
00386         *    'true' if all went fine, else 'false'
00387         *
00388         *  @see
00389         *    - GetColor()
00390         */
00391         virtual bool SetColor(PLCore::uint32 nIndex, const PLGraphics::Color4 &cColor, PLCore::uint32 nChannel = 0) = 0;
00392 
00393 
00394     //[-------------------------------------------------------]
00395     //[ Protected functions                                   ]
00396     //[-------------------------------------------------------]
00397     protected:
00398         /**
00399         *  @brief
00400         *    Constructor
00401         *
00402         *  @param[in] cRenderer
00403         *    Owner renderer
00404         */
00405         PLRENDERER_API VertexBuffer(Renderer &cRenderer);
00406 
00407 
00408     //[-------------------------------------------------------]
00409     //[ Protected data                                        ]
00410     //[-------------------------------------------------------]
00411     protected:
00412         PLCore::Array<Attribute*> m_lstVertexAttributes;    /**< The vertex attributes */
00413         PLCore::uint32            m_nVertexSize;            /**< Size (in bytes) of the vertex buffer */
00414 
00415 
00416     //[-------------------------------------------------------]
00417     //[ Private functions                                     ]
00418     //[-------------------------------------------------------]
00419     private:
00420         /**
00421         *  @brief
00422         *    Copy constructor
00423         *
00424         *  @param[in] cSource
00425         *    Source to copy from
00426         */
00427         VertexBuffer(const VertexBuffer &cSource);
00428 
00429 
00430     //[-------------------------------------------------------]
00431     //[ Private virtual VertexBuffer functions                ]
00432     //[-------------------------------------------------------]
00433     private:
00434         /**
00435         *  @brief
00436         *    Is called after a vertex attribute was added to setup some API dependent stuff
00437         *
00438         *  @param[in, out] cAttribute
00439         *    The added vertex attribute, a returned "Attribute::nSizeAPI" of 0 has to be handled like an error
00440         *
00441         *  @note
00442         *    - This function will setup the API dependent vertex attribute data
00443         *    - It will also update the current vertex size
00444         */
00445         virtual void VertexAttributeAdded(Attribute &cAttribute) = 0;
00446 
00447 
00448     //[-------------------------------------------------------]
00449     //[ Public virtual Buffer functions                       ]
00450     //[-------------------------------------------------------]
00451     public:
00452         PLRENDERER_API virtual void *GetData() override;
00453 
00454 
00455 };
00456 
00457 
00458 //[-------------------------------------------------------]
00459 //[ Namespace                                             ]
00460 //[-------------------------------------------------------]
00461 } // PLRenderer
00462 
00463 
00464 //[-------------------------------------------------------]
00465 //[ Implementation                                        ]
00466 //[-------------------------------------------------------]
00467 #include "PLRenderer/Renderer/VertexBuffer.inl"
00468 
00469 
00470 #endif // __PLRENDERER_VERTEXBUFFER_H__


PixelLight PixelLight 0.9.11-R1
Copyright (C) 2002-2012 by The PixelLight Team
Last modified Thu Feb 23 2012 14:09:01
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported