diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index 487828afcb..6cfa88dec8 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -412,6 +412,10 @@ ConfigVariableBool framebuffer_srgb "means that the output will be properly gamma-corrected, as " "long as all the input textures are either converted from " "original sRGB to linear or sRGB textures are used.")); +ConfigVariableBool framebuffer_float +("framebuffer-float", false, + PRC_DESC("Set this to request a framebuffer that uses floating-point " + "storage for the color channel.")); ConfigVariableInt depth_bits ("depth-bits", 0, diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index eec3b50c56..d36f24c5bf 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -93,6 +93,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_stencil; extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_accum; extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_stereo; extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_srgb; +extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_float; extern EXPCL_PANDA_DISPLAY ConfigVariableInt depth_bits; extern EXPCL_PANDA_DISPLAY ConfigVariableInt color_bits; extern EXPCL_PANDA_DISPLAY ConfigVariableInt alpha_bits; diff --git a/panda/src/display/frameBufferProperties.I b/panda/src/display/frameBufferProperties.I index ceb32c2ffe..eb6da4b0ea 100644 --- a/panda/src/display/frameBufferProperties.I +++ b/panda/src/display/frameBufferProperties.I @@ -59,7 +59,7 @@ is_single_buffered() const { //////////////////////////////////////////////////////////////////// INLINE bool FrameBufferProperties:: is_stereo() const { - return (_property[FBP_stereo] != 0); + return (_flags & FBF_stereo) != 0; } //////////////////////////////////////////////////////////////////// @@ -189,9 +189,9 @@ get_back_buffers() const { // Access: Published // Description: //////////////////////////////////////////////////////////////////// -INLINE int FrameBufferProperties:: +INLINE bool FrameBufferProperties:: get_indexed_color() const { - return _property[FBP_indexed_color]; + return (_flags & FBF_indexed_color) != 0; } //////////////////////////////////////////////////////////////////// @@ -199,9 +199,9 @@ get_indexed_color() const { // Access: Published // Description: //////////////////////////////////////////////////////////////////// -INLINE int FrameBufferProperties:: +INLINE bool FrameBufferProperties:: get_rgb_color() const { - return _property[FBP_rgb_color]; + return (_flags & FBF_rgb_color) != 0; } //////////////////////////////////////////////////////////////////// @@ -209,9 +209,9 @@ get_rgb_color() const { // Access: Published // Description: //////////////////////////////////////////////////////////////////// -INLINE int FrameBufferProperties:: +INLINE bool FrameBufferProperties:: get_stereo() const { - return _property[FBP_stereo]; + return (_flags & FBF_stereo) != 0; } //////////////////////////////////////////////////////////////////// @@ -219,9 +219,9 @@ get_stereo() const { // Access: Published // Description: //////////////////////////////////////////////////////////////////// -INLINE int FrameBufferProperties:: +INLINE bool FrameBufferProperties:: get_force_hardware() const { - return _property[FBP_force_hardware]; + return (_flags & FBF_force_hardware) != 0; } //////////////////////////////////////////////////////////////////// @@ -229,9 +229,39 @@ get_force_hardware() const { // Access: Published // Description: //////////////////////////////////////////////////////////////////// -INLINE int FrameBufferProperties:: +INLINE bool FrameBufferProperties:: get_force_software() const { - return _property[FBP_force_software]; + return (_flags & FBF_force_software) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: FrameBufferProperties::get_srgb_color +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool FrameBufferProperties:: +get_srgb_color() const { + return (_flags & FBF_srgb_color) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: FrameBufferProperties::get_float_color +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool FrameBufferProperties:: +get_float_color() const { + return (_flags & FBF_float_color) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: FrameBufferProperties::get_float_depth +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool FrameBufferProperties:: +get_float_depth() const { + return (_flags & FBF_float_depth) != 0; } //////////////////////////////////////////////////////////////////// @@ -365,9 +395,13 @@ set_back_buffers(int n) { // Description: //////////////////////////////////////////////////////////////////// INLINE void FrameBufferProperties:: -set_indexed_color(int n) { - _property[FBP_indexed_color] = n; - _specified[FBP_indexed_color] = true; +set_indexed_color(bool n) { + if (n) { + _flags |= FBF_indexed_color; + } else { + _flags &= ~FBF_indexed_color; + } + _flags_specified |= FBF_indexed_color; } //////////////////////////////////////////////////////////////////// @@ -376,9 +410,13 @@ set_indexed_color(int n) { // Description: //////////////////////////////////////////////////////////////////// INLINE void FrameBufferProperties:: -set_rgb_color(int n) { - _property[FBP_rgb_color] = n; - _specified[FBP_rgb_color] = true; +set_rgb_color(bool n) { + if (n) { + _flags |= FBF_rgb_color; + } else { + _flags &= ~FBF_rgb_color; + } + _flags_specified |= FBF_rgb_color; } //////////////////////////////////////////////////////////////////// @@ -387,9 +425,13 @@ set_rgb_color(int n) { // Description: //////////////////////////////////////////////////////////////////// INLINE void FrameBufferProperties:: -set_stereo(int n) { - _property[FBP_stereo] = n; - _specified[FBP_stereo] = true; +set_stereo(bool n) { + if (n) { + _flags |= FBF_stereo; + } else { + _flags &= ~FBF_stereo; + } + _flags_specified |= FBF_stereo; } //////////////////////////////////////////////////////////////////// @@ -398,9 +440,13 @@ set_stereo(int n) { // Description: //////////////////////////////////////////////////////////////////// INLINE void FrameBufferProperties:: -set_force_hardware(int n) { - _property[FBP_force_hardware] = n; - _specified[FBP_force_hardware] = true; +set_force_hardware(bool n) { + if (n) { + _flags |= FBF_force_hardware; + } else { + _flags &= ~FBF_force_hardware; + } + _flags_specified |= FBF_force_hardware; } //////////////////////////////////////////////////////////////////// @@ -409,7 +455,56 @@ set_force_hardware(int n) { // Description: //////////////////////////////////////////////////////////////////// INLINE void FrameBufferProperties:: -set_force_software(int n) { - _property[FBP_force_software] = n; - _specified[FBP_force_software] = true; +set_force_software(bool n) { + if (n) { + _flags |= FBF_force_software; + } else { + _flags &= ~FBF_force_software; + } + _flags_specified |= FBF_force_software; +} + +//////////////////////////////////////////////////////////////////// +// Function: FrameBufferProperties::set_srgb_color +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void FrameBufferProperties:: +set_srgb_color(bool n) { + if (n) { + _flags |= FBF_srgb_color; + } else { + _flags &= ~FBF_srgb_color; + } + _flags_specified |= FBF_srgb_color; +} + +//////////////////////////////////////////////////////////////////// +// Function: FrameBufferProperties::set_float_color +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void FrameBufferProperties:: +set_float_color(bool n) { + if (n) { + _flags |= FBF_float_color; + } else { + _flags &= ~FBF_float_color; + } + _flags_specified |= FBF_float_color; +} + +//////////////////////////////////////////////////////////////////// +// Function: FrameBufferProperties::set_float_depth +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void FrameBufferProperties:: +set_float_depth(bool n) { + if (n) { + _flags |= FBF_float_depth; + } else { + _flags &= ~FBF_float_depth; + } + _flags_specified |= FBF_float_depth; } diff --git a/panda/src/display/frameBufferProperties.cxx b/panda/src/display/frameBufferProperties.cxx index 7182b756e6..50053169dd 100644 --- a/panda/src/display/frameBufferProperties.cxx +++ b/panda/src/display/frameBufferProperties.cxx @@ -34,7 +34,10 @@ FrameBufferProperties() { //////////////////////////////////////////////////////////////////// void FrameBufferProperties:: operator = (const FrameBufferProperties ©) { - for (int i=0; i _property[i]) { return false; } } + return true; } @@ -73,9 +82,9 @@ get_default() { return default_props; } - default_props.set_rgb_color(1); + default_props.set_rgb_color(true); default_props.set_back_buffers(back_buffers); - + int num_words = framebuffer_mode.get_num_words(); if (num_words > 0) { display_cat.error() @@ -99,10 +108,10 @@ get_default() { } if (framebuffer_hardware) { - default_props.set_force_hardware(1); + default_props.set_force_hardware(true); } if (framebuffer_software) { - default_props.set_force_software(1); + default_props.set_force_software(true); } if (framebuffer_depth) { default_props.set_depth_bits(1); @@ -120,7 +129,13 @@ get_default() { default_props.set_multisamples(1); } if (framebuffer_stereo) { - default_props.set_stereo(1); + default_props.set_stereo(true); + } + if (framebuffer_srgb) { + default_props.set_srgb_color(true); + } + if (framebuffer_float) { + default_props.set_float_color(true); } if (depth_bits > 0) { default_props.set_depth_bits(depth_bits); @@ -141,10 +156,9 @@ get_default() { default_props.set_multisamples(multisamples); } - if ((default_props._property[FBP_force_software])&& - (default_props._property[FBP_force_hardware])) { - default_props._property[FBP_force_software] = 0; - default_props._property[FBP_force_hardware] = 0; + if ((default_props._flags & FBF_force_software) != 0 && + (default_props._flags & FBF_force_hardware) != 0){ + default_props._flags &= ~(FBF_force_software | FBF_force_hardware); } default_ready = true; @@ -158,7 +172,11 @@ get_default() { //////////////////////////////////////////////////////////////////// bool FrameBufferProperties:: operator == (const FrameBufferProperties &other) const { - for (int i=0; i 0) { out << "depth_bits=" << _property[FBP_depth_bits] << " "; } + if ((_flags & FBF_float_color) != 0) { + out << "float_color "; + } + if ((_flags & FBF_srgb_color) != 0) { + out << "srgb_color "; + } + if ((_flags & FBF_indexed_color) != 0) { + out << "indexed_color "; + } if (_property[FBP_color_bits] > 0) { out << "color_bits=" << _property[FBP_color_bits] << " "; } @@ -243,17 +278,14 @@ output(ostream &out) const { if (_property[FBP_back_buffers] > 0) { out << "back_buffers=" << _property[FBP_back_buffers] << " "; } - if (_property[FBP_indexed_color] > 0) { - out << "indexed_color=" << _property[FBP_indexed_color] << " "; + if ((_flags & FBF_stereo) != 0) { + out << "stereo "; } - if (_property[FBP_stereo] > 0) { - out << "stereo=" << _property[FBP_stereo] << " "; + if ((_flags & FBF_force_hardware) != 0) { + out << "force_hardware "; } - if (_property[FBP_force_hardware] > 0) { - out << "force_hardware=" << _property[FBP_force_hardware] << " "; - } - if (_property[FBP_force_software] > 0) { - out << "force_software=" << _property[FBP_force_software] << " "; + if ((_flags & FBF_force_software) != 0) { + out << "force_software "; } } @@ -287,7 +319,7 @@ get_aux_mask() const { int FrameBufferProperties:: get_buffer_mask() const { int mask = 0; - + if (_property[FBP_back_buffers] > 0) { mask = RenderBuffer::T_front | RenderBuffer::T_back; } else { @@ -310,7 +342,11 @@ get_buffer_mask() const { //////////////////////////////////////////////////////////////////// bool FrameBufferProperties:: is_any_specified() const { - for (int i=0; i 0) { return false; } - if (_property[FBP_indexed_color] > 0) { + if ((_flags & FBF_indexed_color) != 0) { return false; } - if (_property[FBP_force_hardware] > 0) { + if ((_flags & FBF_force_hardware) != 0) { return false; } - if (_property[FBP_force_software] > 0) { + if ((_flags & FBF_force_software) != 0) { + return false; + } + if ((_flags & FBF_srgb_color) != 0) { + return false; + } + if ((_flags & FBF_float_color) != 0) { + return false; + } + if ((_flags & FBF_float_depth) != 0) { return false; } return true; @@ -391,7 +438,7 @@ is_basic() const { //////////////////////////////////////////////////////////////////// void FrameBufferProperties:: set_one_bit_per_channel() { - for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; ++prop) { + for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) { if (_property[prop] > 1) { _property[prop] = 1; } @@ -426,13 +473,13 @@ set_one_bit_per_channel() { int FrameBufferProperties:: get_quality(const FrameBufferProperties &reqs) const { - if ((_property[FBP_indexed_color]==0) && (_property[FBP_rgb_color]==0)) { + if (!get_indexed_color() && !get_rgb_color()) { // Nonfunctioning window. return 0; } - - if ((reqs._property[FBP_rgb_color] > _property[FBP_rgb_color])|| - (reqs._property[FBP_indexed_color] > _property[FBP_indexed_color])) { + + if ((reqs.get_rgb_color() && !get_rgb_color()) || + (reqs.get_indexed_color() && !get_indexed_color())) { // These properties are nonnegotiable. return 0; } @@ -441,17 +488,17 @@ get_quality(const FrameBufferProperties &reqs) const { // Deduct for using the wrong kind of renderer (hardware or software). // Cost: 10,000,000 - - if ((reqs._property[FBP_force_hardware] > _property[FBP_force_hardware])|| - (reqs._property[FBP_force_software] > _property[FBP_force_software])) { + + if ((reqs._flags & FBF_force_hardware) > (_flags & FBF_force_hardware) || + (reqs._flags & FBF_force_software) > (_flags & FBF_force_software)) { quality -= 10000000; } // Deduct for missing depth, color, alpha, stencil, or accum. // Cost: 1,000,000 - for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) { - if ((reqs._property[prop]) && (_property[prop]==0)) { + for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) { + if (reqs._property[prop] && _property[prop] == 0) { quality -= 1000000; } } @@ -459,7 +506,7 @@ get_quality(const FrameBufferProperties &reqs) const { // Deduct for missing aux bitplanes. // Cost: 100,000 - for (int prop=FBP_aux_rgba; prop<=FBP_aux_float; prop++) { + for (int prop = FBP_aux_rgba; prop <= FBP_aux_float; ++prop) { if (reqs._property[prop] > _property[prop]) { quality -= 100000; } @@ -468,13 +515,31 @@ get_quality(const FrameBufferProperties &reqs) const { // Deduct for stereo not enabled. // Cost: 100,000 - if (reqs._property[FBP_stereo] > _property[FBP_stereo]) { + if (reqs.get_stereo() && !get_stereo()) { + quality -= 100000; + } + + // Deduct for not being sRGB-capable. + // Cost: 100,000 + + if (reqs.get_srgb_color() && !get_srgb_color()) { + quality -= 100000; + } + + // Deduct for not having a floating-point format if we requested it. + // Cost: 100,000 + + if (reqs.get_float_color() && !get_float_color()) { + quality -= 100000; + } + + if (reqs.get_float_depth() && !get_float_depth()) { quality -= 100000; } // Deduct for insufficient back-buffers. // Cost: 100,000 - + if (reqs._property[FBP_back_buffers] > _property[FBP_back_buffers]) { quality -= 100000; } @@ -488,7 +553,7 @@ get_quality(const FrameBufferProperties &reqs) const { // Deduct for not enough bits in depth, color, alpha, stencil, or accum. // Cost: 10,000 - for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) { + for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) { if (_property[prop] != 0 && reqs._property[prop] > _property[prop]) { quality -= 10000; } @@ -497,33 +562,33 @@ get_quality(const FrameBufferProperties &reqs) const { // deduct for insufficient multisamples. // Cost: 1,000 - if (_property[FBP_multisamples] != 0 && + if (_property[FBP_multisamples] != 0 && reqs._property[FBP_multisamples] > _property[FBP_multisamples]) { quality -= 1000; } // Deduct for unrequested bitplanes. // Cost: 50 - - for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) { + + for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) { if ((_property[prop]) && (reqs._property[prop] == 0)) { quality -= 50; } } - for (int prop=FBP_aux_rgba; prop<=FBP_aux_float; prop++) { + for (int prop = FBP_aux_rgba; prop <= FBP_aux_float; ++prop) { int extra = _property[prop] > reqs._property[prop]; if (extra > 0) { extra = min(extra, 3); quality -= extra*50; } } - + // Deduct for excessive resolution in any bitplane (unless we asked // for only 1 bit, which is the convention for any amount). // Cost: 50 - - for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) { + + for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) { if (reqs._property[prop] > 1 && _property[prop] > reqs._property[prop]) { quality -= 50; @@ -555,9 +620,9 @@ get_quality(const FrameBufferProperties &reqs) const { quality += _property[prop]; } } - + return quality; -}; +} //////////////////////////////////////////////////////////////////// // Function: FrameBufferProperties::verify_hardware_software @@ -594,8 +659,6 @@ verify_hardware_software(const FrameBufferProperties &props, const string &rende << "hardware/software configuration in your Config.prc file.\n"; return false; } - + return true; } - - diff --git a/panda/src/display/frameBufferProperties.h b/panda/src/display/frameBufferProperties.h index 1d6b68463f..fac9f9e700 100644 --- a/panda/src/display/frameBufferProperties.h +++ b/panda/src/display/frameBufferProperties.h @@ -17,6 +17,7 @@ #include "pandabase.h" #include "pnotify.h" +#include "colorSpace.h" //////////////////////////////////////////////////////////////////// // Class : FrameBufferProperties @@ -44,18 +45,28 @@ private: FBP_multisamples, FBP_coverage_samples, FBP_back_buffers, - FBP_indexed_color, - FBP_rgb_color, - FBP_stereo, - FBP_force_hardware, - FBP_force_software, - + // This is a sentinel value. FBP_COUNT }; - + + enum FrameBufferFlag { + FBF_indexed_color = 0x001, + FBF_rgb_color = 0x002, + FBF_stereo = 0x004, + FBF_force_hardware = 0x008, + FBF_force_software = 0x010, + FBF_srgb_color = 0x020, + FBF_float_color = 0x040, + FBF_float_depth = 0x080, + FBF_all = 0x100-1, + }; + int _property[FBP_COUNT]; - int _specified[FBP_COUNT]; + bool _specified[FBP_COUNT]; + + int _flags; + int _flags_specified; PUBLISHED: @@ -71,11 +82,14 @@ PUBLISHED: INLINE int get_multisamples() const; INLINE int get_coverage_samples() const; INLINE int get_back_buffers() const; - INLINE int get_indexed_color() const; - INLINE int get_rgb_color() const; - INLINE int get_stereo() const; - INLINE int get_force_hardware() const; - INLINE int get_force_software() const; + INLINE bool get_indexed_color() const; + INLINE bool get_rgb_color() const; + INLINE bool get_stereo() const; + INLINE bool get_force_hardware() const; + INLINE bool get_force_software() const; + INLINE bool get_srgb_color() const; + INLINE bool get_float_color() const; + INLINE bool get_float_depth() const; // Individual assigners. INLINE void set_depth_bits(int n); @@ -89,11 +103,14 @@ PUBLISHED: INLINE void set_multisamples(int n); INLINE void set_coverage_samples(int n); INLINE void set_back_buffers(int n); - INLINE void set_indexed_color(int n); - INLINE void set_rgb_color(int n); - INLINE void set_stereo(int n); - INLINE void set_force_hardware(int n); - INLINE void set_force_software(int n); + INLINE void set_indexed_color(bool n); + INLINE void set_rgb_color(bool n); + INLINE void set_stereo(bool n); + INLINE void set_force_hardware(bool n); + INLINE void set_force_software(bool n); + INLINE void set_srgb_color(bool n); + INLINE void set_float_color(bool n); + INLINE void set_float_depth(bool n); // Other. @@ -111,9 +128,9 @@ PUBLISHED: void add_properties(const FrameBufferProperties &other); void output(ostream &out) const; void set_one_bit_per_channel(); - - bool is_stereo() const; - bool is_single_buffered() const; + + INLINE bool is_stereo() const; + INLINE bool is_single_buffered() const; int get_quality(const FrameBufferProperties &reqs) const; bool is_any_specified() const; bool is_basic() const; diff --git a/panda/src/gles2gsg/gles2gsg.h b/panda/src/gles2gsg/gles2gsg.h index 9869257732..401a778c2c 100644 --- a/panda/src/gles2gsg/gles2gsg.h +++ b/panda/src/gles2gsg/gles2gsg.h @@ -96,11 +96,15 @@ typedef char GLchar; #define GL_RG16F GL_RG16F_EXT #define GL_RGB16F GL_RGB16F_EXT #define GL_RGBA16F GL_RGBA16F_EXT +#define GL_RGB16F GL_RGB16F_EXT +#define GL_RGBA16F GL_RGBA16F_EXT +#define GL_RGB32F GL_RGB32F_EXT +#define GL_RGBA32F GL_RGBA32F_EXT #undef SUPPORT_IMMEDIATE_MODE #define APIENTRY #define APIENTRYP * #include "glstuff_src.h" - + #endif // GLES2GSG_H diff --git a/panda/src/glesgsg/glesgsg.h b/panda/src/glesgsg/glesgsg.h index c397e81f7a..d964b48765 100644 --- a/panda/src/glesgsg/glesgsg.h +++ b/panda/src/glesgsg/glesgsg.h @@ -110,11 +110,15 @@ #define GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES #define GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES #define GL_BGRA GL_BGRA_EXT +#define GL_RGB16F GL_RGB16F_EXT +#define GL_RGBA16F GL_RGBA16F_EXT +#define GL_RGB32F GL_RGB32F_EXT +#define GL_RGBA32F GL_RGBA32F_EXT #undef SUPPORT_IMMEDIATE_MODE #define APIENTRY #define APIENTRYP * #include "glstuff_src.h" - + #endif // GLESGSG_H diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 64cdbc8058..6b974dbf84 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -370,6 +370,11 @@ rebuild_bitplanes() { // explicitly bound something to RTP_depth. _use_depth_stencil = false; + } else if (_fb_properties.get_float_depth()) { + // Let's not bother with a depth-stencil buffer + // if a float buffer was requested. + _use_depth_stencil = false; + } else if (_fb_properties.get_depth_bits() > 24) { // We can't give more than 24 depth bits with a depth-stencil buffer. _use_depth_stencil = false; @@ -582,7 +587,10 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, // Adjust the texture format based on the requested framebuffer settings. switch (slot) { case RTP_depth: - if (_fb_properties.get_depth_bits() > 24) { + if (_fb_properties.get_float_depth()) { + tex->set_format(Texture::F_depth_component32); + tex->set_component_type(Texture::T_float); + } else if (_fb_properties.get_depth_bits() > 24) { tex->set_format(Texture::F_depth_component32); } else if (_fb_properties.get_depth_bits() > 16) { tex->set_format(Texture::F_depth_component24); @@ -594,7 +602,12 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, break; case RTP_depth_stencil: tex->set_format(Texture::F_depth_stencil); - tex->set_component_type(Texture::T_unsigned_int_24_8); + + if (_fb_properties.get_float_depth()) { + tex->set_component_type(Texture::T_float); + } else { + tex->set_component_type(Texture::T_unsigned_int_24_8); + } break; case RTP_aux_hrgba_0: case RTP_aux_hrgba_1: @@ -611,16 +624,24 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, tex->set_component_type(Texture::T_float); break; default: - if (_fb_properties.get_color_bits() > 48) { - tex->set_format(Texture::F_rgba32); - // Currently a float format. Should change. - tex->set_component_type(Texture::T_float); - } else if (_fb_properties.get_color_bits() > 24) { - tex->set_format(Texture::F_rgba16); - // Currently a float format. Should change. - tex->set_component_type(Texture::T_float); + if (_fb_properties.get_srgb_color()) { + if (_fb_properties.get_alpha_bits() == 0) { + tex->set_format(Texture::F_srgb); + } else { + tex->set_format(Texture::F_srgb_alpha); + } } else { - tex->set_format(Texture::F_rgba); + if (_fb_properties.get_float_color()) { + tex->set_component_type(Texture::T_float); + } + if (_fb_properties.get_color_bits() > 16 * 3) { + tex->set_format(Texture::F_rgba32); + tex->set_component_type(Texture::T_float); + } else if (_fb_properties.get_color_bits() > 8 * 3) { + tex->set_format(Texture::F_rgba16); + } else { + tex->set_format(Texture::F_rgba); + } } } @@ -730,10 +751,16 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, GLuint gl_format = GL_RGBA; switch (slot) { case RTP_depth_stencil: - gl_format = GL_DEPTH_STENCIL_EXT; + if (_fb_properties.get_float_depth()) { + gl_format = GL_DEPTH32F_STENCIL8; + } else { + gl_format = GL_DEPTH24_STENCIL8; + } break; case RTP_depth: - if (_fb_properties.get_depth_bits() > 24) { + if (_fb_properties.get_float_depth()) { + gl_format = GL_DEPTH_COMPONENT32F; + } else if (_fb_properties.get_depth_bits() > 24) { gl_format = GL_DEPTH_COMPONENT32; } else if (_fb_properties.get_depth_bits() > 16) { gl_format = GL_DEPTH_COMPONENT24; @@ -763,7 +790,41 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, break; default: if (_fb_properties.get_alpha_bits() == 0) { - gl_format = GL_RGB; + if (_fb_properties.get_srgb_color()) { + gl_format = GL_SRGB8; + } else if (_fb_properties.get_float_color()) { + if (_fb_properties.get_color_bits() > 16 * 3) { + gl_format = GL_RGB32F_ARB; + } else { + gl_format = GL_RGB16F_ARB; + } + } else { + if (_fb_properties.get_color_bits() > 16 * 3) { + gl_format = GL_RGBA32F_ARB; + } else if (_fb_properties.get_color_bits() > 8 * 3) { + gl_format = GL_RGB16_EXT; + } else { + gl_format = GL_RGB; + } + } + } else { + if (_fb_properties.get_srgb_color()) { + gl_format = GL_SRGB8_ALPHA8; + } else if (_fb_properties.get_float_color()) { + if (_fb_properties.get_color_bits() > 16 * 3) { + gl_format = GL_RGBA32F_ARB; + } else { + gl_format = GL_RGBA16F_ARB; + } + } else { + if (_fb_properties.get_color_bits() > 16 * 3) { + gl_format = GL_RGB32F_ARB; + } else if (_fb_properties.get_color_bits() > 8 * 3) { + gl_format = GL_RGB16_EXT; + } else { + gl_format = GL_RGB; + } + } } }; #endif @@ -1160,7 +1221,7 @@ open_buffer() { // Count total color buffers. int totalcolor = - (_fb_properties.is_stereo() ? 2 : 1) + + (_fb_properties.get_stereo() ? 2 : 1) + _fb_properties.get_aux_rgba() + _fb_properties.get_aux_hrgba() + _fb_properties.get_aux_float(); @@ -1215,6 +1276,30 @@ open_buffer() { _fb_properties.set_alpha_bits(32); } + if (_fb_properties.get_float_depth()) { + // GL_DEPTH_COMPONENT32F seems the only depth float format. + _fb_properties.set_depth_bits(32); + } + + // We currently only support color formats this big as float. + if (_fb_properties.get_color_bits() > 16 * 3) { + _fb_properties.set_color_bits(32 * 3); + _fb_properties.set_float_color(true); + + if (_fb_properties.get_alpha_bits() > 0) { + _fb_properties.set_alpha_bits(32); + } + } + + if (_fb_properties.get_srgb_color()) { + _fb_properties.set_color_bits(24); + _fb_properties.set_float_color(false); + + if (_fb_properties.get_alpha_bits() > 0) { + _fb_properties.set_alpha_bits(32); + } + } + if (!_gsg->get_supports_depth_stencil()) { // At least we know we won't be getting stencil bits. _fb_properties.set_stencil_bits(0); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index c2ba8f9954..faf07b31b2 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1603,7 +1603,6 @@ reset() { glGetIntegerv(GL_MAX_IMAGE_UNITS_EXT, &_max_image_units); } -#endif // Check availability of multi-bind functions. _supports_multi_bind = false; @@ -1618,6 +1617,7 @@ reset() { << "ARB_multi_bind advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n"; } } +#endif report_my_gl_errors(); @@ -2225,6 +2225,10 @@ begin_frame(Thread *current_thread) { glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); } + if (_current_properties->get_srgb_color()) { + glEnable(GL_FRAMEBUFFER_SRGB); + } + report_my_gl_errors(); return true; } @@ -2276,6 +2280,11 @@ end_scene() { void CLP(GraphicsStateGuardian):: end_frame(Thread *current_thread) { report_my_gl_errors(); + + if (_current_properties->get_srgb_color()) { + glDisable(GL_FRAMEBUFFER_SRGB); + } + #ifdef DO_PSTATS // Check for textures, etc., that are no longer resident. These // calls might be measurably expensive, and they don't have any @@ -4304,11 +4313,19 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, default: // If the texture is a color format, we want to match the - // presence of alpha according to the framebuffer. - if (_current_properties->get_alpha_bits()) { - tex->set_format(Texture::F_rgba); + // presence of sRGB and alpha according to the framebuffer. + if (_current_properties->get_srgb_color()) { + if (_current_properties->get_alpha_bits()) { + tex->set_format(Texture::F_srgb_alpha); + } else { + tex->set_format(Texture::F_srgb); + } } else { - tex->set_format(Texture::F_rgb); + if (_current_properties->get_alpha_bits()) { + tex->set_format(Texture::F_rgba); + } else { + tex->set_format(Texture::F_rgb); + } } } } @@ -4444,11 +4461,17 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, Texture::Format format = tex->get_format(); switch (format) { case Texture::F_depth_stencil: - component_type = Texture::T_unsigned_int_24_8; + if (_current_properties->get_float_depth()) { + component_type = Texture::T_float; + } else { + component_type = Texture::T_unsigned_int_24_8; + } break; case Texture::F_depth_component: - if (_current_properties->get_depth_bits() <= 8) { + if (_current_properties->get_float_depth()) { + component_type = Texture::T_float; + } else if (_current_properties->get_depth_bits() <= 8) { component_type = Texture::T_unsigned_byte; } else if (_current_properties->get_depth_bits() <= 16) { component_type = Texture::T_unsigned_short; @@ -4459,12 +4482,22 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, default: color_mode = true; - if (_current_properties->get_alpha_bits()) { - format = Texture::F_rgba; + if (_current_properties->get_srgb_color()) { + if (_current_properties->get_alpha_bits()) { + format = Texture::F_srgb_alpha; + } else { + format = Texture::F_srgb; + } } else { - format = Texture::F_rgb; + if (_current_properties->get_alpha_bits()) { + format = Texture::F_rgba; + } else { + format = Texture::F_rgb; + } } - if (_current_properties->get_color_bits() <= 24) { + if (_current_properties->get_float_color()) { + component_type = Texture::T_float; + } else if (_current_properties->get_color_bits() <= 24) { component_type = Texture::T_unsigned_byte; } else { component_type = Texture::T_unsigned_short; @@ -4504,7 +4537,7 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, case GL_DEPTH_COMPONENT: GLCAT.spam(false) << "GL_DEPTH_COMPONENT, "; break; - case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH_STENCIL: GLCAT.spam(false) << "GL_DEPTH_STENCIL, "; break; case GL_RGB: @@ -4555,9 +4588,8 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, } } - glReadPixels(xo, yo, w, h, - external_format, get_component_type(component_type), - image_ptr); + glReadPixels(xo, yo, w, h, external_format, + get_component_type(component_type), image_ptr); // We may have to reverse the byte ordering of the image if GL // didn't do it for us. @@ -6324,12 +6356,13 @@ get_component_type(Texture::ComponentType component_type) { GLint CLP(GraphicsStateGuardian):: get_external_image_format(Texture *tex) const { Texture::CompressionMode compression = tex->get_ram_image_compression(); + Texture::Format format = tex->get_format(); if (compression != Texture::CM_off && get_supports_compressed_texture_format(compression)) { switch (compression) { case Texture::CM_on: #ifndef OPENGLES - switch (tex->get_format()) { + switch (format) { case Texture::F_color_index: case Texture::F_depth_component: case Texture::F_depth_component16: @@ -6374,13 +6407,29 @@ get_external_image_format(Texture *tex) const { case Texture::F_luminance_alpha: case Texture::F_luminance_alphamask: return GL_COMPRESSED_LUMINANCE_ALPHA; + + case Texture::F_srgb: + return GL_COMPRESSED_SRGB; + + case Texture::F_srgb_alpha: + return GL_COMPRESSED_SRGB_ALPHA; + + case Texture::F_sluminance: + return GL_COMPRESSED_SLUMINANCE; + + case Texture::F_sluminance_alpha: + return GL_COMPRESSED_SLUMINANCE_ALPHA; } #endif break; #ifndef OPENGLES_1 case Texture::CM_dxt1: - if (Texture::has_alpha(tex->get_format())) { + if (format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + } else if (format == Texture::F_srgb) { + return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + } else if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; } else { return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; @@ -6389,13 +6438,21 @@ get_external_image_format(Texture *tex) const { #ifndef OPENGLES case Texture::CM_dxt3: - return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + } else { + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + } case Texture::CM_dxt5: - return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + } else { + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } case Texture::CM_fxt1: - if (Texture::has_alpha(tex->get_format())) { + if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_FXT1_3DFX; } else { return GL_COMPRESSED_RGB_FXT1_3DFX; @@ -6403,14 +6460,22 @@ get_external_image_format(Texture *tex) const { #else case Texture::CM_pvr1_2bpp: - if (Texture::has_alpha(tex->get_format())) { + if (format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT; + } else if (format == Texture::F_srgb) { + return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT; + } else if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; } else { return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; } case Texture::CM_pvr1_4bpp: - if (Texture::has_alpha(tex->get_format())) { + if (format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT; + } else if (format == Texture::F_srgb) { + return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT; + } else if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; } else { return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; @@ -6427,7 +6492,7 @@ get_external_image_format(Texture *tex) const { } } - switch (tex->get_format()) { + switch (format) { #ifndef OPENGLES case Texture::F_color_index: return GL_COLOR_INDEX; @@ -6438,7 +6503,7 @@ get_external_image_format(Texture *tex) const { case Texture::F_depth_component32: return GL_DEPTH_COMPONENT; case Texture::F_depth_stencil: - return _supports_depth_stencil ? GL_DEPTH_STENCIL_EXT : GL_DEPTH_COMPONENT; + return _supports_depth_stencil ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT; #ifndef OPENGLES case Texture::F_red: case Texture::F_r16: @@ -6460,6 +6525,7 @@ get_external_image_format(Texture *tex) const { case Texture::F_rgb12: case Texture::F_rgb332: case Texture::F_rgb16: + case Texture::F_srgb: #ifdef OPENGLES return GL_RGB; #else @@ -6473,15 +6539,18 @@ get_external_image_format(Texture *tex) const { case Texture::F_rgba12: case Texture::F_rgba16: case Texture::F_rgba32: + case Texture::F_srgb_alpha: #ifdef OPENGLES_2 return GL_RGBA; #else return _supports_bgr ? GL_BGRA : GL_RGBA; #endif case Texture::F_luminance: + case Texture::F_sluminance: return GL_LUMINANCE; case Texture::F_luminance_alphamask: case Texture::F_luminance_alpha: + case Texture::F_sluminance_alpha: return GL_LUMINANCE_ALPHA; } GLCAT.error() @@ -6502,6 +6571,7 @@ get_internal_image_format(Texture *tex) const { if (compression == Texture::CM_default) { compression = (compressed_textures) ? Texture::CM_on : Texture::CM_off; } + Texture::Format format = tex->get_format(); if (tex->get_render_to_texture()) { // no compression for render targets compression = Texture::CM_off; @@ -6520,7 +6590,7 @@ get_internal_image_format(Texture *tex) const { // appropriate choice), since that makes saving the result as a // pre-compressed texture more dependable--this way, we will know // which compression algorithm was applied. - switch (tex->get_format()) { + switch (format) { case Texture::F_color_index: case Texture::F_depth_component: case Texture::F_depth_stencil: @@ -6612,11 +6682,33 @@ get_internal_image_format(Texture *tex) const { return GL_COMPRESSED_LUMINANCE_ALPHA; } break; + + case Texture::F_srgb: + if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) { + return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + } + return GL_COMPRESSED_SRGB; + + case Texture::F_srgb_alpha: + if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) { + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + } + return GL_COMPRESSED_SRGB_ALPHA; + + case Texture::F_sluminance: + return GL_COMPRESSED_SLUMINANCE; + + case Texture::F_sluminance_alpha: + return GL_COMPRESSED_SLUMINANCE_ALPHA; #endif #ifndef OPENGLES_1 case Texture::CM_dxt1: - if (Texture::has_alpha(tex->get_format())) { + if (format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + } else if (format == Texture::F_srgb) { + return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + } else if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; } else { return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; @@ -6625,27 +6717,43 @@ get_internal_image_format(Texture *tex) const { #ifndef OPENGLES case Texture::CM_dxt3: - return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + } else { + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + } case Texture::CM_dxt5: - return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + } else { + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } case Texture::CM_fxt1: - if (Texture::has_alpha(tex->get_format())) { + if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_FXT1_3DFX; } else { return GL_COMPRESSED_RGB_FXT1_3DFX; } #else case Texture::CM_pvr1_2bpp: - if (Texture::has_alpha(tex->get_format())) { + if (format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT; + } else if (format == Texture::F_srgb) { + return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT; + } else if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; } else { return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; } case Texture::CM_pvr1_4bpp: - if (Texture::has_alpha(tex->get_format())) { + if (format == Texture::F_srgb_alpha) { + return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT; + } else if (format == Texture::F_srgb) { + return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT; + } else if (Texture::has_alpha(format)) { return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; } else { return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; @@ -6661,11 +6769,22 @@ get_internal_image_format(Texture *tex) const { } } - switch (tex->get_format()) { + switch (format) { #ifndef OPENGLES case Texture::F_color_index: return GL_COLOR_INDEX; #endif + + case Texture::F_depth_stencil: + if (_supports_depth_stencil) { + if (tex->get_component_type() == Texture::T_float) { + return GL_DEPTH32F_STENCIL8; + } else { + return GL_DEPTH_STENCIL; + } + } + // Fall through. + case Texture::F_depth_component: #ifndef OPENGLES if (tex->get_component_type() == Texture::T_float) { @@ -6710,16 +6829,14 @@ get_internal_image_format(Texture *tex) const { } #endif - case Texture::F_depth_stencil: - if (_supports_depth_stencil) { - return GL_DEPTH_STENCIL_EXT; - } else { - return GL_DEPTH_COMPONENT; - } - case Texture::F_rgba: case Texture::F_rgbm: - return GL_RGBA; + if (tex->get_component_type() == Texture::T_float) { + return GL_RGBA16F; + } else { + return GL_RGBA; + } + case Texture::F_rgba4: return GL_RGBA4; @@ -6730,23 +6847,28 @@ get_internal_image_format(Texture *tex) const { return GL_RGBA; #ifndef OPENGLES_1 case Texture::F_rgba16: - return GL_RGBA16F_EXT; + return GL_RGBA16F; #endif // OPENGLES_1 case Texture::F_rgba32: - return GL_RGBA32F_EXT; + return GL_RGBA32F; #else case Texture::F_rgba8: return GL_RGBA8; case Texture::F_rgba12: return GL_RGBA12; case Texture::F_rgba16: - return GL_RGBA16F_ARB; + return GL_RGBA16F; case Texture::F_rgba32: - return GL_RGBA32F_ARB; + return GL_RGBA32F; #endif // OPENGLES case Texture::F_rgb: - return GL_RGB; + if (tex->get_component_type() == Texture::T_float) { + return GL_RGB16F; + } else { + return GL_RGB; + } + case Texture::F_rgb5: #ifdef OPENGLES // Close enough. @@ -6763,7 +6885,7 @@ get_internal_image_format(Texture *tex) const { case Texture::F_rgb12: return GL_RGB; case Texture::F_rgb16: - return GL_RGB16F_EXT; + return GL_RGB16F; #else case Texture::F_rgb8: return GL_RGB8; @@ -6818,6 +6940,15 @@ get_internal_image_format(Texture *tex) const { case Texture::F_luminance_alphamask: return GL_LUMINANCE_ALPHA; + case Texture::F_srgb: + return GL_SRGB8; + case Texture::F_srgb_alpha: + return GL_SRGB8_ALPHA8; + case Texture::F_sluminance: + return GL_SLUMINANCE8; + case Texture::F_sluminance_alpha: + return GL_SLUMINANCE8_ALPHA8; + default: GLCAT.error() << "Invalid image format in get_internal_image_format(): " @@ -9366,7 +9497,7 @@ upload_texture_image(CLP(TextureContext) *gtc, } if (num_ram_mipmap_levels == 0) { - if ((external_format == GL_DEPTH_STENCIL_EXT) && get_supports_depth_stencil()) { + if ((external_format == GL_DEPTH_STENCIL) && get_supports_depth_stencil()) { #ifdef OPENGLES component_type = GL_UNSIGNED_INT_24_8_OES; #else @@ -9870,11 +10001,15 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { format = Texture::F_depth_component; break; #endif - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: type = Texture::T_unsigned_int_24_8; format = Texture::F_depth_stencil; break; + case GL_DEPTH32F_STENCIL8: + type = Texture::T_float; + format = Texture::F_depth_stencil; + break; case GL_RGBA: case 4: format = Texture::F_rgba; @@ -9985,6 +10120,19 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { format = Texture::F_luminance_alpha; break; + case GL_SRGB: + format = Texture::F_srgb; + break; + case GL_SRGB_ALPHA: + format = Texture::F_srgb_alpha; + break; + case GL_SLUMINANCE: + format = Texture::F_sluminance; + break; + case GL_SLUMINANCE_ALPHA: + format = Texture::F_sluminance_alpha; + break; + #ifndef OPENGLES case GL_COMPRESSED_RGB: format = Texture::F_rgb; @@ -10006,6 +10154,23 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { format = Texture::F_luminance_alpha; compression = Texture::CM_on; break; + + case GL_COMPRESSED_SRGB: + format = Texture::F_srgb; + compression = Texture::CM_on; + break; + case GL_COMPRESSED_SRGB_ALPHA: + format = Texture::F_srgb_alpha; + compression = Texture::CM_on; + break; + case GL_COMPRESSED_SLUMINANCE: + format = Texture::F_sluminance; + compression = Texture::CM_on; + break; + case GL_COMPRESSED_SLUMINANCE_ALPHA: + format = Texture::F_sluminance_alpha; + compression = Texture::CM_on; + break; #endif #ifndef OPENGLES_1 @@ -10017,6 +10182,14 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { format = Texture::F_rgbm; compression = Texture::CM_dxt1; break; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + format = Texture::F_srgb; + compression = Texture::CM_dxt1; + break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + format = Texture::F_srgb_alpha; + compression = Texture::CM_dxt1; + break; #endif #ifdef OPENGLES case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: @@ -10035,6 +10208,23 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { format = Texture::F_rgba; compression = Texture::CM_pvr1_4bpp; break; + + case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT: + format = Texture::F_srgb; + compression = Texture::CM_pvr1_2bpp; + break; + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT: + format = Texture::F_srgb_alpha; + compression = Texture::CM_pvr1_2bpp; + break; + case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT: + format = Texture::F_srgb; + compression = Texture::CM_pvr1_4bpp; + break; + case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: + format = Texture::F_srgb_alpha; + compression = Texture::CM_pvr1_4bpp; + break; #else case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: format = Texture::F_rgba; @@ -10044,6 +10234,14 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { format = Texture::F_rgba; compression = Texture::CM_dxt5; break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + format = Texture::F_srgb_alpha; + compression = Texture::CM_dxt3; + break; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + format = Texture::F_srgb_alpha; + compression = Texture::CM_dxt5; + break; case GL_COMPRESSED_RGB_FXT1_3DFX: format = Texture::F_rgb; compression = Texture::CM_fxt1; diff --git a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx index dce585fd84..83013117bf 100644 --- a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx +++ b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx @@ -153,7 +153,7 @@ get_properties_advanced(FrameBufferProperties &properties, // Now update our framebuffer_mode and bit depth appropriately. int render_type, double_buffer, stereo, red_size, green_size, blue_size, alpha_size, ared_size, agreen_size, ablue_size, aalpha_size, - depth_size, stencil_size, samples, drawable_type, caveat; + depth_size, stencil_size, samples, drawable_type, caveat, srgb_capable; _glXGetFBConfigAttrib(_display, config, GLX_RENDER_TYPE, &render_type); _glXGetFBConfigAttrib(_display, config, GLX_DOUBLEBUFFER, &double_buffer); @@ -171,6 +171,7 @@ get_properties_advanced(FrameBufferProperties &properties, _glXGetFBConfigAttrib(_display, config, GLX_SAMPLES, &samples); _glXGetFBConfigAttrib(_display, config, GLX_DRAWABLE_TYPE, &drawable_type); _glXGetFBConfigAttrib(_display, config, GLX_CONFIG_CAVEAT, &caveat); + _glXGetFBConfigAttrib(_display, config, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable); context_has_pbuffer = false; if ((drawable_type & GLX_PBUFFER_BIT)!=0) { @@ -200,6 +201,10 @@ get_properties_advanced(FrameBufferProperties &properties, properties.set_stereo(true); } + if (srgb_capable) { + properties.set_srgb_color(true); + } + if ((render_type & GLX_RGBA_BIT)!=0) { properties.set_rgb_color(true); } @@ -353,6 +358,10 @@ choose_pixel_format(const FrameBufferProperties &properties, get_properties_advanced(_fbprops, _context_has_pbuffer, _context_has_pixmap, _slow, _fbconfig); + if (!properties.get_srgb_color()) { + _fbprops.set_srgb_color(false); + } + if (glxdisplay_cat.is_debug()) { glxdisplay_cat.debug() << "Selected context " << best_result << ": " << _fbprops << "\n"; diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index b4b96217f9..b65f41964a 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -532,6 +532,8 @@ estimate_texture_memory() const { case Texture::F_luminance: case Texture::F_luminance_alpha: case Texture::F_luminance_alphamask: + case Texture::F_sluminance: + case Texture::F_sluminance_alpha: bpp = 4; break; @@ -541,12 +543,14 @@ estimate_texture_memory() const { case Texture::F_rgb: case Texture::F_rgb5: case Texture::F_rgba5: + case Texture::F_srgb: bpp = 4; break; case Texture::F_color_index: case Texture::F_rgb8: case Texture::F_rgba8: + case Texture::F_srgb_alpha: bpp = 4; break; @@ -1690,6 +1694,19 @@ write(ostream &out, int indent_level) const { case F_rgb16: out << "rgb16"; break; + + case F_srgb: + out << "srgb"; + break; + case F_srgb_alpha: + out << "srgb_alpha"; + break; + case F_sluminance: + out << "sluminance"; + break; + case F_sluminance_alpha: + out << "sluminance_alpha"; + break; } if (cdata->_compression != CM_default) { @@ -2112,6 +2129,14 @@ format_format(Format format) { return "rg16"; case F_rgb16: return "rgb16"; + case F_srgb: + return "srgb"; + case F_srgb_alpha: + return "srgb_alpha"; + case F_sluminance: + return "sluminance"; + case F_sluminance_alpha: + return "sluminance_alpha"; } return "**invalid**"; } @@ -2182,6 +2207,14 @@ string_format(const string &str) { return F_rg16; } else if (cmp_nocase(str, "rgb16") == 0 || cmp_nocase(str, "r16g16b16") == 0) { return F_rgb16; + } else if (cmp_nocase(str, "srgb") == 0) { + return F_srgb; + } else if (cmp_nocase(str, "srgb_alpha") == 0) { + return F_srgb_alpha; + } else if (cmp_nocase(str, "sluminance") == 0) { + return F_sluminance; + } else if (cmp_nocase(str, "sluminance_alpha") == 0) { + return F_sluminance_alpha; } gobj_cat->error() @@ -2541,6 +2574,8 @@ has_alpha(Format format) { case F_rgba32: case F_luminance_alpha: case F_luminance_alphamask: + case F_srgb_alpha: + case F_sluminance_alpha: return true; default: @@ -4743,6 +4778,7 @@ do_reconsider_image_properties(CData *cdata, int x_size, int y_size, int num_com // But only do this the first time the file is loaded, or if the // number of channels in the image changes on subsequent loads. + //TODO: handle sRGB properly switch (num_components) { case 1: if (component_type == T_float) { @@ -4751,19 +4787,19 @@ do_reconsider_image_properties(CData *cdata, int x_size, int y_size, int num_com cdata->_format = F_luminance; } break; - + case 2: cdata->_format = F_luminance_alpha; break; - + case 3: cdata->_format = F_rgb; break; - + case 4: cdata->_format = F_rgba; break; - + default: // Eh? nassertr(false, false); @@ -5023,12 +5059,14 @@ do_set_format(CData *cdata, Texture::Format format) { case F_alpha: case F_luminance: case F_r16: + case F_sluminance: cdata->_num_components = 1; break; case F_luminance_alpha: case F_luminance_alphamask: case F_rg16: + case F_sluminance_alpha: cdata->_num_components = 2; break; @@ -5038,6 +5076,7 @@ do_set_format(CData *cdata, Texture::Format format) { case F_rgb12: case F_rgb332: case F_rgb16: + case F_srgb: cdata->_num_components = 3; break; @@ -5049,6 +5088,7 @@ do_set_format(CData *cdata, Texture::Format format) { case F_rgba12: case F_rgba16: case F_rgba32: + case F_srgb_alpha: cdata->_num_components = 4; break; } diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index 638bbc4120..ed9800680e 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -132,6 +132,13 @@ PUBLISHED: F_r16, F_rg16, F_rgb16, + + // These formats are in the sRGB color space. + // RGB is 2.2 gamma corrected, alpha is always linear. + F_srgb, + F_srgb_alpha, + F_sluminance, + F_sluminance_alpha, }; enum FilterType { @@ -160,7 +167,7 @@ PUBLISHED: // The OpenGL ARB_shadow extension can be thought of as a kind of filtering. FT_shadow, - + // Default is usually linear, but it depends on format. // This was added at the end of the list to avoid bumping TXO version #. FT_default,