Render SDL lightmaps at lower resolutions, as specified by LIGHTMAP_DIV
[supertux.git] / src / video / sdl / sdl_lightmap.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include <iostream>
18
19 #include "video/sdl/sdl_lightmap.hpp"
20 #include "video/sdl/sdl_surface_data.hpp"
21 #include "video/sdl/sdl_texture.hpp"
22 #include "video/sdl/sdl_renderer.hpp"
23 #include "video/sdl/sdl_painter.hpp"
24
25 SDLLightmap::SDLLightmap() :
26   renderer(static_cast<SDLRenderer*>(Renderer::instance())->get_sdl_renderer()),
27   texture(),
28   width(),
29   height(),
30   LIGHTMAP_DIV()
31 {
32   LIGHTMAP_DIV = 8;
33
34   width = SCREEN_WIDTH;
35   height = SCREEN_HEIGHT;
36
37   SDL_Renderer* renderer = static_cast<SDLRenderer*>(Renderer::instance())->get_sdl_renderer();
38   texture = SDL_CreateTexture(renderer,
39                               SDL_PIXELFORMAT_RGB888,
40                               SDL_TEXTUREACCESS_TARGET,
41                               width / LIGHTMAP_DIV,
42                               height / LIGHTMAP_DIV);
43   if (!texture)
44   {
45     std::stringstream msg;
46     msg << "Couldn't create lightmap texture: " << SDL_GetError();
47     throw std::runtime_error(msg.str());
48   }
49 }
50
51 SDLLightmap::~SDLLightmap()
52 {
53   SDL_DestroyTexture(texture);
54 }
55
56 void
57 SDLLightmap::start_draw(const Color &ambient_color)
58 {
59   SDL_SetRenderTarget(renderer, texture);
60
61   Uint8 r = static_cast<Uint8>(ambient_color.red * 255);
62   Uint8 g = static_cast<Uint8>(ambient_color.green * 255);
63   Uint8 b = static_cast<Uint8>(ambient_color.blue * 255);
64
65   SDL_SetRenderDrawColor(renderer, r, g, b, 255);
66   SDL_RenderClear(renderer);
67   SDL_RenderSetScale(renderer, 1.0f / LIGHTMAP_DIV, 1.0f / LIGHTMAP_DIV);
68 }
69
70 void
71 SDLLightmap::end_draw()
72 {
73   SDL_RenderSetScale(renderer, 1.0f, 1.0f);
74   SDL_SetRenderTarget(renderer, NULL);
75 }
76
77 void
78 SDLLightmap::do_draw()
79 {
80   SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD);
81
82   SDL_Rect dst_rect;
83   dst_rect.x = 0;
84   dst_rect.y = 0;
85   dst_rect.w = width;
86   dst_rect.h = height;
87
88   SDL_RenderCopy(renderer, texture, NULL, &dst_rect);
89 }
90
91 void
92 SDLLightmap::draw_surface(const DrawingRequest& request)
93 {
94   SDLPainter::draw_surface(renderer, request);
95 }
96
97 void
98 SDLLightmap::draw_surface_part(const DrawingRequest& request)
99 {
100   SDLPainter::draw_surface_part(renderer, request);
101 }
102
103 void
104 SDLLightmap::draw_gradient(const DrawingRequest& request)
105 {
106   SDLPainter::draw_gradient(renderer, request);
107 }
108
109 void
110 SDLLightmap::draw_filled_rect(const DrawingRequest& request)
111 {
112   SDLPainter::draw_filled_rect(renderer, request);
113 }
114
115 void
116 SDLLightmap::get_light(const DrawingRequest& request) const
117 {
118   const GetLightRequest* getlightrequest
119     = (GetLightRequest*) request.request_data;
120
121   SDL_Rect rect;
122   rect.x = static_cast<int>(request.pos.x * width / SCREEN_WIDTH);
123   rect.y = static_cast<int>(request.pos.y * height / SCREEN_HEIGHT);
124   rect.w = 1;
125   rect.h = 1;
126
127   SDL_SetRenderTarget(renderer, texture);
128   Uint8 pixel[4];
129   int ret = SDL_RenderReadPixels(renderer, &rect,
130                                  SDL_PIXELFORMAT_RGB888,
131                                  pixel,
132                                  1);
133   if (ret != 0)
134   {
135     log_warning << "failed to read pixels: " << SDL_GetError() << std::endl;
136   }
137   SDL_SetRenderTarget(renderer, 0);
138
139   *(getlightrequest->color_ptr) = Color(pixel[2] / 255.0f,
140                                         pixel[1] / 255.0f,
141                                         pixel[0] / 255.0f);
142 }
143
144 /* EOF */