2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 // Updated by GiBy 2013 for SDL2 <giby_the_kid@yahoo.fr>
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "video/sdl/sdl_renderer.hpp"
20 #include "util/log.hpp"
21 #include "video/drawing_request.hpp"
22 #include "video/sdl/sdl_surface_data.hpp"
23 #include "video/sdl/sdl_texture.hpp"
24 #include "video/sdl/sdl_painter.hpp"
31 #include "SDL2/SDL_video.h"
33 SDLRenderer::SDLRenderer() :
37 Renderer::instance_ = this;
39 log_info << "creating SDLRenderer" << std::endl;
40 int width = g_config->window_size.width;
41 int height = g_config->window_size.height;
43 int flags = SDL_WINDOW_RESIZABLE;
44 if(g_config->use_fullscreen)
46 flags |= SDL_WINDOW_FULLSCREEN;
47 width = g_config->fullscreen_size.width;
48 height = g_config->fullscreen_size.height;
52 SCREEN_HEIGHT = height;
54 PHYSICAL_SCREEN_WIDTH = width;
55 PHYSICAL_SCREEN_HEIGHT = height;
57 int ret = SDL_CreateWindowAndRenderer(width, height, flags,
61 std::stringstream msg;
62 msg << "Couldn't set video mode (" << width << "x" << height
63 << "): " << SDL_GetError();
64 throw std::runtime_error(msg.str());
67 SDL_RendererInfo info;
68 if (SDL_GetRendererInfo(renderer, &info) != 0)
70 log_warning << "Couldn't get RendererInfo: " << SDL_GetError() << std::endl;
74 log_info << "SDL_Renderer: " << info.name << std::endl;
75 log_info << "SDL_RendererFlags: " << std::endl;
76 if (info.flags & SDL_RENDERER_SOFTWARE) log_info << " SDL_RENDERER_SOFTWARE" << std::endl;
77 if (info.flags & SDL_RENDERER_ACCELERATED) log_info << " SDL_RENDERER_ACCELERATED" << std::endl;
78 if (info.flags & SDL_RENDERER_PRESENTVSYNC) log_info << " SDL_RENDERER_PRESENTVSYNC" << std::endl;
79 if (info.flags & SDL_RENDERER_TARGETTEXTURE) log_info << " SDL_RENDERER_TARGETTEXTURE" << std::endl;
80 log_info << "Texture Formats: " << std::endl;
81 for(size_t i = 0; i < info.num_texture_formats; ++i)
83 log_info << " " << SDL_GetPixelFormatName(info.texture_formats[i]) << std::endl;
85 log_info << "Max Texture Width: " << info.max_texture_width << std::endl;
86 log_info << "Max Texture Height: " << info.max_texture_height << std::endl;
89 if(texture_manager == 0)
90 texture_manager = new TextureManager();
93 SDLRenderer::~SDLRenderer()
95 SDL_DestroyRenderer(renderer);
96 SDL_DestroyWindow(window);
100 SDLRenderer::draw_surface(const DrawingRequest& request)
102 SDLPainter::draw_surface(renderer, request);
106 SDLRenderer::draw_surface_part(const DrawingRequest& request)
108 SDLPainter::draw_surface_part(renderer, request);
112 SDLRenderer::draw_gradient(const DrawingRequest& request)
114 SDLPainter::draw_gradient(renderer, request);
118 SDLRenderer::draw_filled_rect(const DrawingRequest& request)
120 SDLPainter::draw_filled_rect(renderer, request);
124 SDLRenderer::draw_inverse_ellipse(const DrawingRequest& request)
126 SDLPainter::draw_inverse_ellipse(renderer, request);
130 SDLRenderer::do_take_screenshot()
132 // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
135 if (SDL_GetRendererOutputSize(renderer, &width, &height) != 0)
137 log_warning << "SDL_GetRenderOutputSize failed: " << SDL_GetError() << std::endl;
141 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
142 Uint32 rmask = 0xff000000;
143 Uint32 gmask = 0x00ff0000;
144 Uint32 bmask = 0x0000ff00;
145 Uint32 amask = 0x000000ff;
147 Uint32 rmask = 0x000000ff;
148 Uint32 gmask = 0x0000ff00;
149 Uint32 bmask = 0x00ff0000;
150 Uint32 amask = 0xff000000;
152 SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32,
153 rmask, gmask, bmask, amask);
156 log_warning << "SDL_CreateRGBSurface failed: " << SDL_GetError() << std::endl;
160 int ret = SDL_RenderReadPixels(renderer, NULL,
161 SDL_PIXELFORMAT_ABGR8888,
166 log_warning << "SDL_RenderReadPixels failed: " << SDL_GetError() << std::endl;
171 static const std::string writeDir = PHYSFS_getWriteDir();
172 static const std::string dirSep = PHYSFS_getDirSeparator();
173 static const std::string baseName = "screenshot";
174 static const std::string fileExt = ".bmp";
175 std::string fullFilename;
176 for (int num = 0; num < 1000; num++) {
177 std::ostringstream oss;
179 oss << std::setw(3) << std::setfill('0') << num;
181 std::string fileName = oss.str();
182 fullFilename = writeDir + dirSep + fileName;
183 if (!PHYSFS_exists(fileName.c_str())) {
184 SDL_SaveBMP(surface, fullFilename.c_str());
185 log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
189 log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
198 SDL_RenderPresent(renderer);
202 SDLRenderer::resize(int w , int h)
207 PHYSICAL_SCREEN_WIDTH = w;
208 PHYSICAL_SCREEN_HEIGHT = h;
212 SDLRenderer::set_gamma(float gamma)
215 SDL_CalculateGammaRamp(gamma, ramp);
216 SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);