[Top][All Lists]
[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);
}
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pingus-CVS] r3797 - in trunk/pingus/src: display screen,
grumbel at BerliOS <=