diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 422cfe6390..639e13a54a 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -284,12 +284,14 @@ fix_component_ordering(PTA_uchar &new_image, case GL_RGB: switch (tex->get_component_type()) { case Texture::T_unsigned_byte: + case Texture::T_byte: new_image = PTA_uchar::empty_array(orig_image_size); uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3); result = new_image; break; case Texture::T_unsigned_short: + case Texture::T_short: new_image = PTA_uchar::empty_array(orig_image_size); ushort_bgr_to_rgb((unsigned short *)new_image.p(), (const unsigned short *)orig_image, @@ -305,12 +307,14 @@ fix_component_ordering(PTA_uchar &new_image, case GL_RGBA: switch (tex->get_component_type()) { case Texture::T_unsigned_byte: + case Texture::T_byte: new_image = PTA_uchar::empty_array(orig_image_size); uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4); result = new_image; break; case Texture::T_unsigned_short: + case Texture::T_short: new_image = PTA_uchar::empty_array(orig_image_size); ushort_bgra_to_rgba((unsigned short *)new_image.p(), (const unsigned short *)orig_image, @@ -7808,6 +7812,10 @@ get_component_type(Texture::ComponentType component_type) { #ifndef OPENGLES_1 return GL_INT; #endif + case Texture::T_byte: + return GL_BYTE; + case Texture::T_short: + return GL_SHORT; default: GLCAT.error() << "Invalid Texture::Type value!\n"; return GL_UNSIGNED_BYTE; @@ -8432,6 +8440,10 @@ get_internal_image_format(Texture *tex, bool force_sized) const { #ifndef OPENGLES if (tex->get_component_type() == Texture::T_unsigned_short) { 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 #endif { @@ -8448,27 +8460,32 @@ get_internal_image_format(Texture *tex, bool force_sized) const { return force_sized ? GL_RGBA8 : GL_RGBA; #else 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: - if (tex->get_component_type() == Texture::T_unsigned_byte) { + if (Texture::is_unsigned(tex->get_component_type())) { return GL_R8UI; } else { return GL_R8I; } case Texture::F_rg8i: - if (tex->get_component_type() == Texture::T_unsigned_byte) { + if (Texture::is_unsigned(tex->get_component_type())) { return GL_RG8UI; } else { return GL_RG8I; } case Texture::F_rgb8i: - if (tex->get_component_type() == Texture::T_unsigned_byte) { + if (Texture::is_unsigned(tex->get_component_type())) { return GL_RGB8UI; } else { return GL_RGB8I; } case Texture::F_rgba8i: - if (tex->get_component_type() == Texture::T_unsigned_byte) { + if (Texture::is_unsigned(tex->get_component_type())) { return GL_RGBA8UI; } else { return GL_RGBA8I; @@ -8480,17 +8497,24 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_rgba16: if (tex->get_component_type() == Texture::T_float) { return GL_RGBA16F; - } else { + } else if (Texture::is_unsigned(tex->get_component_type())) { return GL_RGBA16; + } else { + return GL_RGBA16_SNORM; } case Texture::F_rgba32: return GL_RGBA32F; #endif // OPENGLES case Texture::F_rgb: - if (tex->get_component_type() == Texture::T_float) { - return GL_RGB16F; - } else { + switch (tex->get_component_type()) { + case Texture::T_float: return GL_RGB16F; +#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; } @@ -8513,14 +8537,20 @@ get_internal_image_format(Texture *tex, bool force_sized) const { return GL_RGB16F; #else 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: return GL_RGB12; case Texture::F_rgb16: if (tex->get_component_type() == Texture::T_float) { return GL_RGB16F; - } else { + } else if (Texture::is_unsigned(tex->get_component_type())) { return GL_RGB16; + } else { + return GL_RGB16_SNORM; } #endif // OPENGLES case Texture::F_rgb32: @@ -8540,14 +8570,18 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_r16: if (tex->get_component_type() == Texture::T_float) { return GL_R16F; - } else { + } else if (Texture::is_unsigned(tex->get_component_type())) { return GL_R16; + } else { + return GL_R16_SNORM; } case Texture::F_rg16: if (tex->get_component_type() == Texture::T_float) { return GL_RG16F; - } else { + } else if (Texture::is_unsigned(tex->get_component_type())) { return GL_RG16; + } else { + return GL_RG16_SNORM; } #endif @@ -8560,7 +8594,14 @@ get_internal_image_format(Texture *tex, bool force_sized) const { case Texture::F_red: case Texture::F_green: 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 case Texture::F_alpha: @@ -8574,6 +8615,8 @@ get_internal_image_format(Texture *tex, bool force_sized) const { #ifndef OPENGLES if (tex->get_component_type() == Texture::T_float) { 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) { return GL_LUMINANCE16; } else @@ -12117,15 +12160,19 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { break; case GL_R8I: + type = Texture::T_byte; format = Texture::F_r8i; break; case GL_RG8I: + type = Texture::T_byte; format = Texture::F_rg8i; break; case GL_RGB8I: + type = Texture::T_byte; format = Texture::F_rgb8i; break; case GL_RGBA8I: + type = Texture::T_byte; format = Texture::F_rgba8i; break; @@ -12195,6 +12242,19 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { type = Texture::T_unsigned_short; format = Texture::F_r16; 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 #ifndef OPENGLES diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 5f54059fbb..b26c4ebca9 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -1552,10 +1552,12 @@ write(ostream &out, int indent_level) const { switch (cdata->_component_type) { case T_unsigned_byte: + case T_byte: out << " bytes"; break; case T_unsigned_short: + case T_short: out << " shorts"; break; @@ -2001,6 +2003,10 @@ format_component_type(ComponentType ct) { return "unsigned_int_24_8"; case T_int: return "int"; + case T_byte: + return "unsigned_byte"; + case T_short: + return "short"; } return "**invalid**"; @@ -2024,6 +2030,10 @@ string_component_type(const string &str) { return T_unsigned_int_24_8; } else if (cmp_nocase(str, "int") == 0) { 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() @@ -2411,6 +2421,19 @@ make_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 // Access: Public, Static @@ -4525,6 +4548,48 @@ do_get_clear_data(const CData *cdata, unsigned char *into) const { } 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; @@ -5222,10 +5287,12 @@ do_set_component_type(CData *cdata, Texture::ComponentType component_type) { switch (component_type) { case T_unsigned_byte: + case T_byte: cdata->_component_width = 1; break; case T_unsigned_short: + case T_short: cdata->_component_width = 2; break; diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index fff5770693..3ab9d33f02 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -93,6 +93,8 @@ PUBLISHED: T_float, T_unsigned_int_24_8, // Packed T_int, + T_byte, + T_short, }; enum Format { @@ -527,6 +529,7 @@ public: static PT(Texture) make_texture(); public: + static bool is_unsigned(ComponentType ctype); static bool is_specific(CompressionMode compression); static bool has_alpha(Format format); static bool has_binary_alpha(Format format);