Pārlūkot izejas kodu

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

rdb 11 gadi atpakaļ
vecāks
revīzija
b24adbcad1

+ 3 - 3
panda/src/display/graphicsBuffer.cxx

@@ -41,19 +41,19 @@ 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;
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsBuffer::Destructor
 //       Access: Published, Virtual
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 GraphicsBuffer::
 ~GraphicsBuffer() {
 }
- 
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsBuffer::set_size
 //       Access: Public, Virtual

+ 1 - 1
panda/src/display/graphicsBuffer.h

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

+ 27 - 8
panda/src/display/graphicsOutput.I

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

+ 10 - 12
panda/src/display/graphicsOutput.cxx

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

+ 8 - 8
panda/src/display/graphicsOutput.h

@@ -128,10 +128,11 @@ PUBLISHED:
   INLINE RenderTexturePlane get_texture_plane(int i=0) const;
   INLINE RenderTextureMode get_rtm_mode(int i=0) const;
   void clear_render_textures();
-  void add_render_texture(Texture *tex, RenderTextureMode mode, 
+  void add_render_texture(Texture *tex, RenderTextureMode mode,
                           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;
@@ -290,7 +291,7 @@ protected:
 
 private:
   PT(GeomVertexData) create_texture_card_vdata(int x, int y);
-  
+
   DisplayRegion *add_display_region(DisplayRegion *display_region);
   bool do_remove_display_region(DisplayRegion *display_region);
 
@@ -323,7 +324,7 @@ protected:
     RenderTextureMode _rtm_mode;
   };
   typedef pvector<RenderTexture> RenderTextures;
-  
+
 private:
   int _sort;
   int _child_sort;
@@ -346,9 +347,9 @@ protected:
   // have, we don't auto-close the buffer (since that would deallocate
   // the memory associated with the texture).
   pvector<WPT(Texture)> _hold_textures;
-  
+
 protected:
-  LightMutex _lock; 
+  LightMutex _lock;
   // protects _display_regions.
   PT(DisplayRegion) _overlay_display_region;
   typedef pvector< PT(DisplayRegion) > TotalDisplayRegions;
@@ -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;
@@ -394,7 +394,7 @@ protected:
   static PStatCollector _draw_pcollector;
   PStatCollector _cull_window_pcollector;
   PStatCollector _draw_window_pcollector;
-  
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 1 - 2
panda/src/display/graphicsWindow.cxx

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

+ 17 - 19
panda/src/display/parasiteBuffer.cxx

@@ -27,15 +27,15 @@ TypeHandle ParasiteBuffer::_type_handle;
 ParasiteBuffer::
 ParasiteBuffer(GraphicsOutput *host, const string &name,
                int x_size, int y_size, int flags) :
-  GraphicsOutput(host->get_engine(), host->get_pipe(), 
+  GraphicsOutput(host->get_engine(), host->get_pipe(),
                  name, host->get_fb_properties(),
-                 WindowProperties::size(x_size, y_size), flags, 
+                 WindowProperties::size(x_size, y_size), flags,
                  host->get_gsg(), host, false)
 {
 #ifdef DO_MEMORY_USAGE
   MemoryUsage::update_type(this, this);
 #endif
-  
+
   if (display_cat.is_debug()) {
     display_cat.debug()
       << "Creating new parasite buffer " << get_name()
@@ -43,25 +43,24 @@ 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());
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: ParasiteBuffer::Destructor
 //       Access: Published, Virtual
-//  Description: 
+//  Description:
 ////////////////////////////////////////////////////////////////////
 ParasiteBuffer::
 ~ParasiteBuffer() {
@@ -201,19 +200,18 @@ 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()));
     }
   }
-  
+
   clear_cube_map_selection();
   return true;
 }

+ 11 - 8
panda/src/glstuff/glGraphicsBuffer_src.cxx

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

+ 6 - 6
panda/src/glxdisplay/glxGraphicsBuffer.cxx

@@ -178,7 +178,7 @@ open_buffer() {
     // new one that shares with the old gsg.
     DCAST_INTO_R(glxgsg, _gsg, false);
 
-    if (!glxgsg->_context_has_pbuffer || 
+    if (!glxgsg->_context_has_pbuffer ||
         !glxgsg->get_fb_properties().subsumes(_fb_properties)) {
       // We need a new pixel format, and hence a new GSG.
       glxgsg = new glxGraphicsStateGuardian(_engine, _pipe, glxgsg);
@@ -186,7 +186,7 @@ open_buffer() {
       _gsg = glxgsg;
     }
   }
-  
+
   if (glxgsg->_fbconfig == None || !glxgsg->_context_has_pbuffer) {
     // If we didn't use an fbconfig to create the GSG, or it doesn't
     // support buffers, we can't create a PBuffer.
@@ -204,15 +204,15 @@ 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;
     _pbuffer = glxgsg->_glXCreatePbuffer(glxgsg->_display, glxgsg->_fbconfig,

+ 2 - 2
panda/src/glxdisplay/glxGraphicsPixmap.cxx

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