diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 0ed2a2dcbb..e71bbd4271 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -239,17 +239,41 @@ get_texture_reload_priority() const { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::get_cube_map_index +// Function: DisplayRegion::set_cube_map_index // Access: Published -// Description: Returns the cube map face index associated with this +// Description: Deprecated; replaced by set_target_tex_page(). +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +set_cube_map_index(int cube_map_index) { + set_target_tex_page(cube_map_index, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_target_tex_page +// Access: Published +// Description: Returns the target page number associated with this // particular DisplayRegion, or -1 if it is not -// associated with a cube map. See -// set_cube_map_index(). +// associated with a page. See +// set_target_tex_page(). //////////////////////////////////////////////////////////////////// INLINE int DisplayRegion:: -get_cube_map_index() const { +get_target_tex_page() const { CDReader cdata(_cycler); - return cdata->_cube_map_index; + 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; } //////////////////////////////////////////////////////////////////// @@ -776,16 +800,29 @@ get_tex_view_offset() { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegionPipelineReader::get_cube_map_index -// Access: Public -// Description: Returns the cube map face index associated with this +// Function: DisplayRegionPipelineReader::get_target_tex_page +// Access: Published +// Description: Returns the target page number associated with this // particular DisplayRegion, or -1 if it is not -// associated with a cube map. See -// set_cube_map_index(). +// associated with a page. See +// set_target_tex_page(). //////////////////////////////////////////////////////////////////// INLINE int DisplayRegionPipelineReader:: -get_cube_map_index() const { - return _cdata->_cube_map_index; +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; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index 9dd48f5284..dfdf3b9f8e 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -387,22 +387,29 @@ get_cull_traverser() { } //////////////////////////////////////////////////////////////////// -// Function: DisplayRegion::set_cube_map_index +// Function: DisplayRegion::set_target_tex_page // Access: Published, Virtual // Description: This is a special parameter that is only used when -// rendering the faces of a cube map. Normally you -// should not need to set it directly. This sets up the -// DisplayRegion to render to the nth cube map face; the -// value must be between 0 and 5, inclusive. A normal -// DisplayRegion that is not associated with any -// particular cube map should be set to -1. +// rendering the faces of a cube map or multipage and/or +// multiview texture. +// +// This sets up the DisplayRegion to render to the ith +// page and jth view of its associated texture(s); the +// value must be consistent with the range of values +// availble to the texture. A normal DisplayRegion that +// is not associated with any particular page should be +// set to page -1 and view 0. +// +// This is particularly useful when rendering cube maps +// and/or stereo textures. //////////////////////////////////////////////////////////////////// void DisplayRegion:: -set_cube_map_index(int cube_map_index) { +set_target_tex_page(int page, int view) { int pipeline_stage = Thread::get_current_pipeline_stage(); nassertv(pipeline_stage == 0); CDWriter cdata(_cycler); - cdata->_cube_map_index = cube_map_index; + cdata->_target_tex_page = page; + cdata->_target_tex_view = view; } //////////////////////////////////////////////////////////////////// @@ -816,7 +823,8 @@ CData() : _sort(0), _stereo_channel(Lens::SC_mono), _tex_view_offset(0), - _cube_map_index(-1) + _target_tex_page(-1), + _target_tex_view(-1) { } @@ -841,7 +849,8 @@ CData(const DisplayRegion::CData ©) : _sort(copy._sort), _stereo_channel(copy._stereo_channel), _tex_view_offset(copy._tex_view_offset), - _cube_map_index(copy._cube_map_index) + _target_tex_page(copy._target_tex_page), + _target_tex_view(copy._target_tex_view) { } diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 9c1b7ef837..8ab64d7eca 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -111,8 +111,10 @@ PUBLISHED: virtual void set_cull_traverser(CullTraverser *trav); CullTraverser *get_cull_traverser(); - virtual void set_cube_map_index(int cube_map_index); - INLINE int get_cube_map_index() const; + INLINE void set_cube_map_index(int cube_map_index); + virtual void set_target_tex_page(int page, int view); + 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(); @@ -210,7 +212,8 @@ private: int _sort; Lens::StereoChannel _stereo_channel; int _tex_view_offset; - int _cube_map_index; + int _target_tex_page; + int _target_tex_view; PT(CallbackObject) _cull_callback; PT(CallbackObject) _draw_callback; @@ -308,7 +311,8 @@ public: INLINE Lens::StereoChannel get_stereo_channel() const; INLINE int get_tex_view_offset(); INLINE bool get_clear_depth_between_eyes() const; - INLINE int get_cube_map_index() 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 31545d99f9..7e4e80d8ad 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -862,12 +862,14 @@ end_frame_spam(FrameMode mode) { //////////////////////////////////////////////////////////////////// // Function: GraphicsOutput::clear_cube_map_selection // Access: Public -// Description: Clear the variables that select a cube-map face. +// Description: Clear the variables that select a cube-map face (or +// other multipage or multiview texture face). //////////////////////////////////////////////////////////////////// INLINE void GraphicsOutput:: clear_cube_map_selection() { - _cube_map_index = -1; - _cube_map_dr = NULL; + _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 e843bab755..05863d4751 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -106,9 +106,9 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe, _is_valid = false; _flip_ready = false; - _cube_map_index = -1; - _cube_map_dr = NULL; - _tex_view_offset = -1; + _target_tex_page = -1; + _target_tex_view = -1; + _prev_page_dr = NULL; _sort = 0; _child_sort = 0; _got_child_sort = false; @@ -1069,7 +1069,7 @@ make_cube_map(const string &name, int size, NodePath &camera_rig, DisplayRegion *dr; dr = buffer->make_display_region(); - dr->set_cube_map_index(i); + dr->set_target_tex_page(i, 0); dr->copy_clear_settings(*this); dr->set_camera(camera_np); } @@ -1341,13 +1341,16 @@ end_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void GraphicsOutput:: change_scenes(DisplayRegionPipelineReader *new_dr) { - int new_cube_map_index = new_dr->get_cube_map_index(); - if (new_cube_map_index != -1 && - new_cube_map_index != _cube_map_index) { - int old_cube_map_index = _cube_map_index; - DisplayRegion *old_cube_map_dr = _cube_map_dr; - _cube_map_index = new_cube_map_index; - _cube_map_dr = new_dr->get_object(); + 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) { + 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; @@ -1356,83 +1359,55 @@ change_scenes(DisplayRegionPipelineReader *new_dr) { 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 cube map face, so that the subsequent frame will be - // rendered to the new face. + // 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_cube_map(new_cube_map_index); - - } else if (old_cube_map_index != -1) { + } else if (old_target_tex_page != -1) { // In copy-to-texture mode, copy the just-rendered framebuffer - // to the old cube map face. - nassertv(old_cube_map_dr != (DisplayRegion *)NULL); + // 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() << "Copying texture for " << get_name() << " at scene change.\n"; display_cat.debug() - << "cube_map_index = " << old_cube_map_index << "\n"; + << "target_tex_page = " << old_target_tex_page << "\n"; } 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_cube_map_index, - old_cube_map_dr, buffer); + _gsg->framebuffer_copy_to_ram(texture, old_target_tex_page, + old_page_dr, buffer); } else { - _gsg->framebuffer_copy_to_texture(texture, old_cube_map_index, - old_cube_map_dr, buffer); + _gsg->framebuffer_copy_to_texture(texture, old_target_tex_page, + old_page_dr, buffer); } } } } } - - int new_tex_view_offset = new_dr->get_tex_view_offset(); - if (new_tex_view_offset != _tex_view_offset) { - int old_tex_view_offset = _tex_view_offset; - //DisplayRegion *old_cube_map_dr = _cube_map_dr; - _tex_view_offset = new_tex_view_offset; - //_cube_map_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; - Texture *texture = (*ri)._texture; - if (rtm_mode == RTM_bind_or_copy || rtm_mode == RTM_bind_layered) { - // In render-to-texture mode, switch the rendering backend to - // the new view, so that the subsequent frame will be - // rendered to the new view. - - select_tex_view(new_tex_view_offset); - break; - } - } - } } //////////////////////////////////////////////////////////////////// -// Function: GraphicsOutput::select_cube_map +// Function: GraphicsOutput::select_target_tex_page // Access: Public, Virtual // 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. This should -// do whatever needs to be done to switch the buffer to -// the indicated face. +// 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. //////////////////////////////////////////////////////////////////// void GraphicsOutput:: -select_cube_map(int) { -} - -//////////////////////////////////////////////////////////////////// -// Function: GraphicsOutput::select_tex_view -// Access: Public, Virtual -// Description: Called internally when the window is in -// render-to-a-texture mode and the DisplayRegion -// requests that we switch rendering to a different -// texture view. -//////////////////////////////////////////////////////////////////// -void GraphicsOutput:: -select_tex_view(int) { +select_target_tex_page(int, int) { } //////////////////////////////////////////////////////////////////// @@ -1603,7 +1578,7 @@ copy_to_textures() { display_cat.debug() << "Copying texture for " << get_name() << " at frame end.\n"; display_cat.debug() - << "cube_map_index = " << _cube_map_index << "\n"; + << "target_tex_page = " << _target_tex_page << "\n"; } RenderTexturePlane plane = (*ri)._plane; RenderBuffer buffer(_gsg, DrawableRegion::get_renderbuffer_type(plane)); @@ -1613,24 +1588,24 @@ copy_to_textures() { } bool copied = false; - if (_cube_map_dr != (DisplayRegion *)NULL) { + if (_prev_page_dr != (DisplayRegion *)NULL) { if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) { copied = - _gsg->framebuffer_copy_to_ram(texture, _cube_map_index, - _cube_map_dr, buffer); + _gsg->framebuffer_copy_to_ram(texture, _target_tex_page, + _prev_page_dr, buffer); } else { copied = - _gsg->framebuffer_copy_to_texture(texture, _cube_map_index, - _cube_map_dr, buffer); + _gsg->framebuffer_copy_to_texture(texture, _target_tex_page, + _prev_page_dr, buffer); } } else { if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) { copied = - _gsg->framebuffer_copy_to_ram(texture, _cube_map_index, + _gsg->framebuffer_copy_to_ram(texture, _target_tex_page, _overlay_display_region, buffer); } else { copied = - _gsg->framebuffer_copy_to_texture(texture, _cube_map_index, + _gsg->framebuffer_copy_to_texture(texture, _target_tex_page, _overlay_display_region, buffer); } } diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 9574a48015..1e40a7051b 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -260,8 +260,7 @@ public: virtual void end_frame(FrameMode mode, Thread *current_thread); void change_scenes(DisplayRegionPipelineReader *new_dr); - virtual void select_cube_map(int cube_map_index); - virtual void select_tex_view(int tex_view_offset); + virtual void select_target_tex_page(int page, int view); // These methods will be called within the app (main) thread. virtual void begin_flip(); @@ -311,9 +310,9 @@ protected: bool _stereo; string _name; bool _flip_ready; - int _cube_map_index; - DisplayRegion *_cube_map_dr; - int _tex_view_offset; + int _target_tex_page; + int _target_tex_view; + DisplayRegion *_prev_page_dr; PT(Geom) _texture_card; bool _trigger_copy; diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index bd6316fa84..fb630022d4 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -2754,7 +2754,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_cube_map_index(i); + dr->set_target_tex_page(i, 0); dr->set_camera(light_np); dr->set_clear_depth_active(true); } diff --git a/panda/src/display/stereoDisplayRegion.cxx b/panda/src/display/stereoDisplayRegion.cxx index ba16b1ce6c..c328bc3a33 100644 --- a/panda/src/display/stereoDisplayRegion.cxx +++ b/panda/src/display/stereoDisplayRegion.cxx @@ -284,16 +284,16 @@ set_cull_traverser(CullTraverser *trav) { } //////////////////////////////////////////////////////////////////// -// Function: StereoDisplayRegion::set_cube_map_index +// Function: StereoDisplayRegion::set_target_tex_page // Access: Published, Virtual -// Description: Sets the cube_map_index on both the left and +// Description: Sets the page and view on both the left and // right DisplayRegions to the indicated value. //////////////////////////////////////////////////////////////////// void StereoDisplayRegion:: -set_cube_map_index(int cube_map_index) { - DisplayRegion::set_cube_map_index(cube_map_index); - _left_eye->set_cube_map_index(cube_map_index); - _right_eye->set_cube_map_index(cube_map_index); +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); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/stereoDisplayRegion.h b/panda/src/display/stereoDisplayRegion.h index 18e574c315..01b6c3905c 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_cube_map_index(int cube_map_index); + virtual void set_target_tex_page(int page, int view); virtual void output(ostream &out) const; virtual PT(PandaNode) make_cull_result_graph(); diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx index 8524ff21b4..fea31ccfcc 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx @@ -394,7 +394,7 @@ rebuild_bitplanes() { } //////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsBuffer8::select_cube_map +// Function: wdxGraphicsBuffer8::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of @@ -403,8 +403,8 @@ rebuild_bitplanes() { // the indicated face. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer8:: -select_cube_map(int cube_map_index) { - _cube_map_index = cube_map_index; +select_target_tex_page(int page, int view) { + _cube_map_index = page; HRESULT hr; Texture *color_tex = 0; diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.h b/panda/src/dxgsg8/wdxGraphicsBuffer8.h index ab8b63a795..cb5d21ed9c 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.h +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.h @@ -46,7 +46,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void select_cube_map(int cube_map_index); + virtual void select_target_tex_page(int page, int view); virtual void process_events(); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 8e7e3f8bd6..1eaef91715 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -1902,7 +1902,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, // must use a render target type texture for StretchRect tex->set_render_to_texture(true); - int view = dr->get_tex_view_offset(); + int view = dr->get_target_tex_view(); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this); if (tc == (TextureContext *)NULL) { return false; diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index e530e6701e..8fceeb9469 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -582,7 +582,7 @@ rebuild_bitplanes() { } //////////////////////////////////////////////////////////////////// -// Function: wdxGraphicsBuffer9::select_cube_map +// Function: wdxGraphicsBuffer9::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of @@ -591,13 +591,13 @@ rebuild_bitplanes() { // the indicated face. //////////////////////////////////////////////////////////////////// void wdxGraphicsBuffer9:: -select_cube_map(int cube_map_index) { +select_target_tex_page(int page, int view) { DWORD render_target_index; render_target_index = 0; - _cube_map_index = cube_map_index; + _cube_map_index = page; HRESULT hr; Texture *color_tex = 0; diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.h b/panda/src/dxgsg9/wdxGraphicsBuffer9.h index 05e88a027f..91dfd0539f 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.h +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.h @@ -46,7 +46,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void select_cube_map(int cube_map_index); + virtual void select_target_tex_page(int page, int view); virtual void process_events(); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 0811e0bf12..a036d703ca 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -80,7 +80,7 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe, } _shared_depth_buffer = 0; - _active_cube_map_index = -1; + _bound_tex_page = -1; _bound_tex_view = 0; } @@ -125,7 +125,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { begin_frame_spam(mode); check_host_valid(); - _active_cube_map_index = -1; + _bound_tex_page = -1; if (!_is_valid) { if (GLCAT.is_debug()) { @@ -1056,7 +1056,7 @@ end_frame(FrameMode mode, Thread *current_thread) { CLP(GraphicsStateGuardian) *glgsg; DCAST_INTO_V(glgsg, _gsg); glgsg->bind_fbo(0); - _active_cube_map_index = -1; + _bound_tex_page = -1; if (mode == FM_render) { generate_mipmaps(); @@ -1086,110 +1086,97 @@ set_size(int x, int y) { } //////////////////////////////////////////////////////////////////// -// Function: glGraphicsBuffer::select_cube_map +// Function: glGraphicsBuffer::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of -// rendering the six layers of a cube map. This should -// do whatever needs to be done to switch the buffer to -// the indicated face. +// 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. //////////////////////////////////////////////////////////////////// void CLP(GraphicsBuffer):: -select_cube_map(int cube_map_index) { - nassertv(cube_map_index >= 0 && cube_map_index < _fbo.size()); - - if (_active_cube_map_index != -1) { - // Resolve the multisample rendering for the previous face. - if (_requested_multisamples && _fbo_multisample) { - resolve_multisamples(); - } - } +select_target_tex_page(int page, int view) { + nassertv(page >= 0 && page < _fbo.size()); CLP(GraphicsStateGuardian) *glgsg; DCAST_INTO_V(glgsg, _gsg); - glgsg->bind_fbo(_fbo[cube_map_index]); - _active_cube_map_index = cube_map_index; + bool switched_page = (_bound_tex_page != page); + bool switched_view = (_bound_tex_view != view); + + if (switched_page) { + if (_bound_tex_page != -1) { + // Resolve the multisample rendering for the previous face. + if (_requested_multisamples && _fbo_multisample) { + resolve_multisamples(); + } + } + + glgsg->bind_fbo(_fbo[page]); + _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); + } + + GLenum target = glgsg->get_texture_target(tex->get_texture_type()); + if (target == GL_TEXTURE_CUBE_MAP) { + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + _bound_tex_page; + } + + // Create the OpenGL texture object. + TextureContext *tc = tex->prepare_now(view, glgsg->get_prepared_objects(), glgsg); + nassertv(tc != (TextureContext *)NULL); + CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); + glgsg->update_texture(tc, true); + + if (GLCAT.is_spam()) { + GLCAT.spam() + << "Binding texture " << *tex + << " view " << view << " to color attachment.\n"; + } + +#ifndef OPENGLES + GLclampf priority = 1.0f; + glPrioritizeTextures(1, >c->_index, &priority); +#endif + glgsg->update_texture(tc, true); + + if (_rb_size_z == 1) { + if (target == GL_TEXTURE_3D) { + glgsg->_glFramebufferTexture3D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + target, gtc->_index, 0, _bound_tex_page); + } else if (target == GL_TEXTURE_2D_ARRAY_EXT) { + glgsg->_glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + gtc->_index, 0, _bound_tex_page); + } else { + glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + target, gtc->_index, 0); + } + } else { + glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + gtc->_index, 0); + } + + report_my_gl_errors(); + } + + _bound_tex_view = view; + } report_my_gl_errors(); } -//////////////////////////////////////////////////////////////////// -// Function: glGraphicsBuffer::select_tex_view -// Access: Public, Virtual -// Description: Called internally when the window is in -// render-to-a-texture mode and the DisplayRegion -// requests that we switch rendering to a different -// texture view. -// -// In the FBO case, we do this by re-binding the -// texture that is attached to the color plane. -//////////////////////////////////////////////////////////////////// -void CLP(GraphicsBuffer):: -select_tex_view(int view) { - CLP(GraphicsStateGuardian) *glgsg; - DCAST_INTO_V(glgsg, _gsg); - - if (view == _bound_tex_view) { - return; - } - - // 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); - } - - GLenum target = glgsg->get_texture_target(tex->get_texture_type()); - if (target == GL_TEXTURE_CUBE_MAP) { - target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + _active_cube_map_index; - } - - // Create the OpenGL texture object. - TextureContext *tc = tex->prepare_now(view, glgsg->get_prepared_objects(), glgsg); - nassertv(tc != (TextureContext *)NULL); - CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); - glgsg->update_texture(tc, true); - - if (GLCAT.is_spam()) { - GLCAT.spam() - << "Binding texture " << *tex - << " view " << view << " to color attachment.\n"; - } - - #ifndef OPENGLES - GLclampf priority = 1.0f; - glPrioritizeTextures(1, >c->_index, &priority); - #endif - glgsg->update_texture(tc, true); - - if (_rb_size_z == 1) { - if (target == GL_TEXTURE_3D) { - glgsg->_glFramebufferTexture3D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - target, gtc->_index, 0, _active_cube_map_index); - } else if (target == GL_TEXTURE_2D_ARRAY_EXT) { - glgsg->_glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - gtc->_index, 0, _active_cube_map_index); - } else { - glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - target, gtc->_index, 0); - } - } else { - glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - gtc->_index, 0); - } - - report_my_gl_errors(); - } - - _bound_tex_view = view; -} - //////////////////////////////////////////////////////////////////// // Function: glGraphicsBuffer::open_buffer // Access: Protected, Virtual @@ -1531,8 +1518,8 @@ resolve_multisamples() { glgsg->report_my_gl_errors(); GLuint fbo = _fbo[0]; - if (_active_cube_map_index != -1) { - fbo = _fbo[_active_cube_map_index]; + if (_bound_tex_page != -1) { + fbo = _fbo[_bound_tex_page]; } glgsg->_glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo); glgsg->_glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, _fbo_multisample); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.h b/panda/src/glstuff/glGraphicsBuffer_src.h index 8c6117ec9a..21850b2cb6 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.h +++ b/panda/src/glstuff/glGraphicsBuffer_src.h @@ -74,8 +74,7 @@ public: virtual void set_size(int x, int y); - virtual void select_cube_map(int cube_map_index); - virtual void select_tex_view(int tex_view_offset); + virtual void select_target_tex_page(int page, int view); virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual void unshare_depth_buffer(); @@ -129,7 +128,7 @@ 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 _active_cube_map_index; + int _bound_tex_page; int _bound_tex_view; bool _initial_clear; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 883c458b6d..cfeaaea617 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -4282,7 +4282,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, } } - int view = dr->get_tex_view_offset(); + 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); @@ -4463,6 +4463,13 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, component_type, format); } + 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()) { @@ -4513,10 +4520,14 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, unsigned char *image_ptr = tex->modify_ram_image(); size_t image_size = tex->get_ram_image_size(); - if (z >= 0) { - nassertr(z < tex->get_z_size(), false); + if (z >= 0 || view > 0) { image_size = tex->get_expected_ram_page_size(); - image_ptr += z * image_size; + if (z >= 0) { + image_ptr += z * image_size; + } + if (view > 0) { + image_ptr += (view * tex->get_z_size()) * image_size; + } } GLP(ReadPixels)(xo, yo, w, h, diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index eaa344740b..3484249744 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -1359,7 +1359,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, tex->setup_2d_texture(w, h, Texture::T_unsigned_byte, Texture::F_rgba); - int view = dr->get_tex_view_offset(); + 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); @@ -1431,12 +1431,23 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, component_type, format); } + 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) { - nassertr(z < tex->get_z_size(), false); + if (z >= 0 || view > 0) { image_size = tex->get_expected_ram_page_size(); - image_ptr += z * image_size; + if (z >= 0) { + image_ptr += z * image_size; + } + if (view > 0) { + image_ptr += (view * tex->get_z_size()) * image_size; + } } PIXEL *ip = (PIXEL *)(image_ptr + image_size); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index 3dd0df235a..5a3086e488 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -205,7 +205,7 @@ bind_texture_to_pbuffer() { } //////////////////////////////////////////////////////////////////// -// Function: wglGraphicsBuffer::select_cube_map +// Function: wglGraphicsBuffer::select_target_tex_page // Access: Public, Virtual // Description: Called internally when the window is in // render-to-a-texture mode and we are in the process of @@ -214,7 +214,7 @@ bind_texture_to_pbuffer() { // the indicated face. //////////////////////////////////////////////////////////////////// void wglGraphicsBuffer:: -select_cube_map(int cube_map_index) { +select_target_tex_page(int page, int view) { wglGraphicsStateGuardian *wglgsg; DCAST_INTO_V(wglgsg, _gsg); @@ -225,7 +225,7 @@ select_cube_map(int cube_map_index) { int ni = 0; iattrib_list[ni++] = WGL_CUBE_MAP_FACE_ARB; - iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cube_map_index; + iattrib_list[ni++] = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + page; // Terminate the list. nassertv(ni <= max_attrib_list); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.h b/panda/src/wgldisplay/wglGraphicsBuffer.h index 128d877331..94d7c7cf2d 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_cube_map(int cube_map_index); + virtual void select_target_tex_page(int page, int view); virtual void process_events();