targetrenderer.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 by the FIFE team                              *
00003  *   http://www.fifengine.net                                              *
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/imagemanager.h"
00032 #include "util/log/logger.h"
00033 #include "view/camera.h"
00034 
00035 #include "targetrenderer.h"
00036 
00037 
00038 namespace FIFE {
00039     static Logger _log(LM_VIEWVIEW);
00040 
00041     RenderTarget::RenderTarget(RenderBackend* rb, const std::string& name, uint32_t width, uint32_t height):
00042         m_renderbackend(rb) {
00043         m_target = ImageManager::instance()->loadBlank(name, width, height);
00044     }
00045 
00046     RenderTarget::RenderTarget(RenderBackend* rb, ImagePtr& image):
00047         m_renderbackend(rb), m_target(image) {
00048     }
00049 
00050     RenderTarget::~RenderTarget() {
00051     }
00052 
00053     void RenderTarget::addLine(const std::string &group, Point n1, Point n2, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00054         OffRendererElementInfo* info = new OffRendererLineInfo(n1, n2, r, g, b, a);
00055         m_groups[group].push_back(info);
00056     }
00057 
00058     void RenderTarget::addPoint(const std::string &group, Point n, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00059         OffRendererElementInfo* info = new OffRendererPointInfo(n, r, g, b, a);
00060         m_groups[group].push_back(info);
00061     }
00062 
00063     void RenderTarget::addTriangle(const std::string &group, Point n1, Point n2, Point n3, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00064         OffRendererElementInfo* info = new OffRendererTriangleInfo(n1, n2, n3, r, g, b, a);
00065         m_groups[group].push_back(info);
00066     }
00067 
00068     void RenderTarget::addQuad(const std::string &group, Point n1, Point n2, Point n3, Point n4, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00069         OffRendererElementInfo* info = new OffRendererQuadInfo(n1, n2, n3, n4, r, g, b, a);
00070         m_groups[group].push_back(info);
00071     }
00072 
00073     void RenderTarget::addVertex(const std::string &group, Point n, int32_t size, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
00074         OffRendererElementInfo* info = new OffRendererVertexInfo(n, size, r, g, b, a);
00075         m_groups[group].push_back(info);
00076     }
00077 
00078     void RenderTarget::addText(const std::string &group, Point n, IFont* font, const std::string &text) {
00079         OffRendererElementInfo* info = new OffRendererTextInfo(n, font, text);
00080         m_groups[group].push_back(info);
00081     }
00082 
00083     void RenderTarget::addImage(const std::string &group, Point n, ImagePtr image) {
00084         OffRendererElementInfo* info = new OffRendererImageInfo(n, image);
00085         m_groups[group].push_back(info);
00086     }
00087 
00088     void RenderTarget::addAnimation(const std::string &group, Point n, AnimationPtr animation) {
00089         OffRendererElementInfo* info = new OffRendererAnimationInfo(n, animation);
00090         m_groups[group].push_back(info);
00091     }
00092 
00093     void RenderTarget::resizeImage(const std::string &group, Point n, ImagePtr image, int32_t width, int32_t height) {
00094         OffRendererElementInfo* info = new OffRendererResizeInfo(n, image, width, height);
00095         m_groups[group].push_back(info);
00096     }
00097 
00098     void RenderTarget::removeAll(const std::string &group) {
00099         std::vector<OffRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
00100         for (;info_it != m_groups[group].end(); ++info_it) {
00101             delete *info_it;
00102         }
00103         m_groups[group].clear();
00104         m_groups.erase(group);
00105     }
00106 
00107     void RenderTarget::removeAll() {
00108         m_groups.clear();
00109     }
00110 
00111     void RenderTarget::render() {
00112         std::map<std::string, std::vector<OffRendererElementInfo*> >::iterator group_it = m_groups.begin();
00113         for(; group_it != m_groups.end(); ++group_it) {
00114             std::vector<OffRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
00115             for (; info_it != group_it->second.end(); ++info_it) {
00116                 (*info_it)->render(m_renderbackend);
00117             }
00118         }
00119     }
00120 
00121     TargetRenderer::TargetRenderer(RenderBackend* renderbackend) :
00122         m_renderbackend(renderbackend) {
00123     }
00124 
00125     TargetRenderer::~TargetRenderer() {
00126     }
00127 
00128     RenderTargetPtr TargetRenderer::createRenderTarget(const std::string& name, uint32_t width, uint32_t height) {
00129         RenderJob rj;
00130         rj.ndraws = -1;
00131         rj.lasttime_draw = 1;
00132         rj.target = RenderTargetPtr(new RenderTarget(m_renderbackend, name, width, height));
00133         rj.discard = false;
00134 
00135         std::pair<RenderJobMap::iterator, bool> ret =
00136             m_targets.insert(std::make_pair<std::string, RenderJob>(name, rj));
00137 
00138         return ret.first->second.target;
00139     }
00140 
00141     RenderTargetPtr TargetRenderer::createRenderTarget(ImagePtr& image) {
00142         RenderJob rj;
00143         rj.ndraws = -1;
00144         rj.lasttime_draw = 1;
00145         rj.target = RenderTargetPtr(new RenderTarget(m_renderbackend, image));
00146         rj.discard = false;
00147 
00148         std::pair<RenderJobMap::iterator, bool> ret =
00149             m_targets.insert(std::make_pair<std::string, RenderJob>(image->getName(), rj));
00150 
00151         return ret.first->second.target;
00152     }
00153 
00154     void TargetRenderer::setRenderTarget(const std::string& targetname, bool discard, int32_t ndraws) {
00155         RenderJobMap::iterator it = m_targets.find(targetname);
00156         if (it != m_targets.end()) {
00157             it->second.ndraws = ndraws;
00158             it->second.discard = discard;
00159         }
00160     }
00161 
00162     void TargetRenderer::render() {
00163         if (!m_targets.empty()) {
00164             for (RenderJobMap::iterator it = m_targets.begin(); it != m_targets.end(); ++it) {
00165                 if (it->second.ndraws != -1) {
00166                     if (it->second.ndraws <= it->second.lasttime_draw) {
00167                         RenderTargetPtr rt = it->second.target;
00168                         m_renderbackend->attachRenderTarget(rt->m_target, it->second.discard);
00169                         rt->render();
00170                         m_renderbackend->detachRenderTarget();
00171 
00172                         if(it->second.ndraws == 0) {
00173                             it->second.ndraws = -1;
00174                         } else {
00175                             it->second.lasttime_draw = 1;
00176                         }
00177                     } else {
00178                         ++it->second.lasttime_draw;
00179                     }
00180                 }
00181             }
00182         }
00183     }
00184 }