00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <SDL.h>
00026
00027
00028
00029
00030
00031
00032 #include "model/metamodel/grids/cellgrid.h"
00033 #include "model/metamodel/action.h"
00034 #include "model/metamodel/timeprovider.h"
00035 #include "model/structures/map.h"
00036 #include "model/structures/layer.h"
00037 #include "model/structures/instancetree.h"
00038 #include "model/structures/instance.h"
00039 #include "model/structures/location.h"
00040 #include "util/log/logger.h"
00041 #include "util/math/fife_math.h"
00042 #include "util/math/angles.h"
00043 #include "util/time/timemanager.h"
00044 #include "video/renderbackend.h"
00045 #include "video/image.h"
00046 #include "video/imagepool.h"
00047 #include "video/animation.h"
00048 #include "video/animationpool.h"
00049
00050 #include "camera.h"
00051 #include "layercache.h"
00052 #include "visual.h"
00053
00054
00055 namespace FIFE {
00056 static Logger _log(LM_CAMERA);
00057
00058 class MapObserver : public MapChangeListener {
00059 Camera* m_camera;
00060
00061 public:
00062 MapObserver(Camera* camera) {
00063 m_camera = camera;
00064 }
00065 virtual ~MapObserver() {}
00066
00067 virtual void onMapChanged(Map* map, std::vector<Layer*>& changedLayers) {
00068 }
00069
00070 virtual void onLayerCreate(Map* map, Layer* layer) {
00071 m_camera->addLayer(layer);
00072 }
00073
00074 virtual void onLayerDelete(Map* map, Layer* layer) {
00075 m_camera->removeLayer(layer);
00076 }
00077 };
00078
00079 Camera::Camera(const std::string& id,
00080 Layer *layer,
00081 const Rect& viewport,
00082 RenderBackend* renderbackend,
00083 ImagePool* ipool,
00084 AnimationPool* apool):
00085 m_id(id),
00086 m_matrix(),
00087 m_inverse_matrix(),
00088 m_tilt(0),
00089 m_rotation(0),
00090 m_zoom(1),
00091 m_location(),
00092 m_prev_origo(ScreenPoint(0,0,0)),
00093 m_cur_origo(ScreenPoint(0,0,0)),
00094 m_viewport(),
00095 m_screen_cell_width(1),
00096 m_screen_cell_height(1),
00097 m_reference_scale(1),
00098 m_enabled(true),
00099 m_attachedto(NULL),
00100 m_image_dimensions(),
00101 m_iswarped(false),
00102 m_renderers(),
00103 m_pipeline(),
00104 m_updated(false),
00105 m_renderbackend(renderbackend),
00106 m_ipool(ipool),
00107 m_apool(apool),
00108 m_layer_to_instances(),
00109 m_lighting(false),
00110 m_light_colors() {
00111
00112 m_viewport = viewport;
00113 m_map_observer = new MapObserver(this);
00114 m_map = 0;
00115 Location location;
00116 location.setLayer(layer);
00117 setLocation(location);
00118 if(m_renderbackend->getName() == "SDL") {
00119 m_backendSDL = true;
00120 } else {
00121 m_backendSDL = false;
00122 }
00123 }
00124
00125 Camera::~Camera() {
00126
00127 updateMap(NULL);
00128
00129 std::map<std::string, RendererBase*>::iterator r_it = m_renderers.begin();
00130 for(; r_it != m_renderers.end(); ++r_it) {
00131 delete r_it->second;
00132 }
00133 m_renderers.clear();
00134 delete m_map_observer;
00135 }
00136
00137 void Camera::setTilt(double tilt) {
00138 if(m_tilt != tilt) {
00139 m_tilt = tilt;
00140 updateReferenceScale();
00141 updateMatrices();
00142 m_iswarped = true;
00143 }
00144 }
00145
00146 double Camera::getTilt() const {
00147 return m_tilt;
00148 }
00149
00150 void Camera::setRotation(double rotation) {
00151 if(m_rotation != rotation) {
00152 m_rotation = rotation;
00153 updateReferenceScale();
00154 updateMatrices();
00155 m_iswarped = true;
00156 }
00157 }
00158
00159 double Camera::getRotation() const {
00160 return m_rotation;
00161 }
00162
00163 void Camera::setZoom(double zoom) {
00164 if(m_zoom!=zoom) {
00165 m_zoom = zoom;
00166 if (m_zoom < 0.001) {
00167 m_zoom = 0.001;
00168 }
00169 updateMatrices();
00170 }
00171 }
00172
00173 double Camera::getZoom() const {
00174 return m_zoom;
00175 }
00176
00177 void Camera::setCellImageDimensions(unsigned int width, unsigned int height) {
00178 m_screen_cell_width = width;
00179 m_screen_cell_height = height;
00180 updateReferenceScale();
00181 updateMatrices();
00182 m_iswarped = true;
00183 }
00184
00185 void Camera::setLocation(const Location& location) {
00186
00187 if ((m_prev_origo == m_cur_origo) && (m_prev_origo == ScreenPoint(0,0,0))) {
00188 m_cur_origo = toScreenCoordinates(ExactModelCoordinate(0,0,0));
00189 m_prev_origo = m_cur_origo;
00190 }
00191
00192 CellGrid* cell_grid = NULL;
00193 if (location.getLayer()) {
00194 cell_grid = location.getLayer()->getCellGrid();
00195 } else {
00196 throw Exception("Location without layer given to Camera::setLocation");
00197 }
00198 if (!cell_grid) {
00199 throw Exception("Camera layer has no cellgrid specified");
00200 }
00201
00202 m_location = location;
00203 updateMatrices();
00204
00205
00206
00207
00208
00209
00210 updateMap(location.getMap());
00211
00212 m_cur_origo = toScreenCoordinates(ExactModelCoordinate(0,0,0));
00213 }
00214
00215 void Camera::updateMap(Map* map)
00216 {
00217 if(m_map == map)
00218 {
00219 return;
00220 }
00221 if(m_map) {
00222 m_map->removeChangeListener(m_map_observer);
00223 const std::list<Layer*>& layers = m_map->getLayers();
00224 for(std::list<Layer*>::const_iterator i = layers.begin(); i !=layers.end(); ++i) {
00225 removeLayer(*i);
00226 }
00227 }
00228 if(map) {
00229 map->addChangeListener(m_map_observer);
00230 const std::list<Layer*>& layers = map->getLayers();
00231 for(std::list<Layer*>::const_iterator i = layers.begin(); i !=layers.end(); ++i)
00232 addLayer(*i);
00233 }
00234 m_map = map;
00235 }
00236
00237 Point Camera::getCellImageDimensions() {
00238 return getCellImageDimensions(m_location.getLayer());
00239 }
00240
00241 Point Camera::getCellImageDimensions(Layer* layer) {
00242 if (layer == m_location.getLayer()) {
00243 return Point( m_screen_cell_width, m_screen_cell_height );
00244 }
00245 std::map<Layer*, Point>::iterator it = m_image_dimensions.find(layer);
00246 if (it != m_image_dimensions.end()) {
00247 return it->second;
00248 }
00249 Point p;
00250 CellGrid* cg = layer->getCellGrid();
00251 assert(cg);
00252 DoublePoint dimensions = getLogicalCellDimensions(layer);
00253 p.x = static_cast<int>(round(m_reference_scale * dimensions.x));
00254 p.y = static_cast<int>(round(m_reference_scale * dimensions.y));
00255 m_image_dimensions[layer] = p;
00256 return p;
00257 }
00258
00259 Location Camera::getLocation() const {
00260 return m_location;
00261 }
00262
00263 Location& Camera::getLocationRef() {
00264 return m_location;
00265 }
00266
00267 void Camera::setViewPort(const Rect& viewport) {
00268 m_viewport = viewport;
00269 }
00270
00271 const Rect& Camera::getViewPort() const {
00272 return m_viewport;
00273 }
00274
00275 void Camera::setEnabled(bool enabled) {
00276 m_enabled = enabled;
00277 }
00278
00279 bool Camera::isEnabled() {
00280 return m_enabled;
00281 }
00282
00283 Point3D Camera::getOrigin() const {
00284 return m_cur_origo;
00285 }
00286
00287 void Camera::updateMatrices() {
00288 double scale = m_reference_scale;
00289 m_matrix.loadScale(scale, scale, scale);
00290 m_vs_matrix.loadScale(scale,scale,scale);
00291 if (m_location.getLayer()) {
00292 CellGrid* cg = m_location.getLayer()->getCellGrid();
00293 if (cg) {
00294 ExactModelCoordinate pt = m_location.getMapCoordinates();
00295 m_matrix.applyTranslate( -pt.x *m_reference_scale,-pt.y *m_reference_scale, 0);
00296 }
00297 }
00298 scale = m_zoom;
00299 m_matrix.applyScale(scale, scale, scale);
00300 m_matrix.applyRotate(-m_rotation, 0.0, 0.0, 1.0);
00301 m_matrix.applyRotate(-m_tilt, 1.0, 0.0, 0.0);
00302 m_matrix.applyTranslate(+m_viewport.x+m_viewport.w/2, +m_viewport.y+m_viewport.h/2, 0);
00303 m_inverse_matrix = m_matrix.inverse();
00304
00305
00306 m_vs_matrix.applyTranslate(0,0,0);
00307 m_vs_matrix.applyRotate(-m_rotation, 0.0, 0.0, 1.0);
00308 m_vs_matrix.applyRotate(-m_tilt, 1.0, 0.0, 0.0);
00309 m_vs_inverse_matrix = m_vs_matrix.inverse();
00310
00311
00312
00313 m_vscreen_2_screen = m_matrix;
00314
00315 m_vscreen_2_screen.mult4by4(m_vs_inverse_matrix);
00316
00317 const int N=4;
00318 for(int i=0; i!=N; ++i) {
00319 m_vscreen_2_screen[2*N + i] = 0;
00320 m_vscreen_2_screen[i*N + 2] = 0;
00321 }
00322 m_vscreen_2_screen[2*N + 2] = 1;
00323 m_screen_2_vscreen = m_vscreen_2_screen.inverse();
00324
00325
00326
00327 }
00328
00329 void Camera::calculateZValue(ScreenPoint& screen_coords) {
00330 int dy = -(screen_coords.y - toScreenCoordinates(m_location.getMapCoordinates()).y);
00331 screen_coords.z = static_cast<int>(Mathd::Tan(m_tilt * (Mathd::pi() / 180.0)) * static_cast<double>(dy));
00332 }
00333
00334 ExactModelCoordinate Camera::toMapCoordinates(ScreenPoint screen_coords, bool z_calculated) {
00335 if (!z_calculated) {
00336 calculateZValue(screen_coords);
00337 }
00338 return m_inverse_matrix * intPt2doublePt(screen_coords);
00339 }
00340
00341 ScreenPoint Camera::toScreenCoordinates(ExactModelCoordinate elevation_coords) {
00342 ExactModelCoordinate p = elevation_coords;
00343 ScreenPoint pt = doublePt2intPt( m_matrix* p );
00344 return pt;
00345 }
00346
00347 DoublePoint3D Camera::toVirtualScreenCoordinates(ExactModelCoordinate elevation_coords) {
00348 ExactModelCoordinate p = elevation_coords;
00349 DoublePoint3D pt = (m_vs_matrix * p);
00350 return pt;
00351 }
00352
00353 ScreenPoint Camera::virtualScreenToScreen(const DoublePoint3D& p) {
00354 return doublePt2intPt(m_vscreen_2_screen * p);
00355 }
00356
00357 DoublePoint3D Camera::screenToVirtualScreen(const ScreenPoint& p) {
00358 return m_screen_2_vscreen * intPt2doublePt(p);
00359 }
00360
00361 DoublePoint Camera::getLogicalCellDimensions(Layer* layer) {
00362 CellGrid* cg = NULL;
00363 if (layer) {
00364 cg = layer->getCellGrid();
00365 }
00366 assert(cg);
00367
00368 ModelCoordinate cell(0,0);
00369 std::vector<ExactModelCoordinate> vertices;
00370 cg->getVertices(vertices, cell);
00371
00372 DoubleMatrix mtx;
00373 mtx.loadRotate(m_rotation, 0.0, 0.0, 1.0);
00374 mtx.applyRotate(m_tilt, 1.0, 0.0, 0.0);
00375
00376 double x1 = 0;
00377 double x2 = 0;
00378 double y1 = 0;
00379 double y2 = 0;
00380
00381 for (unsigned int i = 0; i < vertices.size(); i++) {
00382 vertices[i] = cg->toMapCoordinates(vertices[i]);
00383 vertices[i] = mtx * vertices[i];
00384 if (i == 0) {
00385 x1 = x2 = vertices[0].x;
00386 y1 = y2 = vertices[0].y;
00387 } else {
00388 x1 = std::min(vertices[i].x, x1);
00389 x2 = std::max(vertices[i].x, x2);
00390 y1 = std::min(vertices[i].y, y1);
00391 y2 = std::max(vertices[i].y, y2);
00392 }
00393 }
00394 return DoublePoint( x2 - x1, y2 - y1 );
00395 }
00396
00397 void Camera::updateReferenceScale() {
00398 DoublePoint dim = getLogicalCellDimensions(m_location.getLayer());
00399 m_reference_scale = static_cast<double>(m_screen_cell_width) / dim.x;
00400
00401 FL_DBG(_log, "Updating reference scale");
00402 FL_DBG(_log, LMsg(" tilt=") << m_tilt << " rot=" << m_rotation);
00403 FL_DBG(_log, LMsg(" m_screen_cell_width=") << m_screen_cell_width);
00404 }
00405
00406 bool Camera::testRenderedViewPort() {
00407 Map* map = m_location.getMap();
00408 Rect cv = m_viewport;
00409 int cv2x = cv.x+cv.w;
00410 int cv2y = cv.y+cv.h;
00411 bool trec1 = false, trec2 = false, trec3 = false, trec4 = false;
00412 Rect rec1 = Rect(cv.x, cv.y, 1, 1);
00413 Rect rec2 = Rect(cv.x, cv2y, 1, 1);
00414 Rect rec3 = Rect(cv2x, cv.y, 1, 1);
00415 Rect rec4 = Rect(cv2x, cv2y, 1, 1);
00416
00417 const std::list<Layer*>& layers = map->getLayers();
00418 std::list<Layer*>::const_iterator layer_it = layers.begin();
00419 m_layer_to_instances.clear();
00420 const RenderList& layer_instances = m_layer_to_instances[*layer_it];
00421 RenderList::const_iterator instance_it = layer_instances.begin();
00422 for(; instance_it != layer_instances.end(); ++instance_it) {
00423 const RenderItem& vc = **instance_it;
00424 if(vc.dimensions.intersects(rec1) && !trec1) {
00425 trec1 = true;
00426 }
00427 if(vc.dimensions.intersects(rec2) && !trec2) {
00428 trec2 = true;
00429 }
00430 if(trec1 && trec2) {
00431 break;
00432 }
00433 }
00434 if(trec1 && trec2) {
00435 RenderList::const_reverse_iterator instance_itr = layer_instances.rbegin();
00436 for(; instance_itr != layer_instances.rend(); ++instance_itr) {
00437 const RenderItem& vc = **instance_itr;
00438 if(vc.dimensions.intersects(rec3) && !trec3) {
00439 trec3 = true;
00440 }
00441 if(vc.dimensions.intersects(rec4) && !trec4) {
00442 trec4 = true;
00443 }
00444 if(trec3 && trec4) {
00445 break;
00446 }
00447 }
00448 }
00449
00450 if(trec1 && trec2 && trec3 && trec4) {
00451 return false;
00452 }
00453 return true;
00454 }
00455
00456 void Camera::getMatchingInstances(ScreenPoint screen_coords, Layer& layer, std::list<Instance*>& instances) {
00457 instances.clear();
00458 const RenderList& layer_instances = m_layer_to_instances[&layer];
00459 RenderList::const_iterator instance_it = layer_instances.end();
00460 while (instance_it != layer_instances.begin()) {
00461 --instance_it;
00462 Instance* i = (*instance_it)->instance;
00463 const RenderItem& vc = **instance_it;
00464 if ((vc.dimensions.contains(Point(screen_coords.x, screen_coords.y)))) {
00465 assert(vc.image);
00466 Uint8 r, g, b, a;
00467 int x = screen_coords.x - vc.dimensions.x;
00468 int y = screen_coords.y - vc.dimensions.y;
00469 if (m_zoom != 1.0) {
00470 double fx = static_cast<double>(x);
00471 double fy = static_cast<double>(y);
00472 double fow = static_cast<double>(vc.image->getWidth());
00473 double foh = static_cast<double>(vc.image->getHeight());
00474 double fsw = static_cast<double>(vc.dimensions.w);
00475 double fsh = static_cast<double>(vc.dimensions.h);
00476 x = static_cast<int>(round(fx / fsw * fow));
00477 y = static_cast<int>(round(fy / fsh * foh));
00478 }
00479 vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
00480
00481 if (a != 0) {
00482 instances.push_back(i);
00483 }
00484 }
00485 }
00486 }
00487
00488 void Camera::getMatchingInstances(Rect screen_rect, Layer& layer, std::list<Instance*>& instances) {
00489 instances.clear();
00490 const RenderList& layer_instances = m_layer_to_instances[&layer];
00491 RenderList::const_iterator instance_it = layer_instances.end();
00492 while (instance_it != layer_instances.begin()) {
00493 --instance_it;
00494 Instance* i = (*instance_it)->instance;;
00495 const RenderItem& vc = **instance_it;
00496 if ((vc.dimensions.intersects(screen_rect))) {
00497 assert(vc.image);
00498 Uint8 r, g, b, a;
00499 for(int xx = screen_rect.x; xx < screen_rect.x + screen_rect.w; xx++) {
00500 for(int yy = screen_rect.y; yy < screen_rect.y + screen_rect.h; yy++) {
00501 if ((vc.dimensions.contains(Point(xx, yy)))) {
00502 int x = xx - vc.dimensions.x;
00503 int y = yy - vc.dimensions.y;
00504 if (m_zoom != 1.0) {
00505 double fx = static_cast<double>(x);
00506 double fy = static_cast<double>(y);
00507 double fow = static_cast<double>(vc.image->getWidth());
00508 double foh = static_cast<double>(vc.image->getHeight());
00509 double fsw = static_cast<double>(vc.dimensions.w);
00510 double fsh = static_cast<double>(vc.dimensions.h);
00511 x = static_cast<int>(round(fx / fsw * fow));
00512 y = static_cast<int>(round(fy / fsh * foh));
00513 }
00514 vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
00515
00516 if (a != 0) {
00517 instances.push_back(i);
00518 goto found_non_transparent_pixel;
00519 }
00520 }
00521 }
00522 }
00523 found_non_transparent_pixel:;
00524 }
00525 }
00526 }
00527
00528 void Camera::getMatchingInstances(Location& loc, std::list<Instance*>& instances, bool use_exactcoordinates) {
00529 instances.clear();
00530 const RenderList& layer_instances = m_layer_to_instances[loc.getLayer()];
00531 RenderList::const_iterator instance_it = layer_instances.end();
00532 while (instance_it != layer_instances.begin()) {
00533 --instance_it;
00534 Instance* i = (*instance_it)->instance;
00535 if (use_exactcoordinates) {
00536 if (i->getLocationRef().getExactLayerCoordinatesRef() == loc.getExactLayerCoordinatesRef()) {
00537 instances.push_back(i);
00538 }
00539 } else {
00540 if (i->getLocationRef().getLayerCoordinates() == loc.getLayerCoordinates()) {
00541 instances.push_back(i);
00542 }
00543 }
00544 }
00545 }
00546
00547 void Camera::attach(Instance *instance) {
00548
00549 if (m_location.getLayer()->getId() != instance->getLocation().getLayer()->getId()) {
00550 FL_WARN(_log, "Tried to attach camera to instance on different layer.");
00551 return ;
00552 }
00553 m_attachedto = instance;
00554 }
00555
00556 void Camera::detach() {
00557 m_attachedto = NULL;
00558 }
00559
00560 void Camera::update() {
00561 if( !m_attachedto ) {
00562 return;
00563 }
00564 Location loc(m_location);
00565 loc.setExactLayerCoordinates( m_attachedto->getLocationRef().getExactLayerCoordinates(m_location.getLayer()) );
00566 setLocation(loc);
00567 updateMatrices();
00568 }
00569
00570 void Camera::refresh() {
00571 updateMatrices();
00572 m_iswarped = true;
00573 }
00574
00575 void Camera::resetUpdates() {
00576 m_iswarped = false;
00577 m_prev_origo = m_cur_origo;
00578 }
00579
00580 bool pipelineSort(const RendererBase* lhs, const RendererBase* rhs) {
00581 return (lhs->getPipelinePosition() < rhs->getPipelinePosition());
00582 }
00583
00584 void Camera::addRenderer(RendererBase* renderer) {
00585 renderer->setRendererListener(this);
00586 m_renderers[renderer->getName()] = renderer;
00587 if (renderer->isEnabled()) {
00588 m_pipeline.push_back(renderer);
00589 }
00590 m_pipeline.sort(pipelineSort);
00591 }
00592
00593 void Camera::onRendererPipelinePositionChanged(RendererBase* renderer) {
00594 m_pipeline.sort(pipelineSort);
00595 }
00596
00597 void Camera::onRendererEnabledChanged(RendererBase* renderer) {
00598 assert(m_renderers[renderer->getName()]);
00599 if (renderer->isEnabled()) {
00600 FL_LOG(_log, LMsg("Enabling renderer ") << renderer->getName());
00601 m_pipeline.push_back(renderer);
00602 m_pipeline.sort(pipelineSort);
00603 } else {
00604 m_pipeline.remove(renderer);
00605 }
00606 }
00607
00608 RendererBase* Camera::getRenderer(const std::string& name) {
00609 return m_renderers[name];
00610 }
00611
00612 void Camera::resetRenderers() {
00613 std::map<std::string, RendererBase*>::iterator r_it = m_renderers.begin();
00614 for (; r_it != m_renderers.end(); ++r_it) {
00615 Map* map = m_location.getMap();
00616 r_it->second->reset();
00617 }
00618 }
00619
00620 void Camera::addLayer(Layer* layer) {
00621 m_cache[layer] = new LayerCache(this, m_ipool, m_apool);
00622 m_cache[layer]->setLayer(layer);
00623 m_layer_to_instances[layer] = RenderList();
00624 }
00625
00626 void Camera::removeLayer(Layer* layer) {
00627 delete m_cache[layer];
00628 m_cache.erase(layer);
00629 m_layer_to_instances.erase(layer);
00630 }
00631
00632 void Camera::setLightingColor(float red, float green, float blue, float alpha) {
00633 m_lighting = true;
00634 m_light_colors.clear();
00635 m_light_colors.push_back(red);
00636 m_light_colors.push_back(green);
00637 m_light_colors.push_back(blue);
00638 m_light_colors.push_back(alpha);
00639 }
00640
00641 std::vector<float> Camera::getLightingColor() {
00642 if(m_light_colors.empty()) {
00643 for(int colors = 0; colors != 4; ++colors) {
00644 m_light_colors.push_back(1.0f);
00645 }
00646 }
00647 return m_light_colors;
00648 }
00649
00650 void Camera::resetLightingColor() {
00651 m_lighting = false;
00652 m_renderbackend->resetLighting();
00653 }
00654
00655 void Camera::render() {
00656 Transform transform = NormalTransform;
00657 if(m_iswarped)
00658 transform = WarpedTransform;
00659 m_iswarped = false;
00660
00661 Map* map = m_location.getMap();
00662 if (!map) {
00663 FL_ERR(_log, "No map for camera found");
00664 return;
00665 }
00666
00667
00668
00669
00670 if (m_renderbackend->getLightingModel() != 0) {
00671 m_renderbackend->resetStencilBuffer(0);
00672 if (m_lighting) {
00673 m_renderbackend->setLighting(m_light_colors[0], m_light_colors[1], m_light_colors[2], m_light_colors[3]);
00674 }
00675 }
00676
00677 if(m_backendSDL) {
00678 m_renderbackend->pushClipArea(getViewPort());
00679 } else {
00680 m_renderbackend->pushClipArea(getViewPort(), testRenderedViewPort());
00681 }
00682
00683
00684
00685
00686 const std::list<Layer*>& layers = map->getLayers();
00687 std::list<Layer*>::const_iterator layer_it = layers.begin();
00688 for (;layer_it != layers.end(); ++layer_it) {
00689 LayerCache* cache = m_cache[*layer_it];
00690 if(!cache) {
00691 addLayer(*layer_it);
00692 cache = m_cache[*layer_it];
00693 FL_ERR(_log, LMsg("Layer Cache miss! (This shouldn't happen!)") << (*layer_it)->getId());
00694 }
00695 RenderList& instances_to_render = m_layer_to_instances[*layer_it];
00696 cache->update(transform, instances_to_render);
00697
00698 std::list<RendererBase*>::iterator r_it = m_pipeline.begin();
00699 for (; r_it != m_pipeline.end(); ++r_it) {
00700 if ((*r_it)->isActivedLayer(*layer_it)) {
00701 (*r_it)->render(this, *layer_it, instances_to_render);
00702 }
00703 }
00704 }
00705
00706 if (m_lighting) {
00707 m_renderbackend->resetLighting();
00708 }
00709
00710 m_renderbackend->popClipArea();
00711 resetUpdates();
00712 m_updated = true;
00713 }
00714
00715 }