diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 529a053d00..1f97ade9e7 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -359,6 +359,12 @@ add_render_texture(Texture *tex, RenderTextureMode mode, // If we're still planning on binding, indicate it in texture properly. tex->set_render_to_texture(true); } + else if ((plane == RTP_depth || plane == RTP_depth_stencil) && _fb_properties.get_depth_bits() == 0) { + // If we're not providing the depth buffer, we need something to copy from. + display_cat.error() + << "add_render_texture: can't copy depth from framebuffer without depth bits!\n"; + return; + } CDWriter cdata(_cycler, true); RenderTexture result; diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 6c54e7c429..cc9845ccc1 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -952,10 +952,17 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, } } else if (_fb_properties.get_float_color()) { // 16-bit floating-point. - if (_fb_properties.get_blue_bits() > 0 || + if (_fb_properties.get_blue_bits() > 10 || _fb_properties.get_color_bits() == 1 || - _fb_properties.get_color_bits() > 16 * 2) { + _fb_properties.get_color_bits() > 32) { gl_format = GL_RGB16F; + } else if (_fb_properties.get_blue_bits() > 0) { + if (_fb_properties.get_red_bits() > 11 || + _fb_properties.get_green_bits() > 11) { + gl_format = GL_RGB16F; + } else { + gl_format = GL_R11F_G11F_B10F; + } } else if (_fb_properties.get_green_bits() > 0 || _fb_properties.get_color_bits() > 16) { gl_format = GL_RG16F; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index a5ad3579a9..86f4e89f3e 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -7378,7 +7378,10 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, switch (format) { case Texture::F_depth_stencil: if (_current_properties->get_float_depth()) { + //NB. In the future we may need a T_float_32_unsigned_int_24_8 format, but + // for now we'll just try to grab the depth component. component_type = Texture::T_float; + format = Texture::F_depth_component32; } else { component_type = Texture::T_unsigned_int_24_8; } @@ -7414,21 +7417,66 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, } } else if (_current_properties->get_float_color()) { if (_current_properties->get_alpha_bits()) { - format = Texture::F_rgba32; + if (_current_properties->get_red_bits() == 16 && + _current_properties->get_green_bits() == 16 && + _current_properties->get_blue_bits() == 16 && + _current_properties->get_alpha_bits() == 16) { + format = Texture::F_rgba16; + } else { + format = Texture::F_rgba32; + } } else if (_current_properties->get_blue_bits()) { - format = Texture::F_rgb32; + if (_current_properties->get_red_bits() == 11 && + _current_properties->get_green_bits() == 11 && + _current_properties->get_blue_bits() == 10) { + format = Texture::F_r11_g11_b10; + } else if (_current_properties->get_red_bits() == 16 && + _current_properties->get_green_bits() == 16 && + _current_properties->get_blue_bits() == 16) { + format = Texture::F_rgb16; + } else { + format = Texture::F_rgb32; + } } else if (_current_properties->get_green_bits()) { - format = Texture::F_rg32; + if (_current_properties->get_red_bits() == 16 && + _current_properties->get_green_bits() == 16) { + format = Texture::F_rg16; + } else { + format = Texture::F_rg32; + } } else { - format = Texture::F_r32; + if (_current_properties->get_red_bits() == 16) { + format = Texture::F_r16; + } else { + format = Texture::F_r32; + } + } + } else if (_current_properties->get_alpha_bits()) { + if (_current_properties->get_red_bits() == 10 && + _current_properties->get_green_bits() == 10 && + _current_properties->get_blue_bits() == 10 && + _current_properties->get_alpha_bits() == 2) { + format = Texture::F_rgb10_a2; + } else { + format = Texture::F_rgba; + } + } else if (_current_properties->get_blue_bits()) { + format = Texture::F_rgb; + } else if (_current_properties->get_green_bits()) { + if (_current_properties->get_red_bits() == 16 && + _current_properties->get_green_bits() == 16) { + format = Texture::F_rg16; + } else { + format = Texture::F_rg; } } else { - if (_current_properties->get_alpha_bits()) { - format = Texture::F_rgba; + if (_current_properties->get_color_bits() == 16) { + format = Texture::F_r16; } else { - format = Texture::F_rgb; + format = Texture::F_red; } } + if (_current_properties->get_float_color()) { component_type = Texture::T_float; } else if (_current_properties->get_color_bits() <= 24 @@ -7481,6 +7529,7 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, external_format = GL_RGBA; } +#ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", "; @@ -7524,10 +7573,72 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, case GL_FLOAT: GLCAT.spam(false) << "GL_FLOAT"; break; + case GL_UNSIGNED_SHORT_4_4_4_4: + GLCAT.spam(false) << "GL_UNSIGNED_SHORT_4_4_4_4"; + break; + case GL_UNSIGNED_SHORT_5_5_5_1: + GLCAT.spam(false) << "GL_UNSIGNED_SHORT_5_5_5_1"; + break; + case GL_UNSIGNED_SHORT_5_6_5: + GLCAT.spam(false) << "GL_UNSIGNED_SHORT_5_6_5"; + break; #ifndef OPENGLES_1 case GL_INT: GLCAT.spam(false) << "GL_INT"; break; + case GL_BYTE: + GLCAT.spam(false) << "GL_BYTE"; + break; + case GL_SHORT: + GLCAT.spam(false) << "GL_SHORT"; + break; + case GL_UNSIGNED_INT: + GLCAT.spam(false) << "GL_UNSIGNED_INT"; + break; + case GL_HALF_FLOAT: + GLCAT.spam(false) << "GL_HALF_FLOAT"; + break; +#endif +#ifndef OPENGLES + case GL_UNSIGNED_BYTE_3_3_2: + GLCAT.spam(false) << "GL_UNSIGNED_BYTE_3_3_2"; + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + GLCAT.spam(false) << "GL_UNSIGNED_BYTE_2_3_3_REV"; + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + GLCAT.spam(false) << "GL_UNSIGNED_SHORT_5_6_5_REV"; + break; + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + GLCAT.spam(false) << "GL_UNSIGNED_SHORT_4_4_4_4_REV"; + break; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + GLCAT.spam(false) << "GL_UNSIGNED_SHORT_1_5_5_5_REV"; + break; + case GL_UNSIGNED_INT_8_8_8_8: + GLCAT.spam(false) << "GL_UNSIGNED_INT_8_8_8_8"; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + GLCAT.spam(false) << "GL_UNSIGNED_INT_8_8_8_8_REV"; + break; + case GL_UNSIGNED_INT_10_10_10_2: + GLCAT.spam(false) << "GL_UNSIGNED_INT_10_10_10_2"; + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: + GLCAT.spam(false) << "GL_UNSIGNED_INT_2_10_10_10_REV"; + break; + case GL_UNSIGNED_INT_24_8: + GLCAT.spam(false) << "GL_UNSIGNED_INT_24_8"; + break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + GLCAT.spam(false) << "GL_UNSIGNED_INT_10F_11F_11F_REV"; + break; + case GL_UNSIGNED_INT_5_9_9_9_REV: + GLCAT.spam(false) << "GL_UNSIGNED_INT_5_9_9_9_REV"; + break; + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + GLCAT.spam(false) << "GL_FLOAT_32_UNSIGNED_INT_24_8_REV"; + break; #endif default: GLCAT.spam(false) << "unknown"; @@ -7536,6 +7647,7 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z, GLCAT.spam(false) << ")" << endl; } +#endif // NDEBUG unsigned char *image_ptr = tex->modify_ram_image(); size_t image_size = tex->get_ram_image_size();