--- /dev/null
+extension MSP_luminance_formats
<command name="glPrimitiveRestartIndex" />
</require>
</extension>
+
+ <extension name="GL_MSP_luminance_formats" supported="gl">
+ <require>
+ <enum name="GL_LUMINANCE" />
+ <enum name="GL_LUMINANCE_ALPHA" />
+ <enum name="GL_LUMINANCE8" />
+ <enum name="GL_LUMINANCE8_ALPHA8" />
+ </require>
+ </extension>
</extensions>
</registry>
namespace GL {
AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float):
- occlude_target(w, h, (RENDER_COLOR,RED)),
+ occlude_target(w, h, (RENDER_COLOR,R8)),
occlude_shader("ambientocclusion_occlude.glsl"),
combine_shader("ambientocclusion_combine.glsl"),
quad(get_fullscreen_quad())
texturing.attach(2, occlude_target.get_target_texture(RENDER_COLOR));
unsigned seed = 1;
- rotate_lookup.storage(RGBA, 4, 4, 1);
+ rotate_lookup.storage(RGBA8, 4, 4, 1);
rotate_lookup.get_default_sampler().set_filter(NEAREST);
unsigned char data[64];
for(unsigned i=0; i<16; ++i)
shdata.uniform("source", 0);
shdata.uniform("curve", 1);
- curve.storage(LUMINANCE, 256, 1);
+ curve.storage(LUMINANCE8, 256, 1);
Sampler &sampler = curve.get_default_sampler();
sampler.set_min_filter(LINEAR);
sampler.set_wrap(CLAMP_TO_EDGE);
#define MSP_GL_DATATYPE_H_
#include "gl.h"
+#include <msp/gl/extensions/nv_half_float.h>
namespace Msp {
namespace GL {
UNSIGNED_SHORT = GL_UNSIGNED_SHORT,
INT = GL_INT,
UNSIGNED_INT = GL_UNSIGNED_INT,
- FLOAT = GL_FLOAT
+ FLOAT = GL_FLOAT,
+ HALF_FLOAT = GL_HALF_FLOAT
};
+unsigned get_type_size(DataType);
+
} // namespace GL
} // namespace Msp
update_interval(1),
update_delay(0)
{
- env_tex.storage(RGB, size, 1);
+ env_tex.storage(RGB8, size, 1);
Sampler &env_samp = env_tex.get_default_sampler();
env_samp.set_wrap(CLAMP_TO_EDGE);
env_samp.set_min_filter(LINEAR);
- depth_buf.storage(DEPTH_COMPONENT, size, size);
+ depth_buf.storage(DEPTH_COMPONENT32F, size, size);
for(unsigned i=0; i<6; ++i)
{
fbo[i].attach(COLOR_ATTACHMENT0, env_tex, TextureCube::enumerate_faces(i), 0);
target_ms = 0;
}
- PixelFormat color_pf = (hdr ? (alpha ? RGBA16F : RGB16F) : (alpha ? RGBA : RGB));
+ PixelFormat color_pf = (hdr ? (alpha ? RGBA16F : RGB16F) : (alpha ? RGBA8 : RGB8));
RenderTargetFormat fmt = (RENDER_COLOR,color_pf, RENDER_DEPTH);
if(!postproc.empty() || samples)
{
#include <msp/gl/extensions/arb_texture_float.h>
-#include <msp/gl/extensions/ext_bgra.h>
+#include <msp/io/print.h>
#include <msp/strings/format.h>
#include "pixelformat.h"
namespace Msp {
namespace GL {
-void operator>>(const LexicalConverter &conv, PixelFormat &fmt)
+void operator>>(const LexicalConverter &conv, PixelComponents &comp)
{
if(conv.get()=="STENCIL_INDEX")
- fmt = STENCIL_INDEX;
+ comp = STENCIL_INDEX;
else if(conv.get()=="DEPTH_COMPONENT")
- fmt = DEPTH_COMPONENT;
+ comp = DEPTH_COMPONENT;
else if(conv.get()=="RED")
- fmt = RED;
+ comp = RED;
else if(conv.get()=="RG")
- fmt = RG;
+ comp = RG;
else if(conv.get()=="RGB")
- fmt = RGB;
+ comp = RGB;
else if(conv.get()=="RGBA")
- fmt = RGBA;
+ comp = RGBA;
else if(conv.get()=="BGR")
- fmt = BGR;
+ comp = BGR;
else if(conv.get()=="BGRA")
- fmt = BGRA;
- else if(conv.get()=="SRGB")
- fmt = SRGB;
- else if(conv.get()=="SRGB_ALPHA")
- fmt = SRGB_ALPHA;
+ comp = BGRA;
else if(conv.get()=="LUMINANCE")
- fmt = LUMINANCE;
+ comp = LUMINANCE;
else if(conv.get()=="LUMINANCE_ALPHA")
- fmt = LUMINANCE_ALPHA;
+ comp = LUMINANCE_ALPHA;
else
throw lexical_error(format("conversion of '%s' to PixelFormat", conv.get()));
}
-PixelFormat pixelformat_from_graphics(Graphics::PixelFormat pf)
+void operator>>(const LexicalConverter &conv, PixelFormat &fmt)
+{
+ if(conv.get()=="R8")
+ fmt = R8;
+ else if(conv.get()=="R16F")
+ fmt = R16F;
+ else if(conv.get()=="R32F")
+ fmt = R32F;
+ else if(conv.get()=="RG8")
+ fmt = RG8;
+ else if(conv.get()=="RG16F")
+ fmt = RG16F;
+ else if(conv.get()=="RG32F")
+ fmt = RG32F;
+ else if(conv.get()=="RGB8")
+ fmt = RGB8;
+ else if(conv.get()=="RGB16F")
+ fmt = RGB16F;
+ else if(conv.get()=="RGB32F")
+ fmt = RGB32F;
+ else if(conv.get()=="RGBA8")
+ fmt = RGBA8;
+ else if(conv.get()=="RGBA16F")
+ fmt = RGBA16F;
+ else if(conv.get()=="RGBA32F")
+ fmt = RGBA32F;
+ else if(conv.get()=="SRGB8")
+ fmt = SRGB8;
+ else if(conv.get()=="SRGB8_ALPHA8")
+ fmt = SRGB8_ALPHA8;
+ else if(conv.get()=="LUMINANCE8")
+ fmt = LUMINANCE8;
+ else if(conv.get()=="LUMINANCE8_ALPHA8")
+ fmt = LUMINANCE8_ALPHA8;
+ else if(conv.get()=="DEPTH_COMPONENT16")
+ fmt = DEPTH_COMPONENT16;
+ else if(conv.get()=="DEPTH_COMPONENT24")
+ fmt = DEPTH_COMPONENT24;
+ else if(conv.get()=="DEPTH_COMPONENT32")
+ fmt = DEPTH_COMPONENT32;
+ else if(conv.get()=="DEPTH_COMPONENT32F")
+ fmt = DEPTH_COMPONENT32F;
+ else
+ {
+ PixelComponents comp;
+ conv >> comp;
+ fmt = make_pixelformat(comp, (comp==DEPTH_COMPONENT ? FLOAT : UNSIGNED_BYTE));
+ IO::print(IO::cerr, "Warning: deprecated conversion of '%s' to PixelFormat\n", conv.get());
+ }
+}
+
+PixelComponents pixelformat_from_graphics(Graphics::PixelFormat pf)
{
switch(pf)
{
}
}
-PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat pf, bool srgb)
+PixelComponents storage_pixelformat_from_graphics(Graphics::PixelFormat pf)
{
- PixelFormat result;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
switch(pf)
{
case Graphics::RGBX:
case Graphics::BGR:
- case Graphics::BGRX: result = RGB; break;
- case Graphics::BGRA: result = RGBA; break;
- default: result = pixelformat_from_graphics(pf);
+ case Graphics::BGRX: return RGB;
+ case Graphics::BGRA: return RGBA;
+ default: return pixelformat_from_graphics(pf);
}
+#pragma GCC diagnostic pop
+}
- if(srgb)
- return get_srgb_pixelformat(result);
- else
- return result;
+PixelFormat pixelformat_from_image(const Graphics::Image &image)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ PixelComponents comp = pixelformat_from_graphics(image.get_format());
+#pragma GCC diagnostic pop
+ return make_pixelformat(comp, UNSIGNED_BYTE);
+}
+
+PixelFormat make_pixelformat(PixelComponents comp, DataType type, bool srgb)
+{
+ if(srgb && type!=UNSIGNED_BYTE && comp!=RGB && comp!=RGBA)
+ throw invalid_argument("make_pixelformat");
+
+ switch(comp)
+ {
+ case RED:
+ switch(type)
+ {
+ case UNSIGNED_BYTE: return R8;
+ case HALF_FLOAT: return R16F;
+ case FLOAT: return R32F;
+ default: throw invalid_argument("make_pixelformat");
+ }
+ case RG:
+ switch(type)
+ {
+ case UNSIGNED_BYTE: return RG8;
+ case HALF_FLOAT: return RG16F;
+ case FLOAT: return RG32F;
+ default: throw invalid_argument("make_pixelformat");
+ }
+ case RGB:
+ switch(type)
+ {
+ case UNSIGNED_BYTE: return (srgb ? SRGB8 : RGB8);
+ case HALF_FLOAT: return RGB16F;
+ case FLOAT: return RGB32F;
+ default: throw invalid_argument("make_pixelformat");
+ }
+ case RGBA:
+ switch(type)
+ {
+ case UNSIGNED_BYTE: return (srgb ? SRGB8_ALPHA8 : RGBA8);
+ case HALF_FLOAT: return RGBA16F;
+ case FLOAT: return RGBA32F;
+ default: throw invalid_argument("make_pixelformat");
+ }
+ case LUMINANCE:
+ if(type!=UNSIGNED_BYTE)
+ throw invalid_argument("make_pixelformat");
+ return LUMINANCE8;
+ case LUMINANCE_ALPHA:
+ if(type!=UNSIGNED_BYTE)
+ throw invalid_argument("make_pixelformat");
+ return LUMINANCE8;
+ case STENCIL_INDEX:
+ if(type!=UNSIGNED_BYTE)
+ throw invalid_argument("make_pixelformat");
+ return STENCIL_INDEX8;
+ case DEPTH_COMPONENT:
+ switch(type)
+ {
+ case UNSIGNED_SHORT: return DEPTH_COMPONENT16;
+ case UNSIGNED_INT: return DEPTH_COMPONENT32;
+ case FLOAT: return DEPTH_COMPONENT32F;
+ default: throw invalid_argument("make_pixelformat");
+ }
+ default:
+ throw invalid_argument("make_pixelformat");
+ }
}
PixelFormat get_base_pixelformat(PixelFormat pf)
{
- PixelFormat unsized = get_unsized_pixelformat(pf);
- switch(unsized)
+ switch(pf)
{
- case SRGB: return RGB;
- case SRGB_ALPHA: return RGBA;
- default: return unsized;
+ case SRGB8: return RGB8;
+ case SRGB8_ALPHA8: return RGBA8;
+ default: return pf;
}
}
-PixelFormat get_unsized_pixelformat(PixelFormat pf)
+PixelComponents get_components(PixelFormat pf)
{
switch(pf)
{
case RG32F: return RG;
case RGB8:
case RGB16F:
- case RGB32F: return RGB;
- case SRGB8: return SRGB;
+ case RGB32F:
+ case SRGB8: return RGB;
case RGBA8:
case RGBA16F:
- case RGBA32F: return RGBA;
- case SRGB8_ALPHA8: return SRGB_ALPHA;
+ case RGBA32F:
+ case SRGB8_ALPHA8: return RGBA;
+ case LUMINANCE8: return LUMINANCE;
+ case LUMINANCE8_ALPHA8: return LUMINANCE_ALPHA;
+ case STENCIL_INDEX8: return STENCIL_INDEX;
case DEPTH_COMPONENT16:
case DEPTH_COMPONENT24:
case DEPTH_COMPONENT32:
case DEPTH_COMPONENT32F: return DEPTH_COMPONENT;
- default: return pf;
- }
-}
-
-PixelFormat get_sized_pixelformat(PixelFormat pf, unsigned size)
-{
- if(!size || size>4)
- throw invalid_argument("get_sized_pixelformat");
-
- pf = get_unsized_pixelformat(pf);
-
- switch(size)
- {
- case 1:
- switch(pf)
- {
- case RED: return R8;
- case RG: return RG8;
- case RGB: return RGB8;
- case RGBA: return RGBA8;
- case SRGB: return SRGB8;
- case SRGB_ALPHA: return SRGB8_ALPHA8;
- default: throw invalid_argument("get_sized_pixelformat");
- }
- case 2:
- switch(pf)
- {
- case RED: return R16F;
- case RG: return RG16F;
- case RGB: return RGB16F;
- case RGBA: return RGBA16F;
- case DEPTH_COMPONENT: return DEPTH_COMPONENT16;
- default: throw invalid_argument("get_sized_pixelformat");
- }
- case 3:
- if(pf==DEPTH_COMPONENT)
- return DEPTH_COMPONENT24;
- else
- throw invalid_argument("get_sized_pixelformat");
- case 4:
- switch(pf)
- {
- case RED: return R32F;
- case RG: return RG32F;
- case RGB: return RGB32F;
- case RGBA: return RGBA32F;
- case DEPTH_COMPONENT: return ARB_depth_buffer_float ? DEPTH_COMPONENT32F : DEPTH_COMPONENT32;
- default: throw invalid_argument("get_sized_pixelformat");
- }
- default:
- throw invalid_argument("get_sized_pixelformat");
+ default: throw invalid_argument("get_components");
}
}
-PixelFormat get_default_sized_pixelformat(PixelFormat pf)
+PixelFormat get_default_sized_pixelformat(PixelComponents comp)
{
- pf = get_unsized_pixelformat(pf);
- unsigned size = 1;
- if(pf==DEPTH_COMPONENT)
+ DataType type = UNSIGNED_BYTE;
+ if(comp==DEPTH_COMPONENT)
{
if(get_gl_api()==OPENGL_ES2 && !ARB_depth_buffer_float)
- size = 2;
+ type = UNSIGNED_SHORT;
else
- size = 4;
+ type = FLOAT;
}
- return get_sized_pixelformat(pf, size);
+ return make_pixelformat(comp, type);
}
PixelFormat get_srgb_pixelformat(PixelFormat pf)
{
switch(pf)
{
- case RGB: return SRGB;
- case RGBA: return SRGB_ALPHA;
case RGB8: return SRGB8;
case RGBA8: return SRGB8_ALPHA8;
default: return pf;
}
}
-unsigned get_component_count(PixelFormat pf)
+unsigned get_component_count(PixelComponents comp)
{
- switch(get_base_pixelformat(pf))
+ switch(comp)
{
case STENCIL_INDEX:
case DEPTH_COMPONENT:
}
}
-unsigned get_component_size(PixelFormat pf)
+DataType get_component_type(PixelFormat pf)
{
switch(pf)
{
case RGBA8:
case SRGB8:
case SRGB8_ALPHA8:
- return 1;
+ case LUMINANCE8:
+ case LUMINANCE8_ALPHA8:
+ return UNSIGNED_BYTE;
case R16F:
case RG16F:
case RGB16F:
case RGBA16F:
+ return HALF_FLOAT;
case DEPTH_COMPONENT16:
- return 2;
- case DEPTH_COMPONENT24:
- return 3;
+ return UNSIGNED_SHORT;
case R32F:
case RG32F:
case RGB32F:
case RGBA32F:
case DEPTH_COMPONENT32:
+ return UNSIGNED_INT;
case DEPTH_COMPONENT32F:
- return 4;
+ return FLOAT;
+ case DEPTH_COMPONENT24:
+ // There's no DataType value with 24-bit size
default:
- return 0;
+ throw invalid_argument("get_component_type");
}
}
unsigned get_pixel_size(PixelFormat pf)
{
- return get_component_count(pf)*max(get_component_size(pf), 1U);
+ return get_component_count(pf)*get_type_size(get_component_type(pf));
}
void require_pixelformat(PixelFormat pf)
case RGBA8:
{ static Require _req(OES_required_internalformat); }
break;
- case RED:
case R8:
- case RG:
case RG8:
{ static Require _req(ARB_texture_rg); }
break;
case RGBA32F:
{ static Require _req(ARB_texture_float); }
break;
- case SRGB:
case SRGB8:
- case SRGB_ALPHA:
case SRGB8_ALPHA8:
{ static Require _req(EXT_texture_sRGB); }
break;
- case BGR:
- case BGRA:
- { static Require _req(EXT_bgra); }
- break;
- case DEPTH_COMPONENT:
- { static Require _req(ARB_depth_texture); }
- break;
case DEPTH_COMPONENT16:
case DEPTH_COMPONENT24:
case DEPTH_COMPONENT32:
case DEPTH_COMPONENT32F:
{ static Require _req(ARB_depth_buffer_float); }
break;
- case STENCIL_INDEX:
+ case STENCIL_INDEX8:
{ static Require _req(OES_texture_stencil8); }
break;
default:
- break;
+ throw invalid_argument("require_pixelformat");
}
}
#ifndef MSP_GL_PIXELFORMAT_H_
#define MSP_GL_PIXELFORMAT_H_
-#include <msp/graphics/pixelformat.h>
+#include <msp/core/attributes.h>
+#include <msp/graphics/image.h>
#include <msp/strings/lexicalcast.h>
#include "gl.h"
#include <msp/gl/extensions/arb_depth_buffer_float.h>
#include <msp/gl/extensions/ext_texture_srgb.h>
#include <msp/gl/extensions/oes_required_internalformat.h>
#include <msp/gl/extensions/oes_texture_stencil8.h>
+#include <msp/gl/extensions/msp_luminance_formats.h>
+#include "datatype.h"
namespace Msp {
namespace GL {
-enum PixelFormat
+enum PixelComponents
{
STENCIL_INDEX = GL_STENCIL_INDEX,
DEPTH_COMPONENT = GL_DEPTH_COMPONENT,
- DEPTH_COMPONENT16 = GL_DEPTH_COMPONENT16,
- DEPTH_COMPONENT24 = GL_DEPTH_COMPONENT24,
- DEPTH_COMPONENT32 = GL_DEPTH_COMPONENT32,
- DEPTH_COMPONENT32F = GL_DEPTH_COMPONENT32F,
RED = GL_RED,
RG = GL_RG,
RGB = GL_RGB,
RGBA = GL_RGBA,
+ BGR = GL_BGR,
+ BGRA = GL_BGRA,
+ LUMINANCE = GL_LUMINANCE,
+ LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA
+};
+
+enum PixelFormat
+{
R8 = GL_R8,
R16F = GL_R16F,
R32F = GL_R32F,
RGBA8 = GL_RGBA8,
RGBA16F = GL_RGBA16F,
RGBA32F = GL_RGBA32F,
- SRGB = GL_SRGB,
- SRGB_ALPHA = GL_SRGB_ALPHA,
SRGB8 = GL_SRGB8,
SRGB8_ALPHA8 = GL_SRGB8_ALPHA8,
- BGR = GL_BGR,
- BGRA = GL_BGRA,
- LUMINANCE = GL_LUMINANCE,
- LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA
+ LUMINANCE8 = GL_LUMINANCE8,
+ LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8,
+ DEPTH_COMPONENT16 = GL_DEPTH_COMPONENT16,
+ DEPTH_COMPONENT24 = GL_DEPTH_COMPONENT24,
+ DEPTH_COMPONENT32 = GL_DEPTH_COMPONENT32,
+ DEPTH_COMPONENT32F = GL_DEPTH_COMPONENT32F,
+ STENCIL_INDEX8 = GL_STENCIL_INDEX8
};
+void operator>>(const LexicalConverter &, PixelComponents &);
void operator>>(const LexicalConverter &, PixelFormat &);
-PixelFormat pixelformat_from_graphics(Graphics::PixelFormat);
-PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat, bool = false);
+DEPRECATED PixelComponents pixelformat_from_graphics(Graphics::PixelFormat);
+DEPRECATED PixelComponents storage_pixelformat_from_graphics(Graphics::PixelFormat, bool);
+PixelFormat pixelformat_from_image(const Graphics::Image &);
+
+PixelFormat make_pixelformat(PixelComponents, DataType, bool = false);
+DEPRECATED PixelFormat get_base_pixelformat(PixelFormat);
+PixelComponents get_components(PixelFormat);
+DEPRECATED PixelFormat get_default_sized_pixelformat(PixelComponents);
+DEPRECATED PixelFormat get_srgb_pixelformat(PixelFormat);
+
+unsigned get_component_count(PixelComponents);
+inline unsigned get_component_count(PixelFormat f)
+{ return get_component_count(get_components(f)); }
+
+DataType get_component_type(PixelFormat);
+inline unsigned get_component_size(PixelFormat f)
+{ return get_type_size(get_component_type(f)); }
-PixelFormat get_base_pixelformat(PixelFormat);
-PixelFormat get_unsized_pixelformat(PixelFormat);
-PixelFormat get_sized_pixelformat(PixelFormat, unsigned = 1);
-PixelFormat get_default_sized_pixelformat(PixelFormat);
-PixelFormat get_srgb_pixelformat(PixelFormat);
-unsigned get_component_count(PixelFormat);
-unsigned get_component_size(PixelFormat);
unsigned get_pixel_size(PixelFormat);
void require_pixelformat(PixelFormat);
+DEPRECATED inline PixelFormat get_sized_pixelformat(PixelComponents c, unsigned s = 1)
+{ return make_pixelformat(c, (s==2 ? HALF_FLOAT : s==4 ? FLOAT : UNSIGNED_BYTE)); }
+
+DEPRECATED inline PixelComponents get_unsized_pixelformat(PixelFormat f)
+{ return get_components(f); }
+
} // namespace GL
} // namespace Msp
{
PixelStore pstore;
unsigned stride = img.get_stride();
- unsigned ncomp = get_component_count(pixelformat_from_graphics(img.get_format()));
+ unsigned ncomp = get_component_count(pixelformat_from_image(img));
pstore.set_canvas_size(img.get_stride()/ncomp, 0);
pstore.set_alignment(min(stride&~(stride-1), 8U));
return pstore;
glDeleteRenderbuffers(1, &id);
}
-PixelFormat Renderbuffer::normalize_format(PixelFormat fmt)
-{
- if(!get_component_size(fmt) && OES_required_internalformat)
- return get_default_sized_pixelformat(fmt);
-
- return fmt;
-}
-
void Renderbuffer::storage(PixelFormat fmt, unsigned wd, unsigned ht)
{
- fmt = normalize_format(fmt);
require_pixelformat(fmt);
width = wd;
height = ht;
if(samples>get_max_samples())
throw out_of_range("Renderbuffer::storage_multisample");
- fmt = normalize_format(fmt);
require_pixelformat(fmt);
width = wd;
unsigned get_width() const { return width; }
unsigned get_height() const { return height; }
-private:
- static PixelFormat normalize_format(PixelFormat);
-
-public:
/** Allocates storage for the renderbuffer. */
void storage(PixelFormat fmt, unsigned wd, unsigned ht);
if(!count)
throw invalid_operation("RenderTargetFormat::operator,");
- PixelFormat unsized = get_unsized_pixelformat(f);
+ PixelComponents comp = get_components(f);
unsigned size = get_component_size(f);
unsigned char out = outputs[count-1];
if(get_output_type(out)>=get_output_type(RENDER_DEPTH))
{
- if(unsized!=DEPTH_COMPONENT)
- throw invalid_argument("RenderTargetformat::operator,");
+ if(comp!=DEPTH_COMPONENT)
+ throw invalid_argument("RenderTargetFormat::operator,");
if(size>1)
--size;
+ if(get_component_type(f)==UNSIGNED_INT)
+ --size;
}
else
{
- if(unsized!=RED && unsized!=RG && unsized!=RGB && unsized!=RGBA)
+ if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA)
throw invalid_argument("RenderTargetformat::operator,");
if(size>3)
--size;
PixelFormat get_output_pixelformat(unsigned char o)
{
- unsigned size = ((o>>2)&3);
- PixelFormat base;
+ PixelComponents comp;
+ DataType type;
if(get_output_type(o)>=get_output_type(RENDER_DEPTH))
{
- base = DEPTH_COMPONENT;
- if(size)
- ++size;
+ static DataType types[4] = { UNSIGNED_SHORT, UNSIGNED_SHORT, UNSIGNED_INT, FLOAT };
+ comp = DEPTH_COMPONENT;
+ type = types[(o>>2)&3];
}
else
{
- static PixelFormat base_formats[4] = { RED, RG, RGB, RGBA };
- base = base_formats[o&3];
- if(size==3)
- ++size;
+ static PixelComponents components[4] = { RED, RG, RGB, RGBA };
+ static DataType types[4] = { UNSIGNED_BYTE, UNSIGNED_SHORT, HALF_FLOAT, FLOAT };
+ comp = components[o&3];
+ type = types[(o>>2)&3];
}
- if(size)
- return get_sized_pixelformat(base, size);
- else
- return base;
+ return make_pixelformat(comp, type);
}
depth_samp.set_min_filter(LINEAR);
depth_samp.set_compare(LEQUAL);
depth_samp.set_wrap(CLAMP_TO_EDGE);
- depth_buf.storage(DEPTH_COMPONENT, size, size, 1);
+ depth_buf.storage(DEPTH_COMPONENT32F, size, size, 1);
fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0);
fbo.require_complete();
Texture::Texture(GLenum t, ResourceManager *m):
id(0),
target(t),
- ifmt(RGB),
+ ifmt(RGB8),
swizzle(NO_SWIZZLE),
auto_gen_mipmap(false),
default_sampler(*this)
glDeleteTextures(1, &id);
}
-DataType Texture::get_alloc_type(PixelFormat fmt)
-{
- return (get_base_pixelformat(fmt)==DEPTH_COMPONENT ? UNSIGNED_SHORT : UNSIGNED_BYTE);
-}
-
void Texture::set_internal_format(PixelFormat fmt)
{
+ PixelComponents comp = get_components(fmt);
FormatSwizzle swiz = NO_SWIZZLE;
- switch(get_base_pixelformat(fmt))
+ switch(comp)
{
case LUMINANCE:
- fmt = RED;
+ comp = RED;
swiz = R_TO_LUMINANCE;
break;
case LUMINANCE_ALPHA:
- fmt = RG;
+ comp = RG;
swiz = RG_TO_LUMINANCE_ALPHA;
break;
default:;
}
- if(!get_component_size(fmt) && OES_required_internalformat)
- fmt = get_default_sized_pixelformat(fmt);
-
+ fmt = make_pixelformat(comp, get_component_type(fmt));
require_pixelformat(fmt);
if(swiz!=NO_SWIZZLE)
static Require _req(ARB_texture_swizzle);
swizzle = swiz;
}
-PixelFormat Texture::get_upload_format(PixelFormat fmt) const
+PixelComponents Texture::get_upload_components(PixelComponents comp) const
{
- if(fmt==LUMINANCE || fmt==LUMINANCE_ALPHA)
- return get_base_pixelformat(ifmt);
+ if(comp==LUMINANCE || comp==LUMINANCE_ALPHA)
+ return get_components(ifmt);
else
- return fmt;
+ return comp;
}
void Texture::apply_swizzle()
~Texture();
protected:
- static DataType get_alloc_type(PixelFormat);
void set_internal_format(PixelFormat);
- PixelFormat get_upload_format(PixelFormat) const;
+ PixelComponents get_upload_components(PixelComponents) const;
void apply_swizzle();
void set_parameter_i(GLenum, int) const;
allocated |= (1<<levels)-1;
}
else
- {
- PixelFormat base_fmt = get_base_pixelformat(ifmt);
- image(level, base_fmt, get_alloc_type(base_fmt), 0);
- }
+ image(level, get_components(ifmt), get_component_type(ifmt), 0);
}
-void Texture1D::image(unsigned level, PixelFormat fmt, DataType type, const void *data)
+void Texture1D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
{
if(width==0)
throw invalid_operation("Texture1D::image");
unsigned w = get_level_size(level);
if(ARB_texture_storage)
- return sub_image(level, 0, w, fmt, type, data);
+ return sub_image(level, 0, w, comp, type, data);
BindRestore _bind(this);
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
apply_swizzle();
}
- glTexImage1D(target, level, ifmt, w, 0, get_upload_format(fmt), type, data);
+ glTexImage1D(target, level, ifmt, w, 0, get_upload_components(comp), type, data);
allocated |= 1<<level;
if(auto_gen_mipmap && level==0)
}
}
-void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelFormat fmt, DataType type, const void *data)
+void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelComponents comp, DataType type, const void *data)
{
if(width==0)
throw invalid_operation("Texture3D::image");
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
- fmt = get_upload_format(fmt);
+ comp = get_upload_components(comp);
if(ARB_direct_state_access)
- glTextureSubImage1D(id, level, x, wd, fmt, type, data);
+ glTextureSubImage1D(id, level, x, wd, comp, type, data);
else
- glTexSubImage1D(target, level, x, wd, fmt, type, data);
+ glTexSubImage1D(target, level, x, wd, comp, type, data);
if(auto_gen_mipmap && level==0)
generate_mipmap();
throw incompatible_data("Texture1D::image");
unsigned w = img.get_width();
- PixelFormat fmt = pixelformat_from_graphics(img.get_format());
+ PixelFormat fmt = pixelformat_from_image(img);
+ PixelComponents comp = get_components(fmt);
+ DataType type = get_component_type(fmt);
if(width==0)
- storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, lv);
+ storage(make_pixelformat(comp, type, srgb), w, lv);
else if(w!=width)
throw incompatible_data("Texture1D::image");
- image(0, fmt, UNSIGNED_BYTE, img.get_data());
+ image(0, comp, type, img.get_data());
}
unsigned Texture1D::get_n_levels() const
void Texture1D::Loader::raw_data(const string &data)
{
- obj.image(0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data());
+ obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
}
void Texture1D::Loader::storage(PixelFormat fmt, unsigned w)
Texture1D();
void storage(PixelFormat, unsigned, unsigned = 0);
+
+ DEPRECATED void storage(PixelComponents c, unsigned w, unsigned l = 0)
+ { storage(make_pixelformat(c, UNSIGNED_BYTE), w, l); }
+
void allocate(unsigned);
- void image(unsigned, PixelFormat, DataType, const void *);
- void sub_image(unsigned, int, unsigned, PixelFormat, DataType, const void *);
+ void image(unsigned, PixelComponents, DataType, const void *);
+ void sub_image(unsigned, int, unsigned, PixelComponents, DataType, const void *);
virtual void image(const Graphics::Image &, unsigned, bool = false);
using Texture::image;
unsigned get_width() const { return width; }
allocated |= (1<<levels)-1;
}
else
- {
- PixelFormat base_fmt = get_base_pixelformat(ifmt);
- image(level, base_fmt, get_alloc_type(base_fmt), 0);
- }
+ image(level, get_components(ifmt), get_component_type(ifmt), 0);
}
-void Texture2D::image(unsigned level, PixelFormat fmt, DataType type, const void *data)
+void Texture2D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
{
if(width==0 || height==0)
throw invalid_operation("Texture2D::image");
get_level_size(level, w, h);
if(ARB_texture_storage)
- return sub_image(level, 0, 0, w, h, fmt, type, data);
+ return sub_image(level, 0, 0, w, h, comp, type, data);
BindRestore _bind(this);
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
apply_swizzle();
}
- glTexImage2D(target, level, ifmt, w, h, 0, get_upload_format(fmt), type, data);
+ glTexImage2D(target, level, ifmt, w, h, 0, get_upload_components(comp), type, data);
allocated |= 1<<level;
if(auto_gen_mipmap && level==0)
}
}
-void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data)
+void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelComponents comp, DataType type, const void *data)
{
if(width==0 || height==0)
throw invalid_operation("Texture2D::sub_image");
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
- fmt = get_upload_format(fmt);
+ comp = get_upload_components(comp);
if(ARB_direct_state_access)
- glTextureSubImage2D(id, level, x, y, wd, ht, fmt, type, data);
+ glTextureSubImage2D(id, level, x, y, wd, ht, comp, type, data);
else
- glTexSubImage2D(target, level, x, y, wd, ht, fmt, type, data);
+ glTexSubImage2D(target, level, x, y, wd, ht, comp, type, data);
if(auto_gen_mipmap && level==0)
generate_mipmap();
{
unsigned w = img.get_width();
unsigned h = img.get_height();
- PixelFormat fmt = pixelformat_from_graphics(img.get_format());
+ PixelFormat fmt = pixelformat_from_image(img);
+ PixelComponents comp = get_components(fmt);
+ DataType type = get_component_type(fmt);
if(width==0)
- storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, lv);
+ storage(make_pixelformat(comp, type, srgb), w, h, lv);
else if(w!=width || h!=height || (lv && lv!=levels))
throw incompatible_data("Texture2D::image");
PixelStore pstore = PixelStore::from_image(img);
BindRestore _bind_ps(pstore);
- image(0, fmt, UNSIGNED_BYTE, from_buffer ? 0 : img.get_data());
+ image(0, comp, type, from_buffer ? 0 : img.get_data());
}
unsigned Texture2D::get_n_levels() const
void Texture2D::Loader::raw_data(const string &data)
{
- obj.image(0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data());
+ obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
}
void Texture2D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h)
it can't be changed. */
void storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned lv = 0);
+ DEPRECATED void storage(PixelComponents cm, unsigned wd, unsigned ht, unsigned lv = 0)
+ { storage(make_pixelformat(cm, UNSIGNED_BYTE), wd, ht, lv); }
+
/** Allocates storage for the texture. The contents are initially
undefined. If storage has already been allocated, does nothing. */
void allocate(unsigned level);
/** Uploads an image to the texture. Storage must be defined beforehand.
The image data must have dimensions and format compatible with the defined
storage. */
- void image(unsigned level, PixelFormat fmt, DataType type, const void *data);
+ void image(unsigned level, PixelComponents fmt, DataType type, const void *data);
/** Updates a rectangular region of the texture. Storage must be defined
and allocated beforehand. The update region must be fully inside the
texture. */
void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht,
- PixelFormat fmt, DataType type, const void *data);
+ PixelComponents fmt, DataType type, const void *data);
/** Uploads an image to the texture. If storage has not been defined, it
will be set to match the image. Otherwise the image must be compatible with
static Require _req(EXT_texture_array);
}
-void Texture2DArray::layer_image(unsigned level, unsigned z, PixelFormat fmt, DataType type, const void *data)
+void Texture2DArray::layer_image(unsigned level, unsigned z, PixelComponents comp, DataType type, const void *data)
{
unsigned w = get_width();
unsigned h = get_height();
unsigned d = get_depth();
get_level_size(level, w, h, d);
- sub_image(level, 0, 0, z, w, h, 1, fmt, type, data);
+ sub_image(level, 0, 0, z, w, h, 1, comp, type, data);
}
void Texture2DArray::layer_image(unsigned level, unsigned z, const Graphics::Image &img)
unsigned w = img.get_width();
unsigned h = img.get_height();
- PixelFormat fmt = pixelformat_from_graphics(img.get_format());
+ PixelFormat fmt = pixelformat_from_image(img);
if(w!=get_width() || h!=get_height())
throw incompatible_data("Texture2DArray::layer_image");
PixelStore pstore = PixelStore::from_image(img);
BindRestore _bind_ps(pstore);
- layer_image(level, z, fmt, UNSIGNED_BYTE, img.get_data());
+ layer_image(level, z, get_components(fmt), get_component_type(fmt), img.get_data());
}
Texture2DArray();
- void layer_image(unsigned, unsigned, PixelFormat, DataType, const void *);
+ void layer_image(unsigned, unsigned, PixelComponents, DataType, const void *);
void layer_image(unsigned, unsigned, const Graphics::Image &);
unsigned get_layers() const { return get_depth(); }
allocated |= (1<<levels)-1;
}
else
- {
- PixelFormat base_fmt = get_base_pixelformat(ifmt);
- image(level, base_fmt, get_alloc_type(base_fmt), 0);
- }
+ image(level, get_components(ifmt), get_component_type(ifmt), 0);
}
-void Texture3D::image(unsigned level, PixelFormat fmt, DataType type, const void *data)
+void Texture3D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
{
if(width==0 || height==0 || depth==0)
throw invalid_operation("Texture3D::image");
get_level_size(level, w, h, d);
if(ARB_texture_storage)
- return sub_image(level, 0, 0, 0, w, h, d, fmt, type, data);
+ return sub_image(level, 0, 0, 0, w, h, d, comp, type, data);
BindRestore _bind(this);
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
apply_swizzle();
}
- glTexImage3D(target, level, ifmt, width, height, depth, 0, get_upload_format(fmt), type, data);
+ glTexImage3D(target, level, ifmt, width, height, depth, 0, get_upload_components(comp), type, data);
allocated |= 1<<level;
if(auto_gen_mipmap && level==0)
}
}
-void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, PixelFormat fmt, DataType type, const void *data)
+void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, PixelComponents comp, DataType type, const void *data)
{
if(width==0 || height==0 || depth==0)
throw invalid_operation("Texture3D::image");
Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
allocate(level);
- fmt = get_upload_format(fmt);
+ comp = get_upload_components(comp);
if(ARB_direct_state_access)
- glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, fmt, type, data);
+ glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, comp, type, data);
else
- glTexSubImage3D(target, level, x, y, z, wd, ht, dp, fmt, type, data);
+ glTexSubImage3D(target, level, x, y, z, wd, ht, dp, comp, type, data);
if(auto_gen_mipmap && level==0)
generate_mipmap();
h = w;
}
- PixelFormat fmt = pixelformat_from_graphics(img.get_format());
+ PixelFormat fmt = pixelformat_from_image(img);
+ PixelComponents comp = get_components(fmt);
+ DataType type = get_component_type(fmt);
if(width==0)
- storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, d, lv);
+ storage(make_pixelformat(comp, type, srgb), w, h, d, lv);
else if(w!=width || h!=height || d!=depth)
throw incompatible_data("Texture3D::load_image");
PixelStore pstore = PixelStore::from_image(img);
BindRestore _bind_ps(pstore);
- image(0, fmt, UNSIGNED_BYTE, img.get_data());
+ image(0, comp, type, img.get_data());
}
unsigned Texture3D::get_n_levels() const
void Texture3D::Loader::raw_data(const string &data)
{
- obj.image(0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data());
+ obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
}
void Texture3D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h, unsigned d)
it can't be changed. */
void storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned dp, unsigned lv = 0);
+ DEPRECATED void storage(PixelComponents c, unsigned w, unsigned h, unsigned d, unsigned l = 0)
+ { storage(make_pixelformat(c, UNSIGNED_BYTE), w, h, d, l); }
+
/** Allocates storage for the texture. The contents are initially
undefined. If storage has already been allocated, does nothing. */
void allocate(unsigned level);
/** Uploads an image to the texture. Storage must be defined beforehand.
The image data must have dimensions and format compatible with the defined
storage. */
- void image(unsigned level, PixelFormat fmt, DataType type, const void *data);
+ void image(unsigned level, PixelComponents, DataType type, const void *data);
/** Updates a cuboid-shaped region of the texture. Storage must be defined
and allocated beforehand. The update region must be fully inside the
texture. */
void sub_image(unsigned level,
int x, int y, int z, unsigned wd, unsigned ht, unsigned dp,
- PixelFormat fmt, DataType type, const void *data);
+ PixelComponents comp, DataType type, const void *data);
/** Uploads an image to the texture. If storage has not been defined, it
will be set to match the image. In this case the image will be treated as
}
else
{
- PixelFormat base_fmt = get_base_pixelformat(ifmt);
- DataType type = get_alloc_type(base_fmt);
+ PixelComponents comp = get_components(ifmt);
+ DataType type = get_component_type(ifmt);
for(unsigned i=0; i<6; ++i)
- image(enumerate_faces(i), level, base_fmt, type, 0);
+ image(enumerate_faces(i), level, comp, type, 0);
}
}
-void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, DataType type, const void *data)
+void TextureCube::image(TextureCubeFace face, unsigned level, PixelComponents comp, DataType type, const void *data)
{
if(size==0)
throw invalid_operation("TextureCube::image");
throw out_of_range("TextureCube::image");
if(ARB_texture_storage)
- return sub_image(face, level, 0, 0, s, s, fmt, type, data);
+ return sub_image(face, level, 0, 0, s, s, comp, type, data);
BindRestore _bind(this);
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
apply_swizzle();
}
- glTexImage2D(face, level, ifmt, s, s, 0, get_upload_format(fmt), type, data);
+ glTexImage2D(face, level, ifmt, s, s, 0, get_upload_components(comp), type, data);
if(level==0)
{
{
for(unsigned i=0; i<6; ++i)
if(enumerate_faces(i)!=face)
- glTexImage2D(enumerate_faces(i), level, ifmt, s, s, 0, get_upload_format(fmt), type, 0);
+ glTexImage2D(enumerate_faces(i), level, ifmt, s, s, 0, comp, type, 0);
allocated |= 64<<level;
}
}
-void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data)
+void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned wd, unsigned ht, PixelComponents comp, DataType type, const void *data)
{
if(size==0)
throw invalid_operation("TextureCube::sub_image");
BindRestore _bind(this);
allocate(level);
- glTexSubImage2D(face, level, x, y, wd, ht, get_upload_format(fmt), type, data);
+ glTexSubImage2D(face, level, x, y, wd, ht, get_upload_components(comp), type, data);
if(auto_gen_mipmap && level==0)
generate_mipmap();
{
unsigned w = img.get_width();
unsigned h = img.get_height();
- PixelFormat fmt = pixelformat_from_graphics(img.get_format());
+ PixelFormat fmt = pixelformat_from_image(img);
if(size==0)
{
if(w!=h)
throw incompatible_data("TextureCube::image");
- storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w);
+ storage(make_pixelformat(get_components(fmt), get_component_type(fmt), srgb), w);
}
else if(w!=size || h!=size)
throw incompatible_data("TextureCube::image");
PixelStore pstore = PixelStore::from_image(img);
BindRestore _bind_ps(pstore);
- image(face, 0, fmt, UNSIGNED_BYTE, img.get_data());
+ image(face, 0, get_components(fmt), get_component_type(fmt), img.get_data());
}
void TextureCube::image(const Graphics::Image &img, unsigned lv, bool srgb)
throw incompatible_data("TextureCube::image");
h /= 6;
- PixelFormat fmt = pixelformat_from_graphics(img.get_format());
+ PixelFormat fmt = pixelformat_from_image(img);
+ PixelComponents comp = get_components(fmt);
+ DataType type = get_component_type(fmt);
if(size==0)
- storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, lv);
+ storage(make_pixelformat(comp, type, srgb), w, lv);
else if(w!=size || h!=size)
throw incompatible_data("TextureCube::image");
const char *cdata = reinterpret_cast<const char *>(img.get_data());
unsigned face_size = img.get_stride()*size;
for(unsigned i=0; i<6; ++i)
- image(enumerate_faces(i), 0, fmt, UNSIGNED_BYTE, cdata+i*face_size);
+ image(enumerate_faces(i), 0, comp, type, cdata+i*face_size);
}
unsigned TextureCube::get_n_levels() const
void TextureCube::Loader::raw_data(TextureCubeFace face, const string &data)
{
- obj.image(face, 0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data());
+ obj.image(face, 0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
}
void TextureCube::Loader::storage(PixelFormat fmt, unsigned s)
it can't be changed. */
void storage(PixelFormat fmt, unsigned size, unsigned lv = 0);
+ DEPRECATED void storage(PixelComponents c, unsigned s, unsigned l = 0)
+ { storage(make_pixelformat(c, UNSIGNED_BYTE), s, l); }
+
/** Allocates storage for the cube faces. The contents are initially
undefined. If storage has already been allocated, does nothing. */
void allocate(unsigned level);
image data must have dimensions and format compatible with the defined
storage. */
void image(TextureCubeFace face, unsigned level,
- PixelFormat fmt, DataType type, const void *data);
+ PixelComponents comp, DataType type, const void *data);
/** Updates a rectangular region of a face. Storage must be defined and
allocated beforehand. The update region must be fully inside the texture.
The data format must be compatible with the defined storage. */
void sub_image(TextureCubeFace face, unsigned level,
int x, int y, unsigned w, unsigned h,
- PixelFormat fmt, DataType type, const void *data);
+ PixelComponents comp, DataType type, const void *data);
void image(TextureCubeFace, const Graphics::Image &, bool = false);