Browse Source

Add an "off" ScissorAttrib, don't apply scissoring to overlay display region so that a full-window clear is truly a full-window clear

rdb 11 years ago
parent
commit
8b7217b4f9

+ 25 - 16
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
-

+ 38 - 0
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

+ 5 - 3
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 &copy) :
   _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)
 {
 }
 

+ 5 - 0
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;

+ 1 - 0
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.
   {

+ 36 - 20
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);
+    }
+
+    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);
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(x, y, width, height);
+  }
 }

+ 12 - 0
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

+ 42 - 10
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();
+  }
 }

+ 5 - 2
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 &params);
   void fillin(DatagramIterator &scan, BamReader *manager);
-  
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 2 - 2
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