Add snorm texture formats

This commit is contained in:
rdb 2015-11-10 18:00:18 +01:00
parent f725cda60c
commit 90f05d7284
3 changed files with 144 additions and 14 deletions

View File

@ -284,12 +284,14 @@ fix_component_ordering(PTA_uchar &new_image,
case GL_RGB: case GL_RGB:
switch (tex->get_component_type()) { switch (tex->get_component_type()) {
case Texture::T_unsigned_byte: case Texture::T_unsigned_byte:
case Texture::T_byte:
new_image = PTA_uchar::empty_array(orig_image_size); new_image = PTA_uchar::empty_array(orig_image_size);
uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3); uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3);
result = new_image; result = new_image;
break; break;
case Texture::T_unsigned_short: case Texture::T_unsigned_short:
case Texture::T_short:
new_image = PTA_uchar::empty_array(orig_image_size); new_image = PTA_uchar::empty_array(orig_image_size);
ushort_bgr_to_rgb((unsigned short *)new_image.p(), ushort_bgr_to_rgb((unsigned short *)new_image.p(),
(const unsigned short *)orig_image, (const unsigned short *)orig_image,
@ -305,12 +307,14 @@ fix_component_ordering(PTA_uchar &new_image,
case GL_RGBA: case GL_RGBA:
switch (tex->get_component_type()) { switch (tex->get_component_type()) {
case Texture::T_unsigned_byte: case Texture::T_unsigned_byte:
case Texture::T_byte:
new_image = PTA_uchar::empty_array(orig_image_size); new_image = PTA_uchar::empty_array(orig_image_size);
uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4); uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4);
result = new_image; result = new_image;
break; break;
case Texture::T_unsigned_short: case Texture::T_unsigned_short:
case Texture::T_short:
new_image = PTA_uchar::empty_array(orig_image_size); new_image = PTA_uchar::empty_array(orig_image_size);
ushort_bgra_to_rgba((unsigned short *)new_image.p(), ushort_bgra_to_rgba((unsigned short *)new_image.p(),
(const unsigned short *)orig_image, (const unsigned short *)orig_image,
@ -7808,6 +7812,10 @@ get_component_type(Texture::ComponentType component_type) {
#ifndef OPENGLES_1 #ifndef OPENGLES_1
return GL_INT; return GL_INT;
#endif #endif
case Texture::T_byte:
return GL_BYTE;
case Texture::T_short:
return GL_SHORT;
default: default:
GLCAT.error() << "Invalid Texture::Type value!\n"; GLCAT.error() << "Invalid Texture::Type value!\n";
return GL_UNSIGNED_BYTE; return GL_UNSIGNED_BYTE;
@ -8432,6 +8440,10 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
#ifndef OPENGLES #ifndef OPENGLES
if (tex->get_component_type() == Texture::T_unsigned_short) { if (tex->get_component_type() == Texture::T_unsigned_short) {
return GL_RGBA16; return GL_RGBA16;
} else if (tex->get_component_type() == Texture::T_short) {
return GL_RGBA16_SNORM;
} else if (tex->get_component_type() == Texture::T_byte) {
return GL_RGBA8_SNORM;
} else } else
#endif #endif
{ {
@ -8448,27 +8460,32 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
return force_sized ? GL_RGBA8 : GL_RGBA; return force_sized ? GL_RGBA8 : GL_RGBA;
#else #else
case Texture::F_rgba8: case Texture::F_rgba8:
return GL_RGBA8; if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGBA8;
} else {
return GL_RGBA8_SNORM;
}
case Texture::F_r8i: case Texture::F_r8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) { if (Texture::is_unsigned(tex->get_component_type())) {
return GL_R8UI; return GL_R8UI;
} else { } else {
return GL_R8I; return GL_R8I;
} }
case Texture::F_rg8i: case Texture::F_rg8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) { if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RG8UI; return GL_RG8UI;
} else { } else {
return GL_RG8I; return GL_RG8I;
} }
case Texture::F_rgb8i: case Texture::F_rgb8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) { if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGB8UI; return GL_RGB8UI;
} else { } else {
return GL_RGB8I; return GL_RGB8I;
} }
case Texture::F_rgba8i: case Texture::F_rgba8i:
if (tex->get_component_type() == Texture::T_unsigned_byte) { if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGBA8UI; return GL_RGBA8UI;
} else { } else {
return GL_RGBA8I; return GL_RGBA8I;
@ -8480,17 +8497,24 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
case Texture::F_rgba16: case Texture::F_rgba16:
if (tex->get_component_type() == Texture::T_float) { if (tex->get_component_type() == Texture::T_float) {
return GL_RGBA16F; return GL_RGBA16F;
} else { } else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGBA16; return GL_RGBA16;
} else {
return GL_RGBA16_SNORM;
} }
case Texture::F_rgba32: case Texture::F_rgba32:
return GL_RGBA32F; return GL_RGBA32F;
#endif // OPENGLES #endif // OPENGLES
case Texture::F_rgb: case Texture::F_rgb:
if (tex->get_component_type() == Texture::T_float) { switch (tex->get_component_type()) {
return GL_RGB16F; case Texture::T_float: return GL_RGB16F;
} else { #ifndef OPENGLES
case Texture::T_unsigned_short: return GL_RGB16;
case Texture::T_short: return GL_RGB16_SNORM;
case Texture::T_byte: return GL_RGB8_SNORM;
#endif
default:
return force_sized ? GL_RGB8 : GL_RGB; return force_sized ? GL_RGB8 : GL_RGB;
} }
@ -8513,14 +8537,20 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
return GL_RGB16F; return GL_RGB16F;
#else #else
case Texture::F_rgb8: case Texture::F_rgb8:
return GL_RGB8; if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGB8;
} else {
return GL_RGB8_SNORM;
}
case Texture::F_rgb12: case Texture::F_rgb12:
return GL_RGB12; return GL_RGB12;
case Texture::F_rgb16: case Texture::F_rgb16:
if (tex->get_component_type() == Texture::T_float) { if (tex->get_component_type() == Texture::T_float) {
return GL_RGB16F; return GL_RGB16F;
} else { } else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RGB16; return GL_RGB16;
} else {
return GL_RGB16_SNORM;
} }
#endif // OPENGLES #endif // OPENGLES
case Texture::F_rgb32: case Texture::F_rgb32:
@ -8540,14 +8570,18 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
case Texture::F_r16: case Texture::F_r16:
if (tex->get_component_type() == Texture::T_float) { if (tex->get_component_type() == Texture::T_float) {
return GL_R16F; return GL_R16F;
} else { } else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_R16; return GL_R16;
} else {
return GL_R16_SNORM;
} }
case Texture::F_rg16: case Texture::F_rg16:
if (tex->get_component_type() == Texture::T_float) { if (tex->get_component_type() == Texture::T_float) {
return GL_RG16F; return GL_RG16F;
} else { } else if (Texture::is_unsigned(tex->get_component_type())) {
return GL_RG16; return GL_RG16;
} else {
return GL_RG16_SNORM;
} }
#endif #endif
@ -8560,7 +8594,14 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
case Texture::F_red: case Texture::F_red:
case Texture::F_green: case Texture::F_green:
case Texture::F_blue: case Texture::F_blue:
return force_sized ? GL_R8 : GL_RED; #ifndef OPENGLES
if (!Texture::is_unsigned(tex->get_component_type())) {
return GL_R8_SNORM;
} else
#endif
{
return force_sized ? GL_R8 : GL_RED;
}
#endif #endif
case Texture::F_alpha: case Texture::F_alpha:
@ -8574,6 +8615,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
#ifndef OPENGLES #ifndef OPENGLES
if (tex->get_component_type() == Texture::T_float) { if (tex->get_component_type() == Texture::T_float) {
return GL_LUMINANCE16F_ARB; return GL_LUMINANCE16F_ARB;
} else if (tex->get_component_type() == Texture::T_short) {
return GL_LUMINANCE16_SNORM;
} else if (tex->get_component_type() == Texture::T_unsigned_short) { } else if (tex->get_component_type() == Texture::T_unsigned_short) {
return GL_LUMINANCE16; return GL_LUMINANCE16;
} else } else
@ -12117,15 +12160,19 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
break; break;
case GL_R8I: case GL_R8I:
type = Texture::T_byte;
format = Texture::F_r8i; format = Texture::F_r8i;
break; break;
case GL_RG8I: case GL_RG8I:
type = Texture::T_byte;
format = Texture::F_rg8i; format = Texture::F_rg8i;
break; break;
case GL_RGB8I: case GL_RGB8I:
type = Texture::T_byte;
format = Texture::F_rgb8i; format = Texture::F_rgb8i;
break; break;
case GL_RGBA8I: case GL_RGBA8I:
type = Texture::T_byte;
format = Texture::F_rgba8i; format = Texture::F_rgba8i;
break; break;
@ -12195,6 +12242,19 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
type = Texture::T_unsigned_short; type = Texture::T_unsigned_short;
format = Texture::F_r16; format = Texture::F_r16;
break; break;
case GL_RGB16_SNORM:
type = Texture::T_short;
format = Texture::F_rgb16;
break;
case GL_RG16_SNORM:
type = Texture::T_short;
format = Texture::F_rg16;
break;
case GL_R16_SNORM:
type = Texture::T_short;
format = Texture::F_r16;
break;
#endif #endif
#ifndef OPENGLES #ifndef OPENGLES

