sketch_layer.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Flexlay - A Generic 2D Game Editor
  2. // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include "sketch_layer.hpp"
  17. #include <iostream>
  18. #include <ClanLib/gl.h>
  19. #include <ClanLib/Core/core_iostream.h>
  20. #include <ClanLib/Core/System/error.h>
  21. #include <ClanLib/Display/display.h>
  22. #include <ClanLib/Display/sprite.h>
  23. #include <ClanLib/Display/pixel_buffer.h>
  24. #include <ClanLib/Display/canvas.h>
  25. #include <ClanLib/Display/blend_func.h>
  26. #include <ClanLib/Display/graphic_context.h>
  27. #include <ClanLib/Display/display_window.h>
  28. #include "gui/editor_map_component.hpp"
  29. #include "flexlay.hpp"
  30. #include "layer_impl.hpp"
  31. #include "math.hpp"
  32. SketchLayer* SketchLayer::current_ = 0;
  33. class SketchLayerImpl : public LayerImpl
  34. {
  35. public:
  36. typedef std::vector<Stroke> Strokes;
  37. Strokes strokes;
  38. /** Used to cache drawings */
  39. CL_Surface surface;
  40. CL_Canvas* canvas;
  41. float last_zoom;
  42. float last_rot;
  43. CL_Pointf last_pos;
  44. SketchLayerImpl()
  45. : surface(CL_PixelBuffer(CL_Display::get_width(), CL_Display::get_height(),
  46. CL_Display::get_width()*4, CL_PixelFormat::rgba8888)),
  47. canvas(0),
  48. last_zoom(0.0f),
  49. last_rot(0)
  50. {
  51. try {
  52. canvas = new CL_Canvas(surface);
  53. } catch(CL_Error& err) {
  54. std::cout << "CL_Error: " << err.message << std::endl;
  55. }
  56. }
  57. ~SketchLayerImpl() {
  58. delete canvas;
  59. }
  60. void add_stroke(const Stroke& stroke)
  61. {
  62. strokes.push_back(stroke);
  63. if (canvas)
  64. {
  65. EditorMapComponent* parent = EditorMapComponent::current();
  66. parent->get_gc_state().push(canvas->get_gc());
  67. stroke.draw(canvas->get_gc());
  68. parent->get_gc_state().pop(canvas->get_gc());
  69. canvas->sync_surface();
  70. }
  71. }
  72. void draw(const GraphicContextState& state, CL_GraphicContext* gc)
  73. {
  74. // Nothing to draw, so we go byebye
  75. if (strokes.empty())
  76. return;
  77. if (canvas)
  78. {
  79. // Draw to canvas
  80. if (last_zoom != state.get_zoom() ||
  81. last_pos != state.get_pos() ||
  82. last_rot != state.get_rotation())
  83. {
  84. // Rerender the image
  85. last_zoom = state.get_zoom();
  86. last_pos = state.get_pos();
  87. last_rot = state.get_rotation();
  88. state.push(canvas->get_gc());
  89. canvas->get_gc()->clear(CL_Color(0, 0, 0, 0));
  90. //canvas->get_gc()->clear(CL_Color::white);
  91. CL_Rectf visible_area = state.get_clip_rect();
  92. for(Strokes::iterator i = strokes.begin(); i != strokes.end(); ++i)
  93. {
  94. // canvas->get_gc()->draw_rect(i->get_bounding_rect(), CL_Color(0, 255, 0));
  95. // canvas->get_gc()->flush();
  96. if (visible_area.is_overlapped(i->get_bounding_rect()))
  97. {
  98. i->draw(canvas->get_gc());
  99. }
  100. }
  101. state.pop(canvas->get_gc());
  102. canvas->sync_surface();
  103. }
  104. surface.set_blend_func(blend_one, blend_one_minus_src_alpha);
  105. CL_Matrix4x4 matrix = CL_Display::get_modelview();
  106. CL_Display::pop_modelview();
  107. surface.draw();
  108. CL_Display::set_modelview(matrix);
  109. // FIXME: I think we need the line below, however with it it
  110. //doesn't work, without it, it does, ClanLib bug or just
  111. //consfusing function names?
  112. //CL_Display::push_modelview();
  113. }
  114. else
  115. {
  116. // Direct Drawing, slow
  117. for(Strokes::iterator i = strokes.begin(); i != strokes.end(); ++i)
  118. {
  119. i->draw(0);
  120. }
  121. }
  122. }
  123. bool has_bounding_rect() const {
  124. return false;
  125. }
  126. };
  127. SketchLayer::SketchLayer()
  128. : impl(new SketchLayerImpl())
  129. {
  130. current_ = this;
  131. }
  132. void
  133. SketchLayer::add_stroke(const Stroke& stroke)
  134. {
  135. if (stroke.get_dab_count() > 0)
  136. impl->add_stroke(stroke);
  137. }
  138. Layer
  139. SketchLayer::to_layer()
  140. {
  141. return Layer(impl);
  142. }
  143. std::vector<Stroke>
  144. SketchLayer::get_strokes()
  145. {
  146. return impl->strokes;
  147. }
  148. CL_Surface
  149. SketchLayer::get_background_surface()
  150. {
  151. return impl->surface;
  152. }
  153. /* EOF */