Viewport array support on DisplayRegion. Not 100% sure if I want to end up sticking to this design, but it works. (I may revert this later.)

This commit is contained in:
rdb 2014-07-07 19:10:15 +00:00
parent 37da1427c0
commit 40c880a1c0
7 changed files with 376 additions and 121 deletions

View File

@ -38,6 +38,34 @@ get_lens_index() const {
return cdata->_lens_index;
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_num_regions
// Access: Published
// Description: Returns the number of regions, see set_num_regions.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegion::
get_num_regions() const {
CDReader cdata(_cycler);
return cdata->_regions.size();
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_num_regions
// Access: Published
// Description: Sets the number of regions that this DisplayRegion
// indicates. Usually, this number is 1 (and it is
// always at least 1), and only the first is used for
// rendering. However, if more than one is provided,
// you may select which one to render into using a
// geometry shader (gl_ViewportIndex in GLSL).
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_num_regions(int i) {
nassertv(i >= 1);
CDWriter cdata(_cycler);
cdata->_regions.resize(i);
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_dimensions
// Access: Published
@ -47,11 +75,24 @@ get_lens_index() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
get_dimensions(0, l, r, b, t);
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_dimensions
// Access: Published
// Description: Retrieves the coordinates of the DisplayRegion's
// rectangle within its GraphicsOutput. These numbers
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
CDReader cdata(_cycler);
l = cdata->_dimensions[0];
r = cdata->_dimensions[1];
b = cdata->_dimensions[2];
t = cdata->_dimensions[3];
const Region &region = cdata->_regions[i];
l = region._dimensions[0];
r = region._dimensions[1];
b = region._dimensions[2];
t = region._dimensions[3];
}
///////////////////////////////////////////////////////////////////
@ -62,9 +103,9 @@ get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) c
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE LVecBase4 DisplayRegion::
get_dimensions() const {
get_dimensions(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions;
return cdata->_regions[i]._dimensions;
}
////////////////////////////////////////////////////////////////////
@ -75,9 +116,9 @@ get_dimensions() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_left() const {
get_left(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[0];
return cdata->_regions[i]._dimensions[0];
}
////////////////////////////////////////////////////////////////////
@ -88,9 +129,9 @@ get_left() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_right() const {
get_right(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[1];
return cdata->_regions[i]._dimensions[1];
}
////////////////////////////////////////////////////////////////////
@ -101,9 +142,9 @@ get_right() const {
// number will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_bottom() const {
get_bottom(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[2];
return cdata->_regions[i]._dimensions[2];
}
////////////////////////////////////////////////////////////////////
@ -114,9 +155,9 @@ get_bottom() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_top() const {
get_top(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[3];
return cdata->_regions[i]._dimensions[3];
}
////////////////////////////////////////////////////////////////////
@ -130,7 +171,35 @@ get_top() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_dimensions(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t) {
set_dimensions(LVecBase4(l, r, b, t));
set_dimensions(0, LVecBase4(l, r, b, t));
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_dimensions
// Access: Published, Virtual
// Description: Changes the portion of the framebuffer this
// DisplayRegion corresponds to. The parameters range
// from 0 to 1, where 0,0 is the lower left corner and
// 1,1 is the upper right; (0, 1, 0, 1) represents the
// whole screen.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_dimensions(int i, PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t) {
set_dimensions(i, LVecBase4(l, r, b, t));
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_dimensions
// Access: Published, Virtual
// Description: Changes the portion of the framebuffer this
// DisplayRegion corresponds to. The parameters range
// from 0 to 1, where 0,0 is the lower left corner and
// 1,1 is the upper right; (0, 1, 0, 1) represents the
// whole screen.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_dimensions(const LVecBase4 &dimensions) {
set_dimensions(0, dimensions);
}
////////////////////////////////////////////////////////////////////
@ -387,9 +456,9 @@ get_draw_callback() const {
// Description: Returns the width of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegion::
get_pixel_width() const {
get_pixel_width(int i) const {
CDReader cdata(_cycler);
return cdata->_pixels[1] - cdata->_pixels[0];
return cdata->_regions[i]._pixels[1] - cdata->_regions[i]._pixels[0];
}
////////////////////////////////////////////////////////////////////
@ -398,9 +467,9 @@ get_pixel_width() const {
// Description: Returns the height of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegion::
get_pixel_height() const {
get_pixel_height(int i) const {
CDReader cdata(_cycler);
return cdata->_pixels[3] - cdata->_pixels[2];
return cdata->_regions[i]._pixels[3] - cdata->_regions[i]._pixels[2];
}
////////////////////////////////////////////////////////////////////
@ -411,11 +480,23 @@ get_pixel_height() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_pixels(int &pl, int &pr, int &pb, int &pt) const {
get_pixels(0, pl, pr, pb, pt);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, in pixels.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const {
CDReader cdata(_cycler);
pl = cdata->_pixels[0];
pr = cdata->_pixels[1];
pb = cdata->_pixels[2];
pt = cdata->_pixels[3];
const Region &region = cdata->_regions[i];
pl = region._pixels[0];
pr = region._pixels[1];
pb = region._pixels[2];
pt = region._pixels[3];
}
////////////////////////////////////////////////////////////////////
@ -427,11 +508,24 @@ get_pixels(int &pl, int &pr, int &pb, int &pt) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels(int &xo, int &yo, int &w, int &h) const {
get_region_pixels(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_region_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, as the pixel location of its bottom-left
// corner, along with a pixel width and height.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const {
CDReader cdata(_cycler);
xo = cdata->_pixels[0];
yo = cdata->_pixels[2];
w = cdata->_pixels[1] - xo;
h = cdata->_pixels[3] - yo;
const Region &region = cdata->_regions[i];
xo = region._pixels[0];
yo = region._pixels[2];
w = region._pixels[1] - xo;
h = region._pixels[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -444,11 +538,25 @@ get_region_pixels(int &xo, int &yo, int &w, int &h) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels_i(int &xo, int &yo, int &w, int &h) const {
get_region_pixels_i(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_region_pixels_i
// Access: Public
// Description: Similar to get_region_pixels(), but returns the upper
// left corner, and the pixel numbers are numbered from
// the top-left corner down, in the DirectX way of
// things.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const {
CDReader cdata(_cycler);
xo = cdata->_pixels_i[0];
yo = cdata->_pixels_i[2];
w = cdata->_pixels_i[1] - xo;
h = cdata->_pixels_i[3] - yo;
const Region &region = cdata->_regions[i];
xo = region._pixels_i[0];
yo = region._pixels_i[2];
w = region._pixels_i[1] - xo;
h = region._pixels_i[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -522,6 +630,18 @@ get_draw_region_pcollector() {
return _draw_region_pcollector;
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::Region::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DisplayRegion::Region::
Region() :
_dimensions(0, 1, 0, 1),
_pixels(0),
_pixels_i(0) {
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::CDataCull::Constructor
// Access: Public
@ -633,6 +753,16 @@ is_any_clear_active() const {
return _object->is_any_clear_active();
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_num_regions
// Access: Published
// Description: Returns the number of regions, see set_num_regions.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader::
get_num_regions() const {
return _cdata->_regions.size();
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_dimensions
// Access: Public
@ -642,10 +772,23 @@ is_any_clear_active() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
l = _cdata->_dimensions[0];
r = _cdata->_dimensions[1];
b = _cdata->_dimensions[2];
t = _cdata->_dimensions[3];
return get_dimensions(0, l, r, b, t);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_dimensions
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion's
// rectangle within its GraphicsOutput. These numbers
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
l = region._dimensions[0];
r = region._dimensions[1];
b = region._dimensions[2];
t = region._dimensions[3];
}
////////////////////////////////////////////////////////////////////
@ -656,8 +799,8 @@ get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) c
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE const LVecBase4 &DisplayRegionPipelineReader::
get_dimensions() const {
return _cdata->_dimensions;
get_dimensions(int i) const {
return _cdata->_regions[i]._dimensions;
}
////////////////////////////////////////////////////////////////////
@ -668,8 +811,8 @@ get_dimensions() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_left() const {
return _cdata->_dimensions[0];
get_left(int i) const {
return _cdata->_regions[i]._dimensions[0];
}
////////////////////////////////////////////////////////////////////
@ -680,8 +823,8 @@ get_left() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_right() const {
return _cdata->_dimensions[1];
get_right(int i) const {
return _cdata->_regions[i]._dimensions[1];
}
////////////////////////////////////////////////////////////////////
@ -692,8 +835,8 @@ get_right() const {
// number will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_bottom() const {
return _cdata->_dimensions[2];
get_bottom(int i) const {
return _cdata->_regions[i]._dimensions[2];
}
////////////////////////////////////////////////////////////////////
@ -704,8 +847,8 @@ get_bottom() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_top() const {
return _cdata->_dimensions[3];
get_top(int i) const {
return _cdata->_regions[i]._dimensions[3];
}
////////////////////////////////////////////////////////////////////
@ -816,10 +959,22 @@ get_draw_callback() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_pixels(int &pl, int &pr, int &pb, int &pt) const {
pl = _cdata->_pixels[0];
pr = _cdata->_pixels[1];
pb = _cdata->_pixels[2];
pt = _cdata->_pixels[3];
get_pixels(0, pl, pr, pb, pt);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, in pixels.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
pl = region._pixels[0];
pr = region._pixels[1];
pb = region._pixels[2];
pt = region._pixels[3];
}
////////////////////////////////////////////////////////////////////
@ -831,10 +986,23 @@ get_pixels(int &pl, int &pr, int &pb, int &pt) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels(int &xo, int &yo, int &w, int &h) const {
xo = _cdata->_pixels[0];
yo = _cdata->_pixels[2];
w = _cdata->_pixels[1] - xo;
h = _cdata->_pixels[3] - yo;
get_region_pixels(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_region_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, as the pixel location of its bottom-left
// corner, along with a pixel width and height.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
xo = region._pixels[0];
yo = region._pixels[2];
w = region._pixels[1] - xo;
h = region._pixels[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -847,10 +1015,24 @@ get_region_pixels(int &xo, int &yo, int &w, int &h) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels_i(int &xo, int &yo, int &w, int &h) const {
xo = _cdata->_pixels_i[0];
yo = _cdata->_pixels_i[2];
w = _cdata->_pixels_i[1] - xo;
h = _cdata->_pixels_i[3] - yo;
get_region_pixels_i(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_region_pixels_i
// Access: Public
// Description: Similar to get_region_pixels(), but returns the upper
// left corner, and the pixel numbers are numbered from
// the top-left corner down, in the DirectX way of
// things.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
xo = region._pixels_i[0];
yo = region._pixels_i[2];
w = region._pixels_i[1] - xo;
h = region._pixels_i[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -859,8 +1041,8 @@ get_region_pixels_i(int &xo, int &yo, int &w, int &h) const {
// Description: Returns the width of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader::
get_pixel_width() const {
return _cdata->_pixels[1] - _cdata->_pixels[0];
get_pixel_width(int i) const {
return _cdata->_regions[i]._pixels[1] - _cdata->_regions[i]._pixels[0];
}
////////////////////////////////////////////////////////////////////
@ -879,6 +1061,6 @@ get_lens_index() const {
// Description: Returns the height of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader::
get_pixel_height() const {
return _cdata->_pixels[3] - _cdata->_pixels[2];
get_pixel_height(int i) const {
return _cdata->_regions[i]._pixels[3] - _cdata->_regions[i]._pixels[2];
}

View File

@ -42,7 +42,8 @@ DisplayRegion(GraphicsOutput *window, const LVecBase4 &dimensions) :
{
_screenshot_buffer_type = window->get_draw_buffer_type();
_draw_buffer_type = window->get_draw_buffer_type();
set_dimensions(dimensions);
set_num_regions(1);
set_dimensions(0, dimensions);
compute_pixels_all_stages();
_window->add_display_region(this);
@ -127,15 +128,15 @@ set_lens_index(int index) {
// whole screen.
////////////////////////////////////////////////////////////////////
void DisplayRegion::
set_dimensions(const LVecBase4 &dimensions) {
set_dimensions(int i, const LVecBase4 &dimensions) {
int pipeline_stage = Thread::get_current_pipeline_stage();
nassertv(pipeline_stage == 0);
CDWriter cdata(_cycler);
cdata->_dimensions = dimensions;
cdata->_regions[i]._dimensions = dimensions;
if (_window != (GraphicsOutput *)NULL && _window->has_size()) {
do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(), cdata);
do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(), cdata);
}
}
@ -419,8 +420,8 @@ set_target_tex_page(int page) {
void DisplayRegion::
output(ostream &out) const {
CDReader cdata(_cycler);
out << "DisplayRegion(" << cdata->_dimensions << ")=pixels("
<< cdata->_pixels << ")";
out << "DisplayRegion(" << cdata->_regions[0]._dimensions
<< ")=pixels(" << cdata->_regions[0]._pixels << ")";
}
////////////////////////////////////////////////////////////////////
@ -635,8 +636,10 @@ void DisplayRegion::
compute_pixels() {
if (_window != (GraphicsOutput *)NULL) {
CDWriter cdata(_cycler, false);
do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
}
}
}
@ -655,8 +658,10 @@ compute_pixels_all_stages() {
if (_window != (GraphicsOutput *)NULL) {
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
}
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
}
@ -672,7 +677,9 @@ compute_pixels_all_stages() {
void DisplayRegion::
compute_pixels(int x_size, int y_size) {
CDWriter cdata(_cycler, false);
do_compute_pixels(x_size, y_size, cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, x_size, y_size, cdata);
}
}
////////////////////////////////////////////////////////////////////
@ -688,7 +695,9 @@ void DisplayRegion::
compute_pixels_all_stages(int x_size, int y_size) {
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
do_compute_pixels(x_size, y_size, cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, x_size, y_size, cdata);
}
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
}
@ -740,34 +749,36 @@ win_display_regions_changed() {
// assumes that we already have the lock.
////////////////////////////////////////////////////////////////////
void DisplayRegion::
do_compute_pixels(int x_size, int y_size, CData *cdata) {
do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
if (display_cat.is_debug()) {
display_cat.debug()
<< "DisplayRegion::do_compute_pixels(" << x_size << ", " << y_size << ")\n";
}
int old_w = cdata->_pixels[1] - cdata->_pixels[0];
int old_h = cdata->_pixels[3] - cdata->_pixels[2];
Region &region = cdata->_regions[i];
cdata->_pixels[0] = int((cdata->_dimensions[0] * x_size) + 0.5);
cdata->_pixels[1] = int((cdata->_dimensions[1] * x_size) + 0.5);
cdata->_pixels_i[0] = cdata->_pixels[0];
cdata->_pixels_i[1] = cdata->_pixels[1];
int old_w = region._pixels[1] - region._pixels[0];
int old_h = region._pixels[3] - region._pixels[2];
region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
region._pixels_i[0] = region._pixels[0];
region._pixels_i[1] = region._pixels[1];
nassertv(_window != (GraphicsOutput *)NULL);
if (_window->get_inverted()) {
// The window is inverted; compute the DisplayRegion accordingly.
cdata->_pixels[2] = int(((1.0f - cdata->_dimensions[3]) * y_size) + 0.5);
cdata->_pixels[3] = int(((1.0f - cdata->_dimensions[2]) * y_size) + 0.5);
cdata->_pixels_i[2] = int((cdata->_dimensions[3] * y_size) + 0.5);
cdata->_pixels_i[3] = int((cdata->_dimensions[2] * y_size) + 0.5);
region._pixels[2] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
region._pixels[3] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
region._pixels_i[2] = int((region._dimensions[3] * y_size) + 0.5);
region._pixels_i[3] = int((region._dimensions[2] * y_size) + 0.5);
} else {
// The window is normal.
cdata->_pixels[2] = int((cdata->_dimensions[2] * y_size) + 0.5);
cdata->_pixels[3] = int((cdata->_dimensions[3] * y_size) + 0.5);
cdata->_pixels_i[2] = int(((1.0f - cdata->_dimensions[2]) * y_size) + 0.5);
cdata->_pixels_i[3] = int(((1.0f - cdata->_dimensions[3]) * y_size) + 0.5);
region._pixels[2] = int((region._dimensions[2] * y_size) + 0.5);
region._pixels[3] = int((region._dimensions[3] * y_size) + 0.5);
region._pixels_i[2] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
region._pixels_i[3] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
}
}
@ -815,9 +826,6 @@ do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
////////////////////////////////////////////////////////////////////
DisplayRegion::CData::
CData() :
_dimensions(0.0f, 1.0f, 0.0f, 1.0f),
_pixels(0, 0, 0, 0),
_pixels_i(0, 0, 0, 0),
_lens_index(0),
_camera_node((Camera *)NULL),
_active(true),
@ -826,6 +834,7 @@ CData() :
_tex_view_offset(0),
_target_tex_page(-1)
{
_regions.push_back(Region());
}
////////////////////////////////////////////////////////////////////
@ -835,9 +844,7 @@ CData() :
////////////////////////////////////////////////////////////////////
DisplayRegion::CData::
CData(const DisplayRegion::CData &copy) :
_dimensions(copy._dimensions),
_pixels(copy._pixels),
_pixels_i(copy._pixels_i),
_regions(copy._regions),
_lens_index(copy._lens_index),
_camera(copy._camera),
_camera_node(copy._camera_node),

View File

@ -72,14 +72,19 @@ public:
INLINE bool operator < (const DisplayRegion &other) const;
PUBLISHED:
INLINE int get_num_regions() const;
INLINE void set_num_regions(int i);
INLINE void get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE LVecBase4 get_dimensions() const;
INLINE PN_stdfloat get_left() const;
INLINE PN_stdfloat get_right() const;
INLINE PN_stdfloat get_bottom() const;
INLINE PN_stdfloat get_top() const;
INLINE void get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE LVecBase4 get_dimensions(int i = 0) const;
INLINE PN_stdfloat get_left(int i = 0) const;
INLINE PN_stdfloat get_right(int i = 0) const;
INLINE PN_stdfloat get_bottom(int i = 0) const;
INLINE PN_stdfloat get_top(int i = 0) const;
INLINE void set_dimensions(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t);
virtual void set_dimensions(const LVecBase4 &dimensions);
INLINE void set_dimensions(int i, PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t);
INLINE void set_dimensions(const LVecBase4 &dimensions);
virtual void set_dimensions(int i, const LVecBase4 &dimensions);
INLINE GraphicsOutput *get_window() const;
GraphicsPipe *get_pipe() const;
@ -123,8 +128,8 @@ PUBLISHED:
INLINE void clear_draw_callback();
INLINE CallbackObject *get_draw_callback() const;
INLINE int get_pixel_width() const;
INLINE int get_pixel_height() const;
INLINE int get_pixel_width(int i = 0) const;
INLINE int get_pixel_height(int i = 0) const;
virtual void output(ostream &out) const;
@ -144,8 +149,11 @@ public:
void compute_pixels(int x_size, int y_size);
void compute_pixels_all_stages(int x_size, int y_size);
INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const;
virtual bool supports_pixel_zoom() const;
@ -157,11 +165,20 @@ public:
INLINE PStatCollector &get_cull_region_pcollector();
INLINE PStatCollector &get_draw_region_pcollector();
struct Region {
INLINE Region();
LVecBase4 _dimensions; // left, right, bottom, top
LVecBase4i _pixels;
LVecBase4i _pixels_i;
};
typedef pvector<Region> Regions;
private:
class CData;
void win_display_regions_changed();
void do_compute_pixels(int x_size, int y_size, CData *cdata);
void do_compute_pixels(int i, int x_size, int y_size, CData *cdata);
void set_active_index(int index);
protected:
@ -194,9 +211,7 @@ private:
return DisplayRegion::get_class_type();
}
LVecBase4 _dimensions; // left, right, bottom, top
LVecBase4i _pixels;
LVecBase4i _pixels_i;
Regions _regions;
int _lens_index; // index into which lens of a camera is associated with this display region. 0 is default
@ -289,12 +304,14 @@ public:
INLINE bool is_any_clear_active() const;
INLINE int get_num_regions() const;
INLINE void get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE const LVecBase4 &get_dimensions() const;
INLINE PN_stdfloat get_left() const;
INLINE PN_stdfloat get_right() const;
INLINE PN_stdfloat get_bottom() const;
INLINE PN_stdfloat get_top() const;
INLINE void get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE const LVecBase4 &get_dimensions(int i = 0) const;
INLINE PN_stdfloat get_left(int i = 0) const;
INLINE PN_stdfloat get_right(int i = 0) const;
INLINE PN_stdfloat get_bottom(int i = 0) const;
INLINE PN_stdfloat get_top(int i = 0) const;
INLINE GraphicsOutput *get_window() const;
GraphicsPipe *get_pipe() const;
@ -309,11 +326,14 @@ public:
INLINE CallbackObject *get_draw_callback() const;
INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const;
INLINE int get_pixel_width() const;
INLINE int get_pixel_height() const;
INLINE int get_pixel_width(int i = 0) const;
INLINE int get_pixel_height(int i = 0) const;
INLINE int get_lens_index() const;

View File

@ -109,10 +109,10 @@ set_pixel_zoom(PN_stdfloat pixel_zoom) {
// indicated dimensions.
////////////////////////////////////////////////////////////////////
void StereoDisplayRegion::
set_dimensions(const LVecBase4 &dimensions) {
DisplayRegion::set_dimensions(dimensions);
_left_eye->set_dimensions(dimensions);
_right_eye->set_dimensions(dimensions);
set_dimensions(int i, const LVecBase4 &dimensions) {
DisplayRegion::set_dimensions(i, dimensions);
_left_eye->set_dimensions(i, dimensions);
_right_eye->set_dimensions(i, dimensions);
}
////////////////////////////////////////////////////////////////////

View File

@ -51,7 +51,7 @@ PUBLISHED:
virtual void set_pixel_zoom(PN_stdfloat pixel_zoom);
// Inherited from DisplayRegion
virtual void set_dimensions(const LVecBase4 &dimensions);
virtual void set_dimensions(int i, const LVecBase4 &dimensions);
virtual bool is_stereo() const;
virtual void set_camera(const NodePath &camera);
virtual void set_active(bool active);

View File

@ -1397,6 +1397,26 @@ reset() {
}
#endif // OPENGLES
#ifndef OPENGLES
_supports_viewport_arrays = false;
if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_viewport_array")) {
_glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)
get_extension_func("glViewportArrayv");
_glScissorArrayv = (PFNGLSCISSORARRAYVPROC)
get_extension_func("glScissorArrayv");
_glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)
get_extension_func("glDepthRangeArrayv");
if (_glViewportArrayv == NULL || _glScissorArrayv == NULL || _glDepthRangeArrayv == NULL) {
GLCAT.warning()
<< "Viewport arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
} else {
_supports_viewport_arrays = true;
}
}
#endif // OPENGLES
_max_fb_samples = 0;
#ifndef OPENGLES
if (_supports_framebuffer_multisample) {
@ -2223,10 +2243,32 @@ prepare_display_region(DisplayRegionPipelineReader *dr) {
_draw_buffer_type = dr->get_object()->get_draw_buffer_type() & _current_properties->get_buffer_mask() & _stereo_buffer_mask;
_draw_buffer_type |= _current_properties->get_aux_mask();
set_draw_buffer(_draw_buffer_type);
glEnable(GL_SCISSOR_TEST);
glScissor(x, y, width, height);
glViewport(x, y, width, height);
if (_supports_viewport_arrays) {
int count = dr->get_num_regions();
GLfloat *viewports = new GLfloat[4 * count];
GLint *scissors = new GLint[4 * count];
for (int i = 0; i < count; ++i) {
GLint *sr = scissors + i * 4;
dr->get_region_pixels(i, sr[0], sr[1], sr[2], sr[3]);
GLfloat *vr = viewports + i * 4;
vr[0] = (GLfloat) sr[0];
vr[1] = (GLfloat) sr[1];
vr[2] = (GLfloat) sr[2];
vr[3] = (GLfloat) sr[3];
}
_glViewportArrayv(0, count, viewports);
_glScissorArrayv(0, count, scissors);
delete[] viewports;
delete[] scissors;
} else {
glScissor(x, y, width, height);
glViewport(x, y, width, height);
}
report_my_gl_errors();
do_point_size();

View File

@ -660,6 +660,7 @@ public:
PFNGLBLITFRAMEBUFFEREXTPROC _glBlitFramebuffer;
PFNGLDRAWBUFFERSPROC _glDrawBuffers;
int _max_fb_samples;
bool _supports_viewport_arrays;
PFNGLGENQUERIESPROC _glGenQueries;
PFNGLBEGINQUERYPROC _glBeginQuery;
@ -719,6 +720,9 @@ public:
PFNGLMEMORYBARRIERPROC _glMemoryBarrier;
PFNGLGETPROGRAMBINARYPROC _glGetProgramBinary;
PFNGLGETINTERNALFORMATIVPROC _glGetInternalformativ;
PFNGLVIEWPORTARRAYVPROC _glViewportArrayv;
PFNGLSCISSORARRAYVPROC _glScissorArrayv;
PFNGLDEPTHRANGEARRAYVPROC _glDepthRangeArrayv;
#endif // OPENGLES
GLenum _edge_clamp;