00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <SDL.h>
00024
00025
00026
00027
00028
00029
00030
00031 #include "video/renderbackend.h"
00032 #include "video/animation.h"
00033 #include "video/fonts/ifont.h"
00034 #include "video/imagemanager.h"
00035 #include "video/image.h"
00036 #include "video/opengl/glimage.h"
00037 #include "video/opengle/gleimage.h"
00038 #include "video/opengl/renderbackendopengl.h"
00039 #include "video/opengle/renderbackendopengle.h"
00040 #include "util/math/fife_math.h"
00041 #include "util/log/logger.h"
00042 #include "util/time/timemanager.h"
00043 #include "model/metamodel/grids/cellgrid.h"
00044 #include "model/metamodel/timeprovider.h"
00045 #include "model/structures/instance.h"
00046 #include "model/structures/layer.h"
00047 #include "model/structures/location.h"
00048
00049 #include "view/camera.h"
00050 #include "lightrenderer.h"
00051
00052
00053 namespace FIFE {
00054 static Logger _log(LM_VIEWVIEW);
00055
00056 LightRendererElementInfo::LightRendererElementInfo(RendererNode n, int32_t src, int32_t dst):
00057 m_anchor(n),
00058 m_src(src),
00059 m_dst(dst),
00060 m_stencil(false),
00061 m_stencil_ref(0) {
00062 }
00063 void LightRendererElementInfo::setStencil(uint8_t stencil_ref) {
00064 m_stencil = true;
00065 m_stencil_ref = stencil_ref;
00066 }
00067 int32_t LightRendererElementInfo::getStencil() {
00068 if(!m_stencil) {
00069 return -1;
00070 }
00071 return m_stencil_ref;
00072 }
00073 void LightRendererElementInfo::removeStencil() {
00074 m_stencil = false;
00075 m_stencil_ref = 0;
00076 }
00077 LightRendererImageInfo::LightRendererImageInfo(RendererNode anchor, ImagePtr image, int32_t src, int32_t dst):
00078 LightRendererElementInfo(anchor, src, dst),
00079 m_image(image){
00080 }
00081 void LightRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
00082 Point p = m_anchor.getCalculatedPoint(cam, layer);
00083 if(m_anchor.getLayer() == layer) {
00084 Rect r;
00085 Rect viewport = cam->getViewPort();
00086 uint32_t width = static_cast<uint32_t>(round(m_image->getWidth() * cam->getZoom()));
00087 uint32_t height = static_cast<uint32_t>(round(m_image->getHeight() * cam->getZoom()));
00088 r.x = p.x-width/2;
00089 r.y = p.y-height/2;
00090 r.w = width;
00091 r.h = height;
00092
00093 if(r.intersects(viewport)) {
00094 uint8_t lm = renderbackend->getLightingModel();
00095 m_image->render(r);
00096 if (m_stencil) {
00097 renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
00098 } else if (lm == 1) {
00099 renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
00100 }
00101 }
00102 }
00103 }
00104 LightRendererAnimationInfo::LightRendererAnimationInfo(RendererNode anchor, AnimationPtr animation, int32_t src, int32_t dst):
00105 LightRendererElementInfo(anchor, src, dst),
00106 m_animation(animation),
00107 m_start_time(TimeManager::instance()->getTime()),
00108 m_time_scale(1.0){
00109 }
00110 void LightRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
00111 Point p = m_anchor.getCalculatedPoint(cam, layer);
00112 if(m_anchor.getLayer() == layer) {
00113 int32_t animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % m_animation->getDuration();
00114 ImagePtr img = m_animation->getFrameByTimestamp(animtime);
00115 Rect r;
00116 Rect viewport = cam->getViewPort();
00117 uint32_t width = static_cast<uint32_t>(round(img->getWidth() * cam->getZoom()));
00118 uint32_t height = static_cast<uint32_t>(round(img->getHeight() * cam->getZoom()));
00119 r.x = p.x-width/2;
00120 r.y = p.y-height/2;
00121 r.w = width;
00122 r.h = height;
00123
00124 if(r.intersects(viewport)) {
00125 uint8_t lm = renderbackend->getLightingModel();
00126 img->render(r);
00127 if (m_stencil) {
00128 renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
00129 } else if (lm == 1) {
00130 renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
00131 }
00132 }
00133 }
00134 }
00135 LightRendererResizeInfo::LightRendererResizeInfo(RendererNode anchor, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst):
00136 LightRendererElementInfo(anchor, src, dst),
00137 m_image(image),
00138 m_width(width),
00139 m_height(height) {
00140 }
00141 void LightRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
00142 Point p = m_anchor.getCalculatedPoint(cam, layer);
00143 if(m_anchor.getLayer() == layer) {
00144 Rect r;
00145 Rect viewport = cam->getViewPort();
00146 uint32_t width = static_cast<uint32_t>(round(m_width * cam->getZoom()));
00147 uint32_t height = static_cast<uint32_t>(round(m_height * cam->getZoom()));
00148 r.x = p.x-width/2;
00149 r.y = p.y-height/2;
00150 r.w = width;
00151 r.h = height;
00152
00153 if(r.intersects(viewport)) {
00154 uint8_t lm = renderbackend->getLightingModel();
00155 m_image->render(r);
00156 if (m_stencil) {
00157 renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
00158 } else if (lm == 1) {
00159 renderbackend->changeRenderInfos(1, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
00160 }
00161 }
00162 }
00163 }
00164 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):
00165 LightRendererElementInfo(anchor, src, dst),
00166 m_intensity(intensity),
00167 m_radius(radius),
00168 m_subdivisions(subdivisions),
00169 m_xstretch(xstretch),
00170 m_ystretch(ystretch),
00171 m_red(r),
00172 m_green(g),
00173 m_blue(b){
00174 }
00175 void LightRendererSimpleLightInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend) {
00176 Point p = m_anchor.getCalculatedPoint(cam, layer);
00177 if(m_anchor.getLayer() == layer) {
00178 double zoom = cam->getZoom();
00179
00180 uint8_t lm = renderbackend->getLightingModel();
00181 renderbackend->drawLightPrimitive(p, m_intensity, m_radius, m_subdivisions,
00182 static_cast<float>(m_xstretch * zoom), static_cast<float>(m_ystretch * zoom),
00183 m_red, m_green, m_blue);
00184
00185 if (m_stencil) {
00186 renderbackend->changeRenderInfos(m_subdivisions, m_src, m_dst, false, true, m_stencil_ref, INCR, GEQUAL);
00187 } else if (lm == 1) {
00188 renderbackend->changeRenderInfos(m_subdivisions, m_src, m_dst, false, true, 255, KEEP, NOTEQUAL);
00189 }
00190 }
00191 }
00192 std::vector<uint8_t> LightRendererSimpleLightInfo::getColor() {
00193 std::vector<uint8_t> colors;
00194 colors.push_back(m_red);
00195 colors.push_back(m_green);
00196 colors.push_back(m_blue);
00197 colors.push_back(m_intensity);
00198 return colors;
00199 }
00200 LightRenderer* LightRenderer::getInstance(IRendererContainer* cnt) {
00201 return dynamic_cast<LightRenderer*>(cnt->getRenderer("LightRenderer"));
00202 }
00203 LightRenderer::LightRenderer(RenderBackend* renderbackend, int32_t position):
00204 RendererBase(renderbackend, position),
00205 m_groups() {
00206 setEnabled(false);
00207 }
00208 LightRenderer::LightRenderer(const LightRenderer& old):
00209 RendererBase(old),
00210 m_groups() {
00211 setEnabled(false);
00212 }
00213 RendererBase* LightRenderer::clone() {
00214 return new LightRenderer(*this);
00215 }
00216 LightRenderer::~LightRenderer() {
00217 }
00218
00219 void LightRenderer::addImage(const std::string &group, RendererNode n, ImagePtr image, int32_t src, int32_t dst) {
00220 LightRendererElementInfo* info = new LightRendererImageInfo(n, image, src, dst);
00221 m_groups[group].push_back(info);
00222 }
00223
00224 void LightRenderer::addAnimation(const std::string &group, RendererNode n, AnimationPtr animation, int32_t src, int32_t dst) {
00225 LightRendererElementInfo* info = new LightRendererAnimationInfo(n, animation, src, dst);
00226 m_groups[group].push_back(info);
00227 }
00228
00229 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) {
00230 LightRendererElementInfo* info = new LightRendererSimpleLightInfo(n, intensity, radius, subdivisions, xstretch, ystretch, r, g, b, src, dst);
00231 m_groups[group].push_back(info);
00232 }
00233
00234 void LightRenderer::resizeImage(const std::string &group, RendererNode n, ImagePtr image, int32_t width, int32_t height, int32_t src, int32_t dst) {
00235 LightRendererElementInfo* info = new LightRendererResizeInfo(n, image, width, height, src, dst);
00236 m_groups[group].push_back(info);
00237 }
00238
00239 void LightRenderer::addStencilTest(const std::string &group, uint8_t stencil_ref) {
00240 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
00241 for (;info_it != m_groups[group].end(); ++info_it) {
00242 (*info_it)->setStencil(stencil_ref);
00243 }
00244 }
00245
00246 void LightRenderer::removeStencilTest(const std::string &group) {
00247 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
00248 for (;info_it != m_groups[group].end(); ++info_it) {
00249 (*info_it)->removeStencil();
00250 }
00251 }
00252
00253 std::list<std::string> LightRenderer::getGroups() {
00254 std::list<std::string> groups;
00255 std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
00256 for(; group_it != m_groups.end(); ++group_it) {
00257 groups.push_back(group_it->first);
00258 }
00259 groups.sort();
00260 groups.unique();
00261 return groups;
00262 }
00263
00264 std::vector<LightRendererElementInfo*> LightRenderer::getLightInfo(const std::string &group) {
00265 std::vector<LightRendererElementInfo*> info;
00266 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
00267 for (;info_it != m_groups[group].end(); ++info_it) {
00268 info.push_back(*info_it);
00269 }
00270 return info;
00271 }
00272
00273 void LightRenderer::removeAll(const std::string &group) {
00274 std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
00275 for (;info_it != m_groups[group].end(); ++info_it) {
00276 delete *info_it;
00277 }
00278 m_groups[group].clear();
00279 m_groups.erase(group);
00280 }
00281
00282 void LightRenderer::removeAll() {
00283 m_groups.clear();
00284 }
00285
00286 void LightRenderer::reset() {
00287 removeAll();
00288 }
00289
00290 void LightRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
00291 uint8_t lm = m_renderbackend->getLightingModel();
00292
00293 if (!layer->areInstancesVisible()) {
00294 return;
00295 }
00296
00297 std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
00298 for (; group_it != m_groups.end(); ++group_it) {
00299 std::vector<LightRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
00300 for (;info_it != group_it->second.end(); ++info_it) {
00301 if (lm != 0) {
00302 if ((*info_it)->getStencil() != -1 && (*info_it)->getStencil() < 255) {
00303 if(info_it != group_it->second.begin()) {
00304 (*info_it)->setStencil((*info_it)->getStencil()+1);
00305 }
00306 }
00307 }
00308 (*info_it)->render(cam, layer, instances, m_renderbackend);
00309 }
00310 }
00311 }
00312
00313 }