fix some stereo-fbo and cube map issues, introducing DisplayRegion::set_target_tex_page()

This commit is contained in:
David Rose 2013-12-06 23:45:40 +00:00
parent 741203a693
commit f615e0beeb
20 changed files with 270 additions and 236 deletions

View File

@ -239,17 +239,41 @@ get_texture_reload_priority() const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_cube_map_index // Function: DisplayRegion::set_cube_map_index
// Access: Published // 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 // particular DisplayRegion, or -1 if it is not
// associated with a cube map. See // associated with a page. See
// set_cube_map_index(). // set_target_tex_page().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int DisplayRegion:: INLINE int DisplayRegion::
get_cube_map_index() const { get_target_tex_page() const {
CDReader cdata(_cycler); 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 // Function: DisplayRegionPipelineReader::get_target_tex_page
// Access: Public // Access: Published
// Description: Returns the cube map face index associated with this // Description: Returns the target page number associated with this
// particular DisplayRegion, or -1 if it is not // particular DisplayRegion, or -1 if it is not
// associated with a cube map. See // associated with a page. See
// set_cube_map_index(). // set_target_tex_page().
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader:: INLINE int DisplayRegionPipelineReader::
get_cube_map_index() const { get_target_tex_page() const {
return _cdata->_cube_map_index; 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;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -387,22 +387,29 @@ get_cull_traverser() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_cube_map_index // Function: DisplayRegion::set_target_tex_page
// Access: Published, Virtual // Access: Published, Virtual
// Description: This is a special parameter that is only used when // Description: This is a special parameter that is only used when
// rendering the faces of a cube map. Normally you // rendering the faces of a cube map or multipage and/or
// should not need to set it directly. This sets up the // multiview texture.
// DisplayRegion to render to the nth cube map face; the //
// value must be between 0 and 5, inclusive. A normal // This sets up the DisplayRegion to render to the ith
// DisplayRegion that is not associated with any // page and jth view of its associated texture(s); the
// particular cube map should be set to -1. // 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:: 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(); int pipeline_stage = Thread::get_current_pipeline_stage();
nassertv(pipeline_stage == 0); nassertv(pipeline_stage == 0);
CDWriter cdata(_cycler); 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), _sort(0),
_stereo_channel(Lens::SC_mono), _stereo_channel(Lens::SC_mono),
_tex_view_offset(0), _tex_view_offset(0),
_cube_map_index(-1) _target_tex_page(-1),
_target_tex_view(-1)
{ {
} }
@ -841,7 +849,8 @@ CData(const DisplayRegion::CData &copy) :
_sort(copy._sort), _sort(copy._sort),
_stereo_channel(copy._stereo_channel), _stereo_channel(copy._stereo_channel),
_tex_view_offset(copy._tex_view_offset), _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)
{ {
} }

View File

@ -111,8 +111,10 @@ PUBLISHED:
virtual void set_cull_traverser(CullTraverser *trav); virtual void set_cull_traverser(CullTraverser *trav);
CullTraverser *get_cull_traverser(); CullTraverser *get_cull_traverser();
virtual void set_cube_map_index(int cube_map_index); INLINE void set_cube_map_index(int cube_map_index);
INLINE int get_cube_map_index() const; 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 set_cull_callback(CallbackObject *object);
INLINE void clear_cull_callback(); INLINE void clear_cull_callback();
@ -210,7 +212,8 @@ private:
int _sort; int _sort;
Lens::StereoChannel _stereo_channel; Lens::StereoChannel _stereo_channel;
int _tex_view_offset; int _tex_view_offset;
int _cube_map_index; int _target_tex_page;
int _target_tex_view;
PT(CallbackObject) _cull_callback; PT(CallbackObject) _cull_callback;
PT(CallbackObject) _draw_callback; PT(CallbackObject) _draw_callback;
@ -308,7 +311,8 @@ public:
INLINE Lens::StereoChannel get_stereo_channel() const; INLINE Lens::StereoChannel get_stereo_channel() const;
INLINE int get_tex_view_offset(); INLINE int get_tex_view_offset();
INLINE bool get_clear_depth_between_eyes() const; 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 CallbackObject *get_draw_callback() const;
INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const;

View File

@ -862,12 +862,14 @@ end_frame_spam(FrameMode mode) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::clear_cube_map_selection // Function: GraphicsOutput::clear_cube_map_selection
// Access: Public // 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:: INLINE void GraphicsOutput::
clear_cube_map_selection() { clear_cube_map_selection() {
_cube_map_index = -1; _target_tex_page = -1;
_cube_map_dr = NULL; _target_tex_view = -1;
_prev_page_dr = NULL;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -106,9 +106,9 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe,
_is_valid = false; _is_valid = false;
_flip_ready = false; _flip_ready = false;
_cube_map_index = -1; _target_tex_page = -1;
_cube_map_dr = NULL; _target_tex_view = -1;
_tex_view_offset = -1; _prev_page_dr = NULL;
_sort = 0; _sort = 0;
_child_sort = 0; _child_sort = 0;
_got_child_sort = false; _got_child_sort = false;
@ -1069,7 +1069,7 @@ make_cube_map(const string &name, int size, NodePath &camera_rig,
DisplayRegion *dr; DisplayRegion *dr;
dr = buffer->make_display_region(); dr = buffer->make_display_region();
dr->set_cube_map_index(i); dr->set_target_tex_page(i, 0);
dr->copy_clear_settings(*this); dr->copy_clear_settings(*this);
dr->set_camera(camera_np); dr->set_camera(camera_np);
} }
@ -1341,13 +1341,16 @@ end_frame(FrameMode mode, Thread *current_thread) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void GraphicsOutput:: void GraphicsOutput::
change_scenes(DisplayRegionPipelineReader *new_dr) { change_scenes(DisplayRegionPipelineReader *new_dr) {
int new_cube_map_index = new_dr->get_cube_map_index(); int new_target_tex_page = new_dr->get_target_tex_page();
if (new_cube_map_index != -1 && int new_target_tex_view = new_dr->get_target_tex_view();
new_cube_map_index != _cube_map_index) { if ((new_target_tex_page != -1 && new_target_tex_page != _target_tex_page) ||
int old_cube_map_index = _cube_map_index; new_target_tex_view != _target_tex_view) {
DisplayRegion *old_cube_map_dr = _cube_map_dr; int old_target_tex_page = _target_tex_page;
_cube_map_index = new_cube_map_index; int old_target_tex_view = _target_tex_view;
_cube_map_dr = new_dr->get_object(); 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); CDReader cdata(_cycler);
RenderTextures::const_iterator ri; RenderTextures::const_iterator ri;
@ -1356,83 +1359,55 @@ change_scenes(DisplayRegionPipelineReader *new_dr) {
Texture *texture = (*ri)._texture; Texture *texture = (*ri)._texture;
if (rtm_mode != RTM_none) { if (rtm_mode != RTM_none) {
if (rtm_mode == RTM_bind_or_copy || rtm_mode == RTM_bind_layered) { if (rtm_mode == RTM_bind_or_copy || rtm_mode == RTM_bind_layered) {
// In render-to-texture mode, switch the rendering backend to // In render-to-texture mode, switch the rendering backend
// the new cube map face, so that the subsequent frame will be // to the new page, so that the subsequent frame will be
// rendered to the new face. // 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_target_tex_page != -1) {
} else if (old_cube_map_index != -1) {
// In copy-to-texture mode, copy the just-rendered framebuffer // In copy-to-texture mode, copy the just-rendered framebuffer
// to the old cube map face. // to the old texture page.
nassertv(old_cube_map_dr != (DisplayRegion *)NULL);
// 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()) { if (display_cat.is_debug()) {
display_cat.debug() display_cat.debug()
<< "Copying texture for " << get_name() << " at scene change.\n"; << "Copying texture for " << get_name() << " at scene change.\n";
display_cat.debug() 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(), RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type(),
get_fb_properties()); get_fb_properties());
if (rtm_mode == RTM_copy_ram) { if (rtm_mode == RTM_copy_ram) {
_gsg->framebuffer_copy_to_ram(texture, old_cube_map_index, _gsg->framebuffer_copy_to_ram(texture, old_target_tex_page,
old_cube_map_dr, buffer); old_page_dr, buffer);
} else { } else {
_gsg->framebuffer_copy_to_texture(texture, old_cube_map_index, _gsg->framebuffer_copy_to_texture(texture, old_target_tex_page,
old_cube_map_dr, buffer); 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 // Access: Public, Virtual
// Description: Called internally when the window is in // Description: Called internally when the window is in
// render-to-a-texture mode and we are in the process of // render-to-a-texture mode and we are in the process of
// rendering the six faces of a cube map. This should // rendering the six faces of a cube map, or any other
// do whatever needs to be done to switch the buffer to // multi-page and/or multi-view texture. This should do
// the indicated face. // whatever needs to be done to switch the buffer to the
// indicated page and view.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void GraphicsOutput:: void GraphicsOutput::
select_cube_map(int) { select_target_tex_page(int, 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) {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -1603,7 +1578,7 @@ copy_to_textures() {
display_cat.debug() display_cat.debug()
<< "Copying texture for " << get_name() << " at frame end.\n"; << "Copying texture for " << get_name() << " at frame end.\n";
display_cat.debug() display_cat.debug()
<< "cube_map_index = " << _cube_map_index << "\n"; << "target_tex_page = " << _target_tex_page << "\n";
} }
RenderTexturePlane plane = (*ri)._plane; RenderTexturePlane plane = (*ri)._plane;
RenderBuffer buffer(_gsg, DrawableRegion::get_renderbuffer_type(plane)); RenderBuffer buffer(_gsg, DrawableRegion::get_renderbuffer_type(plane));
@ -1613,24 +1588,24 @@ copy_to_textures() {
} }
bool copied = false; 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)) { if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
copied = copied =
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index, _gsg->framebuffer_copy_to_ram(texture, _target_tex_page,
_cube_map_dr, buffer); _prev_page_dr, buffer);
} else { } else {
copied = copied =
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index, _gsg->framebuffer_copy_to_texture(texture, _target_tex_page,
_cube_map_dr, buffer); _prev_page_dr, buffer);
} }
} else { } else {
if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) { if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
copied = copied =
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index, _gsg->framebuffer_copy_to_ram(texture, _target_tex_page,
_overlay_display_region, buffer); _overlay_display_region, buffer);
} else { } else {
copied = copied =
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index, _gsg->framebuffer_copy_to_texture(texture, _target_tex_page,
_overlay_display_region, buffer); _overlay_display_region, buffer);
} }
} }

View File

@ -260,8 +260,7 @@ public:
virtual void end_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread);
void change_scenes(DisplayRegionPipelineReader *new_dr); void change_scenes(DisplayRegionPipelineReader *new_dr);
virtual void select_cube_map(int cube_map_index); virtual void select_target_tex_page(int page, int view);
virtual void select_tex_view(int tex_view_offset);
// These methods will be called within the app (main) thread. // These methods will be called within the app (main) thread.
virtual void begin_flip(); virtual void begin_flip();
@ -311,9 +310,9 @@ protected:
bool _stereo; bool _stereo;
string _name; string _name;
bool _flip_ready; bool _flip_ready;
int _cube_map_index; int _target_tex_page;
DisplayRegion *_cube_map_dr; int _target_tex_view;
int _tex_view_offset; DisplayRegion *_prev_page_dr;
PT(Geom) _texture_card; PT(Geom) _texture_card;
bool _trigger_copy; bool _trigger_copy;

