FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
lightrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2019 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"
38 #include "util/math/fife_math.h"
39 #include "util/log/logger.h"
40 #include "util/time/timemanager.h"
44 #include "model/structures/layer.h"
46 
47 #include "view/camera.h"
48 #include "lightrenderer.h"
49 
50 
51 namespace FIFE {
55  static Logger _log(LM_VIEWVIEW);
56 
58  m_anchor(n),
59  m_src(src),
60  m_dst(dst),
61  m_stencil(false),
62  m_stencil_ref(0) {
63  }
65  m_stencil = true;
66  m_stencil_ref = stencil_ref;
67  }
69  if(!m_stencil) {
70  return -1;
71  }
72  return m_stencil_ref;
73  }
75  m_stencil = false;
76  m_stencil_ref = 0;
77  }
78  LightRendererImageInfo::LightRendererImageInfo(RendererNode anchor, ImagePtr image, int32_t src, int32_t dst):
79  LightRendererElementInfo(anchor, src, dst),
80  m_image(image){
81  }
82  void LightRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
83  Point p = m_anchor.getCalculatedPoint(cam, layer, true);
84  if(m_anchor.getLayer() == layer) {
85  Rect r;
86  Rect viewport = cam->getViewPort();
87  uint32_t width = static_cast<uint32_t>(round(m_image->getWidth() * cam->getZoom()));
88  uint32_t height = static_cast<uint32_t>(round(m_image->getHeight() * cam->getZoom()));
89  r.x = p.x-width/2;
90  r.y = p.y-height/2;
91  r.w = width;
92  r.h = height;
93 
94  if(r.intersects(viewport)) {
95  uint8_t lm = renderbackend->getLightingModel();
96  m_image->render(r);
97  if (m_stencil) {
98  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
99  } else if (lm == 1) {
100  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
101  }
102  }
103  }
104  }
106  LightRendererElementInfo(anchor, src, dst),
107  m_animation(animation),
108  m_start_time(TimeManager::instance()->getTime()),
109  m_time_scale(1.0){
110  }
111  void LightRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
112  Point p = m_anchor.getCalculatedPoint(cam, layer, true);
113  if(m_anchor.getLayer() == layer) {
114  int32_t animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % m_animation->getDuration();
115  ImagePtr img = m_animation->getFrameByTimestamp(animtime);
116  Rect r;
117  Rect viewport = cam->getViewPort();
118  uint32_t width = static_cast<uint32_t>(round(img->getWidth() * cam->getZoom()));
119  uint32_t height = static_cast<uint32_t>(round(img->getHeight() * cam->getZoom()));
120  r.x = p.x-width/2;
121  r.y = p.y-height/2;
122  r.w = width;
123  r.h = height;
124 
125  if(r.intersects(viewport)) {
126  uint8_t lm = renderbackend->getLightingModel();
127  img->render(r);
128  if (m_stencil) {
129  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
130  } else if (lm == 1) {
131  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
132  }
133  }
134  }
135  }
136  LightRendererResizeInfo::LightRendererResizeInfo(RendererNode anchor, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst):
137  LightRendererElementInfo(anchor, src, dst),
138  m_image(image),
139  m_width(width),
140  m_height(height) {
141  }
142  void LightRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
143  Point p = m_anchor.getCalculatedPoint(cam, layer, true);
144  if(m_anchor.getLayer() == layer) {
145  Rect r;
146  Rect viewport = cam->getViewPort();
147  uint32_t width = static_cast<uint32_t>(round(m_width * cam->getZoom()));
148  uint32_t height = static_cast<uint32_t>(round(m_height * cam->getZoom()));
149  r.x = p.x-width/2;
150  r.y = p.y-height/2;
151  r.w = width;
152  r.h = height;
153 
154  if(r.intersects(viewport)) {
155  uint8_t lm = renderbackend->getLightingModel();
156  m_image->render(r);
157  if (m_stencil) {
158  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
159  } else if (lm == 1) {
160  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
161  }
162  }
163  }
164  }
165  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):
166  LightRendererElementInfo(anchor, src, dst),
167  m_intensity(intensity),
168  m_radius(radius),
169  m_subdivisions(subdivisions),
170  m_xstretch(xstretch),
171  m_ystretch(ystretch),
172  m_red(r),
173  m_green(g),
174  m_blue(b){
175  }
176  void LightRendererSimpleLightInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
177  Point p = m_anchor.getCalculatedPoint(cam, layer, true);
178  if(m_anchor.getLayer() == layer) {
179  double zoom = cam->getZoom();
180 
181  uint8_t lm = renderbackend->getLightingModel();
183  static_cast<float>(m_xstretch * zoom), static_cast<float>(m_ystretch * zoom),
184  m_red, m_green, m_blue);
185 
186  if (m_stencil) {
187  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
188  } else if (lm == 1) {
189  renderbackend->changeRenderInfos(RENDER_DATA_WITHOUT_Z, 1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
190  }
191  }
192  }
193  std::vector<uint8_t> LightRendererSimpleLightInfo::getColor() {
194  std::vector<uint8_t> colors;
195  colors.push_back(m_red);
196  colors.push_back(m_green);
197  colors.push_back(m_blue);
198  colors.push_back(m_intensity);
199  return colors;
200  }
202  return dynamic_cast<LightRenderer*>(cnt->getRenderer("LightRenderer"));
203  }
204  LightRenderer::LightRenderer(RenderBackend* renderbackend, int32_t position):
205  RendererBase(renderbackend, position),
206  m_groups() {
207  setEnabled(false);
208  }
210  RendererBase(old),
211  m_groups() {
212  setEnabled(false);
213  }
215  return new LightRenderer(*this);
216  }
218  }
219  // Add a static lightmap
220  void LightRenderer::addImage(const std::string &group, RendererNode n, ImagePtr image, int32_t src, int32_t dst) {
221  LightRendererElementInfo* info = new LightRendererImageInfo(n, image, src, dst);
222  m_groups[group].push_back(info);
223  }
224  // Add a animation lightmap
225  void LightRenderer::addAnimation(const std::string &group, RendererNode n, AnimationPtr animation, int32_t src, int32_t dst) {
226  LightRendererElementInfo* info = new LightRendererAnimationInfo(n, animation, src, dst);
227  m_groups[group].push_back(info);
228  }
229  // Add a simple light
230  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) {
231  LightRendererElementInfo* info = new LightRendererSimpleLightInfo(n, intensity, radius, subdivisions, xstretch, ystretch, r, g, b, src, dst);
232  m_groups[group].push_back(info);
233  }
234  // Resize an Image
235  void LightRenderer::resizeImage(const std::string &group, RendererNode n, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst) {
236  LightRendererElementInfo* info = new LightRendererResizeInfo(n, image, width, height, src, dst);
237  m_groups[group].push_back(info);
238  }
239  // Enable stencil test for the group
240  void LightRenderer::addStencilTest(const std::string &group, uint8_t stencil_ref) {
241  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
242  for (;info_it != m_groups[group].end(); ++info_it) {
243  (*info_it)->setStencil(stencil_ref);
244  }
245  }
246  // Disable stencil test for the group
247  void LightRenderer::removeStencilTest(const std::string &group) {
248  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
249  for (;info_it != m_groups[group].end(); ++info_it) {
250  (*info_it)->removeStencil();
251  }
252  }
253  // Return a list of all groups
254  std::list<std::string> LightRenderer::getGroups() {
255  std::list<std::string> groups;
256  std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
257  for(; group_it != m_groups.end(); ++group_it) {
258  groups.push_back(group_it->first);
259  }
260  groups.sort();
261  groups.unique();
262  return groups;
263  }
264  // Return a vector of all LightElementInfos
265  std::vector<LightRendererElementInfo*> LightRenderer::getLightInfo(const std::string &group) {
266  std::vector<LightRendererElementInfo*> info;
267  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
268  for (;info_it != m_groups[group].end(); ++info_it) {
269  info.push_back(*info_it);
270  }
271  return info;
272  }
273  // Remove the group
274  void LightRenderer::removeAll(const std::string &group) {
275  std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
276  for (;info_it != m_groups[group].end(); ++info_it) {
277  delete *info_it;
278  }
279  m_groups[group].clear();
280  m_groups.erase(group);
281  }
282  // Remove all groups
284  std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator it = m_groups.begin();
285  for (; it != m_groups.end(); ++it) {
286  std::vector<LightRendererElementInfo*>::const_iterator info_it = it->second.begin();
287  for (;info_it != it->second.end(); ++info_it) {
288  delete *info_it;
289  }
290  }
291  m_groups.clear();
292  }
293  // Clear all groups
295  removeAll();
296  }
297  // Render
298  void LightRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
300 
301  if (!layer->areInstancesVisible()) {
302  return;
303  }
304 
305  std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
306  for (; group_it != m_groups.end(); ++group_it) {
307  std::vector<LightRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
308  for (;info_it != group_it->second.end(); ++info_it) {
309  if (lm != 0) {
310  if ((*info_it)->getStencil() != -1 && (*info_it)->getStencil() < 255) {
311  if(info_it != group_it->second.begin()) {
312  (*info_it)->setStencil((*info_it)->getStencil()+1);
313  }
314  }
315  }
316  (*info_it)->render(cam, layer, instances, m_renderbackend);
317  }
318  }
319  }
320 
321 }
Abstract interface for all the renderbackends.
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:130
void setStencil(uint8_t stencil_ref)
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)
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)
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:59
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.
bool intersects(const RectType< T > &rect) const
Check whether two rectangles share some area.
Definition: rect.h:227
virtual ~LightRenderer()
Destructor.
RenderBackend * m_renderbackend
Definition: rendererbase.h:171
unsigned char uint8_t
Definition: core.h:38
virtual void changeRenderInfos(RenderDataType type, uint16_t elements, int32_t src, int32_t dst, bool light, bool stentest, uint8_t stenref, GLConstants stenop, GLConstants stenfunc, OverlayType otype=OVERLAY_TYPE_NONE)=0
Dirty helper function to change the render infos.
ImagePtr getFrameByTimestamp(uint32_t timestamp)
Gets the frame image that matches the given timestamp.
Definition: animation.cpp:150
uint32_t getHeight() const
Definition: image.cpp:160
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:99
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)
bool areInstancesVisible() const
Check object visibility.
Definition: layer.cpp:458
virtual void setEnabled(bool enabled)
Enables renderer.
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)
double getZoom() const
Gets camera zoom.
Definition: camera.cpp:188
const Rect & getViewPort() const
Gets the viewport for camera in pixel coordinates.
Definition: camera.cpp:289
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)
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.
uint32_t getDuration() const
Gets the total duration for the whole animation.
Definition: animation.h:138
T w
Width of the rectangle.
Definition: rect.h:90
uint32_t getWidth() const
Definition: image.cpp:151
LightRenderer(RenderBackend *renderbackend, int32_t position)
constructor.