LUMINANCE formats were deprecated in OpenGL 3.0. ARB_texture_swizzle
was not promoted to core until 3.3, so it's possible this won't work on
some transition period hardware.
SLUMINANCE formats are marked as deprecated in mspgl since it's not
possible to properly emulate them through swizzling.
--- /dev/null
+extension ARB_texture_swizzle
LUMINANCE8 = GL_LUMINANCE8,
LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8,
LUMINANCE8 = GL_LUMINANCE8,
LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8,
SLUMINANCE = GL_SLUMINANCE,
SLUMINANCE8 = GL_SLUMINANCE8,
SLUMINANCE_ALPHA = GL_SLUMINANCE_ALPHA,
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_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>
#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),
Texture::Texture(GLenum t, ResourceManager *m):
id(0),
target(t),
fmt = get_sized_pixelformat(fmt, size);
}
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;
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
}
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);
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
}
void Texture::set_parameter_i(GLenum param, int value) const
GENERATE_MIPMAP = 32,
COMPARE = 64,
COMPARE_FUNC = 128,
GENERATE_MIPMAP = 32,
COMPARE = 64,
COMPARE_FUNC = 128,
+ MAX_ANISOTROPY = 256,
+ FORMAT_SWIZZLE = 512
+ };
+
+ enum FormatSwizzle
+ {
+ NO_SWIZZLE,
+ R_TO_LUMINANCE,
+ RG_TO_LUMINANCE_ALPHA
};
unsigned id;
GLenum target;
PixelFormat ifmt;
};
unsigned id;
GLenum target;
PixelFormat ifmt;
TextureFilter min_filter;
TextureFilter mag_filter;
float max_anisotropy;
TextureFilter min_filter;
TextureFilter mag_filter;
float max_anisotropy;
Predicate cmp_func;
mutable int dirty_params;
Predicate cmp_func;
mutable int dirty_params;
+ static int swizzle_orders[];
+
Texture(GLenum, ResourceManager * = 0);
Texture(const Texture &);
Texture &operator=(const Texture &);
Texture(GLenum, ResourceManager * = 0);
Texture(const Texture &);
Texture &operator=(const Texture &);
protected:
static DataType get_alloc_type(PixelFormat);
void set_internal_format(PixelFormat);
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;
void update_parameter(int) const;
void set_parameter_i(GLenum, int) const;
return sub_image(level, 0, w, fmt, type, data);
BindRestore _bind(this);
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)
allocated |= 1<<level;
if(gen_mipmap && level==0)
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
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
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);
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)
allocated |= 1<<level;
if(gen_mipmap && level==0)
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
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
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);
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)
allocated |= 1<<level;
if(gen_mipmap && level==0)
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
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
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);
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;
// XXX Allocation should be tracked per-face, but we'll run out of bits
allocated |= 1<<level;
BindRestore _bind(this);
allocate(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();
if(gen_mipmap && level==0)
auto_generate_mipmap();