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, Location* relative_location, const Point &relative_point):
00053         m_instance(attached_instance),
00054         m_location(relative_location),
00055         m_point(relative_point) {
00056     }
00057     GenericRendererNode::GenericRendererNode(Instance* attached_instance, const Point &relative_point):
00058         m_instance(attached_instance),
00059         m_location(NULL),
00060         m_point(relative_point) {
00061     }
00062     GenericRendererNode::GenericRendererNode(Location* attached_location, const Point &relative_point):
00063         m_instance(NULL),
00064         m_location(attached_location),
00065         m_point(relative_point) {
00066     }
00067     GenericRendererNode::GenericRendererNode(const Point &attached_point):
00068         m_instance(NULL),
00069         m_location(NULL),
00070         m_point(attached_point) {
00071     }
00072     GenericRendererNode::~GenericRendererNode() {
00073     }
00074 
00075     void GenericRendererNode::setAttached(Instance* attached_instance, Location* relative_location, const Point &relative_point) {
00076         m_instance = attached_instance;
00077         m_location = relative_location;
00078         m_point = relative_point;
00079     }
00080     void GenericRendererNode::setAttached(Instance* attached_instance, Location* relative_location) {
00081         m_instance = attached_instance;
00082         m_location = relative_location;
00083     }
00084     void GenericRendererNode::setAttached(Instance* attached_instance, const Point &relative_point) {
00085         m_instance = attached_instance;
00086         m_point = relative_point;
00087     }
00088     void GenericRendererNode::setAttached(Instance* attached_instance) {
00089         m_instance = attached_instance;
00090     }
00091     void GenericRendererNode::setAttached(Location* attached_location, const Point &relative_point) {
00092         m_instance = NULL;
00093         m_location = attached_location;
00094         m_point = relative_point;
00095     }
00096     void GenericRendererNode::setAttached(Location* attached_location) {
00097         m_instance = NULL;
00098         m_location = attached_location;
00099     }
00100     void GenericRendererNode::setAttached(const Point &attached_point) {
00101         m_instance = NULL;
00102         m_location = NULL;
00103         m_point = attached_point;
00104     }
00105 
00106     void GenericRendererNode::setRelative(Location* relative_location) {
00107         if(m_instance == NULL) {
00108             throw NotSupported("No instance attached.");
00109         }
00110         m_location = relative_location;
00111     }
00112     void GenericRendererNode::setRelative(Location* relative_location, Point relative_point) {
00113         if(m_instance == NULL) {
00114             throw NotSupported("No instance attached.");
00115         }
00116         m_location = relative_location;
00117         m_point = relative_point;
00118     }
00119     void GenericRendererNode::setRelative(const Point &relative_point) {
00120         if(m_instance == NULL || m_location == NULL) {
00121             throw NotSupported("No instance or location attached.");
00122         }
00123         m_point = relative_point;
00124     }
00125 
00126     Instance* GenericRendererNode::getAttachedInstance() {
00127         if(m_instance == NULL) {
00128             throw NotSupported("No instance attached.");
00129         }
00130         return m_instance;
00131     }
00132     Location* GenericRendererNode::getAttachedLocation() {
00133         if(m_instance != NULL || m_location == NULL) {
00134             throw NotSupported("No location attached.");
00135         }
00136         return m_location;
00137     }
00138     Point GenericRendererNode::getAttachedPoint() {
00139         if(m_instance != NULL || m_location != NULL) {
00140             throw NotSupported("No point attached.");
00141         }
00142         return m_point;
00143     }
00144 
00145     Location* GenericRendererNode::getOffsetLocation() {
00146         if(m_instance == NULL || m_location == NULL) {
00147             throw NotSupported("No location as offset used.");
00148         }
00149         return m_location;
00150     }
00151     Point GenericRendererNode::getOffsetPoint() {
00152         if(m_instance == NULL && m_location == NULL) {
00153             throw NotSupported("No point as offset used.");
00154         }
00155         return m_point;
00156     }
00157 
00158     Instance* GenericRendererNode::getInstance() {
00159         return m_instance;
00160     }
00161     Location* GenericRendererNode::getLocation() {
00162         return m_location;
00163     }
00164     Point GenericRendererNode::getPoint() {
00165         return m_point;
00166     }
00167 
00168     Point GenericRendererNode::getCalculatedPoint(Camera* cam, Layer* layer, std::vector<Instance*>& instances) {
00169         ScreenPoint p;
00170         if(m_instance != NULL) {
00171             if(m_location != NULL) {
00172                 p = cam->toScreenCoordinates(m_instance->getLocationRef().getMapCoordinates() + m_location->getMapCoordinates());
00173             }
00174             else {
00175                 p = cam->toScreenCoordinates(m_instance->getLocation().getMapCoordinates());
00176             }
00177         }
00178         else if(m_location != NULL) {
00179             p = cam->toScreenCoordinates(m_location->getMapCoordinates());
00180         }
00181         else
00182             return m_point;
00183         return Point(m_point.x + p.x, m_point.y + p.y);
00184     }
00185 
00186     GenericRendererLineInfo::GenericRendererLineInfo(GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b):
00187         GenericRendererElementInfo(),
00188         m_edge1(n1),
00189         m_edge2(n2),
00190         m_red(r),
00191         m_green(g),
00192         m_blue(b) {
00193     }
00194     void GenericRendererLineInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00195         Point p1 = m_edge1.getCalculatedPoint(cam, layer, instances);
00196         Point p2 = m_edge2.getCalculatedPoint(cam, layer, instances);
00197         renderbackend->drawLine(p1, p2, m_red, m_green, m_blue);
00198     }
00199 
00200     GenericRendererPointInfo::GenericRendererPointInfo(GenericRendererNode anchor, uint8_t r, uint8_t g, uint8_t b):
00201         GenericRendererElementInfo(),
00202         m_anchor(anchor),
00203         m_red(r),
00204         m_green(g),
00205         m_blue(b) {
00206     }
00207     void GenericRendererPointInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00208         Point p = m_anchor.getCalculatedPoint(cam, layer, instances);
00209         renderbackend->putPixel(p.x, p.y, m_red, m_green, m_blue);
00210     }
00211 
00212     GenericRendererQuadInfo::GenericRendererQuadInfo(GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, GenericRendererNode n4, uint8_t r, uint8_t g, uint8_t b):
00213         GenericRendererElementInfo(),
00214         m_edge1(n1),
00215         m_edge2(n2),
00216         m_edge3(n3),
00217         m_edge4(n4),
00218         m_red(r),
00219         m_green(g),
00220         m_blue(b) {
00221     }
00222     void GenericRendererQuadInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00223         Point p1 = m_edge1.getCalculatedPoint(cam, layer, instances);
00224         Point p2 = m_edge2.getCalculatedPoint(cam, layer, instances);
00225         Point p3 = m_edge3.getCalculatedPoint(cam, layer, instances);
00226         Point p4 = m_edge4.getCalculatedPoint(cam, layer, instances);
00227         renderbackend->drawQuad(p1, p2, p3, p4, m_red, m_green, m_blue);
00228     }
00229 
00230     GenericRendererVertexInfo::GenericRendererVertexInfo(GenericRendererNode center, int size, uint8_t r, uint8_t g, uint8_t b):
00231         GenericRendererElementInfo(),
00232         m_center(center),
00233         m_size(size),
00234         m_red(r),
00235         m_green(g),
00236         m_blue(b) {
00237     }
00238     void GenericRendererVertexInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00239         Point p = m_center.getCalculatedPoint(cam, layer, instances);
00240         renderbackend->drawVertex(p, m_size, m_red, m_green, m_blue);
00241     }
00242 
00243     GenericRendererImageInfo::GenericRendererImageInfo(GenericRendererNode anchor, int image):
00244         GenericRendererElementInfo(),
00245         m_anchor(anchor),
00246         m_image(image) {
00247     }
00248     void GenericRendererImageInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00249         Point p = m_anchor.getCalculatedPoint(cam, layer, instances);
00250         Image* img = &imagepool->getImage(m_image);
00251         Rect r;
00252         r.x = p.x-img->getWidth()/2;
00253         r.y = p.y-img->getHeight()/2;
00254         r.w = img->getWidth();
00255         r.h = img->getHeight();
00256         img->render(r);
00257     }
00258 
00259     GenericRendererAnimationInfo::GenericRendererAnimationInfo(GenericRendererNode anchor, int animation):
00260         GenericRendererElementInfo(),
00261         m_anchor(anchor),
00262         m_animation(animation),
00263         m_start_time(TimeManager::instance()->getTime()),
00264         m_time_scale(1.0) {
00265     }
00266     void GenericRendererAnimationInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00267         Point p = m_anchor.getCalculatedPoint(cam, layer, instances);
00268         Animation& animation = animpool->getAnimation(m_animation);
00269         int animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % animation.getDuration();
00270         Image* img = animation.getFrameByTimestamp(animtime);
00271         Rect r;
00272         r.x = p.x-img->getWidth()/2;
00273         r.y = p.y-img->getHeight()/2;
00274         r.w = img->getWidth();
00275         r.h = img->getHeight();
00276         img->render(r);
00277     }
00278 
00279     GenericRendererTextInfo::GenericRendererTextInfo(GenericRendererNode anchor, AbstractFont* font, std::string text):
00280         GenericRendererElementInfo(),
00281         m_anchor(anchor),
00282         m_font(font),
00283         m_text(text) {
00284     }
00285     void GenericRendererTextInfo::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
00286         Point p = m_anchor.getCalculatedPoint(cam, layer, instances);
00287         Image* img = m_font->getAsImageMultiline(m_text);
00288         Rect r;
00289         r.x = p.x-img->getWidth()/2;
00290         r.y = p.y-img->getHeight()/2;
00291         r.w = img->getWidth();
00292         r.h = img->getHeight();
00293         img->render(r);
00294     }
00295 
00296     GenericRenderer* GenericRenderer::getInstance(IRendererContainer* cnt) {
00297         return dynamic_cast<GenericRenderer*>(cnt->getRenderer("GenericRenderer"));
00298     }
00299 
00300     GenericRenderer::GenericRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool):
00301         RendererBase(renderbackend, position),
00302         m_imagepool(imagepool),
00303         m_animationpool(animpool),
00304         m_groups() {
00305         setEnabled(false);
00306     }
00307 
00308     GenericRenderer::GenericRenderer(const GenericRenderer& old):
00309         RendererBase(old),
00310         m_imagepool(old.m_imagepool),
00311         m_animationpool(old.m_animationpool),
00312         m_groups() {
00313         setEnabled(false);
00314     }
00315 
00316     RendererBase* GenericRenderer::clone() {
00317         return new GenericRenderer(*this);
00318     }
00319 
00320     GenericRenderer::~GenericRenderer() {
00321     }
00322     void GenericRenderer::addLine(const std::string &group, GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b) {
00323         GenericRendererElementInfo* info = new GenericRendererLineInfo(n1, n2, r, g, b);
00324         m_groups[group].push_back(info);
00325     }
00326     void GenericRenderer::addPoint(const std::string &group, GenericRendererNode n, uint8_t r, uint8_t g, uint8_t b) {
00327         GenericRendererElementInfo* info = new GenericRendererPointInfo(n, r, g, b);
00328         m_groups[group].push_back(info);
00329     }
00330     void GenericRenderer::addQuad(const std::string &group, GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, GenericRendererNode n4, uint8_t r, uint8_t g, uint8_t b) {
00331         GenericRendererElementInfo* info = new GenericRendererQuadInfo(n1, n2, n3, n4, r, g, b);
00332         m_groups[group].push_back(info);
00333     }
00334     void GenericRenderer::addVertex(const std::string &group, GenericRendererNode n, int size, uint8_t r, uint8_t g, uint8_t b) {
00335         GenericRendererElementInfo* info = new GenericRendererVertexInfo(n, size, r, g, b);
00336         m_groups[group].push_back(info);
00337     }
00338     void GenericRenderer::addText(const std::string &group, GenericRendererNode n, AbstractFont* font, const std::string &text) {
00339         GenericRendererElementInfo* info = new GenericRendererTextInfo(n, font, text);
00340         m_groups[group].push_back(info);
00341     }
00342     void GenericRenderer::addImage(const std::string &group, GenericRendererNode n, int image) {
00343         GenericRendererElementInfo* info = new GenericRendererImageInfo(n, image);
00344         m_groups[group].push_back(info);
00345     }
00346     void GenericRenderer::addAnimation(const std::string &group, GenericRendererNode n, int animation) {
00347         GenericRendererElementInfo* info = new GenericRendererAnimationInfo(n, animation);
00348         m_groups[group].push_back(info);
00349     }
00350 
00351     void GenericRenderer::removeAll(const std::string &group) {
00352         std::vector<GenericRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
00353         for (;info_it != m_groups[group].end(); ++info_it) {
00354             delete *info_it;
00355         }
00356         m_groups[group].clear();
00357         m_groups.erase(group);
00358     }
00359 
00360     void GenericRenderer::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances) {
00361         std::map<std::string, std::vector<GenericRendererElementInfo*> >::iterator group_it = m_groups.begin();
00362         for(; group_it != m_groups.end(); ++group_it) {
00363             std::vector<GenericRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
00364             for (;info_it != group_it->second.end(); ++info_it) {
00365                 (*info_it)->render(cam, layer, instances, m_renderbackend, m_imagepool, m_animationpool);
00366             }
00367         }
00368     }
00369 }