From d792c930267157b3a970c59b92fd657cfad31b57 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 4 Apr 2014 08:45:49 +0000 Subject: [PATCH] Overhaul stereo FBOs in Panda making it more reliable, fix MRT bugs, disable auto-GLSL profile choosing on AMD, add max_color_targets (not yet implemented) --- panda/src/display/config_display.cxx | 11 ++ panda/src/display/config_display.h | 1 + panda/src/display/displayRegion.I | 29 +---- panda/src/display/displayRegion.cxx | 11 +- panda/src/display/displayRegion.h | 5 +- panda/src/display/graphicsOutput.I | 3 +- panda/src/display/graphicsOutput.cxx | 98 +++++++++++------ panda/src/display/graphicsOutput.h | 2 +- panda/src/display/graphicsStateGuardian.I | 29 ++++- panda/src/display/graphicsStateGuardian.cxx | 13 ++- panda/src/display/graphicsStateGuardian.h | 7 +- panda/src/display/stereoDisplayRegion.cxx | 24 ++-- panda/src/display/stereoDisplayRegion.h | 2 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 26 +++-- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 12 +- panda/src/dxgsg8/dxTextureContext8.cxx | 6 +- panda/src/dxgsg8/dxTextureContext8.h | 2 +- panda/src/dxgsg8/wdxGraphicsBuffer8.cxx | 2 +- panda/src/dxgsg8/wdxGraphicsBuffer8.h | 4 +- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 23 ++-- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 12 +- panda/src/dxgsg9/dxTextureContext9.cxx | 6 +- panda/src/dxgsg9/dxTextureContext9.h | 2 +- panda/src/dxgsg9/wdxGraphicsBuffer9.cxx | 2 +- panda/src/dxgsg9/wdxGraphicsBuffer9.h | 4 +- panda/src/glstuff/glGraphicsBuffer_src.cxx | 104 ++++++++++-------- panda/src/glstuff/glGraphicsBuffer_src.h | 5 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 104 ++++++++++-------- .../src/glstuff/glGraphicsStateGuardian_src.h | 5 +- panda/src/gsgbase/graphicsStateGuardianBase.h | 6 +- .../tinydisplay/tinyGraphicsStateGuardian.cxx | 17 +-- .../tinydisplay/tinyGraphicsStateGuardian.h | 4 +- panda/src/wgldisplay/wglGraphicsBuffer.cxx | 2 +- panda/src/wgldisplay/wglGraphicsBuffer.h | 2 +- 34 files changed, 327 insertions(+), 258 deletions(-) diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index 68986ca5ed..e89a7df768 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -172,6 +172,17 @@ ConfigVariableInt max_texture_stages "this number of texture stages simultaneously, regardless of " "what the GSG says it can do.")); +ConfigVariableInt max_color_targets +("max-color-targets", -1, + PRC_DESC("Set this to a positive integer to limit the number of " + "color targets reported by the GSG. This can be used to limit " + "the amount of render targets Panda will attempt to use. " + "If this is zero or less, the GSG will report its honest number " + "of color targets, allowing Panda the full use of the graphics " + "card; if it is 1 or more, then Panda will never allow more than " + "this number of color targets simultaneously, regardless of " + "what the GSG says it can do.")); + ConfigVariableBool support_render_texture ("support-render-texture", true, PRC_DESC("Set this true allow use of the render-to-a-texture feature, if it " diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index fa3c372cda..2cd7569f02 100644 --- a/panda/src/display/config_display.h +++ b/panda/src/display/config_display.h @@ -52,6 +52,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool force_parasite_buffer; extern EXPCL_PANDA_DISPLAY ConfigVariableBool prefer_single_buffer; extern EXPCL_PANDA_DISPLAY ConfigVariableInt max_texture_stages; +extern EXPCL_PANDA_DISPLAY ConfigVariableInt max_color_targets; extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_render_texture; extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_rescale_normal; extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_stencil; diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index e71bbd4271..bb549873c0 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -245,7 +245,7 @@ get_texture_reload_priority() const { //////////////////////////////////////////////////////////////////// INLINE void DisplayRegion:: set_cube_map_index(int cube_map_index) { - set_target_tex_page(cube_map_index, 0); + set_target_tex_page(cube_map_index); } //////////////////////////////////////////////////////////////////// @@ -262,20 +262,6 @@ get_target_tex_page() const { return cdata->_target_tex_page; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_target_tex_view -// Access: Published -// Description: Returns the target view number associated with this -// particular DisplayRegion, or -1 if it is not -// associated with a view. See -// set_target_tex_page(). -//////////////////////////////////////////////////////////////////// -INLINE int DisplayRegion:: -get_target_tex_view() const { - CDReader cdata(_cycler); - return cdata->_target_tex_view; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_cull_callback // Access: Published @@ -812,19 +798,6 @@ get_target_tex_page() const { return _cdata->_target_tex_page; } -//////////////////////////////////////////////////////////////////// -// Function: DisplayRegionPipelineReader::get_target_tex_view -// Access: Published -// Description: Returns the target view number associated with this -// particular DisplayRegion, or -1 if it is not -// associated with a view. See -// set_target_tex_page(). -//////////////////////////////////////////////////////////////////// -INLINE int DisplayRegionPipelineReader:: -get_target_tex_view() const { - return _cdata->_target_tex_view; -} - //////////////////////////////////////////////////////////////////// // Function: DisplayRegionPipelineReader::get_draw_callback // Access: Published diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index dfdf3b9f8e..5bf57bf2fa 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -404,12 +404,11 @@ get_cull_traverser() { // and/or stereo textures. //////////////////////////////////////////////////////////////////// void DisplayRegion:: -set_target_tex_page(int page, int view) { +set_target_tex_page(int page) { int pipeline_stage = Thread::get_current_pipeline_stage(); nassertv(pipeline_stage == 0); CDWriter cdata(_cycler); cdata->_target_tex_page = page; - cdata->_target_tex_view = view; } //////////////////////////////////////////////////////////////////// @@ -587,7 +586,7 @@ get_screenshot() { RenderBuffer buffer = gsg->get_render_buffer(get_screenshot_buffer_type(), _window->get_fb_properties()); - if (!gsg->framebuffer_copy_to_ram(tex, -1, this, buffer)) { + if (!gsg->framebuffer_copy_to_ram(tex, 0, -1, this, buffer)) { return NULL; } @@ -823,8 +822,7 @@ CData() : _sort(0), _stereo_channel(Lens::SC_mono), _tex_view_offset(0), - _target_tex_page(-1), - _target_tex_view(-1) + _target_tex_page(-1) { } @@ -849,8 +847,7 @@ CData(const DisplayRegion::CData ©) : _sort(copy._sort), _stereo_channel(copy._stereo_channel), _tex_view_offset(copy._tex_view_offset), - _target_tex_page(copy._target_tex_page), - _target_tex_view(copy._target_tex_view) + _target_tex_page(copy._target_tex_page) { } diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 8ab64d7eca..0de061ab1d 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -112,9 +112,8 @@ PUBLISHED: CullTraverser *get_cull_traverser(); INLINE void set_cube_map_index(int cube_map_index); - virtual void set_target_tex_page(int page, int view); + virtual void set_target_tex_page(int page); INLINE int get_target_tex_page() const; - INLINE int get_target_tex_view() const; INLINE void set_cull_callback(CallbackObject *object); INLINE void clear_cull_callback(); @@ -213,7 +212,6 @@ private: Lens::StereoChannel _stereo_channel; int _tex_view_offset; int _target_tex_page; - int _target_tex_view; PT(CallbackObject) _cull_callback; PT(CallbackObject) _draw_callback; @@ -312,7 +310,6 @@ public: INLINE int get_tex_view_offset(); INLINE bool get_clear_depth_between_eyes() const; INLINE int get_target_tex_page() const; - INLINE int get_target_tex_view() const; INLINE CallbackObject *get_draw_callback() const; INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; diff --git a/panda/src/display/graphicsOutput.I b/panda/src/display/graphicsOutput.I index 7e4e80d8ad..c5afb051c7 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -863,12 +863,11 @@ end_frame_spam(FrameMode mode) { // Function: GraphicsOutput::clear_cube_map_selection // Access: Public // Description: Clear the variables that select a cube-map face (or -// other multipage or multiview texture face). +// other multipage texture face). //////////////////////////////////////////////////////////////////// INLINE void GraphicsOutput:: clear_cube_map_selection() { _target_tex_page = -1; - _target_tex_view = -1; _prev_page_dr = NULL; } diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 05863d4751..273c9d9ae7 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -107,7 +107,6 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe, _is_valid = false; _flip_ready = false; _target_tex_page = -1; - _target_tex_view = -1; _prev_page_dr = NULL; _sort = 0; _child_sort = 0; @@ -373,6 +372,12 @@ add_render_texture(Texture *tex, RenderTextureMode mode, // which has system-imposed restrictions on size). tex->set_size_padded(get_x_size(), get_y_size(), tex->get_z_size()); + if (_fb_properties.is_stereo() && plane == RTP_color) { + if (tex->get_num_views() < 2) { + tex->set_num_views(2); + } + } + if (!support_render_texture || !get_supports_render_texture()) { // Binding is not supported or it is disabled, so just fall back // to copy instead. @@ -1069,7 +1074,7 @@ make_cube_map(const string &name, int size, NodePath &camera_rig, DisplayRegion *dr; dr = buffer->make_display_region(); - dr->set_target_tex_page(i, 0); + dr->set_target_tex_page(i); dr->copy_clear_settings(*this); dr->set_camera(camera_np); } @@ -1342,38 +1347,34 @@ end_frame(FrameMode mode, Thread *current_thread) { void GraphicsOutput:: change_scenes(DisplayRegionPipelineReader *new_dr) { int new_target_tex_page = new_dr->get_target_tex_page(); - int new_target_tex_view = new_dr->get_target_tex_view(); - if ((new_target_tex_page != -1 && new_target_tex_page != _target_tex_page) || - new_target_tex_view != _target_tex_view) { + + if (new_target_tex_page != -1 && new_target_tex_page != _target_tex_page) { + + if (new_target_tex_page == -1) { + new_target_tex_page = 0; + } int old_target_tex_page = _target_tex_page; - int old_target_tex_view = _target_tex_view; DisplayRegion *old_page_dr = _prev_page_dr; _target_tex_page = new_target_tex_page; - _target_tex_view = new_target_tex_view; _prev_page_dr = new_dr->get_object(); CDReader cdata(_cycler); RenderTextures::const_iterator ri; for (ri = cdata->_textures.begin(); ri != cdata->_textures.end(); ++ri) { RenderTextureMode rtm_mode = (*ri)._rtm_mode; + RenderTexturePlane plane = (*ri)._plane; Texture *texture = (*ri)._texture; if (rtm_mode != RTM_none) { if (rtm_mode == RTM_bind_or_copy || rtm_mode == RTM_bind_layered) { // In render-to-texture mode, switch the rendering backend // to the new page, so that the subsequent frame will be // rendered to the correct page. - select_target_tex_page(_target_tex_page, _target_tex_view); + select_target_tex_page(_target_tex_page); } else if (old_target_tex_page != -1) { // In copy-to-texture mode, copy the just-rendered framebuffer // to the old texture page. - // TODO: we should probably pass the view parameter into - // framebuffer_copy_to_xxx(), as we do the page parameter. - // Instead these methods draw the view parameter from - // dr->get_target_tex_view(), which is not altogether wrong - // but is a strange approach. - nassertv(old_page_dr != (DisplayRegion *)NULL); if (display_cat.is_debug()) { display_cat.debug() @@ -1383,12 +1384,31 @@ change_scenes(DisplayRegionPipelineReader *new_dr) { } RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type(), get_fb_properties()); - if (rtm_mode == RTM_copy_ram) { - _gsg->framebuffer_copy_to_ram(texture, old_target_tex_page, - old_page_dr, buffer); + + if (plane == RTP_color && _fb_properties.is_stereo()) { + // We've got two texture views to copy. + RenderBuffer left(_gsg, buffer._buffer_type & ~RenderBuffer::T_right); + RenderBuffer right(_gsg, buffer._buffer_type & ~RenderBuffer::T_left); + + if (rtm_mode == RTM_copy_ram) { + _gsg->framebuffer_copy_to_ram(texture, 0, old_target_tex_page, + old_page_dr, left); + _gsg->framebuffer_copy_to_ram(texture, 1, old_target_tex_page, + old_page_dr, right); + } else { + _gsg->framebuffer_copy_to_texture(texture, 0, old_target_tex_page, + old_page_dr, left); + _gsg->framebuffer_copy_to_texture(texture, 1, old_target_tex_page, + old_page_dr, right); + } } else { - _gsg->framebuffer_copy_to_texture(texture, old_target_tex_page, - old_page_dr, buffer); + if (rtm_mode == RTM_copy_ram) { + _gsg->framebuffer_copy_to_ram(texture, 0, old_target_tex_page, + old_page_dr, buffer); + } else { + _gsg->framebuffer_copy_to_texture(texture, 0, old_target_tex_page, + old_page_dr, buffer); + } } } } @@ -1402,12 +1422,11 @@ change_scenes(DisplayRegionPipelineReader *new_dr) { // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of // rendering the six faces of a cube map, or any other -// multi-page and/or multi-view texture. This should do -// whatever needs to be done to switch the buffer to the -// indicated page and view. +// multi-page texture. This should do whatever needs +// to be done to switch the buffer to the indicated page. //////////////////////////////////////////////////////////////////// void GraphicsOutput:: -select_target_tex_page(int, int) { +select_target_tex_page(int) { } //////////////////////////////////////////////////////////////////// @@ -1588,25 +1607,34 @@ copy_to_textures() { } bool copied = false; + DisplayRegion *dr = _overlay_display_region; if (_prev_page_dr != (DisplayRegion *)NULL) { + dr = _prev_page_dr; + } + + if (plane == RTP_color && _fb_properties.is_stereo()) { + // We've got two texture views to copy. + RenderBuffer left(_gsg, buffer._buffer_type & ~RenderBuffer::T_right); + RenderBuffer right(_gsg, buffer._buffer_type & ~RenderBuffer::T_left); + if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) { - copied = - _gsg->framebuffer_copy_to_ram(texture, _target_tex_page, - _prev_page_dr, buffer); + copied = _gsg->framebuffer_copy_to_ram(texture, 0, _target_tex_page, + dr, left); + copied = _gsg->framebuffer_copy_to_ram(texture, 1, _target_tex_page, + dr, right) && copied; } else { - copied = - _gsg->framebuffer_copy_to_texture(texture, _target_tex_page, - _prev_page_dr, buffer); + copied = _gsg->framebuffer_copy_to_texture(texture, 0, _target_tex_page, + dr, left); + copied = _gsg->framebuffer_copy_to_texture(texture, 1, _target_tex_page, + dr, right) && copied; } } else { if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) { - copied = - _gsg->framebuffer_copy_to_ram(texture, _target_tex_page, - _overlay_display_region, buffer); + copied = _gsg->framebuffer_copy_to_ram(texture, 0, _target_tex_page, + dr, buffer); } else { - copied = - _gsg->framebuffer_copy_to_texture(texture, _target_tex_page, - _overlay_display_region, buffer); + copied = _gsg->framebuffer_copy_to_texture(texture, 0, _target_tex_page, + dr, buffer); } } if (!copied) { diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 1e40a7051b..f138a64433 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -260,7 +260,7 @@ public: virtual void end_frame(FrameMode mode, Thread *current_thread); void change_scenes(DisplayRegionPipelineReader *new_dr); - virtual void select_target_tex_page(int page, int view); + virtual void select_target_tex_page(int page); // These methods will be called within the app (main) thread. virtual void begin_flip(); diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index ce54db6881..4bcc120f72 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -702,15 +702,38 @@ get_supports_geometry_instancing() const { return _supports_geometry_instancing; } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_max_color_targets +// Access: Published +// Description: Returns the maximum number of simultaneous color +// textures that may be attached for render-to-texture, +// as supported by this particular GSG. If you exceed +// this number, the lowest-priority render targets will +// not be applied. Use RenderTarget::set_priority() to +// adjust the relative importance of the different +// render targets. +// +// The value returned may not be meaningful until after +// the graphics context has been fully created (e.g. the +// window has been opened). +//////////////////////////////////////////////////////////////////// +INLINE int GraphicsStateGuardian:: +get_max_color_targets() const { + if (max_color_targets > 0) { + return min(_max_color_targets, (int)max_color_targets); + } + return _max_color_targets; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_maximum_simultaneous_render_targets // Access: Published -// Description: Returns the maximum simultaneous render targets -// supported. +// Description: Deprecated. Use get_max_color_targets() instead, +// which returns the exact same value. //////////////////////////////////////////////////////////////////// INLINE int GraphicsStateGuardian:: get_maximum_simultaneous_render_targets() const { - return _maximum_simultaneous_render_targets; + return get_max_color_targets(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 4aea74171a..715d1a7fee 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -218,7 +218,8 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, _supports_two_sided_stencil = false; _supports_geometry_instancing = false; - _maximum_simultaneous_render_targets = 1; + // Assume a maximum of 1 render target in absence of MRT. + _max_color_targets = 1; _supported_geom_rendering = 0; @@ -1317,14 +1318,14 @@ prepare_display_region(DisplayRegionPipelineReader *dr) { case Lens::SC_left: _color_write_mask = dr->get_window()->get_left_eye_color_mask(); if (_current_properties->is_stereo()) { - _stereo_buffer_mask = ~(RenderBuffer::T_front_right | RenderBuffer::T_back_right); + _stereo_buffer_mask = ~RenderBuffer::T_right; } break; case Lens::SC_right: _color_write_mask = dr->get_window()->get_right_eye_color_mask(); if (_current_properties->is_stereo()) { - _stereo_buffer_mask = ~(RenderBuffer::T_front_left | RenderBuffer::T_back_left); + _stereo_buffer_mask = ~RenderBuffer::T_left; } break; @@ -2150,7 +2151,7 @@ do_issue_light() { // copy. //////////////////////////////////////////////////////////////////// bool GraphicsStateGuardian:: -framebuffer_copy_to_texture(Texture *, int, const DisplayRegion *, +framebuffer_copy_to_texture(Texture *, int, int, const DisplayRegion *, const RenderBuffer &) { return false; } @@ -2167,7 +2168,7 @@ framebuffer_copy_to_texture(Texture *, int, const DisplayRegion *, // indicated texture. //////////////////////////////////////////////////////////////////// bool GraphicsStateGuardian:: -framebuffer_copy_to_ram(Texture *, int, const DisplayRegion *, +framebuffer_copy_to_ram(Texture *, int, int, const DisplayRegion *, const RenderBuffer &) { return false; } @@ -2722,7 +2723,7 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) { for (int i = 0; i < 6; ++i) { PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1); dr->set_lens_index(i); - dr->set_target_tex_page(i, 0); + dr->set_target_tex_page(i); dr->set_camera(light_np); dr->set_clear_depth_active(true); } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index d5a5f08eec..3f7efa8297 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -150,6 +150,7 @@ PUBLISHED: INLINE bool get_supports_two_sided_stencil() const; INLINE bool get_supports_geometry_instancing() const; + INLINE int get_max_color_targets() const; INLINE int get_maximum_simultaneous_render_targets() const; INLINE int get_shader_model() const; @@ -308,9 +309,9 @@ public: virtual void do_issue_light(); virtual bool framebuffer_copy_to_texture - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); virtual bool framebuffer_copy_to_ram - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); virtual void bind_light(PointLight *light_obj, const NodePath &light, int light_id); @@ -495,7 +496,7 @@ protected: bool _supports_two_sided_stencil; bool _supports_geometry_instancing; - int _maximum_simultaneous_render_targets; + int _max_color_targets; int _supported_geom_rendering; bool _color_scale_via_lighting; diff --git a/panda/src/display/stereoDisplayRegion.cxx b/panda/src/display/stereoDisplayRegion.cxx index c328bc3a33..828ef7756a 100644 --- a/panda/src/display/stereoDisplayRegion.cxx +++ b/panda/src/display/stereoDisplayRegion.cxx @@ -52,9 +52,17 @@ StereoDisplayRegion:: //////////////////////////////////////////////////////////////////// void StereoDisplayRegion:: set_clear_active(int n, bool clear_active) { - //DisplayRegion::set_clear_active(n, clear_active); - _left_eye->set_clear_active(n, clear_active); - _right_eye->set_clear_active(n, clear_active); + // The clear_active flag gets set only on the parent, stereo display + // region. + DisplayRegion::set_clear_active(n, clear_active); + + // Except for non-color buffers. These also get set on the + // right display region by default, on the assumption that we want + // to clear these buffers between drawing the eyes, and that the + // right eye is the second of the pair. + if (n != RTP_color) { + _right_eye->set_clear_active(n, clear_active); + } } //////////////////////////////////////////////////////////////////// @@ -64,7 +72,7 @@ set_clear_active(int n, bool clear_active) { //////////////////////////////////////////////////////////////////// void StereoDisplayRegion:: set_clear_value(int n, const LColor &clear_value) { - //DisplayRegion::set_clear_value(n, clear_value); + DisplayRegion::set_clear_value(n, clear_value); _left_eye->set_clear_value(n, clear_value); _right_eye->set_clear_value(n, clear_value); } @@ -290,10 +298,10 @@ set_cull_traverser(CullTraverser *trav) { // right DisplayRegions to the indicated value. //////////////////////////////////////////////////////////////////// void StereoDisplayRegion:: -set_target_tex_page(int page, int view) { - DisplayRegion::set_target_tex_page(page, view); - _left_eye->set_target_tex_page(page, view); - _right_eye->set_target_tex_page(page, view); +set_target_tex_page(int page) { + DisplayRegion::set_target_tex_page(page); + _left_eye->set_target_tex_page(page); + _right_eye->set_target_tex_page(page); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/stereoDisplayRegion.h b/panda/src/display/stereoDisplayRegion.h index 01b6c3905c..56882d4606 100644 --- a/panda/src/display/stereoDisplayRegion.h +++ b/panda/src/display/stereoDisplayRegion.h @@ -61,7 +61,7 @@ PUBLISHED: virtual void set_incomplete_render(bool incomplete_render); virtual void set_texture_reload_priority(int texture_reload_priority); virtual void set_cull_traverser(CullTraverser *trav); - virtual void set_target_tex_page(int page, int view); + virtual void set_target_tex_page(int page); virtual void output(ostream &out) const; virtual PT(PandaNode) make_cull_result_graph(); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index b344e9964d..c8b0730ea4 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -1493,8 +1493,8 @@ end_draw_primitives() { // copy. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: -framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb) { +framebuffer_copy_to_texture(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); int orig_x = tex->get_x_size(); @@ -1504,8 +1504,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, int xo, yo, w, h; dr->get_region_pixels_i(xo, yo, w, h); tex->set_size_padded(w, h); - - TextureContext *tc = tex->prepare_now(0, get_prepared_objects(), this); + + TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); if (tc == (TextureContext *)NULL) { return false; } @@ -1520,7 +1520,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, if (tex->get_texture_type() != Texture::TT_2d_texture) { // For a specialty texture like a cube map, go the slow route // through RAM for now. - return do_framebuffer_copy_to_ram(tex, z, dr, rb, true); + return do_framebuffer_copy_to_ram(tex, view, z, dr, rb, true); } nassertr(dtc->get_d3d_2d_texture() != NULL, false); @@ -1592,7 +1592,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, if (FAILED(hr)) { dxgsg8_cat.info() << "CopyRects failed in copy_texture " << D3DERRORSTRING(hr); - okflag = framebuffer_copy_to_ram(tex, z, dr, rb); + okflag = framebuffer_copy_to_ram(tex, view, z, dr, rb); } SAFE_RELEASE(render_target); @@ -1605,7 +1605,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, } else { // The copy failed. Fall back to copying it to RAM and back. // Terribly slow, but what are you going to do? - return do_framebuffer_copy_to_ram(tex, z, dr, rb, true); + return do_framebuffer_copy_to_ram(tex, view, z, dr, rb, true); } return true; @@ -1623,8 +1623,9 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, // indicated texture. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: -framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb) { - return do_framebuffer_copy_to_ram(tex, z, dr, rb, false); +framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { + return do_framebuffer_copy_to_ram(tex, view, z, dr, rb, false); } //////////////////////////////////////////////////////////////////// @@ -1637,8 +1638,9 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend // copies to texture memory). //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: -do_framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb, bool inverted) { +do_framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb, + bool inverted) { set_read_buffer(rb); RECT rect; @@ -1779,7 +1781,7 @@ do_framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, copy_inverted = !copy_inverted; } DXTextureContext8::d3d_surface_to_texture(rect, temp_surface, - copy_inverted, tex, z); + copy_inverted, tex, view, z); RELEASE(temp_surface, dxgsg8, "temp_surface", RELEASE_ONCE); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 4116089220..9a4412e01b 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -98,12 +98,16 @@ public: bool force); virtual void end_draw_primitives(); - virtual bool framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, + virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb); - virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, + virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb); - bool do_framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb, bool inverted); + bool do_framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, + const RenderBuffer &rb, + bool inverted); virtual void reset(); diff --git a/panda/src/dxgsg8/dxTextureContext8.cxx b/panda/src/dxgsg8/dxTextureContext8.cxx index a14783db23..ab651d6d0c 100644 --- a/panda/src/dxgsg8/dxTextureContext8.cxx +++ b/panda/src/dxgsg8/dxTextureContext8.cxx @@ -1062,7 +1062,8 @@ extract_texture_data() { //////////////////////////////////////////////////////////////////// HRESULT DXTextureContext8:: d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, - bool inverted, Texture *result, int z) { + bool inverted, Texture *result, int view, int z) { + // still need custom conversion since d3d/d3dx has no way to convert // arbitrary fmt to ARGB in-memory user buffer @@ -1079,6 +1080,9 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, nassertr(z < result->get_z_size(), E_FAIL); buf += z * result->get_expected_ram_page_size(); } + if (view > 0) { + buf += (view * result->get_z_size()) * result->get_expected_ram_page_size(); + } if (IsBadWritePtr(d3d_surface, sizeof(DWORD))) { dxgsg8_cat.error() diff --git a/panda/src/dxgsg8/dxTextureContext8.h b/panda/src/dxgsg8/dxTextureContext8.h index 39c6e0c7c4..5fc06f8d0a 100644 --- a/panda/src/dxgsg8/dxTextureContext8.h +++ b/panda/src/dxgsg8/dxTextureContext8.h @@ -44,7 +44,7 @@ public: static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, bool inverted, Texture *result, - int z); + int view, int z); private: HRESULT fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format); diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx index fea31ccfcc..8d5c8bb77e 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx @@ -403,7 +403,7 @@ rebuild_bitplanes() { // the indicated face. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer8:: -select_target_tex_page(int page, int view) { +select_target_tex_page(int page) { _cube_map_index = page; HRESULT hr; diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.h b/panda/src/dxgsg8/wdxGraphicsBuffer8.h index cb5d21ed9c..fe3c5a95de 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.h +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.h @@ -45,8 +45,8 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - - virtual void select_target_tex_page(int page, int view); + + virtual void select_target_tex_page(int page); virtual void process_events(); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 1eaef91715..fd48033eec 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -1887,8 +1887,8 @@ end_draw_primitives() { // copy. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: -framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb) { +framebuffer_copy_to_texture(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); int orig_x = tex->get_x_size(); @@ -1918,7 +1918,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, if (tex->get_texture_type() != Texture::TT_2d_texture) { // For a specialty texture like a cube map, go the slow route // through RAM for now. - return do_framebuffer_copy_to_ram(tex, z, dr, rb, true); + return do_framebuffer_copy_to_ram(tex, view, z, dr, rb, true); } nassertr(dtc->get_d3d_2d_texture() != NULL, false); @@ -2020,7 +2020,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, } else { // The copy failed. Fall back to copying it to RAM and back. // Terribly slow, but what are you going to do? - return do_framebuffer_copy_to_ram(tex, z, dr, rb, true); + return do_framebuffer_copy_to_ram(tex, view, z, dr, rb, true); } return true; @@ -2038,9 +2038,9 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, // indicated texture. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: -framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb) { - return do_framebuffer_copy_to_ram(tex, z, dr, rb, false); +framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { + return do_framebuffer_copy_to_ram(tex, view, z, dr, rb, false); } //////////////////////////////////////////////////////////////////// @@ -2053,8 +2053,9 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, // copies to texture memory). //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: -do_framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb, bool inverted) { +do_framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb, + bool inverted) { set_read_buffer(rb); RECT rect; @@ -2212,7 +2213,7 @@ do_framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, copy_inverted = !copy_inverted; } DXTextureContext9::d3d_surface_to_texture(rect, temp_surface, - copy_inverted, tex, z); + copy_inverted, tex, view, z); RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE); @@ -2445,7 +2446,7 @@ reset() { _supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR); _supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0); - _maximum_simultaneous_render_targets = d3d_caps.NumSimultaneousRTs; + _max_color_targets = d3d_caps.NumSimultaneousRTs; _supports_depth_bias = ((d3d_caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) == (D3DPRASTERCAPS_DEPTHBIAS | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index c9c0df9fd9..c3d3c72bf7 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -126,12 +126,16 @@ public: bool force); virtual void end_draw_primitives(); - virtual bool framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, + virtual bool framebuffer_copy_to_texture(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb); - virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, + virtual bool framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb); - bool do_framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb, bool inverted); + bool do_framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, + const RenderBuffer &rb, + bool inverted); void reset_render_states (void); virtual void reset(); diff --git a/panda/src/dxgsg9/dxTextureContext9.cxx b/panda/src/dxgsg9/dxTextureContext9.cxx index a178fd7484..9fd73be358 100755 --- a/panda/src/dxgsg9/dxTextureContext9.cxx +++ b/panda/src/dxgsg9/dxTextureContext9.cxx @@ -1303,7 +1303,8 @@ extract_texture_data(DXScreenData &screen) { //////////////////////////////////////////////////////////////////// HRESULT DXTextureContext9:: d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface, - bool inverted, Texture *result, int z) { + bool inverted, Texture *result, int view, int z) { + // still need custom conversion since d3d/d3dx has no way to convert // arbitrary fmt to ARGB in-memory user buffer @@ -1320,6 +1321,9 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface, nassertr(z < result->get_z_size(), E_FAIL); buf += z * result->get_expected_ram_page_size(); } + if (view > 0) { + buf += (view * result->get_z_size()) * result->get_expected_ram_page_size(); + } if (IsBadWritePtr(d3d_surface, sizeof(DWORD))) { dxgsg9_cat.error() diff --git a/panda/src/dxgsg9/dxTextureContext9.h b/panda/src/dxgsg9/dxTextureContext9.h index 3d8549b3e4..01a5838042 100755 --- a/panda/src/dxgsg9/dxTextureContext9.h +++ b/panda/src/dxgsg9/dxTextureContext9.h @@ -46,7 +46,7 @@ public: static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface, bool inverted, Texture *result, - int z); + int view, int z); private: HRESULT fill_d3d_texture_mipmap_pixels(int mip_level, int depth_index, D3DFORMAT source_format); diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index 8fceeb9469..646a016185 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -591,7 +591,7 @@ rebuild_bitplanes() { // the indicated face. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer9:: -select_target_tex_page(int page, int view) { +select_target_tex_page(int page) { DWORD render_target_index; diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.h b/panda/src/dxgsg9/wdxGraphicsBuffer9.h index 91dfd0539f..d876c2505e 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.h +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.h @@ -46,8 +46,8 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void select_target_tex_page(int page, int view); - + virtual void select_target_tex_page(int page); + virtual void process_events(); virtual bool share_depth_buffer(GraphicsOutput *graphics_output); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 82590c816b..0e094f4eef 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -81,7 +81,6 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe, _shared_depth_buffer = 0; _bound_tex_page = -1; - _bound_tex_view = 0; } //////////////////////////////////////////////////////////////////// @@ -431,6 +430,17 @@ rebuild_bitplanes() { int next = GL_COLOR_ATTACHMENT0_EXT; if (attach[RTP_color] || _fb_properties.get_color_bits() > 0) { bind_slot(layer, rb_resize, attach, RTP_color, next++); + + if (_fb_properties.is_stereo()) { + // The texture has already been initialized, so bind it straight away. + if (attach[RTP_color] != NULL) { + attach_tex(layer, 1, attach[RTP_color], next++); + } else { + //XXX hack: I needed a slot to use, and we don't currently use RTP_stencil + // which is treated as a color attachment below, so this fits the bill. + bind_slot(layer, rb_resize, attach, RTP_stencil, next++); + } + } _have_any_color = true; } @@ -471,6 +481,9 @@ rebuild_bitplanes() { int next = GL_COLOR_ATTACHMENT0_EXT; if (attach[RTP_color] || _fb_properties.get_color_bits() > 0) { bind_slot_multisample(rb_resize, attach, RTP_color, next++); + if (_fb_properties.is_stereo()) { + //TODO: figure out how multisample is supposed to work with stereo buffers. + } } for (int i=0; i<_fb_properties.get_aux_rgba(); i++) { @@ -498,7 +511,6 @@ rebuild_bitplanes() { _fb_properties.set_alpha_bits(0); } - _bound_tex_view = 0; _initial_clear = false; report_my_gl_errors(); @@ -763,6 +775,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, // Allocate and bind the renderbuffer. glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, _rb[slot]); + if (slot == RTP_depth_stencil) { GLCAT.debug() << "Creating depth stencil renderbuffer.\n"; // Allocate renderbuffer storage for depth stencil. @@ -811,13 +824,16 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, } else { GLCAT.debug() << "Creating color renderbuffer.\n"; glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, gl_format, _rb_size_x, _rb_size_y); - GLint red_size = 0, green_size = 0, blue_size = 0, alpha_size = 0; - glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT, &red_size); - glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT, &green_size); - glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT, &blue_size); - glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT, &alpha_size); - _fb_properties.set_color_bits(red_size + green_size + blue_size); - _fb_properties.set_alpha_bits(alpha_size); + + if (attachpoint == GL_COLOR_ATTACHMENT0_EXT) { + GLint red_size = 0, green_size = 0, blue_size = 0, alpha_size = 0; + glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_RED_SIZE_EXT, &red_size); + glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_GREEN_SIZE_EXT, &green_size); + glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_BLUE_SIZE_EXT, &blue_size); + glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_ALPHA_SIZE_EXT, &alpha_size); + _fb_properties.set_color_bits(red_size + green_size + blue_size); + _fb_properties.set_alpha_bits(alpha_size); + } glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0); glgsg->_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, attachpoint, GL_RENDERBUFFER_EXT, _rb[slot]); @@ -962,6 +978,10 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) { CLP(GraphicsStateGuardian) *glgsg; DCAST_INTO_V(glgsg, _gsg); + if (view >= attach->get_num_views()) { + attach->set_num_views(view + 1); + } + // Create the OpenGL texture object. TextureContext *tc = attach->prepare_now(view, glgsg->get_prepared_objects(), glgsg); nassertv(tc != (TextureContext *)NULL); @@ -985,7 +1005,7 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) { GLenum target = glgsg->get_texture_target(attach->get_texture_type()); if (target == GL_TEXTURE_CUBE_MAP) { target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer; - } + } switch (target) { #ifndef OPENGLES_1 @@ -1097,19 +1117,17 @@ set_size(int x, int y) { // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of // rendering the six faces of a cube map, or any other -// multi-page and/or multi-view texture. This should do -// whatever needs to be done to switch the buffer to the -// indicated page and view. +// multi-page texture. This should do whatever needs +// to be done to switch the buffer to the indicated page. //////////////////////////////////////////////////////////////////// void CLP(GraphicsBuffer):: -select_target_tex_page(int page, int view) { +select_target_tex_page(int page) { nassertv(page >= 0 && page < _fbo.size()); CLP(GraphicsStateGuardian) *glgsg; DCAST_INTO_V(glgsg, _gsg); bool switched_page = (_bound_tex_page != page); - bool switched_view = (_bound_tex_view != view); if (switched_page) { if (_bound_tex_page != -1) { @@ -1123,32 +1141,6 @@ select_target_tex_page(int page, int view) { _bound_tex_page = page; } - if (switched_view || switched_page) { - // We assume that we've already configured the texture earlier - // in bind_bitplanes. Therefore, since we can safely assume that - // all texture views have the same format, we can just bind the - // new view here. - - Texture *tex = _tex[RTP_color]; - if (tex != NULL) { - if (view >= tex->get_num_views()) { - tex->set_num_views(view + 1); - } - - if (GLCAT.is_spam()) { - GLCAT.spam() - << "Binding texture " << *tex - << " view " << view << " to color attachment.\n"; - } - - attach_tex(_bound_tex_page, view, tex, GL_COLOR_ATTACHMENT0_EXT); - - report_my_gl_errors(); - } - - _bound_tex_view = view; - } - report_my_gl_errors(); } @@ -1167,7 +1159,8 @@ open_buffer() { nassertr(_host != 0, false); // Count total color buffers. - int totalcolor = 1 + + int totalcolor = + (_fb_properties.is_stereo() ? 2 : 1) + _fb_properties.get_aux_rgba() + _fb_properties.get_aux_hrgba() + _fb_properties.get_aux_float(); @@ -1229,8 +1222,10 @@ open_buffer() { _fb_properties.set_accum_bits(0); _fb_properties.set_multisamples(_host->get_fb_properties().get_multisamples()); - // Update aux settings to reflect the GL_MAX_DRAW_BUFFERS limit. - int availcolor = glgsg->_max_draw_buffers; + // Update aux settings to reflect the GL_MAX_DRAW_BUFFERS limit, + // if we exceed it, that is. + int availcolor = glgsg->_max_color_targets; + if (totalcolor > availcolor) { int aux_rgba = _fb_properties.get_aux_rgba(); int aux_hrgba = _fb_properties.get_aux_hrgba(); @@ -1238,6 +1233,13 @@ open_buffer() { if (_fb_properties.get_color_bits() > 0 && availcolor > 0) { --availcolor; + if (_fb_properties.is_stereo()) { + if (availcolor > 0) { + --availcolor; + } else { + _fb_properties.set_stereo(0); + } + } } aux_rgba = min(aux_rgba, availcolor); availcolor -= aux_rgba; @@ -1254,7 +1256,6 @@ open_buffer() { _fb_properties.set_back_buffers(0); _fb_properties.set_indexed_color(0); _fb_properties.set_rgb_color(1); - //_fb_properties.set_stereo(0); _fb_properties.set_force_hardware(_host->get_fb_properties().get_force_hardware()); _fb_properties.set_force_software(_host->get_fb_properties().get_force_software()); @@ -1537,21 +1538,28 @@ resolve_multisamples() { #ifndef OPENGLES // Now handle the other color buffers. int next = GL_COLOR_ATTACHMENT1_EXT; - for (int i=0; i<_fb_properties.get_aux_rgba(); i++) { + if (_fb_properties.is_stereo()) { glReadBuffer(next); glDrawBuffer(next); glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y, GL_COLOR_BUFFER_BIT, GL_NEAREST); next += 1; } - for (int i=0; i<_fb_properties.get_aux_hrgba(); i++) { + for (int i = 0; i < _fb_properties.get_aux_rgba(); ++i) { glReadBuffer(next); glDrawBuffer(next); glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y, GL_COLOR_BUFFER_BIT, GL_NEAREST); next += 1; } - for (int i=0; i<_fb_properties.get_aux_float(); i++) { + for (int i = 0; i < _fb_properties.get_aux_hrgba(); ++i) { + glReadBuffer(next); + glDrawBuffer(next); + glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + next += 1; + } + for (int i = 0; i < _fb_properties.get_aux_float(); ++i) { glReadBuffer(next); glDrawBuffer(next); glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y, diff --git a/panda/src/glstuff/glGraphicsBuffer_src.h b/panda/src/glstuff/glGraphicsBuffer_src.h index bf4c0d0c51..8a161e3e0e 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.h +++ b/panda/src/glstuff/glGraphicsBuffer_src.h @@ -74,7 +74,7 @@ public: virtual void set_size(int x, int y); - virtual void select_target_tex_page(int page, int view); + virtual void select_target_tex_page(int page); virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual void unshare_depth_buffer(); @@ -94,7 +94,7 @@ protected: private: - void bind_slot(int face, bool rb_resize, Texture **attach, + void bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane plane, GLenum attachpoint); void bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane plane, GLenum attachpoint); @@ -130,7 +130,6 @@ private: // The cube map face we are currently drawing to or have just // finished drawing to, or -1 if we are not drawing to a cube map. int _bound_tex_page; - int _bound_tex_view; bool _initial_clear; bool _needs_rebuild; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 5135fcab92..de1a653b1a 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -49,20 +49,19 @@ #include "load_prc_file.h" #include "bamCache.h" #include "bamCacheRecord.h" -#include "colorWriteAttrib.h" -#include "depthWriteAttrib.h" -#include "shadeModelAttrib.h" -#include "rescaleNormalAttrib.h" -#include "clipPlaneAttrib.h" #include "alphaTestAttrib.h" -#include "cullFaceAttrib.h" -#include "fogAttrib.h" -#include "depthOffsetAttrib.h" -#include "materialAttrib.h" -#include "stencilAttrib.h" -#include "lightAttrib.h" -#include "scissorAttrib.h" #include "clipPlaneAttrib.h" +#include "colorWriteAttrib.h" +#include "cullFaceAttrib.h" +#include "depthOffsetAttrib.h" +#include "depthWriteAttrib.h" +#include "fogAttrib.h" +#include "lightAttrib.h" +#include "materialAttrib.h" +#include "rescaleNormalAttrib.h" +#include "scissorAttrib.h" +#include "shadeModelAttrib.h" +#include "stencilAttrib.h" #include "graphicsEngine.h" #include "shaderGenerator.h" @@ -955,21 +954,23 @@ reset() { // cgGLGetLatestProfile doesn't seem to return anything other // arbvp1/arbfp1 on non-NVIDIA cards, which is severely limiting. - if ((_shader_caps._active_vprofile == CG_PROFILE_ARBVP1 || - _shader_caps._active_fprofile == CG_PROFILE_ARBFP1) && - cgGLIsProfileSupported(CG_PROFILE_GLSLV) && - cgGLIsProfileSupported(CG_PROFILE_GLSLF)) { + // Actually, it seems that these profiles are horribly broken on these + // cards. Let's not do this. + //if ((_shader_caps._active_vprofile == CG_PROFILE_ARBVP1 || + // _shader_caps._active_fprofile == CG_PROFILE_ARBFP1) && + // cgGLIsProfileSupported(CG_PROFILE_GLSLV) && + // cgGLIsProfileSupported(CG_PROFILE_GLSLF)) { - // So, if this happens, we set it to GLSL, which is - // usually supported on all cards. - _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV; - _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF; + // // So, if this happens, we set it to GLSL, which is + // // usually supported on all cards. + // _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV; + // _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF; #if CG_VERSION_NUM >= 2200 - if (cgGLIsProfileSupported(CG_PROFILE_GLSLG)) { - _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG; - } + // if (cgGLIsProfileSupported(CG_PROFILE_GLSLG)) { + // _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG; + // } #endif - } + //} } _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40; _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40; @@ -1254,12 +1255,12 @@ reset() { _glDrawBuffers = (PFNGLDRAWBUFFERSPROC) get_extension_func(GLPREFIX_QUOTED, "DrawBuffersARB"); } - _max_draw_buffers = 1; + + _max_color_targets = 1; if (_glDrawBuffers != 0) { GLint max_draw_buffers = 0; GLP(GetIntegerv)(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); - _max_draw_buffers = max_draw_buffers; - _maximum_simultaneous_render_targets = max_draw_buffers; + _max_color_targets = max_draw_buffers; } #endif // OPENGLES @@ -4200,8 +4201,8 @@ make_geom_munger(const RenderState *state, Thread *current_thread) { // into which to copy. //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: -framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb) { +framebuffer_copy_to_texture(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { nassertr(tex != NULL && dr != NULL, false); set_read_buffer(rb._buffer_type); if (CLP(color_mask)) { @@ -4282,7 +4283,6 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, } } - int view = dr->get_target_tex_view(); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); nassertr(tc != (TextureContext *)NULL, false); CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); @@ -4390,8 +4390,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, // indicated texture. //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: -framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, - const RenderBuffer &rb) { +framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { nassertr(tex != NULL && dr != NULL, false); set_read_buffer(rb._buffer_type); GLP(PixelStorei)(GL_PACK_ALIGNMENT, 1); @@ -4465,11 +4465,6 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, nassertr(z < tex->get_z_size(), false); - int view = dr->get_target_tex_view(); - if (view >= tex->get_num_views()) { - tex->set_num_views(view + 1); - } - GLenum external_format = get_external_image_format(tex); if (GLCAT.is_spam()) { @@ -5853,27 +5848,37 @@ set_draw_buffer(int rbtype) { if (_current_fbo) { GLuint buffers[16]; - int nbuffers=0; + int nbuffers = 0; int index = 0; if (_current_properties->get_color_bits() > 0) { - if (rbtype & RenderBuffer::T_color) { - buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + (index++); + if (rbtype & RenderBuffer::T_left) { + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; + } + ++index; + if (_current_properties->is_stereo()) { + if (rbtype & RenderBuffer::T_right) { + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; + } + ++index; } } for (int i=0; i<_current_properties->get_aux_rgba(); i++) { if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) { - buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + (index++); + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; } + ++index; } for (int i=0; i<_current_properties->get_aux_hrgba(); i++) { if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) { - buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + (index++); + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; } + ++index; } for (int i=0; i<_current_properties->get_aux_float(); i++) { if (rbtype & (RenderBuffer::T_aux_float_0 << i)) { - buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + (index++); + buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index; } + ++index; } _glDrawBuffers(nbuffers, buffers); @@ -5950,26 +5955,31 @@ set_read_buffer(int rbtype) { } if (_current_fbo) { - GLuint buffer = GL_COLOR_ATTACHMENT0_EXT; int index = 1; + if (_current_properties->is_stereo()) { + if (rbtype & RenderBuffer::T_right) { + buffer = GL_COLOR_ATTACHMENT1_EXT; + } + ++index; + } for (int i=0; i<_current_properties->get_aux_rgba(); i++) { if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) { buffer = GL_COLOR_ATTACHMENT0_EXT + index; } - index += 1; + ++index; } for (int i=0; i<_current_properties->get_aux_hrgba(); i++) { if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) { buffer = GL_COLOR_ATTACHMENT0_EXT + index; } - index += 1; + ++index; } for (int i=0; i<_current_properties->get_aux_float(); i++) { if (rbtype & (RenderBuffer::T_aux_float_0 << i)) { buffer = GL_COLOR_ATTACHMENT0_EXT + index; } - index += 1; + ++index; } GLP(ReadBuffer)(buffer); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index c1aa99f2aa..bba06db847 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -266,9 +266,9 @@ public: virtual void clear(DrawableRegion *region); virtual bool framebuffer_copy_to_texture - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); virtual bool framebuffer_copy_to_ram - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); void apply_fog(Fog *fog); @@ -637,7 +637,6 @@ public: INLINE bool get_supports_framebuffer_blit(); PFNGLBLITFRAMEBUFFEREXTPROC _glBlitFramebuffer; PFNGLDRAWBUFFERSPROC _glDrawBuffers; - int _max_draw_buffers; int _max_fb_samples; PFNGLGENQUERIESPROC _glGenQueries; diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index 4977be3721..4de1ffca8f 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -208,10 +208,10 @@ public: virtual void end_draw_primitives()=0; virtual bool framebuffer_copy_to_texture - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0; + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0; virtual bool framebuffer_copy_to_ram - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0; - + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0; + virtual CoordinateSystem get_internal_coordinate_system() const=0; virtual void bind_light(PointLight *light_obj, const NodePath &light, diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index 3484249744..b607cfe236 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -1350,16 +1350,16 @@ end_draw_primitives() { // copy. //////////////////////////////////////////////////////////////////// bool TinyGraphicsStateGuardian:: -framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, +framebuffer_copy_to_texture(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { nassertr(tex != NULL && dr != NULL, false); - + int xo, yo, w, h; dr->get_region_pixels_i(xo, yo, w, h); tex->setup_2d_texture(w, h, Texture::T_unsigned_byte, Texture::F_rgba); - int view = dr->get_target_tex_view(); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); nassertr(tc != (TextureContext *)NULL, false); TinyTextureContext *gtc = DCAST(TinyTextureContext, tc); @@ -1389,7 +1389,6 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, return true; } - //////////////////////////////////////////////////////////////////// // Function: TinyGraphicsStateGuardian::framebuffer_copy_to_ram // Access: Public, Virtual @@ -1401,10 +1400,11 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, // indicated texture. //////////////////////////////////////////////////////////////////// bool TinyGraphicsStateGuardian:: -framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, +framebuffer_copy_to_ram(Texture *tex, int view, int z, + const DisplayRegion *dr, const RenderBuffer &rb) { nassertr(tex != NULL && dr != NULL, false); - + int xo, yo, w, h; dr->get_region_pixels_i(xo, yo, w, h); @@ -1433,11 +1433,6 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, nassertr(z < tex->get_z_size(), false); - int view = dr->get_target_tex_view(); - if (view >= tex->get_num_views()) { - tex->set_num_views(view + 1); - } - unsigned char *image_ptr = tex->modify_ram_image(); size_t image_size = tex->get_ram_image_size(); if (z >= 0 || view > 0) { diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h index 876fe7b0e4..f9f671866d 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h @@ -82,9 +82,9 @@ public: virtual void end_draw_primitives(); virtual bool framebuffer_copy_to_texture - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); virtual bool framebuffer_copy_to_ram - (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); + (Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb); virtual void set_state_and_transform(const RenderState *state, const TransformState *transform); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index 5a3086e488..5fa7095864 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -214,7 +214,7 @@ bind_texture_to_pbuffer() { // the indicated face. //////////////////////////////////////////////////////////////////// void wglGraphicsBuffer:: -select_target_tex_page(int page, int view) { +select_target_tex_page(int page) { wglGraphicsStateGuardian *wglgsg; DCAST_INTO_V(wglgsg, _gsg); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.h b/panda/src/wgldisplay/wglGraphicsBuffer.h index 94d7c7cf2d..72aac1247b 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.h +++ b/panda/src/wgldisplay/wglGraphicsBuffer.h @@ -49,7 +49,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void select_target_tex_page(int page, int view); + virtual void select_target_tex_page(int page); virtual void process_events();