Commit b8122599 authored by Robert Menzel's avatar Robert Menzel

more texture classes

parent 679894cc
......@@ -50,6 +50,7 @@ public:
GLsizei getDepth (void) const { return depth; }
GLenum getFormat (void) const { return format; }
GLenum getType (void) const { return type; }
glm::uvec3 getSize (void) const { return glm::uvec3( width, height, depth ); }
// ========================================================================================================= \/
// ================================================================================================= SETTERS \/
// ========================================================================================================= \/
......
......@@ -33,7 +33,7 @@ struct Image {
GLenum cubeMapFace; // GL_INVALID_ENUM if texture is not a cube map
};
/*
/**
* A Texture consists of:
* 1. 1..N Images (e.g. mipmap layers)
* 2. an internal data format (datatype and number of channels on the GPU)
......@@ -42,6 +42,15 @@ struct Image {
* The TextureBase class holds the methods to define 2 & 3, the Images (incl. getter and setter)
* vary between different texture types, so subclasses will take care if that.
*
* Every subclass of TextureBase has:
* A constructor which defines the internal format (data layout in GPU memory)
(this can't be changed later)
* A constructor that reserves memory for a certain texture size.
* A setImageData with a SharedTextureData and optinally additional parameters
about which layer/mipmap-level/slice etc. should be set
* Some might also have:
* A resize function which differs in the dimensionality from subclass to subclass.
*/
class TextureBase
{
......@@ -184,9 +193,9 @@ protected:
// kind of texture data:
GLenum mTarget;
GLsizei mWidth;
GLsizei mHeight;
GLsizei mDepth;
GLsizei mWidth; // width
GLsizei mHeight; // height or 1 in case of a 1D texture
GLsizei mDepth; // depth or #of layer in a 2D array, 1 otherwise
GLenum mInternalFormat; // often used, so store it here
// Checks what texture is currently bound at the texture target used by this texture
......@@ -203,7 +212,6 @@ protected:
GLenum getCompatibleType( GLenum _internalFormat );
//void texImage1D( const SharedTextureData &_data, const Image &_target );
//! 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)
......@@ -211,15 +219,15 @@ protected:
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) );
void texSubImage2D( const SharedTextureData &_data, GLint _mipmapLevel, glm::uvec2 _offset = glm::uvec2(0) );
void texImage3D( const SharedTextureData &_data, GLint _mipmapLevel );
void texSubImage3D( const SharedTextureData &_data, GLint _mipmapLevel, glm::ivec3 _offset = glm::ivec3(0) );
void texSubImage3D( const SharedTextureData &_data, GLint _mipmapLevel, glm::uvec3 _offset = glm::uvec3(0) );
//! returns true if space for the texture was allocated
bool textureStorageIsAllocated()
{
return (mWidth*mHeight*mDepth != 0);
return (mWidth != 0);
}
};
ACGL_SMARTPOINTER_TYPEDEFS(TextureBase)
......@@ -227,8 +235,8 @@ ACGL_SMARTPOINTER_TYPEDEFS(TextureBase)
// missing classes:
// GL_TEXTURE_1D x
// GL_TEXTURE_2D x
// GL_TEXTURE_3D
// GL_TEXTURE_1D_ARRAY
// GL_TEXTURE_3D x
// GL_TEXTURE_1D_ARRAY x
// GL_TEXTURE_2D_ARRAY x
// GL_TEXTURE_RECTANGLE x
// GL_TEXTURE_2D_MULTISAMPLE
......@@ -236,7 +244,13 @@ ACGL_SMARTPOINTER_TYPEDEFS(TextureBase)
// GL_TEXTURE_BINDING_CUBE_MAP x
// GL_TEXTURE_BINDING_CUBE_MAP_ARRAY
/**
* In contrast to 'normal' textures these can't have mipmaps and are accessed in the shader by
* pixel-coordinates instead of texture coordinates from 0 to 1.
* Ths makes them a good choice for multiple renderpasses (no mipmaps needed and texture access
* can be done via gl_FragCoord).
* For all other cases use Texture2D.
*/
class TextureRectangle : public TextureBase
{
public:
......@@ -264,6 +278,12 @@ private:
ACGL_SMARTPOINTER_TYPEDEFS(TextureRectangle)
/**
* 1D textures.
* can be used as general purpose data for a shader if texture filtering is wanted, otherwise look
* at TextureBuffers!
* 1D textures can have mipmaps, TextureBuffers can't.
*/
class Texture1D : public TextureBase
{
public:
......@@ -283,6 +303,9 @@ public:
ACGL_SMARTPOINTER_TYPEDEFS(Texture1D)
/**
* "Normal" 2D texture.
*/
class Texture2D : public TextureBase
{
public:
......@@ -303,8 +326,63 @@ ACGL_SMARTPOINTER_TYPEDEFS(Texture2D)
/**
* 3D volume texture.
*/
class Texture3D : public TextureBase
{
public:
Texture3D( GLenum _internalFormat = GL_RGBA ) : TextureBase( GL_TEXTURE_3D, _internalFormat ) {}
Texture3D( const glm::uvec3 &_size, GLenum _internalFormat = GL_RGBA ) : TextureBase( GL_TEXTURE_3D, _internalFormat )
{
resize( _size );
}
//! sets the content of one slice to the given TextureData
void setImageData( const SharedTextureData &_data, uint32_t _slice, uint32_t _mipmapLayer );
//! sets the content of all slices to the given TextureData
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 glm::uvec3 &_newSize );
};
ACGL_SMARTPOINTER_TYPEDEFS(Texture3D)
/**
* Array of 1D textures, technically a 2D texture but without filtering between array layers.
*/
class Texture1DArray : public TextureBase
{
public:
Texture1DArray( GLenum _internalFormat = GL_RGBA ) : TextureBase( GL_TEXTURE_1D_ARRAY, _internalFormat ) {}
Texture1DArray( const glm::uvec2 &_size, GLenum _internalFormat = GL_RGBA ) : TextureBase( GL_TEXTURE_1D_ARRAY, _internalFormat )
{
resize( _size );
}
//! sets the content to the given TextureData to one layer of the texture
void setImageData( const SharedTextureData &_data, uint32_t _layer, uint32_t _mipmapLayer );
//! sets the content to the given TextureData to fill all layers
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 glm::uvec2 &_newSize );
};
ACGL_SMARTPOINTER_TYPEDEFS(Texture1DArray)
/**
* A "stack" of 2D textures. Each must have the same size.
* Can be used to access many texture in a shader without having to deal with the
* texture unit limit.
* Technically a 3D texture but there is no filtering in between the levels (Z-axis of
* the 3D texture).
*/
class Texture2DArray : public TextureBase
{
public:
......@@ -324,6 +402,9 @@ public:
ACGL_SMARTPOINTER_TYPEDEFS(Texture2DArray)
/**
* For environmant mapping.
*/
class TextureCubeMap : public TextureBase
{
public:
......@@ -361,6 +442,9 @@ ACGL_SMARTPOINTER_TYPEDEFS(TextureCubeMap)
//
// Full compatibility with the old Texture class:
//
// Could mimic different kinds of textures in one class, not maintained anymore, use one of the
// other classes.
//
class Texture : public TextureBase
{
//ACGL_NOT_COPYABLE(Texture)
......
......@@ -402,12 +402,99 @@ void Texture2D::resize( const glm::uvec2 &_newSize )
}
void Texture3D::setImageData( const SharedTextureData &_data, uint32_t _slice, uint32_t _mipmapLayer )
{
if (!textureStorageIsAllocated()) {
glm::uvec3 newSize = _data->getSize();
newSize.z = _slice; // _data holds just one slice, so z = 1, resize the texture enough to hold at least _slice number of slices
newSize = newSize * ((unsigned int)1<<_mipmapLayer);
resize(newSize);
}
glm::uvec3 offset = glm::uvec3(0,0,_slice);
texSubImage3D( _data, _mipmapLayer, offset );
}
void Texture3D::setImageData( const SharedTextureData &_data, uint32_t _mipmapLayer )
{
if (!textureStorageIsAllocated()) {
glm::uvec3 newSize = _data->getSize();
newSize = newSize * ((unsigned int)1<<_mipmapLayer);
resize(newSize);
}
glm::uvec3 offset = glm::uvec3(0,0,0);
texSubImage3D( _data, _mipmapLayer, offset );
}
void Texture3D::resize( const glm::uvec3 &_newSize )
{
if (_newSize.x != (unsigned int)mWidth || _newSize.y != (unsigned int)mHeight || _newSize.z != (unsigned int)mDepth) {
SharedTextureData sTexData( new TextureData() );
sTexData->setData (NULL);
sTexData->setWidth (_newSize.x);
sTexData->setHeight(_newSize.y);
sTexData->setDepth (_newSize.z);
sTexData->setFormat(getCompatibleFormat( mInternalFormat ));
sTexData->setType (getCompatibleType( mInternalFormat ));
texImage3D( sTexData, 0 );
}
}
void Texture1DArray::setImageData( const SharedTextureData &_data, uint32_t _layer, uint32_t _mipmapLayer )
{
if (!textureStorageIsAllocated()) {
glm::uvec2 newSize;
newSize.x = _data->getWidth();
newSize.y = _layer;
newSize = newSize * ((unsigned int)1<<_mipmapLayer);
resize(newSize);
}
glm::uvec2 offset = glm::uvec2(0, _layer );
texSubImage2D( _data, _mipmapLayer, offset );
}
void Texture1DArray::setImageData( const SharedTextureData &_data, uint32_t _mipmapLayer )
{
if (!textureStorageIsAllocated()) {
glm::uvec2 newSize;
newSize.x = _data->getWidth();
newSize.y = _data->getHeight();
newSize = newSize * ((unsigned int)1<<_mipmapLayer);
resize(newSize);
}
texSubImage2D( _data, _mipmapLayer );
}
void Texture1DArray::resize( const glm::uvec2 &_newSize )
{
if (_newSize.x != (unsigned int)mWidth || _newSize.y != (unsigned int)mHeight) {
SharedTextureData sTexData( new TextureData() );
sTexData->setData (NULL);
sTexData->setWidth (_newSize.x);
sTexData->setHeight(_newSize.y);
sTexData->setFormat(getCompatibleFormat( mInternalFormat ));
sTexData->setType (getCompatibleType( mInternalFormat ));
texImage2D( sTexData, 0 );
}
}
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
glm::uvec3 offset = glm::uvec3(0,0,_arrayLayer); // the array layer is the offset in Z in a 3D texture
texSubImage3D( _data, _mipmapLayer, offset );
}
}
......@@ -551,7 +638,7 @@ void TextureBase::texImage2D( const SharedTextureData &_data, GLint _mipmapLevel
openGLRareErrorOccured();
}
void TextureBase::texSubImage2D( const SharedTextureData &_data, GLint _mipmapLevel, glm::ivec2 _offset )
void TextureBase::texSubImage2D( const SharedTextureData &_data, GLint _mipmapLevel, glm::uvec2 _offset )
{
// TODO: test if the size is correct?
......@@ -587,7 +674,7 @@ void TextureBase::texImage3D( const SharedTextureData &_data, GLint _mipmapLevel
openGLRareErrorOccured();
}
void TextureBase::texSubImage3D( const SharedTextureData &_data, GLint _mipmapLevel, glm::ivec3 _offset )
void TextureBase::texSubImage3D( const SharedTextureData &_data, GLint _mipmapLevel, glm::uvec3 _offset )
{
bind();
glTexSubImage3D(
......
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