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"
38 #include "video/opengl/renderbackendopengl.h"
39 #include "video/opengle/renderbackendopengle.h"
40 #include "util/math/fife_math.h"
41 #include "util/log/logger.h"
42 #include "util/time/timemanager.h"
43 #include "model/metamodel/grids/cellgrid.h"
44 #include "model/metamodel/timeprovider.h"
45 #include "model/structures/instance.h"
46 #include "model/structures/layer.h"
47 #include "model/structures/location.h"
49 #include "view/camera.h"
50 #include "lightrenderer.h"
54 static Logger _log(LM_VIEWVIEW);
56 LightRendererElementInfo::LightRendererElementInfo(RendererNode n, int32_t src, int32_t dst):
63 void LightRendererElementInfo::setStencil(uint8_t stencil_ref) {
65 m_stencil_ref = stencil_ref;
67 int32_t LightRendererElementInfo::getStencil() {
73 void LightRendererElementInfo::removeStencil() {
77 LightRendererImageInfo::LightRendererImageInfo(RendererNode anchor, ImagePtr image, int32_t src, int32_t dst):
78 LightRendererElementInfo(anchor, src, dst),
81 void LightRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
82 Point p = m_anchor.getCalculatedPoint(cam, layer);
83 if(m_anchor.getLayer() == layer) {
85 Rect viewport = cam->getViewPort();
86 uint32_t width =
static_cast<uint32_t
>(round(m_image->getWidth() * cam->getZoom()));
87 uint32_t height =
static_cast<uint32_t
>(round(m_image->getHeight() * cam->getZoom()));
93 if(r.intersects(viewport)) {
94 uint8_t lm = renderbackend->getLightingModel();
97 renderbackend->changeRenderInfos(1, m_src, m_dst,
false,
true, m_stencil_ref, INCR, GEQUAL);
99 renderbackend->changeRenderInfos(1, m_src, m_dst,
false,
true, 255, KEEP, NOTEQUAL);
104 LightRendererAnimationInfo::LightRendererAnimationInfo(RendererNode anchor, AnimationPtr animation, int32_t src, int32_t dst):
105 LightRendererElementInfo(anchor, src, dst),
106 m_animation(animation),
107 m_start_time(TimeManager::instance()->getTime()),
110 void LightRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
111 Point p = m_anchor.getCalculatedPoint(cam, layer);
112 if(m_anchor.getLayer() == layer) {
113 int32_t animtime =
scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % m_animation->getDuration();
114 ImagePtr img = m_animation->getFrameByTimestamp(animtime);
116 Rect viewport = cam->getViewPort();
117 uint32_t width =
static_cast<uint32_t
>(round(img->getWidth() * cam->getZoom()));
118 uint32_t height =
static_cast<uint32_t
>(round(img->getHeight() * cam->getZoom()));
124 if(r.intersects(viewport)) {
125 uint8_t lm = renderbackend->getLightingModel();
128 renderbackend->changeRenderInfos(1, m_src, m_dst,
false,
true, m_stencil_ref, INCR, GEQUAL);
129 }
else if (lm == 1) {
130 renderbackend->changeRenderInfos(1, m_src, m_dst,
false,
true, 255, KEEP, NOTEQUAL);
135 LightRendererResizeInfo::LightRendererResizeInfo(RendererNode anchor, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst):
136 LightRendererElementInfo(anchor, src, dst),
141 void LightRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
142 Point p = m_anchor.getCalculatedPoint(cam, layer);
143 if(m_anchor.getLayer() == layer) {
145 Rect viewport = cam->getViewPort();
146 uint32_t width =
static_cast<uint32_t
>(round(m_width * cam->getZoom()));
147 uint32_t height =
static_cast<uint32_t
>(round(m_height * cam->getZoom()));
153 if(r.intersects(viewport)) {
154 uint8_t lm = renderbackend->getLightingModel();
157 renderbackend->changeRenderInfos(1, m_src, m_dst,
false,
true, m_stencil_ref, INCR, GEQUAL);
158 }
else if (lm == 1) {
159 renderbackend->changeRenderInfos(1, m_src, m_dst,
false,
true, 255, KEEP, NOTEQUAL);
164 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):
165 LightRendererElementInfo(anchor, src, dst),
166 m_intensity(intensity),
168 m_subdivisions(subdivisions),
169 m_xstretch(xstretch),
170 m_ystretch(ystretch),
175 void LightRendererSimpleLightInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
176 Point p = m_anchor.getCalculatedPoint(cam, layer);
177 if(m_anchor.getLayer() == layer) {
178 double zoom = cam->getZoom();
180 uint8_t lm = renderbackend->getLightingModel();
181 renderbackend->drawLightPrimitive(p, m_intensity, m_radius, m_subdivisions,
182 static_cast<float>(m_xstretch * zoom), static_cast<float>(m_ystretch * zoom),
183 m_red, m_green, m_blue);
186 renderbackend->changeRenderInfos(m_subdivisions, m_src, m_dst,
false,
true, m_stencil_ref, INCR, GEQUAL);
187 }
else if (lm == 1) {
188 renderbackend->changeRenderInfos(m_subdivisions, m_src, m_dst,
false,
true, 255, KEEP, NOTEQUAL);
192 std::vector<uint8_t> LightRendererSimpleLightInfo::getColor() {
193 std::vector<uint8_t> colors;
194 colors.push_back(m_red);
195 colors.push_back(m_green);
196 colors.push_back(m_blue);
197 colors.push_back(m_intensity);
200 LightRenderer* LightRenderer::getInstance(IRendererContainer* cnt) {
201 return dynamic_cast<LightRenderer*
>(cnt->getRenderer(
"LightRenderer"));
203 LightRenderer::LightRenderer(RenderBackend* renderbackend, int32_t position):
204 RendererBase(renderbackend, position),
208 LightRenderer::LightRenderer(
const LightRenderer& old):
213 RendererBase* LightRenderer::clone() {
214 return new LightRenderer(*
this);
216 LightRenderer::~LightRenderer() {
219 void LightRenderer::addImage(
const std::string &group, RendererNode n, ImagePtr image, int32_t src, int32_t dst) {
220 LightRendererElementInfo* info =
new LightRendererImageInfo(n, image, src, dst);
221 m_groups[group].push_back(info);
224 void LightRenderer::addAnimation(
const std::string &group, RendererNode n, AnimationPtr animation, int32_t src, int32_t dst) {
225 LightRendererElementInfo* info =
new LightRendererAnimationInfo(n, animation, src, dst);
226 m_groups[group].push_back(info);
229 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) {
230 LightRendererElementInfo* info =
new LightRendererSimpleLightInfo(n, intensity, radius, subdivisions, xstretch, ystretch, r, g, b, src, dst);
231 m_groups[group].push_back(info);
234 void LightRenderer::resizeImage(
const std::string &group, RendererNode n, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst) {
235 LightRendererElementInfo* info =
new LightRendererResizeInfo(n, image, width, height, src, dst);
236 m_groups[group].push_back(info);
239 void LightRenderer::addStencilTest(
const std::string &group, uint8_t stencil_ref) {
240 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
241 for (;info_it != m_groups[group].end(); ++info_it) {
242 (*info_it)->setStencil(stencil_ref);
246 void LightRenderer::removeStencilTest(
const std::string &group) {
247 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
248 for (;info_it != m_groups[group].end(); ++info_it) {
249 (*info_it)->removeStencil();
253 std::list<std::string> LightRenderer::getGroups() {
254 std::list<std::string> groups;
255 std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
256 for(; group_it != m_groups.end(); ++group_it) {
257 groups.push_back(group_it->first);
264 std::vector<LightRendererElementInfo*> LightRenderer::getLightInfo(
const std::string &group) {
265 std::vector<LightRendererElementInfo*> info;
266 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
267 for (;info_it != m_groups[group].end(); ++info_it) {
268 info.push_back(*info_it);
273 void LightRenderer::removeAll(
const std::string &group) {
274 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
275 for (;info_it != m_groups[group].end(); ++info_it) {
278 m_groups[group].clear();
279 m_groups.erase(group);
282 void LightRenderer::removeAll() {
286 void LightRenderer::reset() {
290 void LightRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
291 uint8_t lm = m_renderbackend->getLightingModel();
293 if (!layer->areInstancesVisible()) {
297 std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
298 for (; group_it != m_groups.end(); ++group_it) {
299 std::vector<LightRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
300 for (;info_it != group_it->second.end(); ++info_it) {
302 if ((*info_it)->getStencil() != -1 && (*info_it)->getStencil() < 255) {
303 if(info_it != group_it->second.begin()) {
304 (*info_it)->setStencil((*info_it)->getStencil()+1);
308 (*info_it)->render(cam, layer, instances, m_renderbackend);
virtual void setEnabled(bool enabled)
uint32_t scaleTime(float multiplier, uint32_t ticks)