FIFE 2008.0
|
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 }