FIFE  2008.0
genericrenderer.cpp
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 
00024 // 3rd party library includes
00025 
00026 // FIFE includes
00027 // These includes are split up in two parts, separated by one empty line
00028 // First block: files included from the FIFE root src directory
00029 // Second block: files included from the same folder
00030 #include "video/renderbackend.h"
00031 #include "video/imagepool.h"
00032 #include "video/animation.h"
00033 #include "video/animationpool.h"
00034 #include "video/fonts/abstractfont.h"
00035 #include "video/image.h"
00036 #include "util/math/fife_math.h"
00037 #include "util/log/logger.h"
00038 #include "util/time/timemanager.h"
00039 #include "model/metamodel/grids/cellgrid.h"
00040 #include "model/metamodel/timeprovider.h"
00041 #include "model/structures/instance.h"
00042 #include "model/structures/layer.h"
00043 #include "model/structures/location.h"
00044 
00045 #include "view/camera.h"
00046 #include "genericrenderer.h"
00047 
00048 
00049 namespace FIFE {
00050     static Logger _log(LM_VIEWVIEW);
00051 
00052     GenericRendererNode::GenericRendererNode(Instance* attached_instance, const Location &relative_location, Layer* relative_layer, const Point &relative_point):
00053         m_instance(attached_instance),
00054         m_location(relative_location),
00055         m_layer(relative_layer),
00056         m_point(relative_point) {
00057     }
00058     GenericRendererNode::GenericRendererNode(Instance* attached_instance, const Location &relative_location, const Point &relative_point):
00059         m_instance(attached_instance),
00060         m_location(relative_location),
00061         m_layer(NULL),
00062         m_point(relative_point) {
00063     }
00064     GenericRendererNode::GenericRendererNode(Instance* attached_instance, Layer* relative_layer, const Point &relative_point):
00065         m_instance(attached_instance),
00066         m_location(NULL),
00067         m_layer(relative_layer),
00068         m_point(relative_point) {
00069     }
00070     GenericRendererNode::GenericRendererNode(Instance* attached_instance, const Point &relative_point):
00071         m_instance(attached_instance),
00072         m_location(NULL),
00073         m_layer(NULL),
00074         m_point(relative_point) {
00075     }
00076     GenericRendererNode::GenericRendererNode(const Location &attached_location, Layer* relative_layer, const Point &relative_point):
00077         m_instance(NULL),
00078         m_location(attached_location),
00079         m_layer(relative_layer),
00080         m_point(relative_point) {
00081     }
00082     GenericRendererNode::GenericRendererNode(const Location &attached_location, const Point &relative_point):
00083         m_instance(NULL),
00084         m_location(attached_location),
00085         m_layer(NULL),
00086         m_point(relative_point) {
00087     }
00088     GenericRendererNode::GenericRendererNode(Layer* attached_layer, const Point &relative_point):
00089         m_instance(NULL),
00090         m_location(NULL),
00091         m_layer(attached_layer),
00092         m_point(relative_point) {
00093     }
00094     GenericRendererNode::GenericRendererNode(const Point &attached_point):
00095         m_instance(NULL),
00096         m_location(NULL),
00097         m_layer(NULL),
00098         m_point(attached_point) {
00099     }
00100     GenericRendererNode::~GenericRendererNode() {
00101     }
00102 
00103     void GenericRendererNode::setAttached(Instance* attached_instance, const Location &relative_location, const Point &relative_point) {
00104         m_instance = attached_instance;
00105         m_location = relative_location;
00106         m_point = relative_point;
00107     }
00108     void GenericRendererNode::setAttached(Instance* attached_instance, const Location &relative_location) {
00109         m_instance = attached_instance;
00110         m_location = relative_location;
00111     }
00112     void GenericRendererNode::setAttached(Instance* attached_instance, const Point &relative_point) {
00113         m_instance = attached_instance;
00114         m_point = relative_point;
00115     }
00116     void GenericRendererNode::setAttached(Instance* attached_instance) {
00117         m_instance = attached_instance;
00118     }
00119     void GenericRendererNode::setAttached(const Location &attached_location, const Point &relative_point) {
00120         m_instance = NULL;
00121         m_location = attached_location;
00122         m_point = relative_point;
00123     }
00124     void GenericRendererNode::setAttached(const Location &attached_location) {
00125         m_instance = NULL;
00126         m_location = attached_location;
00127     }
00128     void GenericRendererNode::setAttached(Layer* attached_layer) {
00129         m_layer = attached_layer;
00130     }
00131     void GenericRendererNode::setAttached(const Point &attached_point) {
00132         m_instance = NULL;
00133         m_location = NULL;
00134         m_point = attached_point;
00135     }
00136 
00137     void GenericRendererNode::setRelative(const Location &relative_location) {
00138         if(m_instance == NULL) {
00139             throw NotSupported("No instance attached.");
00140         }
00141         m_location = relative_location;
00142     }
00143     void GenericRendererNode::setRelative(const Location &relative_location, Point relative_point) {
00144         if(m_instance == NULL) {
00145             throw NotSupported("No instance attached.");
00146         }
00147         m_location = relative_location;
00148         m_point = relative_point;
00149     }
00150     void GenericRendererNode::setRelative(const Point &relative_point) {
00151         if(m_instance == NULL || m_location == NULL) {
00152             throw NotSupported("No instance or location attached.");
00153         }
00154         m_point = relative_point;
00155     }
00156 
00157     Instance* GenericRendererNode::getAttachedInstance() {
00158         if(m_instance == NULL) {
00159             throw NotSupported("No instance attached.");
00160         }
00161         return m_instance;
00162     }
00163     Location GenericRendererNode::getAttachedLocation() {
00164         if(m_instance != NULL || m_location == NULL) {
00165             throw NotSupported("No location attached.");
00166         }
00167         return m_location;
00168     }
00169     Layer* GenericRendererNode::getAttachedLayer() {
00170         if(m_layer == NULL) {
00171             throw NotSupported("No layer attached.");
00172         }
00173         return m_layer;
00174     }
00175     Point GenericRendererNode::getAttachedPoint() {
00176         if(m_instance != NULL || m_location != NULL) {
00177             throw NotSupported("No point attached.");
00178         }
00179         return m_point;
00180     }
00181 
00182     Location GenericRendererNode::getOffsetLocation() {
00183         if(m_instance == NULL || m_location == NULL) {
00184             throw NotSupported("No location as offset used.");
00185         }
00186         return m_location;
00187     }
00188     Point GenericRendererNode::getOffsetPoint() {
00189         if(m_instance == NULL && m_location == NULL) {
00190             throw NotSupported("No point as offset used.");
00191         }
00192         return m_point;
00193     }
00194 
00195     Instance* GenericRendererNode::getInstance() {
00196         return m_instance;
00197     }
00198     Location GenericRendererNode::getLocation() {
00199         return m_location;
00200     }
00201     Layer* GenericRendererNode::getLayer() {
00202         return m_layer;
00203     }
00204     Point GenericRendererNode::getPoint() {
00205         return m_point;
00206     }
00207 
00208     Point GenericRendererNode::getCalculatedPoint(Camera* cam, Layer* layer) {
00209         ScreenPoint p;
00210         if(m_instance != NULL) {
00211             if(m_layer == NULL) {
00212                 m_layer = m_instance->getLocation().getLayer();
00213             }
00214             if(m_location != NULL) {
00215                 p = cam->toScreenCoordinates(m_instance->getLocationRef().getMapCoordinates() + m_location.getMapCoordinates());
00216             } else {
00217                 p = cam->toScreenCoordinates(m_instance->getLocation().getMapCoordinates());
00218             }
00219         } else if(m_location != NULL) {
00220             if(m_layer == NULL) {
00221                 m_layer = m_location.getLayer();
00222             }
00223             p = cam->toScreenCoordinates(m_location.getMapCoordinates());
00224         } else if(m_layer == NULL) {
00225             const std::list<Layer*>& layers = cam->getRenderer("GenericRenderer")->getActiveLayers();
00226             std::list<Layer*>::const_reverse_iterator layer_it = layers.rbegin();
00227             setAttached(*layer_it);
00228         }
00229         return Point(m_point.x + p.x, m_point.y + p.y);
00230     }
00231 
00232     GenericRendererLineInfo::GenericRendererLineInfo(GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
00233         GenericRendererElementInfo(),
00234         m_edge1(n1),
00235         m_edge2(n2),
00236         m_red(r),
00237         m_green(g),
00238         m_blue(b),
00239         m_alpha(a) {
00240     }
00241     void GenericRendererLineInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00242         Point p1 = m_edge1.getCalculatedPoint(cam, layer);
00243         Point p2 = m_edge2.getCalculatedPoint(cam, layer);
00244         if(m_edge1.getLayer() == layer) {
00245             renderbackend->drawLine(p1, p2, m_red, m_green, m_blue, m_alpha);
00246         }
00247     }
00248 
00249     GenericRendererPointInfo::GenericRendererPointInfo(GenericRendererNode anchor, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
00250         GenericRendererElementInfo(),
00251         m_anchor(anchor),
00252         m_red(r),
00253         m_green(g),
00254         m_blue(b),
00255         m_alpha(a) {
00256     }
00257     void GenericRendererPointInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00258         Point p = m_anchor.getCalculatedPoint(cam, layer);
00259         if(m_anchor.getLayer() == layer) {
00260             renderbackend->putPixel(p.x, p.y, m_red, m_green, m_blue, m_alpha);
00261         }
00262     }
00263 
00264     GenericRendererTriangleInfo::GenericRendererTriangleInfo(GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
00265         GenericRendererElementInfo(),
00266         m_edge1(n1),
00267         m_edge2(n2),
00268         m_edge3(n3),
00269         m_red(r),
00270         m_green(g),
00271         m_blue(b),
00272         m_alpha(a) {
00273     }
00274     void GenericRendererTriangleInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00275         Point p1 = m_edge1.getCalculatedPoint(cam, layer);
00276         Point p2 = m_edge2.getCalculatedPoint(cam, layer);
00277         Point p3 = m_edge3.getCalculatedPoint(cam, layer);
00278         if(m_edge1.getLayer() == layer) {
00279             renderbackend->drawTriangle(p1, p2, p3, m_red, m_green, m_blue, m_alpha);
00280         }
00281     }
00282 
00283     GenericRendererQuadInfo::GenericRendererQuadInfo(GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, GenericRendererNode n4, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
00284         GenericRendererElementInfo(),
00285         m_edge1(n1),
00286         m_edge2(n2),
00287         m_edge3(n3),
00288         m_edge4(n4),
00289         m_red(r),
00290         m_green(g),
00291         m_blue(b),
00292         m_alpha(a) {
00293     }
00294     void GenericRendererQuadInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00295         Point p1 = m_edge1.getCalculatedPoint(cam, layer);
00296         Point p2 = m_edge2.getCalculatedPoint(cam, layer);
00297         Point p3 = m_edge3.getCalculatedPoint(cam, layer);
00298         Point p4 = m_edge4.getCalculatedPoint(cam, layer);
00299         if(m_edge1.getLayer() == layer) {
00300             renderbackend->drawQuad(p1, p2, p3, p4, m_red, m_green, m_blue, m_alpha);
00301         }
00302     }
00303 
00304     GenericRendererVertexInfo::GenericRendererVertexInfo(GenericRendererNode center, int size, uint8_t r, uint8_t g, uint8_t b, uint8_t a):
00305         GenericRendererElementInfo(),
00306         m_center(center),
00307         m_size(size),
00308         m_red(r),
00309         m_green(g),
00310         m_blue(b),
00311         m_alpha(a) {
00312     }
00313     void GenericRendererVertexInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00314         Point p = m_center.getCalculatedPoint(cam, layer);
00315         if(m_center.getLayer() == layer) {
00316             renderbackend->drawVertex(p, m_size, m_red, m_green, m_blue, m_alpha);
00317         }
00318     }
00319 
00320     GenericRendererImageInfo::GenericRendererImageInfo(GenericRendererNode anchor, int image):
00321         GenericRendererElementInfo(),
00322         m_anchor(anchor),
00323         m_image(image) {
00324     }
00325     void GenericRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00326         Point p = m_anchor.getCalculatedPoint(cam, layer);
00327         if(m_anchor.getLayer() == layer) {
00328             Image* img = &imagepool->getImage(m_image);
00329             Rect r;
00330             Rect viewport = cam->getViewPort();
00331             unsigned int widtht = round(img->getWidth() * cam->getZoom());
00332             unsigned int height = round(img->getHeight() * cam->getZoom());
00333             r.x = p.x-widtht/2;
00334             r.y = p.y-height/2;
00335             r.w = widtht;
00336             r.h = height;
00337             if(r.intersects(viewport))
00338                 img->render(r);
00339         }
00340     }
00341 
00342     GenericRendererAnimationInfo::GenericRendererAnimationInfo(GenericRendererNode anchor, int animation):
00343         GenericRendererElementInfo(),
00344         m_anchor(anchor),
00345         m_animation(animation),
00346         m_start_time(TimeManager::instance()->getTime()),
00347         m_time_scale(1.0) {
00348     }
00349     void GenericRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00350         Point p = m_anchor.getCalculatedPoint(cam, layer);
00351         if(m_anchor.getLayer() == layer) {
00352             Animation& animation = animpool->getAnimation(m_animation);
00353             int animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % animation.getDuration();
00354             Image* img = animation.getFrameByTimestamp(animtime);
00355             Rect r;
00356             Rect viewport = cam->getViewPort();
00357             unsigned int widtht = round(img->getWidth() * cam->getZoom());
00358             unsigned int height = round(img->getHeight() * cam->getZoom());
00359             r.x = p.x-widtht/2;
00360             r.y = p.y-height/2;
00361             r.w = widtht;
00362             r.h = height;
00363             if(r.intersects(viewport))
00364                 img->render(r);
00365         }
00366     }
00367 
00368     GenericRendererTextInfo::GenericRendererTextInfo(GenericRendererNode anchor, AbstractFont* font, std::string text):
00369         GenericRendererElementInfo(),
00370         m_anchor(anchor),
00371         m_font(font),
00372         m_text(text) {
00373     }
00374     void GenericRendererTextInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00375         Point p = m_anchor.getCalculatedPoint(cam, layer);
00376         if(m_anchor.getLayer() == layer) {
00377             Image* img = m_font->getAsImageMultiline(m_text);
00378             Rect r;
00379             Rect viewport = cam->getViewPort();
00380             r.x = p.x-img->getWidth()/2;
00381             r.y = p.y-img->getHeight()/2;
00382             r.w = img->getWidth();
00383             r.h = img->getHeight();
00384             if(r.intersects(viewport)) {
00385                 renderbackend->disableLighting();
00386                 img->render(r);
00387                 renderbackend->enableLighting();
00388             }
00389         }
00390     }
00391 
00392     GenericRendererResizeInfo::GenericRendererResizeInfo(GenericRendererNode anchor, int image, int width, int height):
00393         GenericRendererElementInfo(),
00394         m_anchor(anchor),
00395         m_image(image),
00396         m_width(width),
00397         m_height(height){
00398     }
00399     void GenericRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00400         Point p = m_anchor.getCalculatedPoint(cam, layer);
00401         if(m_anchor.getLayer() == layer) {
00402             Image* img = &imagepool->getImage(m_image);
00403             Rect r;
00404             Rect viewport = cam->getViewPort();
00405             unsigned int widtht = round(m_width * cam->getZoom());
00406             unsigned int height = round(m_height * cam->getZoom());
00407             r.x = p.x-widtht/2;
00408             r.y = p.y-height/2;
00409             r.w = widtht;
00410             r.h = height;
00411             if(r.intersects(viewport)) {
00412                 img->render(r);
00413             }
00414         }
00415     }
00416     
00417     GenericRenderer* GenericRenderer::getInstance(IRendererContainer* cnt) {
00418         return dynamic_cast<GenericRenderer*>(cnt->getRenderer("GenericRenderer"));
00419     }
00420 
00421     GenericRenderer::GenericRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool):
00422         RendererBase(renderbackend, position),
00423         m_imagepool(imagepool),
00424         m_animationpool(animpool),
00425         m_groups() {
00426         setEnabled(false);
00427     }
00428 
00429     GenericRenderer::GenericRenderer(const GenericRenderer& old):
00430         RendererBase(old),
00431         m_imagepool(old.m_imagepool),
00432         m_animationpool(old.m_animationpool),
00433         m_groups() {
00434         setEnabled(false);
00435     }
00436 
00437     RendererBase* GenericRenderer::clone() {
00438         return new GenericRenderer(*this);
00439     }
00440 
00441     GenericRenderer::~GenericRenderer() {
00442     }
00443     void GenericRenderer::addLine(const std::string &group, GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00444         GenericRendererElementInfo* info = new GenericRendererLineInfo(n1, n2, r, g, b, a);
00445         m_groups[group].push_back(info);
00446     }
00447     void GenericRenderer::addPoint(const std::string &group, GenericRendererNode n, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00448         GenericRendererElementInfo* info = new GenericRendererPointInfo(n, r, g, b, a);
00449         m_groups[group].push_back(info);
00450     }
00451     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) {
00452         GenericRendererElementInfo* info = new GenericRendererTriangleInfo(n1, n2, n3, r, g, b, a);
00453         m_groups[group].push_back(info);
00454     }
00455     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) {
00456         GenericRendererElementInfo* info = new GenericRendererQuadInfo(n1, n2, n3, n4, r, g, b, a);
00457         m_groups[group].push_back(info);
00458     }
00459     void GenericRenderer::addVertex(const std::string &group, GenericRendererNode n, int size, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00460         GenericRendererElementInfo* info = new GenericRendererVertexInfo(n, size, r, g, b, a);
00461         m_groups[group].push_back(info);
00462     }
00463     void GenericRenderer::addText(const std::string &group, GenericRendererNode n, AbstractFont* font, const std::string &text) {
00464         GenericRendererElementInfo* info = new GenericRendererTextInfo(n, font, text);
00465         m_groups[group].push_back(info);
00466     }
00467     void GenericRenderer::addImage(const std::string &group, GenericRendererNode n, int image) {
00468         GenericRendererElementInfo* info = new GenericRendererImageInfo(n, image);
00469         m_groups[group].push_back(info);
00470     }
00471     void GenericRenderer::addAnimation(const std::string &group, GenericRendererNode n, int animation) {
00472         GenericRendererElementInfo* info = new GenericRendererAnimationInfo(n, animation);
00473         m_groups[group].push_back(info);
00474     }
00475     void GenericRenderer::resizeImage(const std::string &group, GenericRendererNode n, int image, int width, int height) {
00476         GenericRendererElementInfo* info = new GenericRendererResizeInfo(n, image, width, height);
00477         m_groups[group].push_back(info);
00478     }
00479     void GenericRenderer::removeAll(const std::string &group) {
00480         std::vector<GenericRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
00481         for (;info_it != m_groups[group].end(); ++info_it) {
00482             delete *info_it;
00483         }
00484         m_groups[group].clear();
00485         m_groups.erase(group);
00486     }
00487 
00488     void GenericRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
00489         std::map<std::string, std::vector<GenericRendererElementInfo*> >::iterator group_it = m_groups.begin();
00490         for(; group_it != m_groups.end(); ++group_it) {
00491             std::vector<GenericRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
00492             for (;info_it != group_it->second.end(); ++info_it) {
00493                 (*info_it)->render(cam, layer, instances, m_renderbackend, m_imagepool, m_animationpool);
00494             }
00495         }
00496     }
00497 }