In January 2021 we will introduce a 10 GB quota for project repositories. Higher limits for individual projects will be available on request. Please see https://doku.lrz.de/display/PUBLIC/GitLab for more information.

* Updated tgt::Texture and WeaklyTypedPointer to use only OpenGL 3 core texture formats

* Adapted shaders to new texture formats
parent 129aa353
......@@ -60,19 +60,19 @@ void main() {
// perform MIP
out_Color = vec4(0.0);
for (float slice = 0.0; slice < 1.0; slice += _3dTextureParams._sizeRCP.z) {
out_Color = max(out_Color, lookupTF(_transferFunction, _transferFunctionParams, getElement3DNormalized(_texture3d, _3dTextureParams, vec3(ex_TexCoord.xy, slice)).a));
out_Color = max(out_Color, lookupTF(_transferFunction, _transferFunctionParams, getElement3DNormalized(_texture3d, _3dTextureParams, vec3(ex_TexCoord.xy, slice)).r));
}
}
else {
// render the corresponding slice
vec3 coord = vec3(ex_TexCoord.xy, (_sliceNumber + 0.5) / (_3dTextureParams._size.z));
out_Color = lookupTF(_transferFunction, _transferFunctionParams, getElement3DNormalized(_texture3d, _3dTextureParams, coord).a);
out_Color = lookupTF(_transferFunction, _transferFunctionParams, getElement3DNormalized(_texture3d, _3dTextureParams, coord).r);
}
}
else {
vec4 texel = getElement2DNormalized(_texture2d, _2dTextureParams, ex_TexCoord.xy);
if (_2dTextureParams._numChannels == 1) {
out_Color = lookupTF(_transferFunction, _transferFunctionParams, (_isDepthTexture ? texel.r : texel.a));
out_Color = lookupTF(_transferFunction, _transferFunctionParams, texel.r);
}
else if (_2dTextureParams._numChannels == 3) {
out_Color = vec4(abs(texel.rgb), 1.0);
......
......@@ -36,10 +36,10 @@
*/
vec3 computeGradientForwardDifferences(in sampler3D tex, in TextureParameters3D texParams, in vec3 texCoords) {
vec3 offset = texParams._sizeRCP;
float v = getElement3DNormalized(tex, texParams, texCoords).a;
float dx = getElement3DNormalized(tex, texParams, texCoords + vec3(offset.x, 0.0, 0.0)).a;
float dy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, offset.y, 0)).a;
float dz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, offset.z)).a;
float v = getElement3DNormalized(tex, texParams, texCoords).r;
float dx = getElement3DNormalized(tex, texParams, texCoords + vec3(offset.x, 0.0, 0.0)).r;
float dy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, offset.y, 0)).r;
float dz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, offset.z)).r;
return vec3(v - dx, v - dy, v - dz) * texParams._voxelSize;
}
......@@ -50,12 +50,12 @@ vec3 computeGradientForwardDifferences(in sampler3D tex, in TextureParameters3D
*/
vec3 computeGradientCentralDifferences(in sampler3D tex, in TextureParameters3D texParams, in vec3 texCoords) {
vec3 offset = texParams._sizeRCP;
float dx = getElement3DNormalized(tex, texParams, texCoords + vec3(offset.x, 0.0, 0.0)).a;
float dy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, offset.y, 0)).a;
float dz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, offset.z)).a;
float mdx = getElement3DNormalized(tex, texParams, texCoords + vec3(-offset.x, 0, 0)).a;
float mdy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, -offset.y, 0)).a;
float mdz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, -offset.z)).a;
float dx = getElement3DNormalized(tex, texParams, texCoords + vec3(offset.x, 0.0, 0.0)).r;
float dy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, offset.y, 0)).r;
float dz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, offset.z)).r;
float mdx = getElement3DNormalized(tex, texParams, texCoords + vec3(-offset.x, 0, 0)).r;
float mdy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, -offset.y, 0)).r;
float mdz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, -offset.z)).r;
return vec3(mdx - dx, mdy - dy, mdz - dz) * texParams._voxelSize * vec3(0.5);
}
......
......@@ -53,20 +53,20 @@ namespace campvis {
size_t WeaklyTypedPointer::numBytes(BaseType pt, size_t numChannels) {
switch (pt) {
case WeaklyTypedPointer::UINT8:
case WeaklyTypedPointer::INT8:
return 1 * numChannels;
case WeaklyTypedPointer::UINT16:
case WeaklyTypedPointer::INT16:
return 2 * numChannels;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return 4 * numChannels;
case WeaklyTypedPointer::FLOAT:
return sizeof(float) * numChannels;
default:
tgtAssert(false, "Should not reach this - called WeaklyTypedPointer::numBytes() with wrong argument!");
return 1;
case WeaklyTypedPointer::UINT8:
case WeaklyTypedPointer::INT8:
return 1 * numChannels;
case WeaklyTypedPointer::UINT16:
case WeaklyTypedPointer::INT16:
return 2 * numChannels;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return 4 * numChannels;
case WeaklyTypedPointer::FLOAT:
return sizeof(float) * numChannels;
default:
tgtAssert(false, "Should not reach this - called WeaklyTypedPointer::numBytes() with wrong argument!");
return 1;
}
};
......@@ -77,16 +77,16 @@ namespace campvis {
GLint WeaklyTypedPointer::getGlFormat() const {
switch (_numChannels) {
case 1:
return GL_ALPHA;
return GL_RED;
case 2:
return GL_LUMINANCE_ALPHA;
return GL_RG;
case 3:
return GL_RGB;
case 4:
return GL_RGBA;
default:
tgtAssert(false, "Should not reach this, wrong number of channels!");
return GL_ALPHA;
return GL_RED;
}
}
......@@ -117,21 +117,36 @@ namespace campvis {
switch (_baseType) {
case WeaklyTypedPointer::UINT8:
case WeaklyTypedPointer::INT8:
return GL_ALPHA8;
return GL_R8;
case WeaklyTypedPointer::UINT16:
case WeaklyTypedPointer::INT16:
return GL_ALPHA16;
return GL_R16;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return GL_ALPHA;
return GL_R32F;
case WeaklyTypedPointer::FLOAT:
return GL_ALPHA32F_ARB;
return GL_R32F;
default:
tgtAssert(false, "Should not reach this - wrong base data type!");
return GL_BYTE;
return GL_RED;
}
case 2:
return GL_LUMINANCE_ALPHA;
switch (_baseType) {
case WeaklyTypedPointer::UINT8:
case WeaklyTypedPointer::INT8:
return GL_RG8;
case WeaklyTypedPointer::UINT16:
case WeaklyTypedPointer::INT16:
return GL_RG16;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return GL_RG32F;
case WeaklyTypedPointer::FLOAT:
return GL_RG32F;
default:
tgtAssert(false, "Should not reach this - wrong base data type!");
return GL_RG;
}
case 3:
switch (_baseType) {
case WeaklyTypedPointer::UINT8:
......@@ -142,12 +157,12 @@ namespace campvis {
return GL_RGB16;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return GL_RGB;
return GL_RGB32F;
case WeaklyTypedPointer::FLOAT:
return GL_RGB32F_ARB;
return GL_RGB32F;
default:
tgtAssert(false, "Should not reach this - wrong base data type!");
return GL_BYTE;
return GL_RGB;
}
case 4:
switch (_baseType) {
......@@ -159,52 +174,110 @@ namespace campvis {
return GL_RGBA16;
case WeaklyTypedPointer::UINT32:
case WeaklyTypedPointer::INT32:
return GL_RGBA;
return GL_RGBA32F;
case WeaklyTypedPointer::FLOAT:
return GL_RGBA32F_ARB;
return GL_RGBA32F;
default:
tgtAssert(false, "Should not reach this - wrong base data type!");
return GL_BYTE;
return GL_RGBA;
}
default:
tgtAssert(false, "Should not reach hier, wrong number of channels!");
return GL_ALPHA;
return GL_RED;
}
}
size_t WeaklyTypedPointer::numChannels(GLint glFormat) {
// supports all formats from http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml
switch (glFormat) {
case 1:
case GL_COLOR_INDEX:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_INTENSITY:
case GL_LUMINANCE:
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_ALPHA_INTEGER_EXT:
case GL_DEPTH_COMPONENT32:
case GL_DEPTH_COMPONENT32F:
case GL_RED:
case GL_R8:
case GL_R8_SNORM:
case GL_R16_SNORM:
case GL_R16F:
case GL_R32F:
case GL_R8I:
case GL_R8UI:
case GL_R16I:
case GL_R16UI:
case GL_R32I:
case GL_R32UI:
return 1;
break;
case 2:
case GL_LUMINANCE_ALPHA:
case GL_DEPTH_STENCIL:
case GL_RG:
case GL_RG8:
case GL_RG8_SNORM:
case GL_RG16:
case GL_RG16_SNORM:
case GL_RG16F:
case GL_RG32F:
case GL_RG8I:
case GL_RG8UI:
case GL_RG16I:
case GL_RG16UI:
case GL_RG32I:
case GL_RG32UI:
return 2;
break;
case 3:
case GL_RGB:
case GL_BGR:
case GL_R3_G3_B2:
case GL_RGB4:
case GL_RGB5:
case GL_RGB8:
case GL_RGB8_SNORM:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16_SNORM:
case GL_SRGB8:
case GL_RGB16F:
case GL_RGB32F:
case GL_R11F_G11F_B10F:
case GL_RGB9_E5:
case GL_RGB8I:
case GL_RGB8UI:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB32I:
case GL_RGB32UI:
return 3;
break;
case 4:
case GL_RGBA:
case GL_BGRA:
case GL_RGBA2:
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGBA8:
case GL_RGBA8_SNORM:
case GL_RGB10_A2:
case GL_RGB10_A2UI:
case GL_RGBA12:
case GL_RGBA16:
case GL_RGBA16F_ARB:
case GL_SRGB8_ALPHA8:
case GL_RGBA16F:
case GL_RGBA32F:
case GL_RGBA8I:
case GL_RGBA8UI:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA32I:
case GL_RGBA32UI:
return 4;
break;
default:
tgtAssert(false, "Unsupported OpenGL data format.");
tgtAssert(false, "Should not reach this, wrong number of gl format!");
return 0;
}
}
......
......@@ -45,28 +45,28 @@ FramebufferObject::~FramebufferObject()
void FramebufferObject::activate()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id_);
glBindFramebuffer(GL_FRAMEBUFFER, id_);
}
void FramebufferObject::deactivate()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FramebufferObject::attachTexture(Texture* texture, GLenum attachment, int mipLevel, int zSlice)
{
switch(texture->getType()) {
case GL_TEXTURE_1D:
glFramebufferTexture1DEXT( GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_1D, texture->getId(), mipLevel );
glFramebufferTexture1D( GL_FRAMEBUFFER, attachment, GL_TEXTURE_1D, texture->getId(), mipLevel );
break;
case GL_TEXTURE_3D:
glFramebufferTexture3DEXT( GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_3D, texture->getId(), mipLevel, zSlice );
glFramebufferTexture3D( GL_FRAMEBUFFER, attachment, GL_TEXTURE_3D, texture->getId(), mipLevel, zSlice );
break;
case GL_TEXTURE_2D_ARRAY_EXT:
glFramebufferTextureLayerEXT( GL_FRAMEBUFFER_EXT, attachment, texture->getId(), mipLevel, zSlice );
case GL_TEXTURE_2D_ARRAY:
glFramebufferTextureLayer( GL_FRAMEBUFFER, attachment, texture->getId(), mipLevel, zSlice );
break;
default: //GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment, texture->getType(), texture->getId(), mipLevel );
glFramebufferTexture2D( GL_FRAMEBUFFER, attachment, texture->getType(), texture->getId(), mipLevel );
break;
}
......@@ -83,6 +83,20 @@ Texture* FramebufferObject::getTextureAtAttachment(GLenum attachment) {
void FramebufferObject::detachTexture(GLenum attachment) {
size_t index = decodeAttachment(attachment);
if (attachments_[index] != 0) {
switch (attachments_[index]->getType()) {
case GL_TEXTURE_1D:
glFramebufferTexture1D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_1D, 0, 0);
break;
case GL_TEXTURE_2D_ARRAY:
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, 0, 0, 0);
break;
case GL_TEXTURE_3D:
glFramebufferTexture3D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_3D, 0, 0, 0);
break;
default: // GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, 0, 0);
break;
}
attachments_[index] = 0;
if (index < TGT_FRAMEBUFFEROBJECT_MAX_SUPPORTED_COLOR_ATTACHMENTS)
......@@ -91,8 +105,6 @@ void FramebufferObject::detachTexture(GLenum attachment) {
else {
LWARNING("Trying to detach unknown texture!");
}
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, 0, 0);
}
void FramebufferObject::detachAll() {
......@@ -112,31 +124,31 @@ bool FramebufferObject::isComplete() const
{
bool complete = false;
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
case GL_FRAMEBUFFER_COMPLETE:
complete = true;
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT");
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT");
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT");
LERROR("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT");
LERROR("GL_FRAMEBUFFER_INCOMPLETE_FORMATS");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT");
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT");
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
LERROR("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER");
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
LERROR("GL_FRAMEBUFFER_UNSUPPORTED_EXT");
case GL_FRAMEBUFFER_UNSUPPORTED:
LERROR("GL_FRAMEBUFFER_UNSUPPORTED");
break;
default:
LERROR("Unknown error!");
......@@ -150,13 +162,13 @@ bool FramebufferObject::isActive() const {
GLuint FramebufferObject::getActiveObject() {
GLint fbo;
glGetIntegerv (GL_FRAMEBUFFER_BINDING_EXT, &fbo);
glGetIntegerv (GL_FRAMEBUFFER_BINDING, &fbo);
return static_cast<GLuint>(fbo);
}
GLuint FramebufferObject::generateId() {
id_ = 0;
glGenFramebuffersEXT(1, &id_);
glGenFramebuffers(1, &id_);
return id_;
}
......
......@@ -42,7 +42,7 @@ Texture::Texture(const tgt::ivec3& dimensions, GLint format, GLint internalforma
, internalformat_(internalformat)
, dataType_(dataType)
, filter_(filter)
, wrapping_(REPEAT)
, wrapping_(CLAMP)
, priority_(-1.f)
, pixels_(0)
{
......@@ -56,7 +56,7 @@ Texture::Texture(const tgt::ivec3& dimensions, GLint format,
, internalformat_(format)
, dataType_(dataType)
, filter_(filter)
, wrapping_(REPEAT)
, wrapping_(CLAMP)
, priority_(-1.f)
, pixels_(0)
{
......@@ -70,7 +70,7 @@ Texture::Texture(GLubyte* data, const tgt::ivec3& dimensions, GLint format, GLin
, internalformat_(internalformat)
, dataType_(dataType)
, filter_(filter)
, wrapping_(REPEAT)
, wrapping_(CLAMP)
, priority_(-1.f)
, pixels_(data)
{
......@@ -85,7 +85,7 @@ Texture::Texture(GLubyte* data, const tgt::ivec3& dimensions, GLint format,
, internalformat_(format)
, dataType_(dataType)
, filter_(filter)
, wrapping_(REPEAT)
, wrapping_(CLAMP)
, priority_(-1.f)
, pixels_(data)
{
......@@ -148,60 +148,106 @@ int Texture::calcBpp(GLint format, GLenum dataType) {
}
int Texture::calcBpp(GLint internalformat) {
// supports all formats from http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml
int bpp = 0;
switch (internalformat) {
case 1:
case GL_COLOR_INDEX:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA8:
case GL_INTENSITY:
case GL_LUMINANCE:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_R8:
case GL_R8_SNORM:
case GL_R8I:
case GL_R8UI:
case GL_R3_G3_B2:
case GL_RGBA2:
bpp = 1;
break;
case 2:
case GL_LUMINANCE_ALPHA:
case GL_INTENSITY16:
case GL_ALPHA16:
case GL_DEPTH_COMPONENT16:
case GL_R16_SNORM:
case GL_R16F:
case GL_R16I:
case GL_R16UI:
case GL_DEPTH_STENCIL:
case GL_RG:
case GL_RG8:
case GL_RG8_SNORM:
case GL_RG8I:
case GL_RG8UI:
case GL_RGB4:
case GL_RGB5:
case GL_RGBA4:
case GL_RGB5_A1:
bpp = 2;
break;
case GL_DEPTH_COMPONENT24:
case GL_RGB:
case GL_RGB8:
case GL_BGR:
case GL_DEPTH_COMPONENT24:
case GL_RGB8_SNORM:
case GL_SRGB8:
case GL_RGB8I:
case GL_RGB8UI:
bpp = 3;
break;
case GL_ALPHA:
case GL_ALPHA32F_ARB:
case GL_DEPTH_COMPONENT32:
case GL_DEPTH_COMPONENT32F:
case GL_R32F:
case GL_R32I:
case GL_R32UI:
case GL_RG16:
case GL_RG16_SNORM:
case GL_RG16F:
case GL_RG16I:
case GL_RG16UI:
case GL_RGB10:
case GL_R11F_G11F_B10F:
case GL_RGB9_E5:
case GL_RGBA:
case GL_RGBA8:
case GL_BGRA:
case GL_DEPTH_COMPONENT32:
case GL_RGBA8_SNORM:
case GL_RGB10_A2:
case GL_RGB10_A2UI:
case GL_SRGB8_ALPHA8:
case GL_RGBA8I:
case GL_RGBA8UI:
bpp = 4;
break;
case GL_RGB16:
case GL_RGB16F_ARB:
case GL_RGB12:
bpp = 5;
break;
case GL_RGB16_SNORM:
case GL_RGB16F:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGBA12:
bpp = 6;
break;
case GL_RG32F:
case GL_RG32I:
case GL_RG32UI:
case GL_RGBA16:
case GL_RGBA16F_ARB:
case GL_RGBA16F:
case GL_RGBA16I:
case GL_RGBA16UI:
bpp = 8;
break;
case GL_RGB32F_ARB:
case GL_RGB32F:
case GL_RGB32I:
case GL_RGB32UI:
bpp = 12;
break;
case GL_RGBA32F_ARB:
case GL_RGBA32F:
case GL_RGBA32I:
case GL_RGBA32UI:
bpp = 16;
break;
......@@ -214,45 +260,93 @@ int Texture::calcBpp(GLint internalformat) {
}
int Texture::calcNumChannels(GLint format) {
// supports all formats from http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml
switch (format) {
case 1:
case GL_COLOR_INDEX:
case GL_RED:
case GL_RED_INTEGER:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_INTENSITY:
case GL_LUMINANCE:
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT24:
case GL_ALPHA_INTEGER_EXT:
return 1;
break;
case 1:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_R8:
case GL_R8_SNORM:
case GL_R16_SNORM:
case GL_R16F:
case GL_R32F:
case GL_R8I:
case GL_R8UI:
case GL_R16I:
case GL_R16UI:
case GL_R32I:
case GL_R32UI:
return 1;
break;
case 2:
case GL_LUMINANCE_ALPHA:
return 2;
break;
case 2:
case GL_DEPTH_STENCIL:
case GL_RG:
case GL_RG8:
case GL_RG8_SNORM:
case GL_RG16:
case GL_RG16_SNORM:
case GL_RG16F:
case GL_RG32F:
case GL_RG8I: