Commit 7443e3ad authored by Robert Menzel's avatar Robert Menzel

added support in TextureData to handle compressed texture data

parent 48019a8f
cmake @ a0eb0dda
Subproject commit 801556b2e0dee07c9661b35d9187cfe5dc3f7267
Subproject commit a0eb0dda91ce5d621d47de52bcecdd494b00e353
......@@ -72,11 +72,14 @@ public:
//! the color space in which the data is represented
ColorSpace getColorSpace() const { return mColorSpace; }
//! in bytes
//! in pixel
glm::uvec3 getSize() const { return glm::uvec3( mWidth, mHeight, mDepth ); }
//! in bytes
size_t getSizeInBytes() const;
//! the byte alignment of each pixel row, (e.g. 1, 2, 4, 8 bytes)
GLsizei getPackAlignment()const;
GLsizei getPackAlignment() const;
//! 1, 2, 3 or 4 based on format
GLsizei getNumberOfChannels() const;
......@@ -96,17 +99,21 @@ public:
//! sets one texel, if the texture has less color components than 4, the superfluous components get ignored.
//! in case the texture is int, the values from 0..1 will get scaled and clamped if needed.
void setTexel( glm::uvec2 _texCoord, glm::vec4 _color );
//! returns true if the data is stored as one of the compressed formats in OpenGL, the compression type is stored in mFormat, mType might be invalid
bool dataIsCompressed() const;
// ========================================================================================================= \/
// ================================================================================================= SETTERS \/
// ========================================================================================================= \/
public:
//! mData has to be created by new GLubyte[...] and will get deleted by this TextureData object!
void setData (GLubyte* _data) { mData = _data; }
void setData (GLubyte* _data) { mData = _data; }
void setWidth (GLsizei _width) { mWidth = _width; }
void setHeight (GLsizei _height) { mHeight = _height; }
void setDepth (GLsizei _depth) { mDepth = _depth; }
void setFormat (GLenum _format) { mFormat = _format; }
void setType (GLenum _type) { mType = _type; }
void setType (GLenum _type) { mType = _type; }
void setPadding (GLsizei _padding) { mPaddingBytesPerRow = _padding; }
void setColorSpace(ColorSpace _colorSpace) { mColorSpace = _colorSpace; }
void setSize (const glm::uvec3& _size) { mWidth = _size.x; mHeight = _size.y; mDepth = _size.z; }
......@@ -117,6 +124,9 @@ public:
private:
size_t getBytesPerScanline() const;
//! returns the size per texel in bits(!) - bits to support compressed types!
size_t getTexelSizeInBits() const;
// ========================================================================================================= \/
// ================================================================================================== FIELDS \/
// ========================================================================================================= \/
......@@ -125,7 +135,7 @@ private:
GLsizei mHeight;
GLsizei mDepth;
GLenum mFormat; // channel types and count
GLenum mType; // data type
GLenum mType; // data type, invalid if the format is a compressed format
GLsizei mPaddingBytesPerRow; // number of padding bytes added per row: glReadPixel can read with padding and
// some image writers support/need this as well (e.g. QT)
ColorSpace mColorSpace;
......
......@@ -85,6 +85,9 @@ bool saveTextureDataToPPM(const SharedTextureData &_textureData, const std::stri
//! save to a PNG file with lodepng
bool saveTextureDataToLodepng( const SharedTextureData &_data, const std::string &_filename );
//! save the imagedata raw to a file
bool saveTextureDataToRAW( const SharedTextureData &_data, const std::string &_filename );
#ifdef ACGL_COMPILE_WITH_QT
bool saveTextureDataToQT( const SharedTextureData &_data, const std::string &_filename );
#endif
......
......@@ -52,9 +52,75 @@ void TextureData::flipVertically()
size_t TextureData::getBytesPerScanline() const
{
return mWidth*getNumberOfChannels()*getGLTypeSize(mType) + mPaddingBytesPerRow;
// if uncompressed -> texel size is a multiple of 8
// if compressed -> mWidth is a multiple of 4
// so this function will work for bitsizes of 2,4,8,16 etc. -> 1 bit per pixel might fail
return (mWidth*getTexelSizeInBits())/8 + mPaddingBytesPerRow;
}
size_t TextureData::getSizeInBytes() const
{
size_t s = getBytesPerScanline(); // correct even for compressed data
if (mHeight > 0) s *= mHeight;
if (mDepth > 0) s *= mDepth;
return s;
}
bool TextureData::dataIsCompressed() const
{
if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || mFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) {
// BC 1 aka DXT 1
return true;
} else if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) {
// BC 2 aka DXT 3
return true;
} else if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) {
// BC 3 aka DXT 5
return true;
} else if (mFormat == GL_COMPRESSED_RED_RGTC1 || mFormat == GL_COMPRESSED_SIGNED_RED_RGTC1) {
// BC 4
return true;
//} else if (mFormat == GL_COMPRESSED_RED_GREEN_RGTC2 || mFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2) {
// // BC 5
// return true;
//} else if (mFormat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT || mFormat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) {
// // BC 6H
// return true;
//} else if (mFormat == GL_COMPRESSED_RGBA_BPTC_UNORM || mFormat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) {
// // BC 7
// return true;
} else {
return false;
}
}
size_t TextureData::getTexelSizeInBits() const
{
if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || mFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) {
// BC 1 aka DXT 1
return 4;
} else if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) {
// BC 2 aka DXT 3
return 8;
} else if (mFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) {
// BC 3 aka DXT 5
return 8;
} else if (mFormat == GL_COMPRESSED_RED_RGTC1 || mFormat == GL_COMPRESSED_SIGNED_RED_RGTC1) {
// BC 4
return 8;
//} else if (mFormat == GL_COMPRESSED_RED_GREEN_RGTC2 || mFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2) {
// // BC 5
// return 8;
//} else if (mFormat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT || mFormat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) {
// // BC 6H
// return 8;
//} else if (mFormat == GL_COMPRESSED_RGBA_BPTC_UNORM || mFormat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) {
// // BC 7
// return 8;
} else {
return ( getNumberOfChannels()*getGLTypeSize(mType) )*8;
}
}
glm::vec4 TextureData::getTexel( glm::uvec2 _texCoord )
{
......
......@@ -136,6 +136,8 @@ bool saveTextureData(const SharedTextureData &_textureData, const std::string &_
#endif
else if (fileEnding == "ppm") {
return saveTextureDataToPPM( _textureData, _filename );
} else if (fileEnding == "raw") {
return saveTextureDataToRAW( _textureData, _filename );
} else {
error() << "texture file format of " << _filename << " not supported" << std::endl;
}
......@@ -571,6 +573,20 @@ SharedTextureData loadTextureDataFromPNM(const std::string& _filename, ColorSpac
// library specific save
///////////////////////////////////////////////////////////////////////////////////////////////////
bool saveTextureDataToRAW( const SharedTextureData &_data, const std::string &_filename )
{
std::ofstream outFileStream(_filename.c_str(), std::ios_base::out | std::ios_base::binary);
if(!outFileStream.good())
{
error() << "saveTextureDataToRAW: Could not open file " << _filename << std::endl;
return false;
}
outFileStream.write( (char*)_data->getData(), _data->getSizeInBytes() );
return true;
}
bool saveTextureDataToPPM(const SharedTextureData& _textureData, const std::string &_filename)
{
std::ofstream outFileStream(_filename.c_str(), std::ios_base::out | std::ios_base::binary);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment