pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] r3797 - in trunk/pingus/src: display screen


From: grumbel at BerliOS
Subject: [Pingus-CVS] r3797 - in trunk/pingus/src: display screen
Date: Sat, 12 Jul 2008 08:11:34 +0200

Author: grumbel
Date: 2008-07-12 08:11:32 +0200 (Sat, 12 Jul 2008)
New Revision: 3797

Modified:
   trunk/pingus/src/display/delta_framebuffer.cpp
   trunk/pingus/src/display/delta_framebuffer.hpp
   trunk/pingus/src/display/display.cpp
   trunk/pingus/src/display/sdl_framebuffer.cpp
   trunk/pingus/src/screen/screen_manager.cpp
Log:
Improved delta drawing code to a state were it actually works somewhat as 
intended, larger resolution should now render quite a bit faster

Modified: trunk/pingus/src/display/delta_framebuffer.cpp
===================================================================
--- trunk/pingus/src/display/delta_framebuffer.cpp      2008-07-11 15:44:01 UTC 
(rev 3796)
+++ trunk/pingus/src/display/delta_framebuffer.cpp      2008-07-12 06:11:32 UTC 
(rev 3797)
@@ -14,11 +14,85 @@
 //  You should have received a copy of the GNU General Public License
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+#include <iostream>
+#include "sdl_framebuffer.hpp"
 #include "delta_framebuffer.hpp"
 
-DeltaFramebuffer::DeltaFramebuffer(Framebuffer* framebuffer_)
-  : framebuffer(framebuffer_)
+struct SurfaceDrawOp {
+  Vector2i     pos;
+  SDL_Surface* surface;
+  Rect         rect;
+  
+  void render(Framebuffer& fb) {
+    fb.draw_surface(surface, rect, pos);
+  }
+  
+  Rect get_region() const {
+    return Rect(pos, rect.get_size());
+  }
+};
+
+class DrawOpBuffer
 {
+private:
+  typedef std::vector<SurfaceDrawOp> DrawOps;
+  DrawOps draw_obs;
+
+public:
+  DrawOpBuffer()
+  {
+  }
+  
+  void clear() {
+    draw_obs.clear();
+  }
+
+  bool has_op(SurfaceDrawOp& op) {
+    for(DrawOps::iterator i = draw_obs.begin(); i != draw_obs.end(); ++i)
+      if (op.surface == i->surface &&
+          op.pos     == i->pos &&
+          op.rect    == op.rect)
+        return true;
+    return false;
+  }
+ 
+  void render(SDLFramebuffer& fb, DrawOpBuffer& frontbuffer) 
+  {
+    std::vector<Rect> update_rects;
+
+    // Find all regions that need updating
+    for(DrawOps::iterator i = draw_obs.begin(); i != draw_obs.end(); ++i)
+      if (!frontbuffer.has_op(*i))
+        update_rects.push_back(i->get_region());
+
+    for(DrawOps::iterator i = frontbuffer.draw_obs.begin(); i != 
frontbuffer.draw_obs.end(); ++i)
+      if (!has_op(*i))
+        update_rects.push_back(i->get_region());
+
+    // Merge rectangles
+
+    // Update all regions that need update
+    for(std::vector<Rect>::iterator i = update_rects.begin(); i != 
update_rects.end(); ++i)
+      {
+        fb.push_cliprect(*i);
+        for(DrawOps::iterator j = draw_obs.begin(); j != draw_obs.end(); ++j)
+          j->render(fb);
+        fb.pop_cliprect();
+
+        fb.update_rect(*i);
+      }
+  }
+ 
+  void add(const SurfaceDrawOp& op) {
+    draw_obs.push_back(op);
+  }
+};
+
+DeltaFramebuffer::DeltaFramebuffer()
+  : framebuffer(new SDLFramebuffer()),
+    frontbuffer(new DrawOpBuffer()),
+    backbuffer(new DrawOpBuffer())
+{
 }
 
 void
@@ -30,9 +104,9 @@
 void
 DeltaFramebuffer::flip()
 {
-  last_drawing_ops = drawing_ops;
-  drawing_ops.clear();
-  framebuffer->flip();
+  backbuffer->render(*framebuffer, *frontbuffer);
+  std::swap(frontbuffer, backbuffer);
+  backbuffer->clear();
 }
 
 void
@@ -54,13 +128,7 @@
   op.pos     = pos;
   op.surface = src;
   op.rect    = Rect(Vector2i(0, 0), Size(src->w, src->h));
-  add_op(op);
-
-  DrawingOps::iterator i = find_op(op);
-  if (i != last_drawing_ops.end())
-    ; //framebuffer->fill_rect(Rect(pos, Size(src->w, src->h)), Color(255, 0, 
0, 100));
-  else
-    framebuffer->draw_surface(src, pos);
+  backbuffer->add(op);
 }
 
 void
@@ -70,14 +138,7 @@
   op.pos     = pos;
   op.surface = src;
   op.rect    = srcrect;
-  add_op(op);
-
-  DrawingOps::iterator i = find_op(op);
-  if (i != last_drawing_ops.end())
-    ; //framebuffer->fill_rect(Rect(pos, srcrect.get_size()), Color(255, 0, 0, 
100));
-  else
-    framebuffer->draw_surface(src, srcrect, pos);
-
+  backbuffer->add(op);
 }
 
 void
@@ -104,23 +165,4 @@
   return framebuffer->get_size();
 }
 
-DeltaFramebuffer::DrawingOps::iterator
-DeltaFramebuffer::find_op(const DeltaFramebuffer::SurfaceDrawOp& op)
-{
-  for(DrawingOps::iterator i = last_drawing_ops.begin(); i != 
last_drawing_ops.end(); ++i)
-    {
-      if (i->pos     == op.pos &&
-          i->surface == op.surface &&
-          i->rect    == op.rect)
-        return i;
-    }
-  return last_drawing_ops.end();
-}
-
-void
-DeltaFramebuffer::add_op(const DeltaFramebuffer::SurfaceDrawOp& op)
-{
-  drawing_ops.push_back(op);
-}
-
 /* EOF */

Modified: trunk/pingus/src/display/delta_framebuffer.hpp
===================================================================
--- trunk/pingus/src/display/delta_framebuffer.hpp      2008-07-11 15:44:01 UTC 
(rev 3796)
+++ trunk/pingus/src/display/delta_framebuffer.hpp      2008-07-12 06:11:32 UTC 
(rev 3797)
@@ -21,26 +21,19 @@
 #include <map>
 #include "../math/vector2i.hpp"
 #include "framebuffer.hpp"
+
+class SDLFramebuffer;
+class DrawOpBuffer;
 
 class DeltaFramebuffer : public Framebuffer
 {
 private:
-  struct SurfaceDrawOp {
-    Vector2i     pos;
-    SDL_Surface* surface;
-    Rect         rect;
-  };
-
-  std::auto_ptr<Framebuffer> framebuffer;
-  typedef std::vector<SurfaceDrawOp> DrawingOps;
-  DrawingOps drawing_ops;
-  DrawingOps last_drawing_ops;
-
-  DrawingOps::iterator find_op(const SurfaceDrawOp& pos);
-  void add_op(const SurfaceDrawOp& op);
-
+  std::auto_ptr<SDLFramebuffer> framebuffer;
+  std::auto_ptr<DrawOpBuffer> frontbuffer;
+  std::auto_ptr<DrawOpBuffer> backbuffer;
+ 
 public:
-  DeltaFramebuffer(Framebuffer* framebuffer);
+  DeltaFramebuffer();
 
   void set_video_mode(int width, int height, bool fullscreen);
   void flip();

Modified: trunk/pingus/src/display/display.cpp
===================================================================
--- trunk/pingus/src/display/display.cpp        2008-07-11 15:44:01 UTC (rev 
3796)
+++ trunk/pingus/src/display/display.cpp        2008-07-12 06:11:32 UTC (rev 
3797)
@@ -58,7 +58,7 @@
   if (!framebuffer.get())
     {
       if (delta_drawing)
-        framebuffer = std::auto_ptr<Framebuffer>(new DeltaFramebuffer(new 
SDLFramebuffer()));
+        framebuffer = std::auto_ptr<Framebuffer>(new DeltaFramebuffer());
       else
         framebuffer = std::auto_ptr<Framebuffer>(new SDLFramebuffer());
     }

Modified: trunk/pingus/src/display/sdl_framebuffer.cpp
===================================================================
--- trunk/pingus/src/display/sdl_framebuffer.cpp        2008-07-11 15:44:01 UTC 
(rev 3796)
+++ trunk/pingus/src/display/sdl_framebuffer.cpp        2008-07-12 06:11:32 UTC 
(rev 3797)
@@ -376,8 +376,13 @@
 }
 
 void
-SDLFramebuffer::update_rect(const Rect& rect)
+SDLFramebuffer::update_rect(const Rect& rect_)
 {
+  Rect rect(Math::clamp(0, rect_.left,   screen->w),
+            Math::clamp(0, rect_.top,    screen->h),
+            Math::clamp(0, rect_.right,  screen->w),
+            Math::clamp(0, rect_.bottom, screen->h));
+
   SDL_UpdateRect(screen, rect.left, rect.top, rect.get_width(), 
rect.get_height());
 }
 

Modified: trunk/pingus/src/screen/screen_manager.cpp
===================================================================
--- trunk/pingus/src/screen/screen_manager.cpp  2008-07-11 15:44:01 UTC (rev 
3796)
+++ trunk/pingus/src/screen/screen_manager.cpp  2008-07-12 06:11:32 UTC (rev 
3797)
@@ -184,7 +184,8 @@
           // Get Time
           read(std::cin, delta);
 
-          // Update InputManager so that SDL_QUIT and stuff can be handled, 
even if the basic events are taken from record
+          // Update InputManager so that SDL_QUIT and stuff can be
+          // handled, even if the basic events are taken from record
           input_manager->update(delta);
           input_controller->clear_events();
           read_events(std::cin, events);
@@ -223,8 +224,10 @@
       
           // cap the framerate at the desired value
           if (delta < 1.0f / desired_fps) {
+            Uint32 sleep_time = static_cast<Uint32>(1000 *((1.0f / 
desired_fps) - delta));
+            // std::cout << "Sleep: " << sleep_time << std::endl;
             // idle delay to make the frame take as long as we want it to
-            SDL_Delay(static_cast<Uint32>(1000 *((1.0f / desired_fps) - 
delta)));
+            SDL_Delay(sleep_time);
           }
         }
     }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]