View File

@ -1552,10 +1552,12 @@ write(ostream &out, int indent_level) const {
switch (cdata->_component_type) { switch (cdata->_component_type) {
case T_unsigned_byte: case T_unsigned_byte:
case T_byte:
out << " bytes"; out << " bytes";
break; break;
case T_unsigned_short: case T_unsigned_short:
case T_short:
out << " shorts"; out << " shorts";
break; break;
@ -2001,6 +2003,10 @@ format_component_type(ComponentType ct) {
return "unsigned_int_24_8"; return "unsigned_int_24_8";
case T_int: case T_int:
return "int"; return "int";
case T_byte:
return "unsigned_byte";
case T_short:
return "short";
} }
return "**invalid**"; return "**invalid**";
@ -2024,6 +2030,10 @@ string_component_type(const string &str) {
return T_unsigned_int_24_8; return T_unsigned_int_24_8;
} else if (cmp_nocase(str, "int") == 0) { } else if (cmp_nocase(str, "int") == 0) {
return T_int; return T_int;
} else if (cmp_nocase(str, "byte") == 0) {
return T_byte;
} else if (cmp_nocase(str, "short") == 0) {
return T_short;
} }
gobj_cat->error() gobj_cat->error()
@ -2411,6 +2421,19 @@ make_texture() {
return new Texture; return new Texture;
} }
////////////////////////////////////////////////////////////////////
// Function: Texture::is_unsigned
// Access: Public, Static
// Description: Returns true if the indicated component type is
// unsigned, false otherwise.
////////////////////////////////////////////////////////////////////
bool Texture::
is_unsigned(Texture::ComponentType ctype) {
return (ctype == T_unsigned_byte ||
ctype == T_unsigned_short ||
ctype == T_unsigned_int_24_8);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Texture::is_specific // Function: Texture::is_specific
// Access: Public, Static // Access: Public, Static
@ -4525,6 +4548,48 @@ do_get_clear_data(const CData *cdata, unsigned char *into) const {
} }
break; break;
} }
case T_byte:
{
LColor scaled = cdata->_clear_color.fmin(LColor(1)).fmax(LColor(-1));
scaled *= 127;
switch (cdata->_num_components) {
case 2:
into[1] = (char)scaled[1];
case 1:
into[0] = (char)scaled[0];
break;
case 4:
into[3] = (char)scaled[3];
case 3: // BGR <-> RGB
into[0] = (char)scaled[2];
into[1] = (char)scaled[1];
into[2] = (char)scaled[0];
break;
}
break;
}
case T_short:
{
LColor scaled = cdata->_clear_color.fmin(LColor(1)).fmax(LColor(-1));
scaled *= 32767;
switch (cdata->_num_components) {
case 2:
((short *)into)[1] = (short)scaled[1];
case 1:
((short *)into)[0] = (short)scaled[0];
break;
case 4:
((short *)into)[3] = (short)scaled[3];
case 3: // BGR <-> RGB
((short *)into)[0] = (short)scaled[2];
((short *)into)[1] = (short)scaled[1];
((short *)into)[2] = (short)scaled[0];
break;
}
break;
}
} }
return cdata->_num_components * cdata->_component_width; return cdata->_num_components * cdata->_component_width;
@ -5222,10 +5287,12 @@ do_set_component_type(CData *cdata, Texture::ComponentType component_type) {
switch (component_type) { switch (component_type) {
case T_unsigned_byte: case T_unsigned_byte:
case T_byte:
cdata->_component_width = 1; cdata->_component_width = 1;
break; break;
case T_unsigned_short: case T_unsigned_short:
case T_short:
cdata->_component_width = 2; cdata->_component_width = 2;
break; break;

View File

@ -93,6 +93,8 @@ PUBLISHED:
T_float, T_float,
T_unsigned_int_24_8, // Packed T_unsigned_int_24_8, // Packed
T_int, T_int,
T_byte,
T_short,
}; };
enum Format { enum Format {
@ -527,6 +529,7 @@ public:
static PT(Texture) make_texture(); static PT(Texture) make_texture();
public: public:
static bool is_unsigned(ComponentType ctype);
static bool is_specific(CompressionMode compression); static bool is_specific(CompressionMode compression);
static bool has_alpha(Format format); static bool has_alpha(Format format);
static bool has_binary_alpha(Format format); static bool has_binary_alpha(Format format);