Skip to content
Snippets Groups Projects
Commit ed0b51d1 authored by Robert Menzel's avatar Robert Menzel
Browse files

added texel set and get functions for texture data

parent ea1be458
Branches
No related tags found
No related merge requests found
......@@ -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 \/
// ========================================================================================================= \/
......
......@@ -49,3 +49,185 @@ size_t TextureData::getBytesPerScanline() const
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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment