PixelLightAPI
.
|
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__
|