Commit 679894cc authored by Robert Menzel's avatar Robert Menzel

added more texture functions, texture readback

parent e758bf11
......@@ -168,6 +168,14 @@ public:
//! Generate mipmaps from the current base texture (i.e. the texture from level 0)
void generateMipmaps(void);
#ifndef ACGL_OPENGLES_VERSION_20
//! get one texture image:
TextureData *getTextureImageRAW( const Image &_image = Image(), GLenum _format = GL_RGBA, GLenum _type = GL_UNSIGNED_BYTE ) const;
SharedTextureData getTextureImage( const Image &_image = Image(), GLenum _format = GL_RGBA, GLenum _type = GL_UNSIGNED_BYTE ) const {
return SharedTextureData( getTextureImageRAW(_image, _format, _type) );
}
#endif // ES 2
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
......@@ -199,6 +207,9 @@ protected:
//! to be used by subclasses, will not check if usage is meaningfull for the
//! texture target, this has to be checked by the subclass (this is why this
//! function is private here)
void texImage1D( const SharedTextureData &_data, GLint _mipmapLevel );
void texSubImage1D( const SharedTextureData &_data, GLint _mipmapLevel, uint32_t _offset = 0 );
void texImage2D( const SharedTextureData &_data, GLint _mipmapLevel );
void texSubImage2D( const SharedTextureData &_data, GLint _mipmapLevel, glm::ivec2 _offset = glm::ivec2(0) );
......@@ -214,7 +225,7 @@ protected:
ACGL_SMARTPOINTER_TYPEDEFS(TextureBase)
// missing classes:
// GL_TEXTURE_1D
// GL_TEXTURE_1D x
// GL_TEXTURE_2D x
// GL_TEXTURE_3D
// GL_TEXTURE_1D_ARRAY
......@@ -253,6 +264,25 @@ private:
ACGL_SMARTPOINTER_TYPEDEFS(TextureRectangle)
class Texture1D : public TextureBase
{
public:
Texture1D( GLenum _internalFormat = GL_RGBA ) : TextureBase( GL_TEXTURE_1D, _internalFormat ) {}
Texture1D( const uint32_t _size, GLenum _internalFormat = GL_RGBA ) : TextureBase( GL_TEXTURE_1D, _internalFormat )
{
resize( _size );
}
//! sets the content to the given TextureData, might resize the texture
void setImageData( const SharedTextureData &_data, uint32_t _mipmapLayer = 0 );
//! content of the texture is undefined after this, this texture will be bound to the active binding point
//! nothing should be bound to the pixel unpack buffer when calling this
void resize( const uint32_t _newSize );
};
ACGL_SMARTPOINTER_TYPEDEFS(Texture1D)
class Texture2D : public TextureBase
{
public:
......@@ -263,14 +293,7 @@ public:
}
//! sets the content to the given TextureData, might resize the texture
void setImageData( const SharedTextureData &_data, uint32_t _mipmapLayer = 0 )
{
if (!textureStorageIsAllocated()) {
texImage2D( _data, _mipmapLayer );
} else {
texSubImage2D( _data, _mipmapLayer );
}
}
void setImageData( const SharedTextureData &_data, uint32_t _mipmapLayer = 0 );
//! content of the texture is undefined after this, this texture will be bound to the active binding point
//! nothing should be bound to the pixel unpack buffer when calling this
......@@ -292,15 +315,7 @@ public:
}
//! sets the content to the given TextureData, might resize the texture
void setImageData( const SharedTextureData &_data, uint32_t _arrayLayer = 0, uint32_t _mipmapLayer = 0 )
{
if (!textureStorageIsAllocated()) {
texImage3D( _data, _mipmapLayer );
} else {
glm::ivec3 offset = glm::ivec3(0,0,_arrayLayer); // the array layer is the offset in Z in a 3D texture
texSubImage3D( _data, _mipmapLayer, offset );
}
}
void setImageData( const SharedTextureData &_data, uint32_t _arrayLayer = 0, uint32_t _mipmapLayer = 0 );
//! content of the texture is undefined after this, this texture will be bound to the active binding point
//! nothing should be bound to the pixel unpack buffer when calling this
......@@ -319,14 +334,7 @@ public:
}
//! sets the content to the given TextureData, might resize the texture
void setImageData( const SharedTextureData &_data, GLenum _cubeSide, uint32_t _mipmapLayer = 0 )
{
if (!textureStorageIsAllocated()) {
texImage2DCube( _data, _cubeSide, _mipmapLayer );
} else {
texSubImage2DCube( _data, _cubeSide, _mipmapLayer );
}
}
void setImageData( const SharedTextureData &_data, GLenum _cubeSide, uint32_t _mipmapLayer = 0 );
//! content of the texture is undefined after this, this texture will be bound to the active binding point
//! nothing should be bound to the pixel unpack buffer when calling this
......
......@@ -22,7 +22,7 @@ ProgramPipeline::ProgramPipeline()
ProgramPipeline::~ProgramPipeline(void)
{
// sampler 0 will get ignored by OpenGL
// value 0 will get ignored by OpenGL
glDeleteProgramPipelines(1, &mObjectName);
}
......
......@@ -259,6 +259,69 @@ GLenum TextureBase::getCompatibleType( GLenum _internalFormat )
return GL_BYTE;
}
#ifndef ACGL_OPENGLES_VERSION_20
TextureData *TextureBase::getTextureImageRAW( const Image &_image, GLenum _format, GLenum _type ) const
{
GLenum target = mTarget;
if (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) {
target = _image.cubeMapFace;
}
// remember the previously bound texture and bind this one
GLuint prevTexture = bindAndGetOldTexture();
// determine the required buffer size to hold the requested LOD level
GLint width, height, depth;
glGetTexLevelParameteriv(mTarget, _image.mipmapLevel, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(mTarget, _image.mipmapLevel, GL_TEXTURE_HEIGHT, &height);
glGetTexLevelParameteriv(mTarget, _image.mipmapLevel, GL_TEXTURE_DEPTH, &depth);
// fetch the image data
int channels = 4;
if (_format == GL_DEPTH_COMPONENT) { channels = 1; } // TODO: test
else if (_format == GL_DEPTH_STENCIL) { channels = 2; } // TODO: test
else if (_format == GL_RED) { channels = 1; }
else if (_format == GL_GREEN) { channels = 1; }
else if (_format == GL_BLUE) { channels = 1; }
else if (_format == GL_RG) { channels = 2; }
else if (_format == GL_RGB) { channels = 3; }
else if (_format == GL_RGBA) { channels = 4; }
else if (_format == GL_BGR) { channels = 3; }
else if (_format == GL_BGRA) { channels = 4; }
else if (_format == GL_RED_INTEGER) { channels = 1; }
else if (_format == GL_GREEN_INTEGER) { channels = 1; }
else if (_format == GL_BLUE_INTEGER) { channels = 1; }
else if (_format == GL_RG_INTEGER) { channels = 2; }
else if (_format == GL_RGB_INTEGER) { channels = 3; }
else if (_format == GL_RGBA_INTEGER) { channels = 4; }
else if (_format == GL_BGR_INTEGER) { channels = 3; }
else if (_format == GL_BGRA_INTEGER) { channels = 4; }
else {
std::cerr << "unknown format: will guess the number of channels" << std::endl;
channels = 4;
}
GLubyte *imageData = new GLubyte[ width * height * getGLTypeSize(_type) * channels ];
glGetTexImage(target, _image.mipmapLevel, _format, _type, (GLvoid*)imageData);
// revert to the previously bound texture
glBindTexture(mTarget, prevTexture);
// store the image data and meta information in a TextureData object
TextureData *dataObject = new TextureData();
dataObject->setWidth( width );
dataObject->setHeight( height );
dataObject->setDepth( depth );
dataObject->setType( _type );
dataObject->setFormat(_format );
dataObject->setData( imageData); // dataObject will take care of freeing imageData
return dataObject;
}
#endif // ES 2
void TextureRectangle::resize( const glm::uvec2 &_newSize )
{
if (_newSize.x != (unsigned int)mWidth || _newSize.y != (unsigned int)mHeight) {
......@@ -288,13 +351,41 @@ void TextureRectangle::setImageData( const SharedTextureData &_data )
_data->getFormat(),
_data->getType(),
_data->getData() );
if (openGLCriticalErrorOccured()) // the guess of compatible formats might be wrong so better test for errors!
{
std::cerr << "foo" << std::endl;
openGLCriticalErrorOccured();
}
void Texture1D::setImageData( const SharedTextureData &_data, uint32_t _mipmapLayer )
{
if (!textureStorageIsAllocated()) {
texImage1D( _data, _mipmapLayer );
} else {
texSubImage1D( _data, _mipmapLayer );
}
}
void Texture1D::resize( const uint32_t _newSize )
{
if (_newSize != (unsigned int)mWidth) {
SharedTextureData sTexData( new TextureData() );
sTexData->setData (NULL);
sTexData->setWidth (_newSize);
sTexData->setFormat(getCompatibleFormat( mInternalFormat ));
sTexData->setType (getCompatibleType( mInternalFormat ));
texImage1D( sTexData, 0 );
}
}
void Texture2D::setImageData( const SharedTextureData &_data, uint32_t _mipmapLayer )
{
if (!textureStorageIsAllocated()) {
texImage2D( _data, _mipmapLayer );
} else {
texSubImage2D( _data, _mipmapLayer );
}
}
void Texture2D::resize( const glm::uvec2 &_newSize )
{
......@@ -311,6 +402,16 @@ void Texture2D::resize( const glm::uvec2 &_newSize )
}
void Texture2DArray::setImageData( const SharedTextureData &_data, uint32_t _arrayLayer, uint32_t _mipmapLayer )
{
if (!textureStorageIsAllocated()) {
texImage3D( _data, _mipmapLayer );
} else {
glm::ivec3 offset = glm::ivec3(0,0,_arrayLayer); // the array layer is the offset in Z in a 3D texture
texSubImage3D( _data, _mipmapLayer, offset );
}
}
void Texture2DArray::resize( const glm::uvec3 &_newSize )
{
if (_newSize.x != (unsigned int)mWidth || _newSize.y != (unsigned int)mHeight || _newSize.z != (unsigned int)mDepth) {
......@@ -327,6 +428,19 @@ void Texture2DArray::resize( const glm::uvec3 &_newSize )
}
void TextureCubeMap::setImageData( const SharedTextureData &_data, GLenum _cubeSide, uint32_t _mipmapLayer )
{
if (!cubeSideIsValid(_cubeSide)) {
std::cerr << "can't set cubemap side as provided enum does not name a side!" << std::endl;
return;
}
if (!textureStorageIsAllocated()) {
texImage2DCube( _data, _cubeSide, _mipmapLayer );
} else {
texSubImage2DCube( _data, _cubeSide, _mipmapLayer );
}
}
void TextureCubeMap::resize( const glm::uvec2 &_newSize )
{
if (_newSize.x != (unsigned int)mWidth || _newSize.y != (unsigned int)mHeight) {
......@@ -387,6 +501,38 @@ void TextureCubeMap::texSubImage2DCube( const SharedTextureData &_data, GLenum _
}
void TextureBase::texImage1D( const SharedTextureData &_data, GLint _mipmapLevel )
{
mWidth = _data->getWidth();
bind();
glTexImage1D(
mTarget,
_mipmapLevel,
mInternalFormat,
mWidth,
0, // no border
_data->getFormat(),
_data->getType(),
_data->getData() );
openGLRareErrorOccured();
}
void TextureBase::texSubImage1D( const SharedTextureData &_data, GLint _mipmapLevel, uint32_t _offset )
{
bind();
glTexSubImage1D(
mTarget,
_mipmapLevel,
_offset,
mWidth,
_data->getFormat(),
_data->getType(),
_data->getData() );
openGLRareErrorOccured();
}
void TextureBase::texImage2D( const SharedTextureData &_data, GLint _mipmapLevel )
{
mWidth = _data->getWidth();
......@@ -462,6 +608,10 @@ void TextureBase::texSubImage3D( const SharedTextureData &_data, GLint _mipmapLe
#ifndef ACGL_OPENGLES_VERSION_20
SharedTextureData Texture::getImageData(GLint _lod, GLenum _type) const
{
Image img;
img.mipmapLevel = _lod;
return getTextureImage( img, mFormat, _type );
/*
if(_type == GL_INVALID_ENUM) _type = mType;
// remember the previously bound texture and bind this one
......@@ -493,5 +643,6 @@ SharedTextureData Texture::getImageData(GLint _lod, GLenum _type) const
dataObject->setData(imageData); // dataObject will take care of freeing imageData
return dataObject;
*/
}
#endif // ES 2.0
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