Commit ed0b51d1 authored by Robert Menzel's avatar Robert Menzel

added texel set and get functions for texture data

parent ea1be458
......@@ -77,6 +77,16 @@ public:
//! flips the image horizontally as some image formats have a different coordinate system as OpenGL has.
void flipHorizontally();
//! returns the texel converted to float (0..1 in case the data was int, -1..1 in case it was unsigned int).
//! If the Image had less than 4 components it get's filled with (0,0,0,1)
//! _texCoord is NOT normalized to 0..1! and gets clamped to the actual image size
//! NOTE: this might be slow, for performance get the raw pointer and work on that!
glm::vec4 getTexel( glm::uvec2 _texCoord );
//! 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 );
// ========================================================================================================= \/
// ================================================================================================= SETTERS \/
// ========================================================================================================= \/
......
......@@ -46,6 +46,188 @@ void TextureData::flipHorizontally()
size_t TextureData::getBytesPerScanline() const
{
return width*getNumberOfChannels()*getGLTypeSize(mType) + paddingBytesPerRow;
return width*getNumberOfChannels()*getGLTypeSize(mType) + paddingBytesPerRow;
}
glm::vec4 TextureData::getTexel( glm::uvec2 _texCoord )
{
// clamp negative to 0:
_texCoord.x = std::max( 0u, _texCoord.x );
_texCoord.y = std::max( 0u, _texCoord.y );
// clamp values larger than the texture size to the maximum:
_texCoord.x = std::min( 0, getWidth() );
_texCoord.y = std::min( 0, getHeight() );
// the byte offset into pData of the desired texel:
size_t texelOffset = _texCoord.y * getBytesPerScanline();
texelOffset += _texCoord.x * getNumberOfChannels()*getGLTypeSize(mType);
// default values:
glm::vec4 result = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
if ( mType == GL_BYTE ) {
GLbyte *data = (GLbyte *) (pData+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 ) {
GLshort *data = (GLshort *) (pData+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 ) {
GLubyte *data = (GLubyte *) (pData+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);
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);
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);
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);
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);
result.r = (float) data[0];
if ( getNumberOfChannels() > 1 ) result.g = (float) data[1];
if ( getNumberOfChannels() > 2 ) result.b = (float) data[2];
if ( getNumberOfChannels() > 3 ) result.a = (float) data[3];
} else {
ACGL::Utils::error() << "datatype " << mType << " not supported for getTexel! Return (0,0,0,1)." << std::endl;
}
return result;
}
void TextureData::setTexel( glm::uvec2 _texCoord, glm::vec4 _color )
{
// clamp negative to 0:
_texCoord.x = std::max( 0u, _texCoord.x );
_texCoord.y = std::max( 0u, _texCoord.y );
// clamp values larger than the texture size to the maximum:
_texCoord.x = std::min( 0, getWidth() );
_texCoord.y = std::min( 0, getHeight() );
// the byte offset into pData of the desired texel:
size_t texelOffset = _texCoord.y * getBytesPerScanline();
texelOffset += _texCoord.x * getNumberOfChannels()*getGLTypeSize(mType);
if ( mType == GL_BYTE ) {
GLbyte *data = (GLbyte *) (pData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(128.0f) );
color = glm::clamp( color, glm::ivec4(-128), glm::ivec4(127) );
data[0] = color.r;
if ( getNumberOfChannels() > 1 ) data[1] = color.g;
if ( getNumberOfChannels() > 2 ) data[2] = color.b;
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_UNSIGNED_BYTE ) {
GLshort *data = (GLshort *) (pData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(255.0f) );
color = glm::clamp( color, glm::ivec4(0), glm::ivec4(255) );
data[0] = color.r;
if ( getNumberOfChannels() > 1 ) data[1] = color.g;
if ( getNumberOfChannels() > 2 ) data[2] = color.b;
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_SHORT ) {
GLubyte *data = (GLubyte *) (pData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(32768.0f) );
color = glm::clamp( color, glm::ivec4(-32768), glm::ivec4(32767) );
data[0] = color.r;
if ( getNumberOfChannels() > 1 ) data[1] = color.g;
if ( getNumberOfChannels() > 2 ) data[2] = color.b;
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_UNSIGNED_SHORT ) {
GLushort *data = (GLushort *) (pData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(65535.0f) );
color = glm::clamp( color, glm::ivec4(0), glm::ivec4(65535) );
data[0] = color.r;
if ( getNumberOfChannels() > 1 ) data[1] = color.g;
if ( getNumberOfChannels() > 2 ) data[2] = color.b;
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_INT ) {
GLint *data = (GLint *) (pData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(2147483648.0f) );
color = glm::clamp( color, glm::ivec4(-2147483648), glm::ivec4(2147483647) );
data[0] = color.r;
if ( getNumberOfChannels() > 1 ) data[1] = color.g;
if ( getNumberOfChannels() > 2 ) data[2] = color.b;
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_UNSIGNED_INT ) {
GLuint *data = (GLuint *) (pData+texelOffset);
glm::ivec4 color = glm::ivec4( _color * glm::vec4(4294967295.0f) );
color = glm::clamp( color, glm::ivec4(0), glm::ivec4(4294967295) );
data[0] = color.r;
if ( getNumberOfChannels() > 1 ) data[1] = color.g;
if ( getNumberOfChannels() > 2 ) data[2] = color.b;
if ( getNumberOfChannels() > 3 ) data[3] = color.a;
} else if ( mType == GL_FLOAT ) {
GLfloat *data = (GLfloat *) (pData+texelOffset);
data[0] = _color.r;
if ( getNumberOfChannels() > 1 ) data[1] = _color.g;
if ( getNumberOfChannels() > 2 ) data[2] = _color.b;
if ( getNumberOfChannels() > 3 ) data[3] = _color.a;
} else if ( mType == GL_DOUBLE ) {
GLdouble *data = (GLdouble *) (pData+texelOffset);
data[0] = (float) _color.r;
if ( getNumberOfChannels() > 1 ) data[1] = (float) _color.g;
if ( getNumberOfChannels() > 2 ) data[2] = (float) _color.b;
if ( getNumberOfChannels() > 3 ) data[3] = (float) _color.a;
} else {
ACGL::Utils::error() << "datatype " << mType << " not supported for setTexel!" << std::endl;
}
}
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