camerazonerenderer.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/image.h"
00032 #include "util/math/fife_math.h"
00033 #include "util/log/logger.h"
00034 #include "model/metamodel/grids/cellgrid.h"
00035 #include "model/structures/instance.h"
00036 #include "model/structures/layer.h"
00037 #include "model/structures/location.h"
00038 
00039 #include "view/camera.h"
00040 #include "camerazonerenderer.h"
00041 
00042 
00043 
00044 namespace FIFE {
00045     static Logger _log(LM_VIEWVIEW);
00046 
00047     CameraZoneRenderer::CameraZoneRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool):
00048         RendererBase(renderbackend, position),
00049         m_imagepool(imagepool),
00050         m_zone_image(NULL) {
00051         setEnabled(false);
00052     }
00053 
00054     CameraZoneRenderer::CameraZoneRenderer(const CameraZoneRenderer& old):
00055         RendererBase(old),
00056         m_imagepool(old.m_imagepool),
00057         m_zone_image(NULL) {
00058         setEnabled(false);
00059     }
00060 
00061     RendererBase* CameraZoneRenderer::clone() {
00062         return new CameraZoneRenderer(*this);
00063     }
00064 
00065     CameraZoneRenderer::~CameraZoneRenderer() {
00066         delete m_zone_image;
00067     }
00068 
00069 
00070 
00071     void CameraZoneRenderer::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances) {
00072         CellGrid* cg = layer->getCellGrid();
00073         if (!cg) {
00074             FL_WARN(_log, "No cellgrid assigned to layer, cannot draw camera zones");
00075             return;
00076         }
00077         // draw this layer's grid as the camera sees it
00078         Rect rect = cam->getViewPort();
00079         if (!m_zone_image) {
00080             // build zone image
00081             int dataSize = rect.w * rect.h;
00082 
00083             // initally all pixels are transparent
00084             uint32_t* data = new uint32_t[dataSize];
00085             uint32_t* end = data + dataSize;
00086 
00087             #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00088                 uint32_t empty_pixel = 0;//0xff << 24;
00089                 uint32_t edge_pixel = 0xff << 16 | 0xff << 24;
00090             #else
00091                 uint32_t empty_pixel = 0;//0xff;
00092                 uint32_t edge_pixel = 0xff << 8 | 0xff;
00093             #endif
00094 
00095             std::fill(data, end, empty_pixel);
00096 
00097             // go from screen coords to grid coords (layer coords)
00098             // Search through pixel space, drawing pixels at boundaries
00099             ModelCoordinate prevLayerCoord;
00100             for (int y = 0; y < rect.h; y++) {
00101                 for (int x = 0; x < rect.w; x++) {
00102                     ExactModelCoordinate mapCoord = cam->toMapCoordinates(ScreenPoint(x, y));
00103                     ModelCoordinate layerCoord = cg->toLayerCoordinates(mapCoord);
00104 
00105                     if (prevLayerCoord != layerCoord) {
00106                         data[x + rect.w * y] = edge_pixel;
00107                     }
00108                     prevLayerCoord = layerCoord;
00109                 }
00110             }
00111 
00112 
00113             for (int x = 0; x < rect.w; x++) {
00114                 for (int y = 0; y < rect.h; y++) {
00115                     ExactModelCoordinate mapCoord = cam->toMapCoordinates(ScreenPoint(x, y));
00116                     ModelCoordinate layerCoord = cg->toLayerCoordinates(mapCoord);
00117 
00118                     if (prevLayerCoord != layerCoord) {
00119                         data[x + rect.w * y] = edge_pixel;
00120                     }
00121                     prevLayerCoord = layerCoord;
00122                 }
00123             }
00124 
00125             m_zone_image =  m_renderbackend->createImage((uint8_t*) data, rect.w, rect.h);
00126             delete data;
00127         }
00128         m_zone_image->render(rect);
00129     }
00130 
00131     void CameraZoneRenderer::setEnabled(bool enabled) {
00132         if (!enabled) {
00133             delete m_zone_image;
00134             m_zone_image = NULL;
00135         }
00136     }
00137 }