FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
lightrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
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 #include <SDL.h>
24 
25 // 3rd party library includes
26 
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
31 #include "video/renderbackend.h"
32 #include "video/animation.h"
33 #include "video/fonts/ifont.h"
34 #include "video/imagemanager.h"
35 #include "video/image.h"
36 #include "video/opengl/glimage.h"
37 #include "video/opengle/gleimage.h"
40 #include "util/math/fife_math.h"
41 #include "util/log/logger.h"
42 #include "util/time/timemanager.h"
46 #include "model/structures/layer.h"
48 
49 #include "view/camera.h"
50 #include "lightrenderer.h"
51 
52 
53 namespace FIFE {
57  static Logger _log(LM_VIEWVIEW);
58 
60  m_anchor(n),
61  m_src(src),
62  m_dst(dst),
63  m_stencil(false),
64  m_stencil_ref(0) {
65  }
67  m_stencil = true;
68  m_stencil_ref = stencil_ref;
69  }
71  if(!m_stencil) {
72  return -1;
73  }
74  return m_stencil_ref;
75  }
77  m_stencil = false;
78  m_stencil_ref = 0;
79  }
80  LightRendererImageInfo::LightRendererImageInfo(RendererNode anchor, ImagePtr image, int32_t src, int32_t dst):
81  LightRendererElementInfo(anchor, src, dst),
82  m_image(image){
83  }
84  void LightRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
85  Point p = m_anchor.getCalculatedPoint(cam, layer);
86  if(m_anchor.getLayer() == layer) {
87  Rect r;
88  Rect viewport = cam->getViewPort();
89  uint32_t width = static_cast<uint32_t>(round(m_image->getWidth() * cam->getZoom()));
90  uint32_t height = static_cast<uint32_t>(round(m_image->getHeight() * cam->getZoom()));
91  r.x = p.x-width/2;
92  r.y = p.y-height/2;
93  r.w = width;
94  r.h = height;
95 
96  if(r.intersects(viewport)) {
97  uint8_t lm = renderbackend->getLightingModel();
98  m_image->render(r);
99  if (m_stencil) {
100  renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
101  } else if (lm == 1) {
102  renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
103  }
104  }
105  }
106  }
108  LightRendererElementInfo(anchor, src, dst),
109  m_animation(animation),
110  m_start_time(TimeManager::instance()->getTime()),
111  m_time_scale(1.0){
112  }
113  void LightRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
114  Point p = m_anchor.getCalculatedPoint(cam, layer);
115  if(m_anchor.getLayer() == layer) {
116  int32_t animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % m_animation->getDuration();
117  ImagePtr img = m_animation->getFrameByTimestamp(animtime);
118  Rect r;
119  Rect viewport = cam->getViewPort();
120  uint32_t width = static_cast<uint32_t>(round(img->getWidth() * cam->getZoom()));
121  uint32_t height = static_cast<uint32_t>(round(img->getHeight() * cam->getZoom()));
122  r.x = p.x-width/2;
123  r.y = p.y-height/2;
124  r.w = width;
125  r.h = height;
126 
127  if(r.intersects(viewport)) {
128  uint8_t lm = renderbackend->getLightingModel();
129  img->render(r);
130  if (m_stencil) {
131  renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
132  } else if (lm == 1) {
133  renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
134  }
135  }
136  }
137  }
138  LightRendererResizeInfo::LightRendererResizeInfo(RendererNode anchor, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst):
139  LightRendererElementInfo(anchor, src, dst),
140  m_image(image),
141  m_width(width),
142  m_height(height) {
143  }
144  void LightRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
145  Point p = m_anchor.getCalculatedPoint(cam, layer);
146  if(m_anchor.getLayer() == layer) {
147  Rect r;
148  Rect viewport = cam->getViewPort();
149  uint32_t width = static_cast<uint32_t>(round(m_width * cam->getZoom()));
150  uint32_t height = static_cast<uint32_t>(round(m_height * cam->getZoom()));
151  r.x = p.x-width/2;
152  r.y = p.y-height/2;
153  r.w = width;
154  r.h = height;
155 
156  if(r.intersects(viewport)) {
157  uint8_t lm = renderbackend->getLightingModel();
158  m_image->render(r);
159  if (m_stencil) {
160  renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
161  } else if (lm == 1) {
162  renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
163  }
164  }
165  }
166  }
167  LightRendererSimpleLightInfo::LightRendererSimpleLightInfo(RendererNode anchor, uint8_t intensity, float radius, int32_t subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int32_t src, int32_t dst):
168  LightRendererElementInfo(anchor, src, dst),
169  m_intensity(intensity),
170  m_radius(radius),
171  m_subdivisions(subdivisions),
172  m_xstretch(xstretch),
173  m_ystretch(ystretch),
174  m_red(r),
175  m_green(g),
176  m_blue(b){
177  }
178  void LightRendererSimpleLightInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
179  Point p = m_anchor.getCalculatedPoint(cam, layer);
180  if(m_anchor.getLayer() == layer) {
181  double zoom = cam->getZoom();
182 
183  uint8_t lm = renderbackend->getLightingModel();
185  static_cast<float>(m_xstretch * zoom), static_cast<float>(m_ystretch * zoom),
186  m_red, m_green, m_blue);
187 
188  if (m_stencil) {
189  renderbackend->changeRenderInfos(m_subdivisions, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
190  } else if (lm == 1) {
191  renderbackend->changeRenderInfos(m_subdivisions, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
192  }
193  }
194  }
195  std::vector<uint8_t> LightRendererSimpleLightInfo::getColor() {
196  std::vector<uint8_t> colors;
197  colors.push_back(m_red);
198  colors.push_back(m_green);
199  colors.push_back(m_blue);
200  colors.push_back(m_intensity);
201  return colors;
202  }
204  return dynamic_cast<LightRenderer*>(cnt->getRenderer("LightRenderer"));
205  }
206  LightRenderer::LightRenderer(RenderBackend* renderbackend, int32_t position):
207  RendererBase(renderbackend, position),
208  m_groups() {
209  setEnabled(false);
210  }
212  RendererBase(old),
213  m_groups() {
214  setEnabled(false);
215  }
217  return new LightRenderer(*this);
218  }
220  }
221  // Add a static lightmap
222  void LightRenderer::addImage(const std::string &group, RendererNode n, ImagePtr image, int32_t src, int32_t dst) {
223  LightRendererElementInfo* info = new LightRendererImageInfo(n, image, src, dst);
224  m_groups[group].push_back(info);
225  }
226  // Add a animation lightmap
227  void LightRenderer::addAnimation(const std::string &group, RendererNode n, AnimationPtr animation, int32_t src, int32_t dst) {
228  LightRendererElementInfo* info = new LightRendererAnimationInfo(n, animation, src, dst);
229  m_groups[group].push_back(info);
230  }
231  // Add a simple light
232  void LightRenderer::addSimpleLight(const std::string &group, RendererNode n, uint8_t intensity, float radius, int32_t subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int32_t src, int32_t dst) {
233  LightRendererElementInfo* info = new LightRendererSimpleLightInfo(n, intensity, radius, subdivisions, xstretch, ystretch, r, g, b, src, dst);
234  m_groups[group].push_back(info);
235  }
236  // Resize an Image
237  void LightRenderer::resizeImage(const std::string &group, RendererNode n, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst) {
238  LightRendererElementInfo* info = new LightRendererResizeInfo(n, image, width, height, src, dst);
239  m_groups[group].push_back(info);
240  }
241  // Enable stencil test for the group
242  void LightRenderer::addStencilTest(const std::string &group, uint8_t stencil_ref) {
243  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
244  for (;info_it != m_groups[group].end(); ++info_it) {
245  (*info_it)->setStencil(stencil_ref);
246  }
247  }
248  // Disable stencil test for the group
249  void LightRenderer::removeStencilTest(const std::string &group) {
250  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
251  for (;info_it != m_groups[group].end(); ++info_it) {
252  (*info_it)->removeStencil();
253  }
254  }
255  // Return a list of all groups
256  std::list<std::string> LightRenderer::getGroups() {
257  std::list<std::string> groups;
258  std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
259  for(; group_it != m_groups.end(); ++group_it) {
260  groups.push_back(group_it->first);
261  }
262  groups.sort();
263  groups.unique();
264  return groups;
265  }
266  // Return a vector of all LightElementInfos
267  std::vector<LightRendererElementInfo*> LightRenderer::getLightInfo(const std::string &group) {
268  std::vector<LightRendererElementInfo*> info;
269  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
270  for (;info_it != m_groups[group].end(); ++info_it) {
271  info.push_back(*info_it);
272  }
273  return info;
274  }
275  // Remove the group
276  void LightRenderer::removeAll(const std::string &group) {
277  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
278  for (;info_it != m_groups[group].end(); ++info_it) {
279  delete *info_it;
280  }
281  m_groups[group].clear();
282  m_groups.erase(group);
283  }
284  // Remove all groups
286  m_groups.clear();
287  }
288  // Clear all groups
290  removeAll();
291  }
292  // Render
293  void LightRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
295 
296  if (!layer->areInstancesVisible()) {
297  return;
298  }
299 
300  std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
301  for (; group_it != m_groups.end(); ++group_it) {
302  std::vector<LightRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
303  for (;info_it != group_it->second.end(); ++info_it) {
304  if (lm != 0) {
305  if ((*info_it)->getStencil() != -1 && (*info_it)->getStencil() < 255) {
306  if(info_it != group_it->second.begin()) {
307  (*info_it)->setStencil((*info_it)->getStencil()+1);
308  }
309  }
310  }
311  (*info_it)->render(cam, layer, instances, m_renderbackend);
312  }
313  }
314  }
315 
316 }
Abstract interface for all the renderbackends.
Definition: renderbackend.h:92
std::list< std::string > getGroups()
void render(Camera *cam, Layer *layer, RenderList &instances)
This method is called by the view to ask renderer to draw its rendering aspect based on given paramet...
std::vector< RenderItem * > RenderList
Definition: renderitem.h:82
void setStencil(uint8_t stencil_ref)
virtual void changeRenderInfos(uint16_t elements, int32_t src, int32_t dst, bool light, bool stentest, uint8_t stenref, GLConstants stenop, GLConstants stenfunc)=0
Dirty helper function to change the render infos.
virtual void render(Camera *cam, Layer *layer, RenderList &instances, RenderBackend *renderbackend)
T h
Height of the rectangle.
Definition: rect.h:93
void reset()
Resets information in the renderer.
LightRendererAnimationInfo(RendererNode n, AnimationPtr animation, int32_t src, int32_t dst)
LightRendererElementInfo(RendererNode n, int32_t src, int32_t dst)
T x
The X Coordinate.
Definition: rect.h:84
LightRendererImageInfo(RendererNode n, ImagePtr image, int32_t src, int32_t dst)
virtual void render(Camera *cam, Layer *layer, RenderList &instances, RenderBackend *renderbackend)
uint32_t getDuration() const
Gets the total duration for the whole animation.
Definition: animation.h:129
Point getCalculatedPoint(Camera *cam, Layer *layer, const bool zoomed=false)
Interface to class owning the renderers Used to get correct subclass of renderer in scripting side (v...
Definition: rendererbase.h:66
static Logger _log(LM_AUDIO)
bool areInstancesVisible() const
Check object visibility.
Definition: layer.cpp:338
virtual RendererBase * getRenderer(const std::string &renderername)=0
Returns renderer with given name.
Camera describes properties of a view port shown in the main screen Main screen can have multiple cam...
Definition: camera.h:58
static TimeManager * instance()
Definition: singleton.h:84
RendererBase * clone()
Makes copy of this renderer.
virtual uint32_t getLightingModel() const =0
Gets the current light model.
uint32_t getHeight() const
Definition: image.cpp:155
virtual ~LightRenderer()
Destructor.
RenderBackend * m_renderbackend
Definition: rendererbase.h:171
unsigned char uint8_t
Definition: core.h:38
const Rect & getViewPort() const
Gets the viewport for camera in pixel coordinates.
Definition: camera.cpp:299
ImagePtr getFrameByTimestamp(uint32_t timestamp)
Gets the frame image that matches the given timestamp.
Definition: animation.cpp:99
std::vector< LightRendererElementInfo * > getLightInfo(const std::string &group)
Base class for all view renderers View renderer renders one aspect of the view shown on screen...
Definition: rendererbase.h:78
virtual void render(Camera *cam, Layer *layer, RenderList &instances, RenderBackend *renderbackend)
LightRendererResizeInfo(RendererNode n, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst)
A basic layer on a map.
Definition: layer.h:98
double getZoom() const
Gets camera zoom.
Definition: camera.cpp:168
void addSimpleLight(const std::string &group, RendererNode n, uint8_t intensity, float radius, int32_t subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int32_t src=-1, int32_t dst=-1)
std::map< std::string, std::vector< LightRendererElementInfo * > > m_groups
static LightRenderer * getInstance(IRendererContainer *cnt)
Gets instance for interface access.
virtual void render(Camera *cam, Layer *layer, RenderList &instances, RenderBackend *renderbackend)
virtual void setEnabled(bool enabled)
Enables renderer.
uint32_t getWidth() const
Definition: image.cpp:146
LightRendererSimpleLightInfo(RendererNode n, uint8_t intensity, float radius, int32_t subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int32_t src, int32_t dst)
T y
The Y Coordinate.
Definition: rect.h:87
void addStencilTest(const std::string &group, uint8_t stencil_ref=0)
Time Manager.
Definition: timemanager.h:50
void resizeImage(const std::string &group, RendererNode n, ImagePtr image, int32_t width, int32_t height, int32_t src=-1, int32_t dst=-1)
void removeStencilTest(const std::string &group)
bool intersects(const RectType< T > &rect) const
Check whether two rectangles share some area.
Definition: rect.h:227
virtual void render(const Rect &rect, uint8_t alpha=255, uint8_t const *rgb=0)=0
Renders itself to the current render target (main screen or attached destination image) at the rectan...
std::vector< uint8_t > getColor()
uint32_t scaleTime(float multiplier, uint32_t ticks)
Utility function to calculate time scaling.
void addAnimation(const std::string &group, RendererNode n, AnimationPtr animation, int32_t src=-1, int32_t dst=-1)
void addImage(const std::string &group, RendererNode n, ImagePtr image, int32_t src=-1, int32_t dst=-1)
unsigned int uint32_t
Definition: core.h:40
virtual void drawLightPrimitive(const Point &p, uint8_t intensity, float radius, int32_t subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue)=0
Draws a light primitive that based on a triangle fan.
T w
Width of the rectangle.
Definition: rect.h:90
LightRenderer(RenderBackend *renderbackend, int32_t position)
constructor.