PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: TextureBuffer.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_TEXTUREBUFFER_H__ 00024 #define __PLRENDERER_TEXTUREBUFFER_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include <PLGraphics/PLGraphics.h> 00032 #include "PLRenderer/Renderer/Resource.h" 00033 00034 00035 //[-------------------------------------------------------] 00036 //[ Forward declarations ] 00037 //[-------------------------------------------------------] 00038 namespace PLGraphics { 00039 class Image; 00040 class Color4; 00041 } 00042 00043 00044 //[-------------------------------------------------------] 00045 //[ Namespace ] 00046 //[-------------------------------------------------------] 00047 namespace PLRenderer { 00048 00049 00050 //[-------------------------------------------------------] 00051 //[ Classes ] 00052 //[-------------------------------------------------------] 00053 /** 00054 * @brief 00055 * Abstract renderer texture buffer resource base class 00056 * 00057 * @remarks 00058 * In the literature, for a volume an element is called voxel, and a texture element is called texel. 00059 * To stay name compatible with PLGraphics::ImageBuffer, we will just use the term pixel. 00060 */ 00061 class TextureBuffer : public Resource { 00062 00063 00064 //[-------------------------------------------------------] 00065 //[ Friends ] 00066 //[-------------------------------------------------------] 00067 friend class RendererBackend; 00068 00069 00070 //[-------------------------------------------------------] 00071 //[ Public definitions ] 00072 //[-------------------------------------------------------] 00073 public: 00074 /** 00075 * @brief 00076 * Texture buffer flags 00077 */ 00078 enum EFlags { 00079 Mipmaps = 1<<0, /**< Use mipmaps (see GetNumOfMipmaps() for more information) */ 00080 Compression = 1<<1, /**< Use texture buffer compression if possible (is ignored if a certain internal format is forced) */ 00081 RenderTarget = 1<<2 /**< This texture buffer can be used as render target */ 00082 }; 00083 00084 /** 00085 * @brief 00086 * Texture buffer pixel formats 00087 */ 00088 enum EPixelFormat { 00089 // Unsigned formats 00090 L8 = 0, /**< 8-bit pixel format, all bits luminance */ 00091 L16 = 1, /**< 16-bit pixel format, all bits luminance */ 00092 A8 = 2, /**< 8-bit pixel format, all bits alpha */ 00093 L4A4 = 3, /**< 8-bit pixel format, 4 bits for luminance and alpha */ 00094 L8A8 = 4, /**< 16-bit pixel format, 8 bits for luminance and alpha */ 00095 D16 = 5, /**< 16-bit z-buffer bit depth */ 00096 D24 = 6, /**< 32-bit z-buffer bit depth using 24 bits for the depth channel */ 00097 D32 = 7, /**< 32-bit z-buffer bit depth */ 00098 R3G3B2 = 8, /**< 8-bit pixel format, 3 bits red, 3 bits green and 2 bits blue */ 00099 R5G6B5 = 9, /**< 16-bit pixel format, 5 bits red, 6 bits green and 5 bits blue */ 00100 R5G5B5A1 = 10, /**< 16-bit pixel format, 5 bits red, 5 bits green, 5 bits blue and 1 bits alpha */ 00101 R4G4B4A4 = 11, /**< 16-bit pixel format, 4 bits for red, green, blue and alpha */ 00102 R8G8B8 = 12, /**< 24-bit (or 32-bit if 24-bits are not supported by the hardware) pixel format, 8 bits for red, green and blue */ 00103 R8G8B8A8 = 13, /**< 32-bit pixel format, 8 bits for red, green, blue and alpha */ 00104 R10G10B10A2 = 14, /**< 32-bit pixel format, 10 bits for red, green, blue and 2 bits for alpha */ 00105 R16G16B16A16 = 15, /**< 64-bit pixel format, 16 bits for red, green, blue and alpha */ 00106 DXT1 = 16, /**< DXT1 compression (known as BC1 in DirectX 10, RGB compression: 8:1, 8 bytes per block) */ 00107 DXT3 = 17, /**< DXT3 compression (known as BC2 in DirectX 10, RGBA compression: 4:1, 16 bytes per block) */ 00108 DXT5 = 18, /**< DXT5 compression (known as BC3 in DirectX 10, RGBA compression: 4:1, 16 bytes per block) */ 00109 LATC1 = 19, /**< 1 component texture compression (also known as 3DC+/ATI1N, known as BC4 in DirectX 10, 8 bytes per block) */ 00110 LATC2 = 20, /**< 2 component texture compression (luminance & alpha compression 4:1 -> normal map compression, also known as 3DC/ATI2N, known as BC5 in DirectX 10, 16 bytes per block) */ 00111 // Floating-point formats 00112 L16F = 21, /**< 16-bit float format using 16 bits for luminance */ 00113 L32F = 22, /**< 32-bit float format using 32 bits for luminance */ 00114 R16G16B16A16F = 23, /**< 64-bit float format using 16 bits for the each channel (red, green, blue, alpha) */ 00115 R32G32B32A32F = 24, /**< 128-bit float format using 32 bits for the each channel (red, green, blue, alpha) */ 00116 // End 00117 Unknown = 25 /**< Unknown texture buffer pixel format */ 00118 }; 00119 static const PLCore::uint32 NumOfPixelFormats = 25; /**< Number of pixel formats */ 00120 00121 00122 //[-------------------------------------------------------] 00123 //[ Public static functions ] 00124 //[-------------------------------------------------------] 00125 public: 00126 /** 00127 * @brief 00128 * Returns the texture buffer pixel format of a given image (PLGraphics::Image) 00129 * 00130 * @param[in] cImage 00131 * Image to get the texture buffer pixel format from 00132 * @param[in] bNoCompression 00133 * Do NOT use texture buffer compression? 00134 * 00135 * @return 00136 * The texture buffer pixel format of the given image 00137 */ 00138 static PLRENDERER_API EPixelFormat GetFormatFromImage(const PLGraphics::Image &cImage, bool bNoCompression = false); 00139 00140 /** 00141 * @brief 00142 * Returns whether or not the given texture buffer format is compressed 00143 * 00144 * @param[in] nFormat 00145 * Texture buffer pixel format 00146 * 00147 * @return 00148 * 'true' if the texture buffer format is compressed, else 'false' 00149 */ 00150 static PLRENDERER_API bool IsCompressedFormat(EPixelFormat nFormat); 00151 00152 /** 00153 * @brief 00154 * Returns whether or not the given texture buffer format is a depth buffer format 00155 * 00156 * @param[in] nFormat 00157 * Texture buffer pixel format 00158 * 00159 * @return 00160 * 'true' if the texture buffer format is a depth buffer format, else 'false' 00161 */ 00162 static PLRENDERER_API bool IsDepthFormat(EPixelFormat nFormat); 00163 00164 /** 00165 * @brief 00166 * If the given texture buffer format is compressed, a proper uncompressed texture buffer format will be returned 00167 * 00168 * @param[in] nFormat 00169 * Texture buffer pixel format 00170 * 00171 * @return 00172 * Uncompressed texture buffer format, if the given format was not compressed, the given format will be returned 00173 */ 00174 static PLRENDERER_API EPixelFormat GetUncompressedFormat(EPixelFormat nFormat); 00175 00176 /** 00177 * @brief 00178 * Returns whether or not the given texture buffer format is a floating point format 00179 * 00180 * @param[in] nFormat 00181 * Texture buffer pixel format 00182 * 00183 * @return 00184 * 'true' if the texture buffer format is a floating point format, else 'false' 00185 */ 00186 static PLRENDERER_API bool IsFloatingPointFormat(EPixelFormat nFormat); 00187 00188 /** 00189 * @brief 00190 * Returns the number of components per pixel 00191 * 00192 * @param[in] nFormat 00193 * Texture buffer pixel format 00194 * 00195 * @return 00196 * The number of components per pixel, 0 if unknown format 00197 */ 00198 static PLRENDERER_API PLCore::uint32 GetComponentsPerPixel(EPixelFormat nFormat); 00199 00200 /** 00201 * @brief 00202 * Returns the number of bytes per pixel component 00203 * 00204 * @param[in] nFormat 00205 * Texture buffer pixel format 00206 * 00207 * @return 00208 * The number of bytes per pixel component, 0 if unknown format or no full byte per component 00209 */ 00210 static PLRENDERER_API PLCore::uint32 GetBytesPerPixelComponent(EPixelFormat nFormat); 00211 00212 /** 00213 * @brief 00214 * Returns the number of bytes per pixel 00215 * 00216 * @param[in] nFormat 00217 * Texture buffer pixel format 00218 * 00219 * @return 00220 * The number of bytes per pixel, 0 if unknown format or no full byte per pixel (compressed format) 00221 */ 00222 static PLRENDERER_API PLCore::uint32 GetBytesPerPixel(EPixelFormat nFormat); 00223 00224 00225 //[-------------------------------------------------------] 00226 //[ Public functions ] 00227 //[-------------------------------------------------------] 00228 public: 00229 /** 00230 * @brief 00231 * Destructor 00232 */ 00233 PLRENDERER_API virtual ~TextureBuffer(); 00234 00235 /** 00236 * @brief 00237 * Returns the texture buffer flags 00238 * 00239 * @return 00240 * The texture buffer flags (see EFlags) 00241 */ 00242 inline PLCore::uint32 GetFlags() const; 00243 00244 /** 00245 * @brief 00246 * Returns the texture buffer pixel format 00247 * 00248 * @return 00249 * The texture buffer pixel format 00250 */ 00251 inline EPixelFormat GetFormat() const; 00252 00253 /** 00254 * @brief 00255 * Returns whether or not the used texture buffer format is compressed 00256 * 00257 * @return 00258 * 'true' if the used texture buffer format is compressed, else 'false' 00259 */ 00260 inline bool IsCompressedFormat() const; 00261 00262 /** 00263 * @brief 00264 * Returns whether or not the used texture buffer format is a depth buffer format 00265 * 00266 * @return 00267 * 'true' if the used texture buffer format is a depth buffer format, else 'false' 00268 */ 00269 inline bool IsDepthFormat() const; 00270 00271 /** 00272 * @brief 00273 * If the used texture buffer format is compressed, a proper uncompressed texture buffer format will be returned 00274 * 00275 * @return 00276 * Uncompressed texture buffer format, if the used format was not compressed, the used format will be returned 00277 */ 00278 inline EPixelFormat GetUncompressedFormat() const; 00279 00280 /** 00281 * @brief 00282 * Returns whether or not the used texture buffer format is a floating point format 00283 * 00284 * @return 00285 * 'true' if the texture buffer format is a floating point format, else 'false' 00286 */ 00287 inline bool IsFloatingPointFormat() const; 00288 00289 /** 00290 * @brief 00291 * Returns the number of components per pixel 00292 * 00293 * @return 00294 * The number of components per pixel, 0 if unknown format 00295 */ 00296 inline PLCore::uint32 GetComponentsPerPixel() const; 00297 00298 /** 00299 * @brief 00300 * Returns the number of bytes per pixel component 00301 * 00302 * @return 00303 * The number of bytes per pixel component, 0 if unknown format or no full byte per component 00304 */ 00305 inline PLCore::uint32 GetBytesPerPixelComponent() const; 00306 00307 /** 00308 * @brief 00309 * Returns the number of bytes per pixel 00310 * 00311 * @return 00312 * The number of bytes per pixel, 0 if unknown format or no full byte per pixel (compressed format) 00313 */ 00314 inline PLCore::uint32 GetBytesPerPixel() const; 00315 00316 /** 00317 * @brief 00318 * Returns the number of mipmap levels 00319 * 00320 * @return 00321 * The number of mipmap levels, 0 if there are no mipmaps 00322 * (maybe not supported or not desired for this texture buffer) 00323 * 00324 * @remarks 00325 * Level 0 is the 'original' base image and GetNumOfMipmaps() is the version with the lowest resolution 00326 * which is normally 1x1. For a 2D texture buffer, the number of mipmaps down to 1x1 is calculated by 00327 * log2(max(width, height)). For a 32x16 texture buffer, this will result in the following additional 00328 * mipmaps: 16x8, 8x4, 4x2, 2x1, 1x1 00329 * 00330 * Note that mipmaps are only created/used from a given image if the flag 'Mipmaps' is set. 00331 */ 00332 inline PLCore::uint32 GetNumOfMipmaps() const; 00333 00334 /** 00335 * @brief 00336 * Returns the number of faces 00337 * 00338 * @return 00339 * The number of faces, always >0! 00340 */ 00341 inline PLCore::uint8 GetNumOfFaces() const; 00342 00343 /** 00344 * @brief 00345 * Returns the total number of pixels including all mipmaps 00346 * 00347 * @return 00348 * The total number of pixels including all mipmaps 00349 */ 00350 PLRENDERER_API PLCore::uint32 GetTotalNumOfPixels() const; 00351 00352 /** 00353 * @brief 00354 * Returns the total number of bytes required for the texture buffer data including all mipmaps 00355 * 00356 * @return 00357 * The number of bytes required for the texture buffer data including all mipmaps 00358 * 00359 * @note 00360 * - If the texture buffer is using a compressed format, compression is also taken into account 00361 */ 00362 inline PLCore::uint32 GetTotalNumOfBytes() const; 00363 00364 /** 00365 * @brief 00366 * Returns the image (PLGraphics::Image) settings required to be able to store the texture buffer data within an image 00367 * 00368 * @param[out] nDataFormat 00369 * Receives the required image data format 00370 * @param[out] nColorFormat 00371 * Receives the required image color format 00372 * @param[out] nCompression 00373 * Receives the required image compression 00374 * @param[out] nTextureBufferFomat 00375 * Receives the required texture buffer format to use within "TextureBuffer::Download()" in order to ask the GPU for the texture buffer data 00376 * 00377 * @return 00378 * 'true' if all went fine, else 'false' 00379 * 00380 * @remarks 00381 * This method maps the internal texture buffer format as close as possible to image data format and image color format. 00382 * -> We may also need to choose another texture buffer format for the GPU texture buffer data request 00383 * -> We can't e.g. just change PLGraphics in order to use the same pixel format scheme as the texture buffer 00384 * because PLGraphics has to be generic, while texture buffer has to support special GPU formats usually not 00385 * used in generic image processing 00386 */ 00387 PLRENDERER_API bool GetFormatForImage(PLGraphics::EDataFormat &nDataFormat, PLGraphics::EColorFormat &nColorFormat, PLGraphics::ECompression &nCompression, EPixelFormat &nTextureBufferFomat) const; 00388 00389 /** 00390 * @brief 00391 * Returns the texture buffer data as image 00392 * 00393 * @param[out] cImage 00394 * Receives the texture buffer data (no need to allocated the image, this is done automatically, just pass in any image instance) 00395 * 00396 * @return 00397 * 'true' if all went fine, else 'false' 00398 */ 00399 PLRENDERER_API bool DownloadAsImage(PLGraphics::Image &cImage) const; 00400 00401 /** 00402 * @brief 00403 * Downloads the texture buffer content and returns the number of NAN values in it 00404 * 00405 * @param[in] nMipmap 00406 * Mipmap level (0 - GetNumOfMipmaps()) 00407 * @param[in] nFace 00408 * ID of the texture buffer face which should be downloaded if this is a cube texture buffer 00409 * 00410 * @return 00411 * Number of NAN values (pixel components are counted individually) 00412 * 00413 * @remarks 00414 * If there are NAN values inside a texture buffer used for rendering, nasty "black boxes" (NVIDIA) or 00415 * "white boxes" (ATI) may appear. This function may help you to pinpoint the place were the NANs are produces. 00416 * 00417 * @note 00418 * - This function can only be used if the texture buffer format is a floating point one 00419 * - This function should only be used for debugging 00420 */ 00421 PLRENDERER_API PLCore::uint32 GetNumOfNANValues(PLCore::uint32 nMipmap = 0, PLCore::uint8 nFace = 0) const; 00422 00423 /** 00424 * @brief 00425 * Downloads the texture buffer content, replaces pixels containing a NAN value by a given color, and uploads the fixed texture buffer 00426 * 00427 * @param[in] cColor 00428 * Color for pixels containing a NAN value 00429 * @param[in] nMipmap 00430 * Mipmap level (0 - GetNumOfMipmaps()) 00431 * @param[in] nFace 00432 * ID of the texture buffer face which should be fixed if this is a cube texture buffer 00433 * 00434 * @return 00435 * Number of fixed NAN pixels 00436 * 00437 * @see 00438 * - GetNumOfNANValues() 00439 */ 00440 PLRENDERER_API PLCore::uint32 FixNANValues(const PLGraphics::Color4 &cColor, PLCore::uint32 nMipmap = 0, PLCore::uint8 nFace = 0); 00441 00442 00443 //[-------------------------------------------------------] 00444 //[ Public virtual TextureBuffer functions ] 00445 //[-------------------------------------------------------] 00446 public: 00447 /** 00448 * @brief 00449 * Returns whether or not the texture has a power of two dimension (POT) 00450 * 00451 * @return 00452 * 'true' if the texture has a power of two dimension, else 'false' 00453 * 00454 * @remarks 00455 * Although modern graphics APIs and graphics hardware is often capable to deal with 00456 * non power of two dimension, there might be certain restrictions up to unexpected 00457 * driver crashes within certain situations. This methods exists to make it easier 00458 * to check for this sort of texture dimension. A texture is only power of two when 00459 * it's power of two along each axis - except array textures which are considered 00460 * to be a stack of 2D textures. 00461 */ 00462 virtual bool IsPowerOfTwo() const = 0; 00463 00464 /** 00465 * @brief 00466 * Returns the number of pixels of a certain mipmap level 00467 * 00468 * @param[in] nMipmap 00469 * Mipmap level (0 - GetNumOfMipmaps()) 00470 * 00471 * @return 00472 * The number of pixels of a certain mipmap level 00473 * 00474 * @note 00475 * - If this is a cube texture, the number of pixels of all faces together will be returned 00476 */ 00477 virtual PLCore::uint32 GetNumOfPixels(PLCore::uint32 nMipmap = 0) const = 0; 00478 00479 /** 00480 * @brief 00481 * Returns the number of bytes required to hold certain mipmap level texture buffer data 00482 * 00483 * @param[in] nMipmap 00484 * Mipmap level (0 - GetNumOfMipmaps()) 00485 * @param[in] nFormat 00486 * Target texture buffer pixel format, if Unknown, the format of THIS texture buffer is chosen automatically 00487 * 00488 * @return 00489 * The number of bytes required to hold certain mipmap level texture buffer data 00490 * 00491 * @note 00492 * - If 'nFormat' is a compressed format, compression is also taken into account 00493 * - If this is a cube texture, the number of bytes of all faces together will be returned 00494 */ 00495 virtual PLCore::uint32 GetNumOfBytes(PLCore::uint32 nMipmap = 0, EPixelFormat nFormat = Unknown) const = 0; 00496 00497 /** 00498 * @brief 00499 * Uploads data to the GPU 00500 * 00501 * @param[in] nMipmap 00502 * Mipmap level (0 - GetNumOfMipmaps()) 00503 * @param[in] nFormat 00504 * Texture buffer pixel format of 'pData', can not be 'Unknown'. If this is a compressed format, 00505 * it MUST be the same format this texture buffer has. 00506 * @param[in] pData 00507 * Pointer to the data to upload, MUST have at least GetNumOfBytes(nMipmap, nFormat) bytes! 00508 * @param[in] nFace 00509 * ID of the texture buffer face which should be uploaded if this is a cube texture buffer 00510 * 00511 * @return 00512 * 'true' if all went fine, else 'false' (invalid mipmap level? invalid data?) 00513 */ 00514 virtual bool Upload(PLCore::uint32 nMipmap, EPixelFormat nFormat, const void *pData, PLCore::uint8 nFace = 0) = 0; 00515 00516 /** 00517 * @brief 00518 * Downloads data from the GPU 00519 * 00520 * @param[in] nMipmap 00521 * Mipmap level (0 - GetNumOfMipmaps()) 00522 * @param[in] nFormat 00523 * Texture buffer pixel format of 'pData', can not be 'Unknown'. If this is a compressed format, 00524 * it MUST be the same format this texture buffer has. 00525 * @param[out] pData 00526 * Will receive the downloaded data, MUST have at least GetNumOfBytes(nMipmap, nFormat) bytes! 00527 * @param[in] nFace 00528 * ID of the texture buffer face which should be downloaded if this is a cube texture buffer 00529 * 00530 * @return 00531 * 'true' if all went fine, else 'false' (invalid mipmap level? invalid data?) 00532 */ 00533 virtual bool Download(PLCore::uint32 nMipmap, EPixelFormat nFormat, void *pData, PLCore::uint8 nFace = 0) const = 0; 00534 00535 00536 //[-------------------------------------------------------] 00537 //[ Protected functions ] 00538 //[-------------------------------------------------------] 00539 protected: 00540 /** 00541 * @brief 00542 * Constructor 00543 * 00544 * @param[in] cRenderer 00545 * Owner renderer 00546 * @param[in] nType 00547 * Resource type 00548 * @param[in] nFlags 00549 * Texture buffer flags (see EFlags) 00550 */ 00551 PLRENDERER_API TextureBuffer(Renderer &cRenderer, EType nType, PLCore::uint32 nFlags); 00552 00553 00554 //[-------------------------------------------------------] 00555 //[ Protected virtual TextureBuffer functions ] 00556 //[-------------------------------------------------------] 00557 protected: 00558 /** 00559 * @brief 00560 * Makes this texture buffer to the renderers current texture buffer 00561 * 00562 * @param[in] nStage 00563 * Texture stage 00564 * 00565 * @return 00566 * 'true' if all went fine, else 'false' 00567 */ 00568 virtual bool MakeCurrent(PLCore::uint32 nStage) = 0; 00569 00570 00571 //[-------------------------------------------------------] 00572 //[ Protected data ] 00573 //[-------------------------------------------------------] 00574 protected: 00575 PLCore::uint32 m_nFlags; /**< Texture buffer flags (see EFlags) */ 00576 EPixelFormat m_nFormat; /**< Texture buffer pixel format */ 00577 PLCore::uint32 m_nNumOfElements; /**< The number of elements */ 00578 PLCore::uint32 m_nNumOfMipmaps; /**< Number of mipmap levels (the base level is 0) */ 00579 PLCore::uint32 m_nTotalNumOfBytes; /**< Total number of bytes required to the texture buffer data including all mipmaps */ 00580 00581 00582 //[-------------------------------------------------------] 00583 //[ Private functions ] 00584 //[-------------------------------------------------------] 00585 private: 00586 /** 00587 * @brief 00588 * Copy constructor 00589 * 00590 * @param[in] cSource 00591 * Source to copy from 00592 */ 00593 TextureBuffer(const TextureBuffer &cSource); 00594 00595 /** 00596 * @brief 00597 * Copy operator 00598 * 00599 * @param[in] cSource 00600 * Source to copy from 00601 * 00602 * @return 00603 * Reference to this instance 00604 */ 00605 TextureBuffer &operator =(const TextureBuffer &cSource); 00606 00607 00608 }; 00609 00610 00611 //[-------------------------------------------------------] 00612 //[ Namespace ] 00613 //[-------------------------------------------------------] 00614 } // PLRenderer 00615 00616 00617 //[-------------------------------------------------------] 00618 //[ Implementation ] 00619 //[-------------------------------------------------------] 00620 #include "PLRenderer/Renderer/TextureBuffer.inl" 00621 00622 00623 #endif // __PLRENDERER_TEXTUREBUFFER_H__
|