X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fvideo%2Fdrawing_context.cpp;h=faa95ddf58486b97cdf06b202aeeb6289eba98c6;hb=6492679a300bff2c17505c5d9bc9d333eeba384d;hp=82890be7235cc7dec4d825e88f5c5e779b122f4a;hpb=c1277f5b7db9f55d1d28f658b4e804f32b76f0ce;p=supertux.git diff --git a/src/video/drawing_context.cpp b/src/video/drawing_context.cpp index 82890be72..faa95ddf5 100644 --- a/src/video/drawing_context.cpp +++ b/src/video/drawing_context.cpp @@ -14,34 +14,25 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include "video/drawing_context.hpp" + #include #include -#include "video/drawing_context.hpp" - -#include "obstack/obstackpp.hpp" +#include "math/sizef.hpp" #include "supertux/gameconfig.hpp" -#include "supertux/main.hpp" +#include "supertux/globals.hpp" +#include "util/obstackpp.hpp" #include "video/drawing_request.hpp" #include "video/lightmap.hpp" #include "video/renderer.hpp" #include "video/surface.hpp" #include "video/texture.hpp" #include "video/texture_manager.hpp" -#include "video/video_systems.hpp" +#include "video/video_system.hpp" -static inline int next_po2(int val) -{ - int result = 1; - while(result < val) - result *= 2; - - return result; -} - -DrawingContext::DrawingContext() : - renderer(0), - lightmap(0), +DrawingContext::DrawingContext(VideoSystem& video_system_) : + video_system(video_system_), transformstack(), transform(), blend_stack(), @@ -61,24 +52,28 @@ DrawingContext::DrawingContext() : DrawingContext::~DrawingContext() { - delete renderer; - delete lightmap; + clear_drawing_requests(lightmap_requests); + clear_drawing_requests(drawing_requests); obstack_free(&obst, NULL); } void -DrawingContext::init_renderer() +DrawingContext::clear_drawing_requests(DrawingRequests& requests_) { - delete renderer; - delete lightmap; - - renderer = new_renderer(); - lightmap = new_lightmap(); + for(auto& request : requests_) + { + if (request->request_data) + { + request->request_data->~DrawingRequestData(); + } + request->~DrawingRequest(); + } + requests_.clear(); } void -DrawingContext::draw_surface(const Surface* surface, const Vector& position, +DrawingContext::draw_surface(SurfacePtr surface, const Vector& position, float angle, const Color& color, const Blend& blend, int layer) { @@ -102,21 +97,24 @@ DrawingContext::draw_surface(const Surface* surface, const Vector& position, request->color = color; request->blend = blend; - request->request_data = const_cast (surface); + SurfaceRequest* surfacerequest = new(obst) SurfaceRequest(); + surfacerequest->surface = surface.get(); + request->request_data = surfacerequest; requests->push_back(request); } void -DrawingContext::draw_surface(const Surface* surface, const Vector& position, +DrawingContext::draw_surface(SurfacePtr surface, const Vector& position, int layer) { draw_surface(surface, position, 0.0f, Color(1.0f, 1.0f, 1.0f), Blend(), layer); } void -DrawingContext::draw_surface_part(const Surface* surface, const Vector& source, - const Vector& size, const Vector& dest, int layer) +DrawingContext::draw_surface_part(SurfacePtr surface, + const Rectf& srcrect, const Rectf& dstrect, + int layer) { assert(surface != 0); @@ -124,38 +122,23 @@ DrawingContext::draw_surface_part(const Surface* surface, const Vector& source, request->target = target; request->type = SURFACE_PART; - request->pos = transform.apply(dest); + request->pos = transform.apply(dstrect.p1); request->layer = layer; request->drawing_effect = transform.drawing_effect; request->alpha = transform.alpha; SurfacePartRequest* surfacepartrequest = new(obst) SurfacePartRequest(); - surfacepartrequest->size = size; - surfacepartrequest->source = source; - surfacepartrequest->surface = surface; - - // clip on screen borders - if(request->pos.x < 0) { - surfacepartrequest->size.x += request->pos.x; - if(surfacepartrequest->size.x <= 0) - return; - surfacepartrequest->source.x -= request->pos.x; - request->pos.x = 0; - } - if(request->pos.y < 0) { - surfacepartrequest->size.y += request->pos.y; - if(surfacepartrequest->size.y <= 0) - return; - surfacepartrequest->source.y -= request->pos.y; - request->pos.y = 0; - } + surfacepartrequest->srcrect = srcrect; + surfacepartrequest->dstsize = dstrect.get_size(); + surfacepartrequest->surface = surface.get(); + request->request_data = surfacepartrequest; requests->push_back(request); } void -DrawingContext::draw_text(const Font* font, const std::string& text, +DrawingContext::draw_text(FontPtr font, const std::string& text, const Vector& position, FontAlignment alignment, int layer, Color color) { DrawingRequest* request = new(obst) DrawingRequest(); @@ -169,7 +152,7 @@ DrawingContext::draw_text(const Font* font, const std::string& text, request->color = color; TextRequest* textrequest = new(obst) TextRequest(); - textrequest->font = font; + textrequest->font = font.get(); textrequest->text = text; textrequest->alignment = alignment; request->request_data = textrequest; @@ -178,7 +161,7 @@ DrawingContext::draw_text(const Font* font, const std::string& text, } void -DrawingContext::draw_center_text(const Font* font, const std::string& text, +DrawingContext::draw_center_text(FontPtr font, const std::string& text, const Vector& position, int layer, Color color) { draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y), @@ -231,14 +214,14 @@ DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size, } void -DrawingContext::draw_filled_rect(const Rect& rect, const Color& color, +DrawingContext::draw_filled_rect(const Rectf& rect, const Color& color, int layer) { draw_filled_rect(rect, color, 0.0f, layer); } void -DrawingContext::draw_filled_rect(const Rect& rect, const Color& color, float radius, int layer) +DrawingContext::draw_filled_rect(const Rectf& rect, const Color& color, float radius, int layer) { DrawingRequest* request = new(obst) DrawingRequest(); @@ -257,7 +240,7 @@ DrawingContext::draw_filled_rect(const Rect& rect, const Color& color, float rad fillrectrequest->radius = radius; request->request_data = fillrectrequest; - requests->push_back(request); + requests->push_back(request); } void @@ -274,13 +257,21 @@ DrawingContext::draw_inverse_ellipse(const Vector& pos, const Vector& size, cons request->alpha = transform.alpha; InverseEllipseRequest* ellipse = new(obst)InverseEllipseRequest; - + ellipse->color = color; ellipse->color.alpha = color.alpha * transform.alpha; ellipse->size = size; request->request_data = ellipse; - requests->push_back(request); + requests->push_back(request); +} + +Rectf +DrawingContext::get_cliprect() const +{ + return Rectf(get_translation().x, get_translation().y, + get_translation().x + SCREEN_WIDTH, + get_translation().y + SCREEN_HEIGHT); } void @@ -314,22 +305,23 @@ DrawingContext::get_light(const Vector& position, Color* color) void DrawingContext::do_drawing() { -#ifdef DEBUG assert(transformstack.empty()); assert(target_stack.empty()); -#endif transformstack.clear(); target_stack.clear(); //Use Lightmap if ambient color is not white. - bool use_lightmap = ( ambient_color.red != 1.0f || ambient_color.green != 1.0f || - ambient_color.blue != 1.0f ); + bool use_lightmap = ( ambient_color.red != 1.0f || + ambient_color.green != 1.0f || + ambient_color.blue != 1.0f ); // PART1: create lightmap if(use_lightmap) { - lightmap->start_draw(ambient_color); + Lightmap& lightmap = video_system.get_lightmap(); + + lightmap.start_draw(ambient_color); handle_drawing_requests(lightmap_requests); - lightmap->end_draw(); + lightmap.end_draw(); DrawingRequest* request = new(obst) DrawingRequest(); request->target = NORMAL; @@ -337,20 +329,25 @@ DrawingContext::do_drawing() request->layer = LAYER_HUD - 1; drawing_requests.push_back(request); } - lightmap_requests.clear(); + Renderer& renderer = video_system.get_renderer(); + renderer.start_draw(); handle_drawing_requests(drawing_requests); - drawing_requests.clear(); + renderer.end_draw(); + + clear_drawing_requests(lightmap_requests); + clear_drawing_requests(drawing_requests); + obstack_free(&obst, NULL); obstack_init(&obst); // if a screenshot was requested, take one if (screenshot_requested) { - renderer->do_take_screenshot(); + renderer.do_take_screenshot(); screenshot_requested = false; } - renderer->flip(); + renderer.flip(); } class RequestPtrCompare @@ -363,76 +360,79 @@ public: }; void -DrawingContext::handle_drawing_requests(DrawingRequests& requests) +DrawingContext::handle_drawing_requests(DrawingRequests& requests_) { - std::stable_sort(requests.begin(), requests.end(), RequestPtrCompare()); + std::stable_sort(requests_.begin(), requests_.end(), RequestPtrCompare()); + + Renderer& renderer = video_system.get_renderer(); + Lightmap& lightmap = video_system.get_lightmap(); DrawingRequests::const_iterator i; - for(i = requests.begin(); i != requests.end(); ++i) { + for(i = requests_.begin(); i != requests_.end(); ++i) { const DrawingRequest& request = **i; switch(request.target) { case NORMAL: switch(request.type) { case SURFACE: - renderer->draw_surface(request); + renderer.draw_surface(request); break; case SURFACE_PART: - renderer->draw_surface_part(request); + renderer.draw_surface_part(request); break; case GRADIENT: - renderer->draw_gradient(request); + renderer.draw_gradient(request); break; case TEXT: { - const TextRequest* textrequest = (TextRequest*) request.request_data; - textrequest->font->draw(renderer, textrequest->text, request.pos, + const TextRequest* textrequest = static_cast(request.request_data); + textrequest->font->draw(&renderer, textrequest->text, request.pos, textrequest->alignment, request.drawing_effect, request.color, request.alpha); } break; case FILLRECT: - renderer->draw_filled_rect(request); + renderer.draw_filled_rect(request); break; case INVERSEELLIPSE: - renderer->draw_inverse_ellipse(request); + renderer.draw_inverse_ellipse(request); break; case DRAW_LIGHTMAP: - lightmap->do_draw(); + lightmap.do_draw(); break; case GETLIGHT: - lightmap->get_light(request); + lightmap.get_light(request); break; } break; case LIGHTMAP: switch(request.type) { case SURFACE: - lightmap->draw_surface(request); + lightmap.draw_surface(request); break; case SURFACE_PART: - lightmap->draw_surface_part(request); + lightmap.draw_surface_part(request); break; case GRADIENT: - lightmap->draw_gradient(request); + lightmap.draw_gradient(request); break; case TEXT: { - const TextRequest* textrequest = (TextRequest*) request.request_data; - textrequest->font->draw(renderer, textrequest->text, request.pos, + const TextRequest* textrequest = static_cast(request.request_data); + textrequest->font->draw(&renderer, textrequest->text, request.pos, textrequest->alignment, request.drawing_effect, request.color, request.alpha); } break; case FILLRECT: - lightmap->draw_filled_rect(request); + lightmap.draw_filled_rect(request); break; case INVERSEELLIPSE: assert(!"InverseEllipse doesn't make sense on the lightmap"); break; case DRAW_LIGHTMAP: - lightmap->do_draw(); + lightmap.do_draw(); break; case GETLIGHT: - lightmap->get_light(request); + lightmap.get_light(request); break; } break; @@ -493,13 +493,13 @@ DrawingContext::pop_target() } void -DrawingContext::set_target(Target target) +DrawingContext::set_target(Target target_) { - this->target = target; - if(target == LIGHTMAP) { + this->target = target_; + if(target_ == LIGHTMAP) { requests = &lightmap_requests; } else { - assert(target == NORMAL); + assert(target_ == NORMAL); requests = &drawing_requests; } } @@ -510,7 +510,7 @@ DrawingContext::set_ambient_color( Color new_color ) ambient_color = new_color; } -void +void DrawingContext::take_screenshot() { screenshot_requested = true;