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
// 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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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 &copy) :
_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)
{
}

View File

@ -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;

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);
}

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
// 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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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();

View File

@ -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;

View File

@ -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();

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
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;

View File

@ -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;

View File

@ -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();

View File

@ -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,54 +1086,38 @@ 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());
select_target_tex_page(int page, int view) {
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.
if (_requested_multisamples && _fbo_multisample) {
resolve_multisamples();
}
}
CLP(GraphicsStateGuardian) *glgsg;
DCAST_INTO_V(glgsg, _gsg);
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;
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
@ -1147,7 +1131,7 @@ select_tex_view(int view) {
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;
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + _bound_tex_page;
}
// Create the OpenGL texture object.
@ -1162,19 +1146,19 @@ select_tex_view(int view) {
<< " view " << view << " to color attachment.\n";
}
#ifndef OPENGLES
#ifndef OPENGLES
GLclampf priority = 1.0f;
glPrioritizeTextures(1, &gtc->_index, &priority);
#endif
#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);
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, _active_cube_map_index);
gtc->_index, 0, _bound_tex_page);
} else {
glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
target, gtc->_index, 0);
@ -1188,6 +1172,9 @@ select_tex_view(int view) {
}
_bound_tex_view = view;
}
report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
@ -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);

View File

@ -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;

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);
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,11 +4520,15 @@ 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();
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,
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);
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,13 +1431,24 @@ 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();
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);
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
// 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);

View File

@ -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();