Fix issues resizing OpenGL FBOs. Use LVecBase2i for storing buffer size.

This commit is contained in:
rdb 2014-09-16 14:51:13 +00:00
parent 89b824597c
commit b24adbcad1
10 changed files with 86 additions and 69 deletions

View File

@ -41,7 +41,7 @@ GraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
<< "Creating new offscreen buffer " << get_name() << "\n";
}
_overlay_display_region->compute_pixels(_x_size, _y_size);
_overlay_display_region->compute_pixels(_size.get_x(), _size.get_y());
_open_request = OR_none;
}

View File

@ -40,7 +40,7 @@ protected:
PUBLISHED:
virtual ~GraphicsBuffer();
void set_size(int x, int y);
virtual void set_size(int x, int y);
public:
virtual void request_open();

View File

@ -150,6 +150,25 @@ get_rtm_mode(int i) const {
return cdata->_textures[i]._rtm_mode;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::get_size
// Access: Published
// Description: Returns the visible size of the window or buffer, if
// it is known. In certain cases (e.g. fullscreen
// windows), the size may not be known until after the
// object has been fully created. Check has_size()
// first.
//
// Certain objects (like windows) may change size
// spontaneously; this method is not thread-safe. To
// get the size of a window in a thread-safe manner,
// query get_properties().
////////////////////////////////////////////////////////////////////
INLINE const LVecBase2i &GraphicsOutput::
get_size() const {
return _size;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::get_x_size
// Access: Published
@ -166,7 +185,7 @@ get_rtm_mode(int i) const {
////////////////////////////////////////////////////////////////////
INLINE int GraphicsOutput::
get_x_size() const {
return _x_size;
return _size.get_x();
}
////////////////////////////////////////////////////////////////////
@ -185,7 +204,7 @@ get_x_size() const {
////////////////////////////////////////////////////////////////////
INLINE int GraphicsOutput::
get_y_size() const {
return _y_size;
return _size.get_y();
}
////////////////////////////////////////////////////////////////////
@ -198,7 +217,7 @@ get_y_size() const {
////////////////////////////////////////////////////////////////////
INLINE int GraphicsOutput::
get_fb_x_size() const {
return max(int(_x_size * get_pixel_factor()), 1);
return max(int(_size.get_x() * get_pixel_factor()), 1);
}
////////////////////////////////////////////////////////////////////
@ -211,7 +230,7 @@ get_fb_x_size() const {
////////////////////////////////////////////////////////////////////
INLINE int GraphicsOutput::
get_fb_y_size() const {
return max(int(_y_size * get_pixel_factor()), 1);
return max(int(_size.get_y() * get_pixel_factor()), 1);
}
////////////////////////////////////////////////////////////////////
@ -226,7 +245,7 @@ get_fb_y_size() const {
INLINE int GraphicsOutput::
get_sbs_left_x_size() const {
PN_stdfloat left_w = _sbs_left_dimensions[1] - _sbs_left_dimensions[0];
return max(int(_x_size * left_w), 1);
return max(int(_size.get_x() * left_w), 1);
}
////////////////////////////////////////////////////////////////////
@ -241,7 +260,7 @@ get_sbs_left_x_size() const {
INLINE int GraphicsOutput::
get_sbs_left_y_size() const {
PN_stdfloat left_h = _sbs_left_dimensions[3] - _sbs_left_dimensions[2];
return max(int(_y_size * left_h), 1);
return max(int(_size.get_y() * left_h), 1);
}
////////////////////////////////////////////////////////////////////
@ -256,7 +275,7 @@ get_sbs_left_y_size() const {
INLINE int GraphicsOutput::
get_sbs_right_x_size() const {
PN_stdfloat right_w = _sbs_right_dimensions[1] - _sbs_right_dimensions[0];
return max(int(_x_size * right_w), 1);
return max(int(_size.get_x() * right_w), 1);
}
////////////////////////////////////////////////////////////////////
@ -271,7 +290,7 @@ get_sbs_right_x_size() const {
INLINE int GraphicsOutput::
get_sbs_right_y_size() const {
PN_stdfloat right_h = _sbs_right_dimensions[3] - _sbs_right_dimensions[2];
return max(int(_y_size * right_h), 1);
return max(int(_size.get_y() * right_h), 1);
}
////////////////////////////////////////////////////////////////////

View File

@ -78,7 +78,8 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe,
bool default_stereo_flags) :
_lock("GraphicsOutput"),
_cull_window_pcollector(_cull_pcollector, name),
_draw_window_pcollector(_draw_pcollector, name)
_draw_window_pcollector(_draw_pcollector, name),
_size(0, 0)
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, this);
@ -90,13 +91,11 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe,
_fb_properties = fb_prop;
_name = name;
_creation_flags = flags;
_x_size = _y_size = 0;
_has_size = win_prop.has_size();
_is_nonzero_size = false;
if (_has_size) {
_x_size = win_prop.get_x_size();
_y_size = win_prop.get_y_size();
_is_nonzero_size = (_x_size > 0 && _y_size > 0);
_size = win_prop.get_size();
_is_nonzero_size = (_size[0] > 0 && _size[1] > 0);
}
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
// If we're tracking the host size, we assume we'll be nonzero
@ -546,14 +545,14 @@ set_inverted(bool inverted) {
if (_inverted != inverted) {
_inverted = inverted;
if (_y_size != 0) {
if (get_y_size() != 0) {
// All of our DisplayRegions need to recompute their pixel
// positions now.
TotalDisplayRegions::iterator dri;
for (dri = _total_display_regions.begin();
dri != _total_display_regions.end();
++dri) {
(*dri)->compute_pixels(_x_size, _y_size);
(*dri)->compute_pixels(get_x_size(), get_y_size());
}
}
}
@ -1102,7 +1101,7 @@ make_cube_map(const string &name, int size, NodePath &camera_rig,
NodePath GraphicsOutput::
get_texture_card() {
if (_texture_card == 0) {
PT(GeomVertexData) vdata = create_texture_card_vdata(_x_size, _y_size);
PT(GeomVertexData) vdata = create_texture_card_vdata(get_x_size(), get_y_size());
PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
strip->set_shade_model(Geom::SM_uniform);
strip->add_next_vertices(4);
@ -1262,11 +1261,10 @@ clear_pipe() {
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
set_size_and_recalc(int x, int y) {
_x_size = x;
_y_size = y;
_size.set(x, y);
_has_size = true;
_is_nonzero_size = (_x_size > 0 && _y_size > 0);
_is_nonzero_size = (x > 0 && y > 0);
int fb_x_size = get_fb_x_size();
int fb_y_size = get_fb_y_size();
@ -1498,7 +1496,7 @@ process_events() {
void GraphicsOutput::
pixel_factor_changed() {
if (_has_size) {
set_size_and_recalc(_x_size, _y_size);
set_size_and_recalc(get_x_size(), get_y_size());
}
}

View File

@ -132,6 +132,7 @@ PUBLISHED:
RenderTexturePlane bitplane=RTP_COUNT);
void setup_render_texture(Texture *tex, bool allow_bind, bool to_ram);
INLINE const LVecBase2i &get_size() const;
INLINE int get_x_size() const;
INLINE int get_y_size() const;
INLINE int get_fb_x_size() const;
@ -382,8 +383,7 @@ protected:
protected:
int _creation_flags;
int _x_size;
int _y_size;
LVecBase2i _size;
bool _has_size;
bool _is_valid;
bool _is_nonzero_size;

View File

@ -170,8 +170,7 @@ request_properties(const WindowProperties &requested_properties) {
// stick. This is helpful for the MultitexReducer, which needs to
// know the size of the textures that it will be working with,
// even if the texture hasn't been fully generated yet.
_x_size = _requested_properties.get_x_size();
_y_size = _requested_properties.get_y_size();
_size = _requested_properties.get_size();
// Don't set _has_size yet, because we don't really know yet.
}

View File

@ -45,14 +45,13 @@ ParasiteBuffer(GraphicsOutput *host, const string &name,
_creation_flags = flags;
if (flags & GraphicsPipe::BF_size_track_host) {
x_size = host->get_x_size();
y_size = host->get_y_size();
_size = host->get_size();
} else {
_size.set(x_size, y_size);
}
_x_size = x_size;
_y_size = y_size;
_has_size = true;
_overlay_display_region->compute_pixels(_x_size, _y_size);
_overlay_display_region->compute_pixels(_size.get_x(), _size.get_y());
_is_valid = true;
set_inverted(host->get_gsg()->get_copy_texture_inverted());
@ -201,16 +200,15 @@ begin_frame(FrameMode mode, Thread *current_thread) {
}
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
if ((_host->get_x_size() != _x_size)||
(_host->get_y_size() != _y_size)) {
if (_host->get_size() != _size) {
set_size_and_recalc(_host->get_x_size(),
_host->get_y_size());
}
} else {
if (_host->get_x_size() < _x_size ||
_host->get_y_size() < _y_size) {
set_size_and_recalc(min(_x_size, _host->get_x_size()),
min(_y_size, _host->get_y_size()));
if (_host->get_x_size() < get_x_size() ||
_host->get_y_size() < get_y_size()) {
set_size_and_recalc(min(get_x_size(), _host->get_x_size()),
min(get_y_size(), _host->get_y_size()));
}
}

View File

@ -155,8 +155,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
}
}
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
if ((_host->get_x_size() != _x_size)||
(_host->get_y_size() != _y_size)) {
if (_host->get_size() != _size) {
// We also need to rebuild if we need to change size.
_needs_rebuild = true;
}
@ -277,14 +276,14 @@ rebuild_bitplanes() {
// Calculate bitplane size. This can be larger than the buffer.
if (_creation_flags & GraphicsPipe::BF_size_track_host) {
if ((_host->get_x_size() != _x_size)||
(_host->get_y_size() != _y_size)) {
if (_host->get_size() != _size) {
set_size_and_recalc(_host->get_x_size(),
_host->get_y_size());
}
}
int bitplane_x = _x_size;
int bitplane_y = _y_size;
int bitplane_x = get_x_size();
int bitplane_y = get_y_size();
if (Texture::get_textures_power_2() != ATS_none) {
bitplane_x = Texture::up_to_power_2(bitplane_x);
bitplane_y = Texture::up_to_power_2(bitplane_y);
@ -602,7 +601,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
if (tex->get_texture_type() != Texture::TT_cube_map && _rb_size_z > 1) {
tex->set_z_size(_rb_size_z);
}
tex->set_pad_size(_rb_size_x - _x_size, _rb_size_y - _y_size);
tex->set_pad_size(_rb_size_x - get_x_size(), _rb_size_y - get_y_size());
// Adjust the texture format based on the requested framebuffer settings.
switch (slot) {
@ -1072,6 +1071,10 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) {
gtc->set_active(true);
_texture_contexts.push_back(gtc);
// It seems that binding the texture is necessary before binding
// to a framebuffer attachment.
glgsg->apply_texture(gtc);
#ifndef OPENGLES
GLclampf priority = 1.0f;
glPrioritizeTextures(1, &gtc->_index, &priority);
@ -1191,7 +1194,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsBuffer)::
set_size(int x, int y) {
if (_x_size != x || _y_size != y) {
if (_size.get_x() != x || _size.get_y() != y) {
_needs_rebuild = true;
}

View File

@ -204,14 +204,14 @@ open_buffer() {
nassertr(n < max_attrib_list, false);
attrib_list[n] = (int)None;
_pbuffer = glxgsg->_glXCreateGLXPbufferSGIX(glxgsg->_display, glxgsg->_fbconfig,
_x_size, _y_size, attrib_list);
get_x_size(), get_y_size(), attrib_list);
} else {
// The official GLX 1.3 version passes in the size in the attrib
// list.
attrib_list[n++] = GLX_PBUFFER_WIDTH;
attrib_list[n++] = _x_size;
attrib_list[n++] = get_x_size();
attrib_list[n++] = GLX_PBUFFER_HEIGHT;
attrib_list[n++] = _y_size;
attrib_list[n++] = get_y_size();
nassertr(n < max_attrib_list, false);
attrib_list[n] = (int)None;

View File

@ -214,7 +214,7 @@ open_buffer() {
}
_x_pixmap = XCreatePixmap(_display, _drawable,
_x_size, _y_size, visual_info->depth);
get_x_size(), get_y_size(), visual_info->depth);
if (_x_pixmap == None) {
glxdisplay_cat.error()
<< "Failed to create X pixmap.\n";