The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 3df24932 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Completely refactored and cleaned up cgt::Texture interface:

* cleaned up cgt::Texture's constructors: only two left - to create an empty texture or a non-empty one
* cgt::Texture will no longer hold a copy of the image data in local memory
* removed a lot of redundant/confusing methods
* no longer needed to call uploadTexture() even though you don't want to upload sth.
* Adapted all known code to the new interface
* Removed cgt::TextureReaderDevil

refs #613
parent ee50620e
......@@ -32,6 +32,7 @@
#include "core/datastructures/datahandle.h"
#include "core/datastructures/renderdata.h"
#include "core/datastructures/imagerepresentationgl.h"
#include "core/datastructures/imagerepresentationlocal.h"
#include "core/datastructures/facegeometry.h"
#include "core/datastructures/geometrydatafactory.h"
#include "core/classification/tfgeometry1d.h"
......@@ -283,6 +284,7 @@ namespace campvis {
const ImageData* id = static_cast<const ImageData*>(_textures[texIndx].getData());
const cgt::Texture* tex = id->getRepresentation<ImageRepresentationGL>()->getTexture();
const ImageRepresentationLocal* localRep = id->getRepresentation<ImageRepresentationLocal>();
cgt::ivec2 imageSize = id->getSize().xy();
cgt::vec2 lookupTexelFloat = cgt::vec2((e->coord() % _quadSize) * imageSize) / cgt::vec2(_quadSize);
......@@ -295,19 +297,28 @@ namespace campvis {
lookupTexelFloat /= (ratioRatio > 1) ? cgt::vec2(1.f, 1.f / ratioRatio) : cgt::vec2(ratioRatio, 1.f);
cgt::ivec2 lookupTexel(lookupTexelFloat);
cgt::svec3 lookupTexel(lookupTexelFloat.x, imageSize.y - lookupTexelFloat.y, 0);
if (lookupTexel.x >= 0 && lookupTexel.y >= 0 && lookupTexel.x < imageSize.x && lookupTexel.y < imageSize.y) {
if(tex->isDepthTexture()) {
emit s_depthChanged(tex->depthAsFloat(lookupTexel.x, imageSize.y - lookupTexel.y - 1));
if (tex->isDepthTexture()) {
emit s_depthChanged(localRep->getElementNormalized(lookupTexel, 0));
}
else {
if (tex->getDimensions().z != 1) {
if (p_currentSlice.getValue() >= 0 && p_currentSlice.getValue() < tex->getDimensions().z) {
emit s_colorChanged(tex->texelAsFloat(lookupTexel.x, imageSize.y - lookupTexel.y - 1, p_currentSlice.getValue()));
lookupTexel.z = static_cast<size_t>(p_currentSlice.getValue());
cgt::vec4 texel(0.f);
for (size_t i = 0; i < id->getNumChannels(); ++i) {
texel[i] = localRep->getElementNormalized(lookupTexel, i);
}
emit s_colorChanged(texel);
}
}
else if (tex->getDimensions().y != 1) {
emit s_colorChanged(tex->texelAsFloat(lookupTexel.x, imageSize.y - lookupTexel.y - 1));
cgt::vec4 texel(0.f);
for (size_t i = 0; i < id->getNumChannels(); ++i) {
texel[i] = localRep->getElementNormalized(lookupTexel, i);
}
emit s_colorChanged(texel);
}
}
}
......@@ -386,7 +397,6 @@ namespace campvis {
for (std::map<QString, QtDataHandle>::iterator it = _handles.begin(); it != _handles.end(); ++it) {
if (const ImageData* img = dynamic_cast<const ImageData*>(it->second.getData())) {
if (const ImageRepresentationGL* imgGL = img->getRepresentation<ImageRepresentationGL>()) {
imgGL->downloadTexture();
_textures.push_back(it->second);
maxSlices = std::max(maxSlices, imgGL->getTexture()->getDimensions().z);
}
......@@ -395,14 +405,12 @@ namespace campvis {
for (size_t i = 0; i < rd->getNumColorTextures(); ++i) {
const ImageRepresentationGL* imgGL = rd->getColorTexture(i)->getRepresentation<ImageRepresentationGL>();
if (imgGL) {
imgGL->downloadTexture();
_textures.push_back(rd->getColorDataHandle(i));
}
}
if (rd->hasDepthTexture()) {
const ImageRepresentationGL* imgGL = rd->getDepthTexture()->getRepresentation<ImageRepresentationGL>();
if (imgGL) {
imgGL->downloadTexture();
_textures.push_back(rd->getDepthDataHandle());
}
......@@ -454,8 +462,6 @@ namespace campvis {
if (rd != nullptr && rd->getNumColorTextures() > 0) {
auto rep = rd->getColorTexture(0)->getRepresentation<ImageRepresentationGL>();
if (rep != nullptr) {
const_cast<cgt::Texture*>(rep->getTexture())->downloadTexture();
if (textureIndex < 0 || textureIndex >= static_cast<int>(_textures.size())) {
_textures.push_back(rd->getColorDataHandle(0));
}
......
......@@ -497,14 +497,9 @@ namespace campvis {
// extract the data
WeaklyTypedPointer wtp(WeaklyTypedPointer::UINT8, 1, 0);
const ImageRepresentationGL* repGL = id->getRepresentation<ImageRepresentationGL>(false);
if (repGL != 0) // if it's a GL texture, download it (we do not want to use the automatic conversion method here)
wtp = repGL->getWeaklyTypedPointer();
else {
const ImageRepresentationLocal* repLocal = id->getRepresentation<ImageRepresentationLocal>(true);
if (repLocal != 0)
wtp = repLocal->getWeaklyTypedPointer();
}
const ImageRepresentationLocal* repLocal = id->getRepresentation<ImageRepresentationLocal>(true);
if (repLocal != 0)
wtp = repLocal->getWeaklyTypedPointer();
if (wtp._pointer == 0) {
LERROR("Could not extract image to save.");
......
......@@ -227,9 +227,21 @@ namespace campvis {
// create texture
GLenum dataType = GL_UNSIGNED_BYTE;
_texture = new cgt::Texture(_size, GL_RGBA, dataType, cgt::Texture::LINEAR);
GLenum type = GL_TEXTURE_1D;
switch (getDimensionality()) {
case 1:
type = GL_TEXTURE_1D;
break;
case 2:
type = GL_TEXTURE_2D;
break;
default:
cgtAssert(false, "This TF dimensionality is currently not supported - you have to implement it yourself!");
break;
}
_texture = new cgt::Texture(type, _size, GL_RGBA8, cgt::Texture::LINEAR);
_texture->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
_texture->uploadTexture();
LGL_ERROR;
// attach texture to FBO
......
......@@ -60,19 +60,20 @@ namespace campvis {
delete _texture;
GLenum dataType = GL_UNSIGNED_BYTE;
_texture = new cgt::Texture(_size, GL_RGBA, dataType, cgt::Texture::LINEAR);
_texture = new cgt::Texture(GL_TEXTURE_1D, _size, GL_RGBA8, cgt::Texture::LINEAR);
_texture->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
cgt::col4* texels = new cgt::col4[_size.x];
cgt::col4 diff = _rightColor - _leftColor;
for (size_t i = 0; i < _size.x; ++i) {
float multiplier = static_cast<float>(i) / (_size.x - 1);
cgt::col4& texel = _texture->texel<cgt::col4>(i);
cgt::col4& texel = texels[i];
for (size_t j = 0; j < 4; ++j) {
texel[j] = static_cast<uint8_t>(_leftColor[j] + (static_cast<float>(diff[j]) * multiplier));
}
}
_texture->uploadTexture();
_texture->uploadTexture(reinterpret_cast<GLubyte*>(texels), GL_RGBA, GL_UNSIGNED_BYTE);
_dirtyTexture = false;
}
......
......@@ -98,7 +98,7 @@ namespace campvis {
// converting from GL representation
cgt::OpenGLJobProcessor::ScopedSynchronousGlJobExecution jobGuard;
if (tester->getTexture()->getDataType() != TypeTraits<BASETYPE, NUMCHANNELS>::glDataType)
if (cgt::Texture::calcMatchingDataType(tester->getTexture()->getInternalFormat()) != TypeTraits<BASETYPE, NUMCHANNELS>::glDataType)
LDEBUGC("CAMPVis.core.datastructures.GenericLocalConversion", "Performing conversion between data types, you may lose information or the resulting data may show other unexpected features.");
WeaklyTypedPointer wtp = tester->getWeaklyTypedPointerConvert(TypeTraits<BASETYPE, NUMCHANNELS>::glDataType);
......
......@@ -69,46 +69,40 @@ namespace campvis {
}
ImageRepresentationGL* ImageRepresentationGL::clone(ImageData* newParent) const {
GLubyte* data = _texture->downloadTextureToBuffer();
WeaklyTypedPointer wtp(WeaklyTypedPointer::baseType(_texture->getDataType()), WeaklyTypedPointer::numChannels(_texture->getFormat()), data);
WeaklyTypedPointer wtp = getWeaklyTypedPointerCopy();
ImageRepresentationGL* toReturn = ImageRepresentationGL::create(newParent, wtp);
delete data;
delete static_cast<GLubyte*>(wtp._pointer);
return toReturn;
}
void ImageRepresentationGL::createTexture(const WeaklyTypedPointer& wtp) {
cgtAssert(wtp._pointer != 0, "Pointer to image data must not be 0!");
_texture = new cgt::Texture(reinterpret_cast<GLubyte*>(wtp._pointer), getSize(), wtp.getGlFormat(), wtp.getGlInternalFormat(), wtp.getGlDataType(), cgt::Texture::LINEAR);
setupAndUploadTexture(_texture, wtp.isInteger(), wtp.isSigned());
}
void ImageRepresentationGL::setupAndUploadTexture(cgt::Texture* texture, bool isInteger, bool isSigned) {
// Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
switch (getDimensionality()) {
GLenum type = GL_TEXTURE_1D;
switch (_parent->getDimensionality()) {
case 1:
_texture->setType(GL_TEXTURE_1D);
type = GL_TEXTURE_1D;
break;
case 2:
_texture->setType(GL_TEXTURE_2D);
type = GL_TEXTURE_2D;
break;
case 3:
_texture->setType(GL_TEXTURE_3D);
type = GL_TEXTURE_3D;
break;
default:
cgtAssert(false, "Unsupported dimensionality of image.");
cgtAssert(false, "This dimensionality is not supported!");
break;
}
_texture = new cgt::Texture(type, getSize(), wtp.getGlInternalFormat(), cgt::Texture::LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
cgt::TextureUnit tempUnit;
tempUnit.activate();
_texture->bind();
// map signed integer types from [-1.0:1.0] to [0.0:1.0] in order to avoid clamping of negative values
if (isInteger && isSigned) {
if (wtp.isInteger() && wtp.isSigned()) {
glPixelTransferf(GL_RED_SCALE, 0.5f);
glPixelTransferf(GL_GREEN_SCALE, 0.5f);
glPixelTransferf(GL_BLUE_SCALE, 0.5f);
......@@ -122,10 +116,10 @@ namespace campvis {
//_mappingInformation.setRealWorldMapping(LinearMapping<float>(.5f, .5f));
}
_texture->uploadTexture();
_texture->uploadTexture(reinterpret_cast<GLubyte*>(wtp._pointer), wtp.getGlFormat(), wtp.getGlDataType());
_texture->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
if (isInteger && isSigned) {
if (wtp.isInteger() && wtp.isSigned()) {
// restore default
glPixelTransferf(GL_RED_SCALE, 1.0f);
glPixelTransferf(GL_GREEN_SCALE, 1.0f);
......@@ -138,9 +132,6 @@ namespace campvis {
glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
}
// revoke ownership of local pixel data from the texture
_texture->setPixelData(0);
cgt::TextureUnit::setZeroUnit();
LGL_ERROR;
}
......@@ -191,12 +182,7 @@ namespace campvis {
LGL_ERROR;
}
void ImageRepresentationGL::downloadTexture() const {
_texture->downloadTexture();
}
const cgt::Texture* ImageRepresentationGL::getTexture() const {
return _texture;
}
......@@ -204,9 +190,6 @@ namespace campvis {
size_t sum = 0;
if (_texture != 0) {
sum += sizeof(cgt::Texture);
if (_texture->getPixelData() != 0) {
sum += _texture->getBpp() + _texture->getArraySize();
}
}
return sizeof(*this) + sum;
......@@ -216,25 +199,23 @@ namespace campvis {
return _texture->getSizeOnGPU();
}
const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointer() const {
if (_texture->getPixelData() == 0) {
_texture->downloadTexture();
}
return WeaklyTypedPointer(WeaklyTypedPointer::baseType(_texture->getDataType()), _texture->getNumChannels(), _texture->getPixelData());
}
void ImageRepresentationGL::unbind() const {
_texture->unbind();
}
const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointerCopy() const {
void* ptr = _texture->downloadTextureToBuffer(_texture->getFormat(), _texture->getDataType());
return WeaklyTypedPointer(WeaklyTypedPointer::baseType(_texture->getDataType()), _texture->getNumChannels(), ptr);
GLint format = cgt::Texture::calcMatchingFormat(_texture->getInternalFormat());
GLenum dataType = cgt::Texture::calcMatchingDataType(_texture->getInternalFormat());
GLubyte* data = _texture->downloadTextureToBuffer(format, dataType);
return WeaklyTypedPointer(WeaklyTypedPointer::baseType(dataType), _texture->getNumChannels(), data);
}
const WeaklyTypedPointer ImageRepresentationGL::getWeaklyTypedPointerConvert(GLenum dataType) const {
void* ptr = _texture->downloadTextureToBuffer(_texture->getFormat(), dataType);
return WeaklyTypedPointer(WeaklyTypedPointer::baseType(dataType), _texture->getNumChannels(), ptr);
GLint format = cgt::Texture::calcMatchingFormat(_texture->getInternalFormat());
GLubyte* data = _texture->downloadTextureToBuffer(format, dataType);
return WeaklyTypedPointer(WeaklyTypedPointer::baseType(dataType), _texture->getNumChannels(), data);
}
}
\ No newline at end of file
......@@ -106,12 +106,6 @@ namespace campvis {
*/
void unbind() const;
/**
* Download the OpenGL texture from the GPU memory to the texture cpu buffer.
* \return _texture
*/
void downloadTexture() const;
/**
* Gets the OpenGL texture.
* \return _texture
......@@ -119,15 +113,6 @@ namespace campvis {
const cgt::Texture* getTexture() const;
/**
* Returns a WeaklyTypedPointer to the data of this representation.
* You do \b not own the pointer - do \b not modify its content!
* \see ImageRepresentationGL::getWeaklyTypedPointerCopy()
* \note Make sure to call this method from a valid OpenGL context.
* \return A WeaklyTypedPointer to the data of this representation. Neither you own nor you may modify its data!
*/
const WeaklyTypedPointer getWeaklyTypedPointer() const;
/**
* Returns a WeaklyTypedPointer to the data of this representation.
* Caller will own the pointer - take care to eventually delete it!
......
......@@ -78,46 +78,7 @@ namespace campvis {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// create texture
cgt::Texture* tex = 0;
switch(internalFormat) {
case GL_RGB:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, cgt::Texture::LINEAR);
break;
case GL_RGB16F_ARB:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_RGB, GL_RGB16F_ARB, GL_FLOAT, cgt::Texture::LINEAR);
break;
case GL_RGBA:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, cgt::Texture::LINEAR);
break;
case GL_RGBA8:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA8, GL_UNSIGNED_BYTE, cgt::Texture::LINEAR);
break;
case GL_RGBA16:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA16, GL_UNSIGNED_SHORT, cgt::Texture::LINEAR);
break;
case GL_RGBA16F:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA16F, GL_FLOAT, cgt::Texture::LINEAR);
break;
case GL_RGBA32F:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_RGBA, GL_RGBA32F, GL_FLOAT, cgt::Texture::LINEAR);
break;
case GL_DEPTH_COMPONENT16:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_FLOAT, cgt::Texture::LINEAR);
break;
case GL_DEPTH_COMPONENT24:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT24, GL_FLOAT, cgt::Texture::LINEAR);
break;
#ifdef GL_DEPTH_COMPONENT32F
case GL_DEPTH_COMPONENT32F:
tex = new cgt::Texture(0, getRenderTargetSize(), GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F, GL_FLOAT, cgt::Texture::LINEAR);
break;
#endif
default:
cgtAssert(false, "Unknown internal format!");
}
tex->uploadTexture();
cgt::Texture* tex = new cgt::Texture(GL_TEXTURE_2D, getRenderTargetSize(), internalFormat, cgt::Texture::LINEAR);
tex->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
// attach texture to FBO
......
......@@ -119,8 +119,7 @@ namespace campvis {
// create temporary textures
cgt::Texture* tempTextures[2];
for (size_t i = 0; i < 2; ++i) {
tempTextures[i] = new cgt::Texture(0, cgt::ivec3(texSize, 1), GL_RGBA, GL_RGBA32F, GL_FLOAT, cgt::Texture::NEAREST);
tempTextures[i]->uploadTexture();
tempTextures[i] = new cgt::Texture(GL_TEXTURE_2D, cgt::ivec3(texSize, 1), GL_RGBA32F, cgt::Texture::NEAREST);
tempTextures[i]->setWrapping(cgt::Texture::CLAMP_TO_EDGE);
}
......@@ -184,7 +183,7 @@ namespace campvis {
}
// read back stuff
GLenum readBackFormat = outputTex->getFormat();
GLenum readBackFormat = cgt::Texture::calcMatchingFormat(outputTex->getInternalFormat());
size_t channels = outputTex->getNumChannels();
toReturn.resize(channels);
glReadBuffer(GL_COLOR_ATTACHMENT0);
......
......@@ -134,17 +134,11 @@ namespace campvis {
}
cgt::Texture* BinaryBrickedVolume::exportToImageData() const {
cgt::Texture* toReturn = new cgt::Texture(_bricks, _dimPackedBricks, GL_RED_INTEGER, GL_R8UI, GL_UNSIGNED_BYTE, cgt::Texture::NEAREST);
LGL_ERROR;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
cgt::TextureUnit tempUnit;
tempUnit.activate();
toReturn->bind();
toReturn->uploadTexture();
LGL_ERROR;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
cgt::Texture* toReturn = new cgt::Texture(GL_TEXTURE_3D, _dimPackedBricks, GL_R8UI, _bricks, GL_RED_INTEGER, GL_UNSIGNED_BYTE, cgt::Texture::NEAREST);
toReturn->setWrapping(cgt::Texture::CLAMP);
toReturn->setPixelData(0);
cgt::TextureUnit::setZeroUnit();
LGL_ERROR;
......
......@@ -43,7 +43,6 @@ SET(CGT_SOURCES
stopwatch.cpp
texture.cpp
texturereader.cpp
texturereaderdevil.cpp
texturereadertga.cpp
textureunit.cpp
cgt_gl.cpp
......
......@@ -40,9 +40,6 @@
#include "cgt/shadermanager.h"
#include "cgt/event/eventhandler.h"
#ifdef CGT_HAS_DEVIL
#include "cgt/texturereaderdevil.h"
#endif
#include "cgt/texturereadertga.h"
namespace cgt {
......
This diff is collapsed.
......@@ -59,40 +59,30 @@ public:
MIRRORED_REPEAT = GL_MIRRORED_REPEAT
};
Texture()
: priority_(-1.f), pixels_(0), id_(0)
{}
//FIXME: these ctors are ambiguous due to the default params, you need to specify all
// arguments or the compile won't know which one you mean. joerg
/**
* Without data and internalformat argument, type_ is calculated by
* dimensions and a new chunk of data will be allocated on the heap.
*/
Texture(const cgt::ivec3& dimensions, GLint format = GL_RGBA,
GLenum dataType = GL_UNSIGNED_BYTE, Filter filter = LINEAR);
/**
* Without data and with internalformat argument, type_ is calculated by
* dimensions and a new chunk of data will be allocated on the heap.
* Creates an empty texture with the given parameters.
*
* \param type OpenGL texture type
* \param dimensions Size of the texture
* \param internalFormat Internal storage format
* \param filter Filter to apply during sampling (defaults to linear)
*/
Texture(const cgt::ivec3& dimensions, GLint format, GLint internalformat,
GLenum dataType = GL_UNSIGNED_BYTE, Filter filter = LINEAR);
Texture(GLenum type, const cgt::ivec3& dimensions, GLint internalFormat, Filter filter = LINEAR);
/**
* With data and without internalformat argument, type_ is calculated by
* dimensions and no new chunk of data will be allocated on the heap.
* Creates a new OpenGL texture and initializes it with the given data.
* \note Works the same as constructing with the non-uploading ctor and then
* calling uploadTexture(data, format, dataType).
* \param type OpenGL texture type
* \param dimensions Size of the texture
* \param internalformat Internal storage format
* \param data Pointer to data to upload, may be 0, but then you could use the other ctor directly...
* \param format OpenGL Format of the data in \a data.
* \param dataType OpenGL data type of the data in \a data.
* \param filter Filter to apply during sampling (defaults to linear)
*/
Texture(GLubyte* data, const cgt::ivec3& dimensions, GLint format = GL_RGBA,
GLenum dataType = GL_UNSIGNED_BYTE, Filter filter = LINEAR);
/**
* With data and internalformat argument, type_ is calculated by
* dimensions and no new chunk of data will be allocated on the heap.
*/
Texture(GLubyte* data, const cgt::ivec3& dimensions, GLint format, GLint internalformat,
GLenum dataType = GL_UNSIGNED_BYTE, Filter filter = LINEAR);
Texture(GLenum type, const cgt::ivec3& dimensions, GLint internalFormat,
GLubyte* data, GLint format, GLenum dataType, Filter filter = LINEAR);
/**
* The destructor deletes the Texture in OpenGL.
......@@ -100,19 +90,6 @@ public:
*/
virtual ~Texture();
/// allocates an appropriate buffer for the texture
void alloc() {
arraySize_ = hmul(dimensions_) * bpp_;
pixels_ = new GLubyte[arraySize_];
}
/// destroys the buffer for the texture and sets arraySize_ to zero
void destroy() {
arraySize_ = 0;
if(pixels_)
delete[] pixels_;
pixels_ = 0;// so nothing really nasty can happen
}
/// calculates the bytes per pixel from format dataType and dataType
static int calcBpp(GLint format, GLenum dataType);
......@@ -120,69 +97,48 @@ public:
/// calculates the bytes per pixel from the internal format
static int calcBpp(GLint internalformat);
/// calculates the number of channels from the passed texture format
static int calcNumChannels(GLint format);
/// calculates the number of channels from the passed internal format
static int calcNumChannels(GLint internalFormat);
///calculates size on the GPU (using internalformat)
int getSizeOnGPU() const;
static GLint calcMatchingFormat(GLint internalFormat);
static GLenum calcMatchingDataType(GLint internalFormat);
/**
* calculates the type_ (GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D or GL_TEXTURE_RECTANGLE_ARB) from
* dimensions_
*
* @param textureRectangle Determines, wether texture should be a texture rectangle
* GL_TEXTURE_RECTANGLE_ARB
*/
GLenum calcType(bool textureRectangle = false);
* Determines the best-matching internal format for the given OpenGL format and data type
* \param format OpenGL Format of the data
* \param dataType OpenGL data type of the data
*/
static GLint calcInternalFormat(GLint format, GLenum dataType);
/// calculates size on the GPU (using internalformat)
int getSizeOnGPU() const;
/**
* Bind the texture to the active texture unit and target.
*
* Note: This does not enable texturing (use enable()).
*/
void bind() const
{
void bind() const {
glBindTexture(type_ , id_);
}
/**
* unbind the current texture from the active texture unit and target.
*/
void unbind() const
{
void unbind() const {
glBindTexture(type_, 0);
}
/**
* Enable texturing on the active texture unit.
*/
void enable() const
{
glEnable(type_);
}
/**
* Disable texturing on the active texture unit
* Return OpenGL texture ID
*/
void disable() const
{
glDisable(type_);
}
/**
* Return OpenGL texture ID
*/
GLuint getId() const { return id_; }
/**
* Set OpenGL texture ID.