FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
sdlimage.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2019 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <cassert>
24 #include <iostream>
25 
26 // 3rd party library includes
27 
28 // FIFE includes
29 // These includes are split up in two parts, separated by one empty line
30 // First block: files included from the FIFE root src directory
31 // Second block: files included from the same folder
32 #include "util/base/exception.h"
33 #include "util/log/logger.h"
34 #include "util/structures/rect.h"
35 #include "video/imagemanager.h"
36 #include "video/renderbackend.h"
37 
38 #include "renderbackendsdl.h"
39 #include "sdlimage.h"
40 
41 namespace FIFE {
45  static Logger _log(LM_VIDEO);
46 
48  Image(loader) {
49  resetSdlimage();
50  }
51 
52  SDLImage::SDLImage(const std::string& name, IResourceLoader* loader):
53  Image(name, loader) {
54  resetSdlimage();
55  }
56 
57  SDLImage::SDLImage(SDL_Surface* surface):
58  Image(surface) {
59  resetSdlimage();
60  }
61 
62  SDLImage::SDLImage(const std::string& name, SDL_Surface* surface):
63  Image(name, surface) {
64  resetSdlimage();
65  }
66 
67  SDLImage::SDLImage(const uint8_t* data, uint32_t width, uint32_t height):
68  Image(data, width, height) {
69  resetSdlimage();
70  }
71 
72  SDLImage::SDLImage(const std::string& name, const uint8_t* data, uint32_t width, uint32_t height):
73  Image(name, data, width, height) {
74  resetSdlimage();
75  }
76 
79  m_texture = NULL;
80  }
81 
83  invalidate();
84  }
85 
87  if (m_texture && !m_shared) {
88  SDL_DestroyTexture(m_texture);
89  }
90  m_texture = NULL;
91  }
92 
93  void SDLImage::setSurface(SDL_Surface* surface) {
94  invalidate();
95  reset(surface);
96  resetSdlimage();
97  }
98 
99  void SDLImage::render(const Rect& rect, uint8_t alpha, uint8_t const* rgb) {
100  if (alpha == 0) {
101  return;
102  }
103 
104  SDL_Surface* target = RenderBackend::instance()->getRenderTargetSurface();
105  assert(target != m_surface); // can't draw on the source surface
106 
107  if (rect.right() < 0 || rect.x > static_cast<int32_t>(target->w) ||
108  rect.bottom() < 0 || rect.y > static_cast<int32_t>(target->h)) {
109  return;
110  }
111 
112  SDL_Rect tarRect;
113  tarRect.x = rect.x;
114  tarRect.y = rect.y;
115  tarRect.w = rect.w;
116  tarRect.h = rect.h;
117 
118  Rect tmpRect = m_shared ? getSubImageRect() : getArea();
119  SDL_Rect srcRect;
120  srcRect.x = tmpRect.x;
121  srcRect.y = tmpRect.y;
122  srcRect.w = tmpRect.w;
123  srcRect.h = tmpRect.h;
124 
125  SDL_Renderer* renderer = static_cast<RenderBackendSDL*>(RenderBackend::instance())->getRenderer();
126 
127  // create texture
128  if (!m_texture) {
129  if (!m_surface) {
130  load();
131  }
132  m_texture = SDL_CreateTextureFromSurface(renderer, m_surface);
133  }
134 
135  // set additonal color and alpha mods
136  if (rgb) {
137  SDL_SetTextureColorMod(m_texture, rgb[0], rgb[1], rgb[2]);
138  SDL_SetTextureAlphaMod(m_texture, rgb[3]);
139  } else {
140  SDL_SetTextureColorMod(m_texture, 255, 255, 255);
141  SDL_SetTextureAlphaMod(m_texture, 255);
142  }
143  // set render color
144  SDL_SetRenderDrawColor(renderer, 255, 255, 255, alpha);
145 
146  if (SDL_RenderCopy(renderer, m_texture, &srcRect, &tarRect) != 0) {
147  throw SDLException(SDL_GetError());
148  }
149  }
150 
151  size_t SDLImage::getSize() {
152  size_t size = 0;
153  if (m_surface && !m_shared) {
154  size += m_surface->h * m_surface->pitch;
155  }
156 
157  return size;
158  }
159 
160  void SDLImage::useSharedImage(const ImagePtr& shared, const Rect& region) {
161  if(shared->getState() != IResource::RES_LOADED) {
162  shared->load();
163  }
164  SDL_Surface* surface = shared->getSurface();
165  if (!surface) {
166  shared->load();
167  surface = shared->getSurface();
168  }
169  SDLImage* image = static_cast<SDLImage*>(shared.get());
170  m_texture = image->getTexture();
171  if (!m_texture) {
172  // create atlas texture
173  SDL_Renderer* renderer = static_cast<RenderBackendSDL*>(RenderBackend::instance())->getRenderer();
174  m_texture = SDL_CreateTextureFromSurface(renderer, surface);
175  image->setTexture(m_texture);
176  }
177  setSurface(surface);
178  m_shared = true;
179  m_subimagerect = region;
180  m_atlas_img = shared;
181  m_atlas_name = shared->getName();
183  }
184 
186  validateShared();
187  }
188 
190  if (m_atlas_name.empty()) {
191  return;
192  }
193 
196  load();
197  }
198  }
199 
200  void SDLImage::load() {
201  if (!m_atlas_name.empty()) {
202  // check atlas image
203  // if it does not exist, it is created.
206  m_atlas_img = newAtlas;
207  }
209  } else {
210  Image::load();
211  }
212  }
213 
214  void SDLImage::free() {
215  // save the image offsets
216  int32_t xshift = m_xshift;
217  int32_t yshift = m_yshift;
218  setSurface(NULL);
219  m_xshift = xshift;
220  m_yshift = yshift;
222  }
223 
224  SDL_Texture* SDLImage::getTexture() {
225  return m_texture;
226  }
227 
228  void SDLImage::setTexture(SDL_Texture* texture) {
229  if (m_texture == texture) {
230  return;
231  }
232  if (m_texture && !m_shared) {
233  SDL_DestroyTexture(m_texture);
234  }
235  m_texture = texture;
236  }
237 }
virtual ImagePtr create(IResourceLoader *loader=0)
Creates a blank Image but does not load it immediately.
void reset(SDL_Surface *surface)
Resets the image to default values (including the x and y shift values), frees the current surface an...
Definition: image.cpp:110
virtual bool exists(const std::string &name)
Checks to see if an Image exists.
void validateShared()
Definition: sdlimage.cpp:189
virtual ResourceState getState()
Definition: resource.h:70
virtual void load()
Definition: image.cpp:124
Base Class for Images.
Definition: image.h:48
int32_t m_xshift
Definition: image.h:162
const SDL_Color & getColorKey() const
Gets the global colorkey setting.
SDL_Surface * m_surface
Definition: image.h:160
T h
Height of the rectangle.
Definition: rect.h:93
SDL_Color m_colorkey
Definition: sdlimage.h:67
SDL_Texture * m_texture
Definition: sdlimage.h:69
The main class of the SDL-based renderer.
T x
The X Coordinate.
Definition: rect.h:84
The SDL implementation of the Image base class.
Definition: sdlimage.h:40
Rect getArea() const
Definition: image.cpp:176
void setTexture(SDL_Texture *texture)
Definition: sdlimage.cpp:228
static Logger _log(LM_AUDIO)
ImagePtr m_atlas_img
Definition: sdlimage.h:72
SDL_Texture * getTexture()
Definition: sdlimage.cpp:224
virtual size_t getSize()
Definition: sdlimage.cpp:151
static RenderBackend * instance()
Definition: singleton.h:84
unsigned char uint8_t
Definition: core.h:38
virtual void render(const Rect &rect, uint8_t alpha=255, uint8_t const *rgb=0)
Renders itself to the current render target (main screen or attached destination image) at the rectan...
Definition: sdlimage.cpp:99
SDL_Surface * getSurface()
Definition: image.h:96
virtual ~SDLImage()
Definition: sdlimage.cpp:82
virtual const std::string & getName()
Definition: resource.h:66
ResourceState m_state
Definition: resource.h:81
T y
The Y Coordinate.
Definition: rect.h:87
T right() const
The X coordinate of the right edge.
Definition: rect.h:168
Rect m_subimagerect
Definition: image.h:177
void resetSdlimage()
Definition: sdlimage.cpp:77
virtual void setState(const ResourceState &state)
Definition: resource.h:71
SDL_Surface * getRenderTargetSurface()
Returns currently attached render surface.
virtual void invalidate()
Invalidates the Image causing it to be reset or re-loaded.
Definition: sdlimage.cpp:86
bool m_shared
Definition: image.h:175
virtual void forceLoadInternal()
Forces to load the image into internal memory of GPU.
Definition: sdlimage.cpp:185
const Rect & getSubImageRect() const
Returns area of the image it occupies in the shared image.
Definition: image.h:152
std::string m_atlas_name
Definition: sdlimage.h:74
virtual void setSurface(SDL_Surface *surface)
This frees the current suface and replaces it with the surface passed in the parameter (which can be ...
Definition: sdlimage.cpp:93
T * get() const
allows direct access to underlying pointer
Definition: sharedptr.h:155
unsigned int uint32_t
Definition: core.h:40
virtual void load()
Definition: sdlimage.cpp:200
SDLImage(IResourceLoader *loader=0)
Definition: sdlimage.cpp:47
virtual void free()
Definition: sdlimage.cpp:214
virtual void useSharedImage(const ImagePtr &shared, const Rect &region)
After this call all image data will be taken from the given image and its subregion.
Definition: sdlimage.cpp:160
T w
Width of the rectangle.
Definition: rect.h:90
T bottom() const
The Y coordinate of the bottom edge.
Definition: rect.h:173
int32_t m_yshift
Definition: image.h:164