#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_GRAPHICS_RASTERIZATION_PIXELFORMAT_H #define NUCLEX_GRAPHICS_RASTERIZATION_PIXELFORMAT_H #include namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // namespace PixelFormat { /// Data formats that can be used to describe a pixel /// /// /// The enum values are defined as follows: /// /// /// ssssssss pppppppp nnnnnnnn nnnnnnnn /// /// /// Where 's' indicates the size of the smallest unit addressable in the pixel format /// in bytes. For a 32 bit RGBA format, this would be 4 (if a write to the texture /// was off by two bytes, R would become B, G would become A and so on). Compressed /// pixel formats may have larger chunks - DXT5 for example would only be addressable /// in units of 16 bytes. /// /// /// The next byte, 'p' contains the number of bits per pixel. It is useful for /// calculating the amount of memory required to hold an image of size x by y. /// /// /// In the remaining two bytes, tagged as 'n', a unique id of each pixel format /// will be stored. /// /// enum Enum { /// 8 bit single color stored in the red channel R8_Unsigned = (1 << 24) | (8 << 16) | 0, /// 16 bit with two colors, each in an 8 bit channel R8_G8_Signed = (2 << 24) | (16 << 16) | 1, /// 16 bit with three colors B5_G6_R5_Unsigned = (2 << 24) | (16 << 16) | 2, // TODO: Remove this format. It looks ugly and I can use the slot for something better. /// 16 bit color with alpha using 4 bits for each channel B4_G4_R4_A4_Unsigned = (2 << 24) | (16 << 16) | 3, /// 32 bit color with alpha using 8 bits for each channel /// /// This is probably the most widely used any compatible texture format. /// R8_G8_B8_A8_Unsigned = (4 << 24) | (32 << 16) | 4, /// 32 bit color with alpha using 8 bits for each channel R8_G8_B8_A8_Signed = (4 << 24) | (32 << 16) | 5, /// Compressed RGB turning every 64 bits into 16 pixels BC1_Compressed = (8 << 24) | (4 << 16) | 1000, /// Compressed RGB with alpha turning every 128 bits into 16 pixels BC2_Compressed = (16 << 24) | (8 << 16) | 1001, /// Compressed RGB with alpha turning every 128 bits into 16 pixels BC3_Compressed = (16 << 24) | (8 << 16) | 1002, /// 8 bit alpha channel only Modern_A8_Unsigned = (1 << 24) | (8 << 16) | 2000, /// 16 bit red channel only Modern_R16_Unsigned = (2 << 24) | (16 << 16) | 2001, /// 32 bit with two 16 bit color channels Modern_R16_G16_Unsigned = (4 << 24) | (32 << 16) | 2002, /// 32 bit with two half-precision floating point color channels Modern_R16_G16_Float = (4 << 24) | (32 << 16) | 2003, /// 32 bit floating point red channel only Modern_R32_Float = (4 << 24) | (32 << 16) | 2004, /// 64 bit color with alpha using 16 bit color channels Modern_R16_G16_B16_A16_Unsigned = (8 << 24) | (64 << 16) | 2005, /// 64 bit color with alpha as half-precision floating point channels Modern_R16_G16_B16_A16_Float = (8 << 24) | (64 << 16) | 2006 }; } // namespace PixelFormat // ------------------------------------------------------------------------------------------- // /// /// Determines the smallest bits used per pixel in the specifid pixel format /// /// Pixel format whose bits per pixel will be determined /// The bits per pixel in the specified pixel format inline std::size_t CountBitsPerPixel(PixelFormat::Enum pixelFormat) { return (static_cast(pixelFormat) >> 16) & 0xFF; } // ------------------------------------------------------------------------------------------- // /// /// Determines the smallest number of bytes that can be modified in the given format /// /// Pixel format whose unit size will be determined /// The smallest changeable number of bytes in the specified pixel format inline std::size_t CountBitsPerBlock(PixelFormat::Enum pixelFormat) { return (static_cast(pixelFormat) >> 24) * 8; } // ------------------------------------------------------------------------------------------- // /// /// Determines the number of bytes required to store the specified number of pixels /// /// /// Number of pixels for which the memory required will be calculated /// /// Pixel format for which the size will be determined /// The size of a single pixel in the specified pixel format inline std::size_t CountRequiredBytes( std::size_t pixelCount, PixelFormat::Enum pixelFormat ) { return ((CountBitsPerPixel(pixelFormat) * pixelCount) + 7) / 8; // Always round up } // ------------------------------------------------------------------------------------------- // /// Determines the vertical size of a single block /// Pixel format for which the lines will be determined /// The vertical size of a single block in the specified pixel format inline std::size_t CountLinesPerBlock(PixelFormat::Enum pixelFormat) { switch(pixelFormat) { case PixelFormat::BC1_Compressed: case PixelFormat::BC2_Compressed: case PixelFormat::BC3_Compressed: { return 4; } default: { return 1; } } } // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization #endif // NUCLEX_GRAPHICS_RASTERIZATION_PIXELFORMAT_H