Commit 6d9ff644 authored by Janis Born's avatar Janis Born

some refactorings regarding texture loading with color space preference

parent 7e456138
......@@ -20,8 +20,8 @@ enum ColorSpace
COLOR_SPACE_SRGB
};
/// Converts an OpenGL color format to an equivalent format of the given color space. If there is no matching format, the format is returned unchanged.
GLenum formatToColorSpace(GLenum _inputFormat, ColorSpace _colorSpace);
//! Recommends an OpenGL internal format for a given pair of format and color spaces
GLenum recommendedInternalFormat(GLenum _format, ColorSpace _colorSpace);
} // OpenGL
} // ACGL
......
......@@ -16,6 +16,7 @@
#include <ACGL/Base/Macros.hh>
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Data/ColorSpace.hh>
#include <ACGL/OpenGL/Tools.hh>
#include <ACGL/Math/Math.hh>
......@@ -29,51 +30,59 @@ class TextureData
// ========================================================================================================= \/
public:
TextureData(void)
: pData(NULL),
width(0),
height(0),
depth(0),
format(GL_RGBA),
: mData(NULL),
mWidth(0),
mHeight(0),
mDepth(0),
mFormat(GL_RGBA),
mType(GL_UNSIGNED_BYTE),
paddingBytesPerRow(0)
mPaddingBytesPerRow(0),
mColorSpace(COLOR_SPACE_AUTO_DETECT)
{}
virtual ~TextureData(void)
{
delete[] pData;
delete[] mData;
}
// ========================================================================================================= \/
// ================================================================================================= GETTERS \/
// ========================================================================================================= \/
public:
GLubyte* getData (void) const { return pData; }
//! pointer to the raw pixel data
GLubyte* getData() const { return mData; }
//! width in pixel
GLsizei getWidth (void) const { return width; }
//! width in pixels
GLsizei getWidth() const { return mWidth; }
//! height in pixel
GLsizei getHeight (void) const { return height; }
//! height in pixels
GLsizei getHeight() const { return mHeight; }
//! depth in pixel
GLsizei getDepth (void) const { return depth; }
//! depth in pixels
GLsizei getDepth() const { return mDepth; }
//! channels etc. e.g. GL_RGB
GLenum getFormat (void) const { return format; }
//! channels etc. (e.g. GL_RGB)
GLenum getFormat() const { return mFormat; }
//! data type (e.g. GL_BYTE)
GLenum getType (void) const { return mType; }
GLenum getType() const { return mType; }
//! each line can have a few bytes of padding, number of bytes is returned
GLsizei getPadding (void) const { return paddingBytesPerRow; }
GLsizei getPadding() const { return mPaddingBytesPerRow; }
//! the color space in which the data is represented
ColorSpace getColorSpace() const { return mColorSpace; }
//! in bytes
glm::uvec3 getSize (void) const { return glm::uvec3( width, height, depth ); }
glm::uvec3 getSize() const { return glm::uvec3( mWidth, mHeight, mDepth ); }
//! the byte alignment of each pixel row, e.g. 1,2,4,8 (bytes)
//! the byte alignment of each pixel row, (e.g. 1, 2, 4, 8 bytes)
GLsizei getPackAlignment()const;
//! 1,2,3 or 4 based on format
GLsizei getNumberOfChannels() const;
//! 1, 2, 3 or 4 based on format
GLsizei getNumberOfChannels() const;
//! A recommended value for the internalFormat enum of a Texture object. Based on the format, type and color space
GLenum getRecommendedInternalFormat() const;
//! flips the image vertically as some image formats have a different coordinate system as OpenGL has. (flip it upside down)
void flipVertically();
......@@ -91,32 +100,35 @@ public:
// ================================================================================================= SETTERS \/
// ========================================================================================================= \/
public:
//! _pData has to be created by new GLubyte[...] and will get deleted by this TextureData object!
void setData (GLubyte* _pData) { pData = _pData; }
void setWidth (GLsizei _width) { width = _width; }
void setHeight(GLsizei _height) { height = _height; }
void setDepth (GLsizei _depth) { depth = _depth; }
void setFormat(GLenum _format) { format = _format; }
void setType (GLenum _type) { mType = _type; }
void setPadding(GLsizei _padding){ paddingBytesPerRow = _padding; }
void setSize (const glm::uvec3 &_size) { width = _size.x; height = _size.y; depth = _size.z; }
//! mData has to be created by new GLubyte[...] and will get deleted by this TextureData object!
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 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; }
//! deletes the data attached to this object
void deleteData() { delete[] pData; pData = NULL; }
void deleteData() { delete[] mData; mData = NULL; }
private:
size_t getBytesPerScanline() const;
// ========================================================================================================= \/
// ================================================================================================== FIELDS \/
// ========================================================================================================= \/
private:
size_t getBytesPerScanline() const;
GLubyte* pData;
GLsizei width;
GLsizei height;
GLsizei depth;
GLenum format; // channel types and count
GLenum mType; // data type
GLsizei paddingBytesPerRow; // number of padding bytes added per row: glReadPixel can read with padding and
// some image writers support/need this as well (e.g. QT)
GLubyte* mData;
GLsizei mWidth;
GLsizei mHeight;
GLsizei mDepth;
GLenum mFormat; // channel types and count
GLenum mType; // data type
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;
};
ACGL_SMARTPOINTER_TYPEDEFS(TextureData)
......
......@@ -38,7 +38,7 @@ void registerTextureLoadFunction(std::vector<std::string> _endings, TextureLoadF
void unregisterTextureLoadFunction(TextureLoadFuncPtr _function);
//! generic load function that will use one of the loading functions below based on the file ending
SharedTextureData loadTextureData(const std::string &_filename);
SharedTextureData loadTextureData(const std::string &_filename, ColorSpace _colorSpace = COLOR_SPACE_AUTO_DETECT);
//! generic save function that will use one of the saving functions below based on the file ending
bool saveTextureData(const SharedTextureData &_textureData, const std::string &_filename);
......@@ -59,21 +59,21 @@ inline bool saveScreenshotWithDate( const std::string& _fileEnding = "png" ) {
///////////////////////////////////////////////////////////////////////////////////////////////////
//! loads from a PNG using the simple lodepng library
SharedTextureData loadTextureDataFromLodepng(const std::string &_filename);
SharedTextureData loadTextureDataFromLodepng(const std::string& _filename, ColorSpace _colorSpace = COLOR_SPACE_AUTO_DETECT);
#ifdef ACGL_COMPILE_WITH_QT
//! loads various formats from the QT library
SharedTextureData loadTextureDataFromQT(const std::string &_filename);
SharedTextureData loadTextureDataFromQT(const std::string& _filename, ColorSpace _colorSpace = COLOR_SPACE_AUTO_DETECT);
#endif
//! loads RGBE aka Radiance files
SharedTextureData loadTextureDataFromRGBE(const std::string &_filename);
SharedTextureData loadTextureDataFromRGBE(const std::string& _filename, ColorSpace _colorSpace = COLOR_SPACE_AUTO_DETECT);
//! loads EXR / OpenEXR files iff the library is present AT RUNTIME (linux only)
SharedTextureData loadTextureDataFromEXR(const std::string &_filename);
SharedTextureData loadTextureDataFromEXR(const std::string& _filename, ColorSpace _colorSpace = COLOR_SPACE_AUTO_DETECT);
//! loads PNM / PPM files:
SharedTextureData loadTextureDataFromPNM(const std::string &_filename);
SharedTextureData loadTextureDataFromPNM(const std::string& _filename, ColorSpace _colorSpace = COLOR_SPACE_AUTO_DETECT);
///////////////////////////////////////////////////////////////////////////////////////////////////
// library specific save
......
......@@ -6,40 +6,10 @@
#include <ACGL/OpenGL/Data/ColorSpace.hh>
using namespace ACGL;
using namespace ACGL::OpenGL;
// Format conversion helpers
namespace
{
GLenum formatToLinear(GLenum _format)
{
switch(_format)
{
// Core
case GL_SRGB: return GL_RGB;
case GL_SRGB8: return GL_RGB8;
case GL_SRGB_ALPHA: return GL_RGBA;
case GL_SRGB8_ALPHA8: return GL_RGBA8;
case GL_COMPRESSED_SRGB: return GL_COMPRESSED_RGB;
case GL_COMPRESSED_SRGB_ALPHA: return GL_COMPRESSED_RGBA;
case GL_COMPRESSED_SRGB8_ETC2: return GL_COMPRESSED_RGB8_ETC2;
case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: return GL_COMPRESSED_RGBA8_ETC2_EAC;
case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
// EXT_texture_sRGB, EXT_texture_compression_s3tc
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
// OpenGL 4.2?
//case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: return GL_COMPRESSED_RGBA_BPTC_UNORM;
}
return _format;
}
GLenum formatToSRGB(GLenum _format)
{
switch(_format)
......@@ -69,12 +39,17 @@ GLenum formatToSRGB(GLenum _format)
}
GLenum ACGL::OpenGL::formatToColorSpace(GLenum _inputFormat, ColorSpace _colorSpace)
namespace ACGL {
namespace OpenGL {
GLenum recommendedInternalFormat(GLenum _format, ColorSpace _colorSpace)
{
switch(_colorSpace)
{
case COLOR_SPACE_LINEAR: return formatToLinear(_inputFormat);
case COLOR_SPACE_SRGB: return formatToSRGB(_inputFormat);
default: return _inputFormat;
case COLOR_SPACE_SRGB: return formatToSRGB(_format);
default: return _format;
}
}
}
}
......@@ -12,8 +12,8 @@ using namespace ACGL::OpenGL;
GLsizei TextureData::getPackAlignment() const
{
size_t dataAlignment = Utils::pointerAlignment( pData );
size_t rowAlignment = Utils::pointerAlignment( pData + getBytesPerScanline() );
size_t dataAlignment = Utils::pointerAlignment( mData );
size_t rowAlignment = Utils::pointerAlignment( mData + getBytesPerScanline() );
return std::min( dataAlignment, rowAlignment ); //minimum of the data and the begining of the second row
}
......@@ -21,7 +21,13 @@ GLsizei TextureData::getPackAlignment() const
GLsizei TextureData::getNumberOfChannels() const
{
return ACGL::OpenGL::getNumberOfChannels( format );
return ACGL::OpenGL::getNumberOfChannels( mFormat );
}
GLenum TextureData::getRecommendedInternalFormat() const
{
return recommendedInternalFormat(mFormat, mColorSpace);
}
......@@ -30,11 +36,11 @@ void TextureData::flipVertically()
size_t scanlineInBytes = getBytesPerScanline();
GLubyte *tmpScanLine = new GLubyte[ scanlineInBytes ];
for (GLsizei line = 0; line < height/2; ++line) {
for (GLsizei line = 0; line < mHeight/2; ++line) {
size_t topLine = line;
size_t bottomLine = height - line - 1;
void *topLinePtr = pData + topLine*scanlineInBytes;
void *bottomLinePtr = pData + bottomLine*scanlineInBytes;
size_t bottomLine = mHeight - line - 1;
void *topLinePtr = mData + topLine*scanlineInBytes;
void *bottomLinePtr = mData + bottomLine*scanlineInBytes;
memcpy( tmpScanLine, topLinePtr, scanlineInBytes ); // top -> tmp
memcpy( topLinePtr, bottomLinePtr, scanlineInBytes ); // bottom -> top
memcpy( bottomLinePtr, tmpScanLine, scanlineInBytes ); // tmp -> bottom
......@@ -46,7 +52,7 @@ void TextureData::flipVertically()
size_t TextureData::getBytesPerScanline() const
{
return width*getNumberOfChannels()*getGLTypeSize(mType) + paddingBytesPerRow;
return mWidth*getNumberOfChannels()*getGLTypeSize(mType) + mPaddingBytesPerRow;
}
......@@ -68,56 +74,56 @@ glm::vec4 TextureData::getTexel( glm::uvec2 _texCoord )
glm::vec4 result = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
if ( mType == GL_BYTE ) {
GLbyte *data = (GLbyte *) (pData+texelOffset);
GLbyte *data = (GLbyte *) (mData+texelOffset);
result.r = data[0]/128.0f; // to -1..1
if ( getNumberOfChannels() > 1 ) result.g = data[1]/128.0f;
if ( getNumberOfChannels() > 2 ) result.b = data[2]/128.0f;
if ( getNumberOfChannels() > 3 ) result.a = data[3]/128.0f;
} else if ( mType == GL_UNSIGNED_BYTE ) {
GLubyte *data = (GLubyte *) (pData+texelOffset);
GLubyte *data = (GLubyte *) (mData+texelOffset);
result.r = data[0]/255.0f; // to 0..1
if ( getNumberOfChannels() > 1 ) result.g = data[1]/255.0f;
if ( getNumberOfChannels() > 2 ) result.b = data[2]/255.0f;
if ( getNumberOfChannels() > 3 ) result.a = data[3]/255.0f;
} else if ( mType == GL_SHORT ) {
GLshort *data = (GLshort *) (pData+texelOffset);
GLshort *data = (GLshort *) (mData+texelOffset);
result.r = data[0]/32768.0f; // to -1..1
if ( getNumberOfChannels() > 1 ) result.g = data[1]/32768.0f;
if ( getNumberOfChannels() > 2 ) result.b = data[2]/32768.0f;
if ( getNumberOfChannels() > 3 ) result.a = data[3]/32768.0f;
} else if ( mType == GL_UNSIGNED_SHORT ) {
GLushort *data = (GLushort *) (pData+texelOffset);
GLushort *data = (GLushort *) (mData+texelOffset);
result.r = data[0]/65535.0f; // to 0..1
if ( getNumberOfChannels() > 1 ) result.g = data[1]/65535.0f;
if ( getNumberOfChannels() > 2 ) result.b = data[2]/65535.0f;
if ( getNumberOfChannels() > 3 ) result.a = data[3]/65535.0f;
} else if ( mType == GL_INT ) {
GLint *data = (GLint *) (pData+texelOffset);
GLint *data = (GLint *) (mData+texelOffset);
result.r = data[0]/2147483648.0f; // to -1..1
if ( getNumberOfChannels() > 1 ) result.g = data[1]/2147483648.0f;
if ( getNumberOfChannels() > 2 ) result.b = data[2]/2147483648.0f;
if ( getNumberOfChannels() > 3 ) result.a = data[3]/2147483648.0f;
} else if ( mType == GL_UNSIGNED_INT ) {
GLuint *data = (GLuint *) (pData+texelOffset);
GLuint *data = (GLuint *) (mData+texelOffset);
result.r = data[0]/4294967295.0f; // to 0..1
if ( getNumberOfChannels() > 1 ) result.g = data[1]/4294967295.0f;
if ( getNumberOfChannels() > 2 ) result.b = data[2]/4294967295.0f;
if ( getNumberOfChannels() > 3 ) result.a = data[3]/4294967295.0f;
} else if ( mType == GL_FLOAT ) {
GLfloat *data = (GLfloat *) (pData+texelOffset);
GLfloat *data = (GLfloat *) (mData+texelOffset);
result.r = data[0];
if ( getNumberOfChannels() > 1 ) result.g = data[1];
if ( getNumberOfChannels() > 2 ) result.b = data[2];
if ( getNumberOfChannels() > 3 ) result.a = data[3];
} else if ( mType == GL_DOUBLE ) {
GLdouble *data = (GLdouble *) (pData+texelOffset);
GLdouble *data = (GLdouble *) (mData+texelOffset);
result.r = (float) data[0];
if ( getNumberOfChannels() > 1 ) result.g = (float) data[1];
if ( getNumberOfChannels() > 2 ) result.b = (float) data[2];
......@@ -132,7 +138,7 @@ glm::vec4 TextureData::getTexel( glm::uvec2 _texCoord )
void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
{
assert( pData && "can't set texels if there is no data store, define data using setData()" );
assert( mData && "can't set texels if there is no data store, define data using setData()" );
// clamp negative to 0:
_texCoord.x = std::max( 0u, _texCoord.x );
_texCoord.y = std::max( 0u, _texCoord.y );
......@@ -146,7 +152,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
texelOffset += _texCoord.x * getNumberOfChannels()*getGLTypeSize(mType);
if ( mType == GL_BYTE ) {
GLbyte *data = (GLbyte *) (pData+texelOffset);
GLbyte *data = (GLbyte *) (mData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(128.0f) );
color = glm::clamp( color, glm::ivec4(-128), glm::ivec4(127) );
......@@ -157,7 +163,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_UNSIGNED_BYTE ) {
GLubyte *data = (GLubyte *) (pData+texelOffset);
GLubyte *data = (GLubyte *) (mData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(255.0f) );
color = glm::clamp( color, glm::ivec4(0), glm::ivec4(255) );
......@@ -168,7 +174,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_SHORT ) {
GLshort *data = (GLshort *) (pData+texelOffset);
GLshort *data = (GLshort *) (mData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(32768.0f) );
color = glm::clamp( color, glm::ivec4(-32768), glm::ivec4(32767) );
......@@ -179,7 +185,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_UNSIGNED_SHORT ) {
GLushort *data = (GLushort *) (pData+texelOffset);
GLushort *data = (GLushort *) (mData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(65535.0f) );
color = glm::clamp( color, glm::ivec4(0), glm::ivec4(65535) );
......@@ -190,7 +196,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_INT ) {
GLint *data = (GLint *) (pData+texelOffset);
GLint *data = (GLint *) (mData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(2147483648.0f) );
color = glm::clamp( color, glm::ivec4(-2147483648), glm::ivec4(2147483647) );
......@@ -201,7 +207,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_UNSIGNED_INT ) {
GLuint *data = (GLuint *) (pData+texelOffset);
GLuint *data = (GLuint *) (mData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(4294967295.0f) );
color = glm::clamp( color, glm::ivec4(0), glm::ivec4(4294967295) );
......@@ -212,7 +218,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_FLOAT ) {
GLfloat *data = (GLfloat *) (pData+texelOffset);
GLfloat *data = (GLfloat *) (mData+texelOffset);
data[0] = _color.r;
if ( getNumberOfChannels() > 1 ) data[1] = _color.g;
......@@ -220,7 +226,7 @@ void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
if ( getNumberOfChannels() > 3 ) data[3] = _color.a;
} else if ( mType == GL_DOUBLE ) {
GLdouble *data = (GLdouble *) (pData+texelOffset);
GLdouble *data = (GLdouble *) (mData+texelOffset);
data[0] = (float) _color.r;
if ( getNumberOfChannels() > 1 ) data[1] = (float) _color.g;
......
......@@ -85,35 +85,37 @@ void unregisterTextureLoadFunction(TextureLoadFuncPtr _function)
}
}
SharedTextureData loadTextureData(const std::string &_filename)
SharedTextureData loadTextureData(const std::string &_filename, ColorSpace _colorSpace)
{
// lower case file ending:
std::string fileEnding = getFileEnding( _filename );
if(textureLoadFunctions.find(fileEnding) != textureLoadFunctions.end())
return textureLoadFunctions[fileEnding](_filename);
if (fileEnding == "png") {
return loadTextureDataFromLodepng( _filename );
SharedTextureData textureData;
if(textureLoadFunctions.find(fileEnding) != textureLoadFunctions.end()) {
textureData = textureLoadFunctions[fileEnding](_filename);
} else if (fileEnding == "png") {
textureData = loadTextureDataFromLodepng( _filename );
} else if (fileEnding == "hdr") {
return loadTextureDataFromRGBE( _filename );
textureData = loadTextureDataFromRGBE( _filename );
} else if (fileEnding == "exr") {
return loadTextureDataFromEXR( _filename );
textureData = loadTextureDataFromEXR( _filename );
} else if (fileEnding == "ppm") {
return loadTextureDataFromPNM( _filename );
textureData = loadTextureDataFromPNM( _filename );
}
#ifdef ACGL_COMPILE_WITH_QT
else if ( fileEnding == "bmp" || fileEnding == "jpg" || fileEnding == "jpeg"
|| fileEnding == "png" || fileEnding == "pbm" || fileEnding == "ppm"
|| fileEnding == "tif" || fileEnding == "tiff"|| fileEnding == "xbm"
|| fileEnding == "xpm" || fileEnding == "pgm") {
return loadTextureDataFromQT( _filename );
textureData = loadTextureDataFromQT( _filename );
}
#endif
else {
error() << "texture file format of " << _filename << " not supported" << std::endl;
}
return SharedTextureData();
return textureData;
}
bool saveTextureData(const SharedTextureData &_textureData, const std::string &_filename)
......@@ -193,7 +195,7 @@ public:
size_t mSize;
};
SharedTextureData loadTextureDataFromLodepng(const std::string &_filename)
SharedTextureData loadTextureDataFromLodepng(const std::string &_filename, ColorSpace _colorSpace)
{
SharedTextureData data;
......@@ -264,6 +266,7 @@ SharedTextureData loadTextureDataFromLodepng(const std::string &_filename)
data->setHeight(height);
data->setType(glType);
data->setFormat(glFormat);
data->setColorSpace(_colorSpace); // no auto-detection
// Flip
data->flipVertically();
......@@ -279,7 +282,7 @@ SharedTextureData loadTextureDataFromLodepng(const std::string &_filename)
#ifdef ACGL_COMPILE_WITH_QT
//! loads from the QT library
SharedTextureData loadTextureDataFromQT(const std::string &_filename)
SharedTextureData loadTextureDataFromQT(const std::string& _filename, ColorSpace _colorSpace)
{
SharedTextureData data = SharedTextureData( new TextureData() );
......@@ -297,12 +300,13 @@ SharedTextureData loadTextureDataFromQT(const std::string &_filename)
data->setData( pImageData );
data->setWidth( image.width() );
data->setHeight( image.height() );
data->setColorSpace(_colorSpace); // no auto-detection
return data;
}
#endif
SharedTextureData loadTextureDataFromRGBE(const std::string &_filename)
SharedTextureData loadTextureDataFromRGBE(const std::string& _filename, ColorSpace _colorSpace)
{
SharedTextureData data = SharedTextureData( new TextureData() );
......@@ -319,11 +323,12 @@ SharedTextureData loadTextureDataFromRGBE(const std::string &_filename)
data->setWidth( texWidth );
data->setFormat( GL_RGB );
data->setType( GL_FLOAT );
data->setColorSpace(_colorSpace); // no auto-detection
return data;
}
SharedTextureData loadTextureDataFromEXR(const std::string &_filename)
SharedTextureData loadTextureDataFromEXR(const std::string& _filename, ColorSpace _colorSpace)
{
#ifndef ACGL_BUILD_WITH_EXR
error() << "can't load EXR file " << _filename << " ACGL was not build with EXR support" << std::endl;
......@@ -352,6 +357,7 @@ SharedTextureData loadTextureDataFromEXR(const std::string &_filename)
data->setWidth( dimension.x );
data->setFormat( GL_RGBA );
data->setType( GL_HALF_FLOAT );
data->setColorSpace(_colorSpace); // no auto-detection
} catch(Iex::BaseExc &e) {
error() << "EXR loading failed: " << e.what() << std::endl;
return SharedTextureData();
......@@ -394,7 +400,7 @@ std::istream& loadTextureDataFromPNM_filterPNMComments(std::istream& _in)
return _in;
}
SharedTextureData loadTextureDataFromPNM(const std::string &_filename)
SharedTextureData loadTextureDataFromPNM(const std::string& _filename, ColorSpace _colorSpace)
{
std::ifstream fileStream( _filename.c_str() );
......@@ -403,7 +409,7 @@ SharedTextureData loadTextureDataFromPNM(const std::string &_filename)
return SharedTextureData();
}
SharedTextureData texture = SharedTextureData( new TextureData() );
SharedTextureData textureData = SharedTextureData( new TextureData() );
// Read the PNM header
std::string header;
......@@ -545,18 +551,19 @@ SharedTextureData loadTextureDataFromPNM(const std::string &_filename)
return SharedTextureData();
}
texture->setData(data); // data will get deleted by the TextureData destructor!
texture->setDepth(1); // 2D so, depth is 1
texture->setHeight(height);
texture->setWidth(width);
textureData->setData(data); // data will get deleted by the TextureData destructor!
textureData->setDepth(1); // 2D so, depth is 1
textureData->setHeight(height);
textureData->setWidth(width);
#ifdef ACGL_OPENGL_ES
texture->setFormat(GL_RGB);
#else
texture->setFormat(components == 3 ? GL_RGB : GL_RED);
textureData->setFormat(components == 3 ? GL_RGB : GL_RED);
#endif
texture->setType(outputDataType);
textureData->setType(outputDataType);
textureData->setColorSpace(_colorSpace); // no auto-detection
return texture;
return textureData;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
......
......@@ -25,17 +25,19 @@ SharedTexture2D loadTexture2D(const std::string& _filename, ColorSpace _colorSpa
}
else
{
SharedTexture2D texture = std::make_shared<Texture2D>();
SharedTextureData data = loadTextureData(_filename);
if (!data) {
ACGL::Utils::error() << "can't create Texture from file " << _filename << " creating small empty texture instead." << std::endl;
texture->resize( glm::uvec2(4,4) );
} else {
SharedTextureData data = loadTextureData(_filename, _colorSpace);