FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
genericrenderer.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2008 by the FIFE team *
3  * http://www.fifengine.de *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 
24 // 3rd party library includes
25 
26 // FIFE includes
27 // These includes are split up in two parts, separated by one empty line
28 // First block: files included from the FIFE root src directory
29 // Second block: files included from the same folder
30 #include "video/renderbackend.h"
31 #include "video/imagepool.h"
32 #include "video/animation.h"
33 #include "video/animationpool.h"
34 #include "video/fonts/abstractfont.h"
35 #include "video/image.h"
36 #include "util/math/fife_math.h"
37 #include "util/log/logger.h"
38 #include "util/time/timemanager.h"
39 #include "model/metamodel/grids/cellgrid.h"
40 #include "model/metamodel/timeprovider.h"
41 #include "model/structures/instance.h"
42 #include "model/structures/layer.h"
43 #include "model/structures/location.h"
44 
45 #include "view/camera.h"
46 #include "genericrenderer.h"
47 
48 
49 namespace FIFE {
50  static Logger _log(LM_VIEWVIEW);
51 
52  GenericRendererNode::GenericRendererNode(Instance* attached_instance, const Location &relative_location, Layer* relative_layer, const Point &relative_point):
53  m_instance(attached_instance),
54  m_location(relative_location),
55  m_layer(relative_layer),
56  m_point(relative_point) {
57  }
58  GenericRendererNode::GenericRendererNode(Instance* attached_instance, const Location &relative_location, const Point &relative_point):
59  m_instance(attached_instance),
60  m_location(relative_location),
61  m_layer(NULL),
62  m_point(relative_point) {
63  }
64  GenericRendererNode::GenericRendererNode(Instance* attached_instance, Layer* relative_layer, const Point &relative_point):
65  m_instance(attached_instance),
66  m_location(NULL),
67  m_layer(relative_layer),
68  m_point(relative_point) {
69  }
70  GenericRendererNode::GenericRendererNode(Instance* attached_instance, const Point &relative_point):
71  m_instance(attached_instance),
72  m_location(NULL),
73  m_layer(NULL),
74  m_point(relative_point) {
75  }
76  GenericRendererNode::GenericRendererNode(const Location &attached_location, Layer* relative_layer, const Point &relative_point):
77  m_instance(NULL),
78  m_location(attached_location),
79  m_layer(relative_layer),
80  m_point(relative_point) {
81  }
82  GenericRendererNode::GenericRendererNode(const Location &attached_location, const Point &relative_point):
83  m_instance(NULL),
84  m_location(attached_location),
85  m_layer(NULL),
86  m_point(relative_point) {
87  }
88  GenericRendererNode::GenericRendererNode(Layer* attached_layer, const Point &relative_point):
89  m_instance(NULL),
90  m_location(NULL),
91  m_layer(attached_layer),
92  m_point(relative_point) {
93  }
94  GenericRendererNode::GenericRendererNode(const Point &attached_point):
95  m_instance(NULL),
96  m_location(NULL),
97  m_layer(NULL),
98  m_point(attached_point) {
99  }
100  GenericRendererNode::~GenericRendererNode() {
101  }
102 
103  void GenericRendererNode::setAttached(Instance* attached_instance, const Location &relative_location, const Point &relative_point) {
104  m_instance = attached_instance;
105  m_location = relative_location;
106  m_point = relative_point;
107  }
108  void GenericRendererNode::setAttached(Instance* attached_instance, const Location &relative_location) {
109  m_instance = attached_instance;
110  m_location = relative_location;
111  }
112  void GenericRendererNode::setAttached(Instance* attached_instance, const Point &relative_point) {
113  m_instance = attached_instance;
114  m_point = relative_point;
115  }
116  void GenericRendererNode::setAttached(Instance* attached_instance) {
117  m_instance = attached_instance;
118  }
119  void GenericRendererNode::setAttached(const Location &attached_location, const Point &relative_point) {
120  m_instance = NULL;
121  m_location = attached_location;
122  m_point = relative_point;
123  }
124  void GenericRendererNode::setAttached(const Location &attached_location) {
125  m_instance = NULL;
126  m_location = attached_location;
127  }
128  void GenericRendererNode::setAttached(Layer* attached_layer) {
129  m_layer = attached_layer;
130  }
131  void GenericRendererNode::setAttached(const Point &attached_point) {
132  m_instance = NULL;
133  m_location = NULL;
134  m_point = attached_point;
135  }
136 
137  void GenericRendererNode::setRelative(const Location &relative_location) {
138  if(m_instance == NULL) {
139  throw NotSupported("No instance attached.");
140  }
141  m_location = relative_location;
142  }
143  void GenericRendererNode::setRelative(const Location &relative_location, Point relative_point) {
144  if(m_instance == NULL) {
145  throw NotSupported("No instance attached.");
146  }
147  m_location = relative_location;
148  m_point = relative_point;
149  }
150  void GenericRendererNode::setRelative(const Point &relative_point) {
151  if(m_instance == NULL || m_location == NULL) {
152  throw NotSupported("No instance or location attached.");
153  }
154  m_point = relative_point;
155  }
156 
157  Instance* GenericRendererNode::getAttachedInstance() {
158  if(m_instance == NULL) {
159  throw NotSupported("No instance attached.");
160  }
161  return m_instance;
162  }
163  Location GenericRendererNode::getAttachedLocation() {
164  if(m_instance != NULL || m_location == NULL) {
165  throw NotSupported("No location attached.");
166  }
167  return m_location;
168  }
169  Layer* GenericRendererNode::getAttachedLayer() {
170  if(m_layer == NULL) {
171  throw NotSupported("No layer attached.");
172  }
173  return m_layer;
174  }
175  Point GenericRendererNode::getAttachedPoint() {
176  if(m_instance != NULL || m_location != NULL) {
177  throw NotSupported("No point attached.");
178  }
179  return m_point;
180  }
181 
182  Location GenericRendererNode::getOffsetLocation() {
183  if(m_instance == NULL || m_location == NULL) {
184  throw NotSupported("No location as offset used.");
185  }
186  return m_location;
187  }
188  Point GenericRendererNode::getOffsetPoint() {
189  if(m_instance == NULL && m_location == NULL) {
190  throw NotSupported("No point as offset used.");
191  }
192  return m_point;
193  }
194 
195  Instance* GenericRendererNode::getInstance() {
196  return m_instance;
197  }
198  Location GenericRendererNode::getLocation() {
199  return m_location;
200  }
201  Layer* GenericRendererNode::getLayer() {
202  return m_layer;
203  }
204  Point GenericRendererNode::getPoint() {
205  return m_point;
206  }
207 
208  Point GenericRendererNode::getCalculatedPoint(Camera* cam, Layer* layer) {
209  ScreenPoint p;
210  if(m_instance != NULL) {
211  if(m_layer == NULL) {
212  m_layer = m_instance->getLocation().getLayer();
213  }
214  if(m_location != NULL) {
215  p = cam->toScreenCoordinates(m_instance->getLocationRef().getMapCoordinates() + m_location.getMapCoordinates());
216  } else {
217  p = cam->toScreenCoordinates(m_instance->getLocation().getMapCoordinates());
218  }
219  } else if(m_location != NULL) {
220  if(m_layer == NULL) {
221  m_layer = m_location.getLayer();
222  }
223  p = cam->toScreenCoordinates(m_location.getMapCoordinates());
224  } else if(m_layer == NULL) {
225  const std::list<Layer*>& layers = cam->getRenderer("GenericRenderer")->getActiveLayers();
226  std::list<Layer*>::const_reverse_iterator layer_it = layers.rbegin();
227  setAttached(*layer_it);
228  }
229  return Point(m_point.x + p.x, m_point.y + p.y);
230  }
231 
232  GenericRendererLineInfo::GenericRendererLineInfo(GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
233  GenericRendererElementInfo(),
234  m_edge1(n1),
235  m_edge2(n2),
236  m_red(r),
237  m_green(g),
238  m_blue(b),
239  m_alpha(a) {
240  }
241  void GenericRendererLineInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
242  Point p1 = m_edge1.getCalculatedPoint(cam, layer);
243  Point p2 = m_edge2.getCalculatedPoint(cam, layer);
244  if(m_edge1.getLayer() == layer) {
245  renderbackend->drawLine(p1, p2, m_red, m_green, m_blue, m_alpha);
246  }
247  }
248 
249  GenericRendererPointInfo::GenericRendererPointInfo(GenericRendererNode anchor, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
250  GenericRendererElementInfo(),
251  m_anchor(anchor),
252  m_red(r),
253  m_green(g),
254  m_blue(b),
255  m_alpha(a) {
256  }
257  void GenericRendererPointInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
258  Point p = m_anchor.getCalculatedPoint(cam, layer);
259  if(m_anchor.getLayer() == layer) {
260  renderbackend->putPixel(p.x, p.y, m_red, m_green, m_blue, m_alpha);
261  }
262  }
263 
264  GenericRendererTriangleInfo::GenericRendererTriangleInfo(GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
265  GenericRendererElementInfo(),
266  m_edge1(n1),
267  m_edge2(n2),
268  m_edge3(n3),
269  m_red(r),
270  m_green(g),
271  m_blue(b),
272  m_alpha(a) {
273  }
274  void GenericRendererTriangleInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
275  Point p1 = m_edge1.getCalculatedPoint(cam, layer);
276  Point p2 = m_edge2.getCalculatedPoint(cam, layer);
277  Point p3 = m_edge3.getCalculatedPoint(cam, layer);
278  if(m_edge1.getLayer() == layer) {
279  renderbackend->drawTriangle(p1, p2, p3, m_red, m_green, m_blue, m_alpha);
280  }
281  }
282 
283  GenericRendererQuadInfo::GenericRendererQuadInfo(GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, GenericRendererNode n4, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
284  GenericRendererElementInfo(),
285  m_edge1(n1),
286  m_edge2(n2),
287  m_edge3(n3),
288  m_edge4(n4),
289  m_red(r),
290  m_green(g),
291  m_blue(b),
292  m_alpha(a) {
293  }
294  void GenericRendererQuadInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
295  Point p1 = m_edge1.getCalculatedPoint(cam, layer);
296  Point p2 = m_edge2.getCalculatedPoint(cam, layer);
297  Point p3 = m_edge3.getCalculatedPoint(cam, layer);
298  Point p4 = m_edge4.getCalculatedPoint(cam, layer);
299  if(m_edge1.getLayer() == layer) {
300  renderbackend->drawQuad(p1, p2, p3, p4, m_red, m_green, m_blue, m_alpha);
301  }
302  }
303 
304  GenericRendererVertexInfo::GenericRendererVertexInfo(GenericRendererNode center, int size, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
305  GenericRendererElementInfo(),
306  m_center(center),
307  m_size(size),
308  m_red(r),
309  m_green(g),
310  m_blue(b),
311  m_alpha(a) {
312  }
313  void GenericRendererVertexInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
314  Point p = m_center.getCalculatedPoint(cam, layer);
315  if(m_center.getLayer() == layer) {
316  renderbackend->drawVertex(p, m_size, m_red, m_green, m_blue, m_alpha);
317  }
318  }
319 
320  GenericRendererImageInfo::GenericRendererImageInfo(GenericRendererNode anchor, int image):
321  GenericRendererElementInfo(),
322  m_anchor(anchor),
323  m_image(image) {
324  }
325  void GenericRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
326  Point p = m_anchor.getCalculatedPoint(cam, layer);
327  if(m_anchor.getLayer() == layer) {
328  Image* img = &imagepool->getImage(m_image);
329  Rect r;
330  Rect viewport = cam->getViewPort();
331  unsigned int widtht = round(img->getWidth() * cam->getZoom());
332  unsigned int height = round(img->getHeight() * cam->getZoom());
333  r.x = p.x-widtht/2;
334  r.y = p.y-height/2;
335  r.w = widtht;
336  r.h = height;
337  if(r.intersects(viewport))
338  img->render(r);
339  }
340  }
341 
342  GenericRendererAnimationInfo::GenericRendererAnimationInfo(GenericRendererNode anchor, int animation):
343  GenericRendererElementInfo(),
344  m_anchor(anchor),
345  m_animation(animation),
346  m_start_time(TimeManager::instance()->getTime()),
347  m_time_scale(1.0) {
348  }
349  void GenericRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
350  Point p = m_anchor.getCalculatedPoint(cam, layer);
351  if(m_anchor.getLayer() == layer) {
352  Animation& animation = animpool->getAnimation(m_animation);
353  int animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % animation.getDuration();
354  Image* img = animation.getFrameByTimestamp(animtime);
355  Rect r;
356  Rect viewport = cam->getViewPort();
357  unsigned int widtht = round(img->getWidth() * cam->getZoom());
358  unsigned int height = round(img->getHeight() * cam->getZoom());
359  r.x = p.x-widtht/2;
360  r.y = p.y-height/2;
361  r.w = widtht;
362  r.h = height;
363  if(r.intersects(viewport))
364  img->render(r);
365  }
366  }
367 
368  GenericRendererTextInfo::GenericRendererTextInfo(GenericRendererNode anchor, AbstractFont* font, std::string text):
369  GenericRendererElementInfo(),
370  m_anchor(anchor),
371  m_font(font),
372  m_text(text) {
373  }
374  void GenericRendererTextInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
375  Point p = m_anchor.getCalculatedPoint(cam, layer);
376  if(m_anchor.getLayer() == layer) {
377  Image* img = m_font->getAsImageMultiline(m_text);
378  Rect r;
379  Rect viewport = cam->getViewPort();
380  r.x = p.x-img->getWidth()/2;
381  r.y = p.y-img->getHeight()/2;
382  r.w = img->getWidth();
383  r.h = img->getHeight();
384  if(r.intersects(viewport)) {
385  renderbackend->disableLighting();
386  img->render(r);
387  renderbackend->enableLighting();
388  }
389  }
390  }
391 
392  GenericRendererResizeInfo::GenericRendererResizeInfo(GenericRendererNode anchor, int image, int width, int height):
393  GenericRendererElementInfo(),
394  m_anchor(anchor),
395  m_image(image),
396  m_width(width),
397  m_height(height){
398  }
399  void GenericRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
400  Point p = m_anchor.getCalculatedPoint(cam, layer);
401  if(m_anchor.getLayer() == layer) {
402  Image* img = &imagepool->getImage(m_image);
403  Rect r;
404  Rect viewport = cam->getViewPort();
405  unsigned int widtht = round(m_width * cam->getZoom());
406  unsigned int height = round(m_height * cam->getZoom());
407  r.x = p.x-widtht/2;
408  r.y = p.y-height/2;
409  r.w = widtht;
410  r.h = height;
411  if(r.intersects(viewport)) {
412  img->render(r);
413  }
414  }
415  }
416 
417  GenericRenderer* GenericRenderer::getInstance(IRendererContainer* cnt) {
418  return dynamic_cast<GenericRenderer*>(cnt->getRenderer("GenericRenderer"));
419  }
420 
421  GenericRenderer::GenericRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool):
422  RendererBase(renderbackend, position),
423  m_imagepool(imagepool),
424  m_animationpool(animpool),
425  m_groups() {
426  setEnabled(false);
427  }
428 
429  GenericRenderer::GenericRenderer(const GenericRenderer& old):
430  RendererBase(old),
431  m_imagepool(old.m_imagepool),
432  m_animationpool(old.m_animationpool),
433  m_groups() {
434  setEnabled(false);
435  }
436 
437  RendererBase* GenericRenderer::clone() {
438  return new GenericRenderer(*this);
439  }
440 
441  GenericRenderer::~GenericRenderer() {
442  }
443  void GenericRenderer::addLine(const std::string &group, GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
444  GenericRendererElementInfo* info = new GenericRendererLineInfo(n1, n2, r, g, b, a);
445  m_groups[group].push_back(info);
446  }
447  void GenericRenderer::addPoint(const std::string &group, GenericRendererNode n, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
448  GenericRendererElementInfo* info = new GenericRendererPointInfo(n, r, g, b, a);
449  m_groups[group].push_back(info);
450  }
451  void GenericRenderer::addTriangle(const std::string &group, GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
452  GenericRendererElementInfo* info = new GenericRendererTriangleInfo(n1, n2, n3, r, g, b, a);
453  m_groups[group].push_back(info);
454  }
455  void GenericRenderer::addQuad(const std::string &group, GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, GenericRendererNode n4, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
456  GenericRendererElementInfo* info = new GenericRendererQuadInfo(n1, n2, n3, n4, r, g, b, a);
457  m_groups[group].push_back(info);
458  }
459  void GenericRenderer::addVertex(const std::string &group, GenericRendererNode n, int size, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
460  GenericRendererElementInfo* info = new GenericRendererVertexInfo(n, size, r, g, b, a);
461  m_groups[group].push_back(info);
462  }
463  void GenericRenderer::addText(const std::string &group, GenericRendererNode n, AbstractFont* font, const std::string &text) {
464  GenericRendererElementInfo* info = new GenericRendererTextInfo(n, font, text);
465  m_groups[group].push_back(info);
466  }
467  void GenericRenderer::addImage(const std::string &group, GenericRendererNode n, int image) {
468  GenericRendererElementInfo* info = new GenericRendererImageInfo(n, image);
469  m_groups[group].push_back(info);
470  }
471  void GenericRenderer::addAnimation(const std::string &group, GenericRendererNode n, int animation) {
472  GenericRendererElementInfo* info = new GenericRendererAnimationInfo(n, animation);
473  m_groups[group].push_back(info);
474  }
475  void GenericRenderer::resizeImage(const std::string &group, GenericRendererNode n, int image, int width, int height) {
476  GenericRendererElementInfo* info = new GenericRendererResizeInfo(n, image, width, height);
477  m_groups[group].push_back(info);
478  }
479  void GenericRenderer::removeAll(const std::string &group) {
480  std::vector<GenericRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
481  for (;info_it != m_groups[group].end(); ++info_it) {
482  delete *info_it;
483  }
484  m_groups[group].clear();
485  m_groups.erase(group);
486  }
487 
488  void GenericRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
489  std::map<std::string, std::vector<GenericRendererElementInfo*> >::iterator group_it = m_groups.begin();
490  for(; group_it != m_groups.end(); ++group_it) {
491  std::vector<GenericRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
492  for (;info_it != group_it->second.end(); ++info_it) {
493  (*info_it)->render(cam, layer, instances, m_renderbackend, m_imagepool, m_animationpool);
494  }
495  }
496  }
497 }