diff --git a/direct/src/filter/FilterManager.py b/direct/src/filter/FilterManager.py index a7d702918e..bd14c7c6f6 100644 --- a/direct/src/filter/FilterManager.py +++ b/direct/src/filter/FilterManager.py @@ -42,18 +42,18 @@ class FilterManager(DirectObject): # Create the notify category - if (FilterManager.notify == None): + if FilterManager.notify is None: FilterManager.notify = directNotify.newCategory("FilterManager") # Find the appropriate display region. region = None - for i in range(win.getNumDisplayRegions()): - dr = win.getDisplayRegion(i) + for dr in win.getDisplayRegions(): drcam = dr.getCamera() - if (drcam == cam): region=dr + if drcam == cam: + region = dr - if (region == None): + if region is None: self.notify.error('Could not find appropriate DisplayRegion to filter') return False @@ -218,16 +218,18 @@ class FilterManager(DirectObject): self.region.setCamera(quadcam) - dr = buffer.getDisplayRegion(0) - self.setStackedClears(dr, self.rclears, self.wclears) + self.setStackedClears(buffer, self.rclears, self.wclears) if (auxtex0): - dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) - dr.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5, 0.5, 1.0, 0.0)) + buffer.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) + buffer.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5, 0.5, 1.0, 0.0)) if (auxtex1): - dr.setClearActive(GraphicsOutput.RTPAuxRgba1, 1) + buffer.setClearActive(GraphicsOutput.RTPAuxRgba1, 1) self.region.disableClears() if (self.isFullscreen()): self.win.disableClears() + + dr = buffer.makeDisplayRegion() + dr.disableClears() dr.setCamera(self.camera) dr.setActive(1) @@ -249,7 +251,7 @@ class FilterManager(DirectObject): winx, winy = self.getScaledSize(mul, div, align) depthbits = bool(depthtex != None) - + buffer = self.createBuffer("filter-stage", winx, winy, texgroup, depthbits) if (buffer == None): @@ -269,9 +271,18 @@ class FilterManager(DirectObject): lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) - - buffer.getDisplayRegion(0).setCamera(quadcam) - buffer.getDisplayRegion(0).setActive(1) + + dr = buffer.makeDisplayRegion((0, 1, 0, 1)) + dr.disableClears() + dr.setCamera(quadcam) + dr.setActive(True) + dr.setScissorEnabled(False) + + # This clear stage is important if the buffer is padded, so that + # any pixels accidentally sampled in the padded region won't + # be reading from unititialised memory. + buffer.setClearColor((0, 0, 0, 1)) + buffer.setClearColorActive(True) self.buffers.append(buffer) self.sizes.append((mul, div, align)) @@ -307,7 +318,6 @@ class FilterManager(DirectObject): buffer.addRenderTexture(auxtex1, GraphicsOutput.RTMBindOrCopy, GraphicsOutput.RTPAuxRgba1) buffer.setSort(self.nextsort) buffer.disableClears() - buffer.getDisplayRegion(0).disableClears() self.nextsort += 1 return buffer @@ -339,4 +349,3 @@ class FilterManager(DirectObject): self.nextsort = self.win.getSort() - 1000 self.basex = 0 self.basey = 0 - diff --git a/panda/src/display/displayRegion.I b/panda/src/display/displayRegion.I index 1e30c2c55b..5f14074538 100644 --- a/panda/src/display/displayRegion.I +++ b/panda/src/display/displayRegion.I @@ -331,6 +331,32 @@ get_target_tex_page() const { return cdata->_target_tex_page; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::set_scissor_enabled +// Access: Published +// Description: Sets whether or not scissor testing is enabled +// for this region. The default is true, except for +// the overlay display region. +//////////////////////////////////////////////////////////////////// +INLINE void DisplayRegion:: +set_scissor_enabled(bool scissor_enabled) { + CDWriter cdata(_cycler); + cdata->_scissor_enabled = scissor_enabled; +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegion::get_scissor_enabled +// Access: Published +// Description: Returns whether or not scissor testing is enabled +// for this region. The default is true, except for +// the overlay display region. +//////////////////////////////////////////////////////////////////// +INLINE bool DisplayRegion:: +get_scissor_enabled() const { + CDReader cdata(_cycler); + return cdata->_scissor_enabled; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegion::set_cull_callback // Access: Published @@ -941,6 +967,18 @@ get_target_tex_page() const { return _cdata->_target_tex_page; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayRegionPipelineReader::get_scissor_enabled +// Access: Published +// Description: Returns whether or not scissor testing is enabled +// for this region. The default is true, except for +// the overlay display region. +//////////////////////////////////////////////////////////////////// +INLINE bool DisplayRegionPipelineReader:: +get_scissor_enabled() const { + return _cdata->_scissor_enabled; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayRegionPipelineReader::get_draw_callback // Access: Published diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index c540d5ac5f..f6a6189737 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -392,7 +392,7 @@ get_cull_traverser() { // Access: Published, Virtual // Description: This is a special parameter that is only used when // rendering the faces of a cube map or multipage and/or -// multiview texture. +// multiview texture. // // This sets up the DisplayRegion to render to the ith // page and jth view of its associated texture(s); the @@ -832,7 +832,8 @@ CData() : _sort(0), _stereo_channel(Lens::SC_mono), _tex_view_offset(0), - _target_tex_page(-1) + _target_tex_page(-1), + _scissor_enabled(true) { _regions.push_back(Region()); } @@ -852,7 +853,8 @@ CData(const DisplayRegion::CData ©) : _sort(copy._sort), _stereo_channel(copy._stereo_channel), _tex_view_offset(copy._tex_view_offset), - _target_tex_page(copy._target_tex_page) + _target_tex_page(copy._target_tex_page), + _scissor_enabled(copy._scissor_enabled) { } diff --git a/panda/src/display/displayRegion.h b/panda/src/display/displayRegion.h index 2d3dfd1bbe..811b913e5c 100644 --- a/panda/src/display/displayRegion.h +++ b/panda/src/display/displayRegion.h @@ -121,6 +121,9 @@ PUBLISHED: virtual void set_target_tex_page(int page); INLINE int get_target_tex_page() const; + INLINE void set_scissor_enabled(bool scissor_enabled); + INLINE bool get_scissor_enabled() const; + INLINE void set_cull_callback(CallbackObject *object); INLINE void clear_cull_callback(); INLINE CallbackObject *get_cull_callback() const; @@ -224,6 +227,7 @@ private: Lens::StereoChannel _stereo_channel; int _tex_view_offset; int _target_tex_page; + bool _scissor_enabled; PT(CallbackObject) _cull_callback; PT(CallbackObject) _draw_callback; @@ -324,6 +328,7 @@ public: INLINE int get_tex_view_offset(); INLINE bool get_clear_depth_between_eyes() const; INLINE int get_target_tex_page() const; + INLINE bool get_scissor_enabled() const; INLINE CallbackObject *get_draw_callback() const; INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const; diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 4fd7ccc435..78f7c3f429 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -151,6 +151,7 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe, // clear() and get_screenshot(). _overlay_display_region = make_mono_display_region(0.0f, 1.0f, 0.0f, 1.0f); _overlay_display_region->set_active(false); + _overlay_display_region->set_scissor_enabled(false); // Make sure the "active" flag is set true for pipeline stage 0. { diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index dee772d370..3dea898c7b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2282,7 +2282,7 @@ clear(DrawableRegion *clearable) { // to be a draw buffer attrib. Until then, this little hack // to put things back the way they were after // prepare_display_region will do. - + set_draw_buffer(_draw_buffer_type); } @@ -2298,7 +2298,7 @@ clear(DrawableRegion *clearable) { } } } - + if (clearable->get_clear_depth_active()) { #ifdef OPENGLES glClearDepthf(clearable->get_clear_depth()); @@ -2369,12 +2369,16 @@ prepare_display_region(DisplayRegionPipelineReader *dr) { _draw_buffer_type |= _current_properties->get_aux_mask(); set_draw_buffer(_draw_buffer_type); - glEnable(GL_SCISSOR_TEST); + if (dr->get_scissor_enabled()) { + glEnable(GL_SCISSOR_TEST); + } else { + glDisable(GL_SCISSOR_TEST); + } if (_supports_viewport_arrays) { int count = dr->get_num_regions(); - GLfloat *viewports = new GLfloat[4 * count]; - GLint *scissors = new GLint[4 * count]; + GLfloat *viewports = (GLfloat *)alloca(sizeof(GLfloat) * 4 * count); + GLint *scissors = (GLint *)alloca(sizeof(GLint) * 4 * count); for (int i = 0; i < count; ++i) { GLint *sr = scissors + i * 4; @@ -2386,13 +2390,15 @@ prepare_display_region(DisplayRegionPipelineReader *dr) { vr[3] = (GLfloat) sr[3]; } _glViewportArrayv(0, count, viewports); - _glScissorArrayv(0, count, scissors); - delete[] viewports; - delete[] scissors; + if (dr->get_scissor_enabled()) { + _glScissorArrayv(0, count, scissors); + } } else { - glScissor(x, y, width, height); glViewport(x, y, width, height); + if (dr->get_scissor_enabled()) { + glScissor(x, y, width, height); + } } report_my_gl_errors(); @@ -11112,7 +11118,6 @@ bind_fbo(GLuint fbo) { _current_fbo = fbo; } - //////////////////////////////////////////////////////////////////// // GL stencil code section //////////////////////////////////////////////////////////////////// @@ -11348,9 +11353,9 @@ do_issue_stencil() { } } - if (stencil -> get_render_state (StencilAttrib::SRS_clear)) { + if (stencil -> get_render_state (StencilAttrib::SRS_clear)) { GLbitfield mask = 0; - + // clear stencil buffer glClearStencil(stencil -> get_render_state (StencilAttrib::SRS_clear_value)); mask |= GL_STENCIL_BUFFER_BIT; @@ -11366,18 +11371,29 @@ do_issue_stencil() { //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::do_issue_scissor // Access: Protected -// Description: +// Description: //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_scissor() { const ScissorAttrib *target_scissor = DCAST(ScissorAttrib, _target_rs->get_attrib_def(ScissorAttrib::get_class_slot())); - const LVecBase4 &frame = target_scissor->get_frame(); - int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f); - int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f); - int width = (int)(_viewport_width * (frame[1] - frame[0]) + 0.5f); - int height = (int)(_viewport_height * (frame[3] - frame[2]) + 0.5f); + if (target_scissor->is_off()) { + if (_current_display_region->get_scissor_enabled()) { + glDisable(GL_SCISSOR_TEST); + } + } else { + if (!_current_display_region->get_scissor_enabled()) { + glEnable(GL_SCISSOR_TEST); + } - glEnable(GL_SCISSOR_TEST); - glScissor(x, y, width, height); + const LVecBase4 &frame = target_scissor->get_frame(); + + int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f); + int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f); + int width = (int)(_viewport_width * (frame[1] - frame[0]) + 0.5f); + int height = (int)(_viewport_height * (frame[3] - frame[2]) + 0.5f); + + glEnable(GL_SCISSOR_TEST); + glScissor(x, y, width, height); + } } diff --git a/panda/src/pgraph/scissorAttrib.I b/panda/src/pgraph/scissorAttrib.I index d04829cabc..30dc087324 100644 --- a/panda/src/pgraph/scissorAttrib.I +++ b/panda/src/pgraph/scissorAttrib.I @@ -26,6 +26,18 @@ make(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top) { return make(LVecBase4(left, right, bottom, top)); } +//////////////////////////////////////////////////////////////////// +// Function: ScissorAttrib::is_off +// Access: Published +// Description: Returns true if the ScissorAttrib is an 'off' +// ScissorAttrib, indicating that scissor testing is +// disabled. +//////////////////////////////////////////////////////////////////// +INLINE bool ScissorAttrib:: +is_off() const { + return _off; +} + //////////////////////////////////////////////////////////////////// // Function: ScissorAttrib::get_frame // Access: Published diff --git a/panda/src/pgraph/scissorAttrib.cxx b/panda/src/pgraph/scissorAttrib.cxx index cafc949bc6..24b5111f99 100644 --- a/panda/src/pgraph/scissorAttrib.cxx +++ b/panda/src/pgraph/scissorAttrib.cxx @@ -22,7 +22,7 @@ TypeHandle ScissorAttrib::_type_handle; int ScissorAttrib::_attrib_slot; -CPT(RenderAttrib) ScissorAttrib::_off; +CPT(RenderAttrib) ScissorAttrib::_off_attrib; //////////////////////////////////////////////////////////////////// // Function: ScissorAttrib::Constructor @@ -32,7 +32,8 @@ CPT(RenderAttrib) ScissorAttrib::_off; //////////////////////////////////////////////////////////////////// ScissorAttrib:: ScissorAttrib(const LVecBase4 &frame) : - _frame(frame) + _frame(frame), + _off(false) { // Impose sensible bounds. _frame[0] = max(min(_frame[0], (PN_stdfloat)1.0), (PN_stdfloat)0.0); @@ -49,12 +50,13 @@ ScissorAttrib(const LVecBase4 &frame) : //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) ScissorAttrib:: make_off() { - if (_off != 0) { - return _off; + if (_off_attrib != NULL) { + return _off_attrib; } ScissorAttrib *attrib = new ScissorAttrib(LVecBase4(0.0f, 1.0f, 0.0f, 1.0f)); - _off = return_new(attrib); - return _off; + attrib->_off = true; + _off_attrib = return_new(attrib); + return _off_attrib; } //////////////////////////////////////////////////////////////////// @@ -80,13 +82,14 @@ make(const LVecBase4 &frame) { //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) ScissorAttrib:: make_default() { - return return_new(new ScissorAttrib(LVecBase4(0.0f, 1.0f, 0.0f, 1.0f))); + return make_off(); + //return return_new(new ScissorAttrib(LVecBase4(0.0f, 1.0f, 0.0f, 1.0f))); } //////////////////////////////////////////////////////////////////// // Function: ScissorAttrib::output // Access: Public, Virtual -// Description: +// Description: //////////////////////////////////////////////////////////////////// void ScissorAttrib:: output(ostream &out) const { @@ -112,6 +115,19 @@ int ScissorAttrib:: compare_to_impl(const RenderAttrib *other) const { const ScissorAttrib *ta; DCAST_INTO_R(ta, other, 0); + + if (!_off && !ta->_off) { + return 0; + } + + if (_off && !ta->_off) { + return -1; + } + + if (!_off && ta->_off) { + return 1; + } + return _frame.compare_to(ta->_frame); } @@ -128,7 +144,9 @@ compare_to_impl(const RenderAttrib *other) const { size_t ScissorAttrib:: get_hash_impl() const { size_t hash = 0; - hash = _frame.add_hash(hash); + if (!_off) { + hash = _frame.add_hash(hash); + } return hash; } @@ -151,14 +169,22 @@ get_hash_impl() const { //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) ScissorAttrib:: compose_impl(const RenderAttrib *other) const { + if (_off) { + return other; + } + const ScissorAttrib *ta; DCAST_INTO_R(ta, other, 0); + if (ta->_off) { + return this; + } + LVecBase4 new_frame(max(ta->_frame[0], _frame[0]), min(ta->_frame[1], _frame[1]), max(ta->_frame[2], _frame[2]), min(ta->_frame[3], _frame[3])); - + ScissorAttrib *attrib = new ScissorAttrib(new_frame); return return_new(attrib); } @@ -185,6 +211,7 @@ write_datagram(BamWriter *manager, Datagram &dg) { RenderAttrib::write_datagram(manager, dg); _frame.write_datagram(dg); + dg.add_bool(_off); } //////////////////////////////////////////////////////////////////// @@ -219,4 +246,9 @@ fillin(DatagramIterator &scan, BamReader *manager) { RenderAttrib::fillin(scan, manager); _frame.read_datagram(scan); + _off = false; + + if (manager->get_file_minor_ver() >= 34) { + _off = scan.get_bool(); + } } diff --git a/panda/src/pgraph/scissorAttrib.h b/panda/src/pgraph/scissorAttrib.h index 0004ccc7c2..e3e63f6685 100644 --- a/panda/src/pgraph/scissorAttrib.h +++ b/panda/src/pgraph/scissorAttrib.h @@ -48,6 +48,8 @@ PUBLISHED: static CPT(RenderAttrib) make(const LVecBase4 &frame); static CPT(RenderAttrib) make_default(); + INLINE bool is_off() const; + INLINE const LVecBase4 &get_frame() const; public: @@ -60,7 +62,8 @@ protected: private: LVecBase4 _frame; - static CPT(RenderAttrib) _off; + bool _off; + static CPT(RenderAttrib) _off_attrib; PUBLISHED: static int get_class_slot() { @@ -77,7 +80,7 @@ public: protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); void fillin(DatagramIterator &scan, BamReader *manager); - + public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/putil/bam.h b/panda/src/putil/bam.h index 2f1907f36b..cbc4e583f4 100644 --- a/panda/src/putil/bam.h +++ b/panda/src/putil/bam.h @@ -33,7 +33,7 @@ static const unsigned short _bam_major_ver = 6; // Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData. static const unsigned short _bam_first_minor_ver = 14; -static const unsigned short _bam_minor_ver = 33; +static const unsigned short _bam_minor_ver = 34; // Bumped to minor version 14 on 12/19/07 to change default ColorAttrib. // Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort. // Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level. @@ -54,6 +54,6 @@ static const unsigned short _bam_minor_ver = 33; // Bumped to minor version 31 on 2/16/12 to add DepthOffsetAttrib::_min_value, _max_value. // Bumped to minor version 32 on 6/11/12 to add Texture::_has_read_mipmaps. // Bumped to minor version 33 on 8/17/13 to add UvScrollNode::_w_speed. - +// Bumped to minor version 34 on 9/16/14 to add ScissorAttrib::_off. #endif