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

This commit is contained in:
rdb 2014-09-16 20:44:39 +00:00
parent 579f4c7f47
commit 8b7217b4f9
10 changed files with 171 additions and 53 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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.
{

View File

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

View File

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

View File

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

View File

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

View File

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