View File

@ -2754,7 +2754,7 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
for (int i = 0; i < 6; ++i) { for (int i = 0; i < 6; ++i) {
PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1); PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
dr->set_lens_index(i); 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_camera(light_np);
dr->set_clear_depth_active(true); dr->set_clear_depth_active(true);
} }

View File

@ -284,16 +284,16 @@ set_cull_traverser(CullTraverser *trav) {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: StereoDisplayRegion::set_cube_map_index // Function: StereoDisplayRegion::set_target_tex_page
// Access: Published, Virtual // 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. // right DisplayRegions to the indicated value.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void StereoDisplayRegion:: void StereoDisplayRegion::
set_cube_map_index(int cube_map_index) { set_target_tex_page(int page, int view) {
DisplayRegion::set_cube_map_index(cube_map_index); DisplayRegion::set_target_tex_page(page, view);
_left_eye->set_cube_map_index(cube_map_index); _left_eye->set_target_tex_page(page, view);
_right_eye->set_cube_map_index(cube_map_index); _right_eye->set_target_tex_page(page, view);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -61,7 +61,7 @@ PUBLISHED:
virtual void set_incomplete_render(bool incomplete_render); virtual void set_incomplete_render(bool incomplete_render);
virtual void set_texture_reload_priority(int texture_reload_priority); virtual void set_texture_reload_priority(int texture_reload_priority);
virtual void set_cull_traverser(CullTraverser *trav); 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 void output(ostream &out) const;
virtual PT(PandaNode) make_cull_result_graph(); virtual PT(PandaNode) make_cull_result_graph();

View File

@ -394,7 +394,7 @@ rebuild_bitplanes() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::select_cube_map // Function: wdxGraphicsBuffer8::select_target_tex_page
// Access: Public, Virtual // Access: Public, Virtual
// Description: Called internally when the window is in // Description: Called internally when the window is in
// render-to-a-texture mode and we are in the process of // render-to-a-texture mode and we are in the process of
@ -403,8 +403,8 @@ rebuild_bitplanes() {
// the indicated face. // the indicated face.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8:: void wdxGraphicsBuffer8::
select_cube_map(int cube_map_index) { select_target_tex_page(int page, int view) {
_cube_map_index = cube_map_index; _cube_map_index = page;
HRESULT hr; HRESULT hr;
Texture *color_tex = 0; Texture *color_tex = 0;

View File

@ -46,7 +46,7 @@ public:
virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_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(); virtual void process_events();

View File

@ -1902,7 +1902,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
// must use a render target type texture for StretchRect // must use a render target type texture for StretchRect
tex->set_render_to_texture(true); 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); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
if (tc == (TextureContext *)NULL) { if (tc == (TextureContext *)NULL) {
return false; return false;

View File

@ -582,7 +582,7 @@ rebuild_bitplanes() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer9::select_cube_map // Function: wdxGraphicsBuffer9::select_target_tex_page
// Access: Public, Virtual // Access: Public, Virtual
// Description: Called internally when the window is in // Description: Called internally when the window is in
// render-to-a-texture mode and we are in the process of // render-to-a-texture mode and we are in the process of
@ -591,13 +591,13 @@ rebuild_bitplanes() {
// the indicated face. // the indicated face.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer9:: void wdxGraphicsBuffer9::
select_cube_map(int cube_map_index) { select_target_tex_page(int page, int view) {
DWORD render_target_index; DWORD render_target_index;
render_target_index = 0; render_target_index = 0;
_cube_map_index = cube_map_index; _cube_map_index = page;
HRESULT hr; HRESULT hr;
Texture *color_tex = 0; Texture *color_tex = 0;

View File

@ -46,7 +46,7 @@ public:
virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_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(); virtual void process_events();

View File

@ -80,7 +80,7 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe,
} }
_shared_depth_buffer = 0; _shared_depth_buffer = 0;
_active_cube_map_index = -1; _bound_tex_page = -1;
_bound_tex_view = 0; _bound_tex_view = 0;
} }
@ -125,7 +125,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
begin_frame_spam(mode); begin_frame_spam(mode);
check_host_valid(); check_host_valid();
_active_cube_map_index = -1; _bound_tex_page = -1;
if (!_is_valid) { if (!_is_valid) {
if (GLCAT.is_debug()) { if (GLCAT.is_debug()) {
@ -1056,7 +1056,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
CLP(GraphicsStateGuardian) *glgsg; CLP(GraphicsStateGuardian) *glgsg;
DCAST_INTO_V(glgsg, _gsg); DCAST_INTO_V(glgsg, _gsg);
glgsg->bind_fbo(0); glgsg->bind_fbo(0);
_active_cube_map_index = -1; _bound_tex_page = -1;
if (mode == FM_render) { if (mode == FM_render) {
generate_mipmaps(); generate_mipmaps();
@ -1086,54 +1086,38 @@ set_size(int x, int y) {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: glGraphicsBuffer::select_cube_map // Function: glGraphicsBuffer::select_target_tex_page
// Access: Public, Virtual // Access: Public, Virtual
// Description: Called internally when the window is in // Description: Called internally when the window is in
// render-to-a-texture mode and we are in the process of // render-to-a-texture mode and we are in the process of
// rendering the six layers of a cube map. This should // rendering the six faces of a cube map, or any other
// do whatever needs to be done to switch the buffer to // multi-page and/or multi-view texture. This should do
// the indicated face. // whatever needs to be done to switch the buffer to the
// indicated page and view.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CLP(GraphicsBuffer):: void CLP(GraphicsBuffer)::
select_cube_map(int cube_map_index) { select_target_tex_page(int page, int view) {
nassertv(cube_map_index >= 0 && cube_map_index < _fbo.size()); nassertv(page >= 0 && page < _fbo.size());
if (_active_cube_map_index != -1) { 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) {
// Resolve the multisample rendering for the previous face. // Resolve the multisample rendering for the previous face.
if (_requested_multisamples && _fbo_multisample) { if (_requested_multisamples && _fbo_multisample) {
resolve_multisamples(); resolve_multisamples();
} }
} }
CLP(GraphicsStateGuardian) *glgsg; glgsg->bind_fbo(_fbo[page]);
DCAST_INTO_V(glgsg, _gsg); _bound_tex_page = page;
glgsg->bind_fbo(_fbo[cube_map_index]);
_active_cube_map_index = cube_map_index;
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;
} }
if (switched_view || switched_page) {
// We assume that we've already configured the texture earlier // We assume that we've already configured the texture earlier
// in bind_bitplanes. Therefore, since we can safely assume that // in bind_bitplanes. Therefore, since we can safely assume that
// all texture views have the same format, we can just bind the // all texture views have the same format, we can just bind the
@ -1147,7 +1131,7 @@ select_tex_view(int view) {
GLenum target = glgsg->get_texture_target(tex->get_texture_type()); GLenum target = glgsg->get_texture_target(tex->get_texture_type());
if (target == GL_TEXTURE_CUBE_MAP) { if (target == GL_TEXTURE_CUBE_MAP) {
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + _active_cube_map_index; target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + _bound_tex_page;
} }
// Create the OpenGL texture object. // Create the OpenGL texture object.
@ -1162,19 +1146,19 @@ select_tex_view(int view) {
<< " view " << view << " to color attachment.\n"; << " view " << view << " to color attachment.\n";
} }
#ifndef OPENGLES #ifndef OPENGLES
GLclampf priority = 1.0f; GLclampf priority = 1.0f;
glPrioritizeTextures(1, &gtc->_index, &priority); glPrioritizeTextures(1, &gtc->_index, &priority);
#endif #endif
glgsg->update_texture(tc, true); glgsg->update_texture(tc, true);
if (_rb_size_z == 1) { if (_rb_size_z == 1) {
if (target == GL_TEXTURE_3D) { if (target == GL_TEXTURE_3D) {
glgsg->_glFramebufferTexture3D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, glgsg->_glFramebufferTexture3D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
target, gtc->_index, 0, _active_cube_map_index); target, gtc->_index, 0, _bound_tex_page);
} else if (target == GL_TEXTURE_2D_ARRAY_EXT) { } else if (target == GL_TEXTURE_2D_ARRAY_EXT) {
glgsg->_glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, glgsg->_glFramebufferTextureLayer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
gtc->_index, 0, _active_cube_map_index); gtc->_index, 0, _bound_tex_page);
} else { } else {
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
target, gtc->_index, 0); target, gtc->_index, 0);
@ -1188,6 +1172,9 @@ select_tex_view(int view) {
} }
_bound_tex_view = view; _bound_tex_view = view;
}
report_my_gl_errors();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -1531,8 +1518,8 @@ resolve_multisamples() {
glgsg->report_my_gl_errors(); glgsg->report_my_gl_errors();
GLuint fbo = _fbo[0]; GLuint fbo = _fbo[0];
if (_active_cube_map_index != -1) { if (_bound_tex_page != -1) {
fbo = _fbo[_active_cube_map_index]; fbo = _fbo[_bound_tex_page];
} }
glgsg->_glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo); glgsg->_glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo);
glgsg->_glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, _fbo_multisample); glgsg->_glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, _fbo_multisample);

View File

@ -74,8 +74,7 @@ public:
virtual void set_size(int x, int y); virtual void set_size(int x, int y);
virtual void select_cube_map(int cube_map_index); virtual void select_target_tex_page(int page, int view);
virtual void select_tex_view(int tex_view_offset);
virtual bool share_depth_buffer(GraphicsOutput *graphics_output); virtual bool share_depth_buffer(GraphicsOutput *graphics_output);
virtual void unshare_depth_buffer(); virtual void unshare_depth_buffer();
@ -129,7 +128,7 @@ private:
// The cube map face we are currently drawing to or have just // 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. // 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; int _bound_tex_view;
bool _initial_clear; bool _initial_clear;

View File

@ -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); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
nassertr(tc != (TextureContext *)NULL, false); nassertr(tc != (TextureContext *)NULL, false);
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); 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); 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); GLenum external_format = get_external_image_format(tex);
if (GLCAT.is_spam()) { if (GLCAT.is_spam()) {
@ -4513,11 +4520,15 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
unsigned char *image_ptr = tex->modify_ram_image(); unsigned char *image_ptr = tex->modify_ram_image();
size_t image_size = tex->get_ram_image_size(); size_t image_size = tex->get_ram_image_size();
if (z >= 0) { if (z >= 0 || view > 0) {
nassertr(z < tex->get_z_size(), false);
image_size = tex->get_expected_ram_page_size(); image_size = tex->get_expected_ram_page_size();
if (z >= 0) {
image_ptr += z * image_size; image_ptr += z * image_size;
} }
if (view > 0) {
image_ptr += (view * tex->get_z_size()) * image_size;
}
}
GLP(ReadPixels)(xo, yo, w, h, GLP(ReadPixels)(xo, yo, w, h,
external_format, get_component_type(component_type), external_format, get_component_type(component_type),

View File

@ -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); 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); TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
nassertr(tc != (TextureContext *)NULL, false); nassertr(tc != (TextureContext *)NULL, false);
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc); TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
@ -1431,13 +1431,24 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
component_type, format); 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(); unsigned char *image_ptr = tex->modify_ram_image();
size_t image_size = tex->get_ram_image_size(); size_t image_size = tex->get_ram_image_size();
if (z >= 0) { if (z >= 0 || view > 0) {
nassertr(z < tex->get_z_size(), false);
image_size = tex->get_expected_ram_page_size(); image_size = tex->get_expected_ram_page_size();
if (z >= 0) {
image_ptr += z * image_size; image_ptr += z * image_size;
} }
if (view > 0) {
image_ptr += (view * tex->get_z_size()) * image_size;
}
}
PIXEL *ip = (PIXEL *)(image_ptr + image_size); PIXEL *ip = (PIXEL *)(image_ptr + image_size);
PIXEL *fo = _c->zb->pbuf + xo + yo * _c->zb->linesize / PSZB; PIXEL *fo = _c->zb->pbuf + xo + yo * _c->zb->linesize / PSZB;

View File

@ -205,7 +205,7 @@ bind_texture_to_pbuffer() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: wglGraphicsBuffer::select_cube_map // Function: wglGraphicsBuffer::select_target_tex_page
// Access: Public, Virtual // Access: Public, Virtual
// Description: Called internally when the window is in // Description: Called internally when the window is in
// render-to-a-texture mode and we are in the process of // render-to-a-texture mode and we are in the process of
@ -214,7 +214,7 @@ bind_texture_to_pbuffer() {
// the indicated face. // the indicated face.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void wglGraphicsBuffer:: void wglGraphicsBuffer::
select_cube_map(int cube_map_index) { select_target_tex_page(int page, int view) {
wglGraphicsStateGuardian *wglgsg; wglGraphicsStateGuardian *wglgsg;
DCAST_INTO_V(wglgsg, _gsg); DCAST_INTO_V(wglgsg, _gsg);
@ -225,7 +225,7 @@ select_cube_map(int cube_map_index) {
int ni = 0; int ni = 0;
iattrib_list[ni++] = WGL_CUBE_MAP_FACE_ARB; 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. // Terminate the list.
nassertv(ni <= max_attrib_list); nassertv(ni <= max_attrib_list);

View File

@ -49,7 +49,7 @@ public:
virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_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(); virtual void process_events();