mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
fix some stereo-fbo and cube map issues, introducing DisplayRegion::set_target_tex_page()
This commit is contained in:
parent
741203a693
commit
f615e0beeb
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user