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
00026
00027
00028
00029
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 }