--- /dev/null
+extension ARB_texture_swizzle
LUMINANCE8 = GL_LUMINANCE8,
LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8,
+
+ // Deprecated
SLUMINANCE = GL_SLUMINANCE,
SLUMINANCE8 = GL_SLUMINANCE8,
SLUMINANCE_ALPHA = GL_SLUMINANCE_ALPHA,
#include <msp/gl/extensions/arb_direct_state_access.h>
#include <msp/gl/extensions/arb_shadow.h>
+#include <msp/gl/extensions/arb_texture_swizzle.h>
#include <msp/gl/extensions/ext_framebuffer_object.h>
#include <msp/gl/extensions/ext_texture3d.h>
#include <msp/gl/extensions/ext_texture_filter_anisotropic.h>
}
+int Texture::swizzle_orders[] =
+{
+ GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA,
+ GL_RED, GL_RED, GL_RED, GL_ONE,
+ GL_RED, GL_RED, GL_RED, GL_GREEN
+};
+
Texture::Texture(GLenum t, ResourceManager *m):
id(0),
target(t),
fmt = get_sized_pixelformat(fmt, size);
}
+ FormatSwizzle swiz = NO_SWIZZLE;
+ if(ARB_texture_rg && ARB_texture_swizzle)
+ {
+ if(fmt==LUMINANCE8 || fmt==SLUMINANCE8)
+ {
+ fmt = R8;
+ swiz = R_TO_LUMINANCE;
+ }
+ else if(fmt==LUMINANCE8_ALPHA8 || fmt==SLUMINANCE8_ALPHA8)
+ {
+ fmt = RG8;
+ swiz = RG_TO_LUMINANCE_ALPHA;
+ }
+ }
+
require_pixelformat(fmt);
ifmt = fmt;
+ swizzle = swiz;
+ if(swizzle)
+ update_parameter(FORMAT_SWIZZLE);
+}
+
+PixelFormat Texture::get_upload_format(PixelFormat fmt) const
+{
+ if(fmt==LUMINANCE || fmt==LUMINANCE_ALPHA)
+ return get_base_pixelformat(ifmt);
+ else
+ return fmt;
}
void Texture::update_parameter(int mask) const
set_parameter_i(GL_TEXTURE_COMPARE_MODE, (compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE));
if(mask&COMPARE_FUNC)
set_parameter_i(GL_TEXTURE_COMPARE_FUNC, cmp_func);
+ if(mask&FORMAT_SWIZZLE)
+ {
+ if(ARB_direct_state_access)
+ glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
+ else
+ glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
+ }
}
void Texture::set_parameter_i(GLenum param, int value) const
GENERATE_MIPMAP = 32,
COMPARE = 64,
COMPARE_FUNC = 128,
- MAX_ANISOTROPY = 256
+ MAX_ANISOTROPY = 256,
+ FORMAT_SWIZZLE = 512
+ };
+
+ enum FormatSwizzle
+ {
+ NO_SWIZZLE,
+ R_TO_LUMINANCE,
+ RG_TO_LUMINANCE_ALPHA
};
unsigned id;
GLenum target;
PixelFormat ifmt;
+ FormatSwizzle swizzle;
TextureFilter min_filter;
TextureFilter mag_filter;
float max_anisotropy;
Predicate cmp_func;
mutable int dirty_params;
+ static int swizzle_orders[];
+
Texture(GLenum, ResourceManager * = 0);
Texture(const Texture &);
Texture &operator=(const Texture &);
protected:
static DataType get_alloc_type(PixelFormat);
void set_internal_format(PixelFormat);
+ PixelFormat get_upload_format(PixelFormat) const;
void update_parameter(int) const;
void set_parameter_i(GLenum, int) const;
return sub_image(level, 0, w, fmt, type, data);
BindRestore _bind(this);
- glTexImage1D(target, level, ifmt, w, 0, fmt, type, data);
+ glTexImage1D(target, level, ifmt, w, 0, get_upload_format(fmt), type, data);
allocated |= 1<<level;
if(gen_mipmap && level==0)
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
+ fmt = get_upload_format(fmt);
if(ARB_direct_state_access)
glTextureSubImage1D(id, level, x, wd, fmt, type, data);
else
return sub_image(level, 0, 0, w, h, fmt, type, data);
BindRestore _bind(this);
- glTexImage2D(target, level, ifmt, w, h, 0, fmt, type, data);
+ glTexImage2D(target, level, ifmt, w, h, 0, get_upload_format(fmt), type, data);
allocated |= 1<<level;
if(gen_mipmap && level==0)
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
+ fmt = get_upload_format(fmt);
if(ARB_direct_state_access)
glTextureSubImage2D(id, level, x, y, wd, ht, fmt, type, data);
else
return sub_image(level, 0, 0, 0, w, h, d, fmt, type, data);
BindRestore _bind(this);
- glTexImage3D(target, level, ifmt, width, height, depth, 0, fmt, type, data);
+ glTexImage3D(target, level, ifmt, width, height, depth, 0, get_upload_format(fmt), type, data);
allocated |= 1<<level;
if(gen_mipmap && level==0)
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
+ fmt = get_upload_format(fmt);
if(ARB_direct_state_access)
glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, fmt, type, data);
else
return sub_image(face, level, 0, 0, s, s, fmt, type, data);
BindRestore _bind(this);
- glTexImage2D(face, level, ifmt, s, s, 0, fmt, type, data);
+ glTexImage2D(face, level, ifmt, s, s, 0, get_upload_format(fmt), type, data);
// XXX Allocation should be tracked per-face, but we'll run out of bits
allocated |= 1<<level;
BindRestore _bind(this);
allocate(level);
- glTexSubImage2D(face, level, x, y, wd, ht, fmt, type, data);
+ glTexSubImage2D(face, level, x, y, wd, ht, get_upload_format(fmt), type, data);
if(gen_mipmap && level==0)
auto_generate_mipmap();