source: trunk/engine/core/view/renderers/genericrenderer.cpp @ 3513

Revision 3513, 18.7 KB checked in by helios2000, 3 years ago (diff)
  • Property svn:eol-style set to native
Line 
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
49namespace 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}
Note: See TracBrowser for help on using the repository browser.