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_);
}