Merge lp:~widelands-dev/widelands/remove_software_rendering into lp:widelands
- remove_software_rendering
- Merge into trunk
Proposed by
SirVer
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 7275 | ||||||||
Proposed branch: | lp:~widelands-dev/widelands/remove_software_rendering | ||||||||
Merge into: | lp:widelands | ||||||||
Diff against target: |
3423 lines (+409/-2210) 39 files modified
src/graphic/CMakeLists.txt (+9/-13) src/graphic/gl/game_renderer.cc (+2/-2) src/graphic/gl/road_program.cc (+2/-2) src/graphic/gl/road_program.h (+3/-3) src/graphic/gl/surface.cc (+0/-171) src/graphic/gl/surface.h (+0/-68) src/graphic/gl/surface_screen.cc (+0/-8) src/graphic/gl/surface_screen.h (+2/-4) src/graphic/gl/surface_texture.cc (+7/-15) src/graphic/gl/surface_texture.h (+5/-6) src/graphic/graphic.cc (+53/-112) src/graphic/graphic.h (+1/-7) src/graphic/image_transformations.cc (+1/-9) src/graphic/sdl/game_renderer.cc (+0/-279) src/graphic/sdl/game_renderer.h (+0/-55) src/graphic/sdl/surface.cc (+0/-355) src/graphic/sdl/surface.h (+0/-77) src/graphic/sdl/terrain.cc (+0/-34) src/graphic/sdl/terrain.h (+0/-668) src/graphic/sdl/utils.cc (+0/-30) src/graphic/sdl/utils.h (+0/-29) src/graphic/sdl/vertex.h (+0/-39) src/graphic/sdl_utils.cc (+28/-0) src/graphic/sdl_utils.h (+29/-0) src/graphic/surface.cc (+163/-31) src/graphic/surface.h (+50/-36) src/graphic/text/CMakeLists.txt (+1/-0) src/graphic/text/sdl_ttf_font.cc (+1/-1) src/graphic/text/test/CMakeLists.txt (+1/-0) src/graphic/text/test/render_richtext.cc (+19/-5) src/graphic/texture.cc (+8/-79) src/graphic/texture.h (+9/-17) src/logic/map_info.cc (+4/-16) src/ui_fsmenu/options.cc (+0/-12) src/ui_fsmenu/options.h (+0/-3) src/wlapplication.cc (+8/-14) src/wlapplication.h (+1/-1) src/wlapplication_messages.cc (+1/-2) src/wui/mapview.cc (+1/-7) |
||||||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/remove_software_rendering | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
GunChleoc | Approve | ||
Review via email: mp+242587@code.launchpad.net |
Commit message
- Removes software renderering.
- Moves code from GLSurface into Surface. GLSurface is gone now.
- Changes stand alone richtext renderer to bring up a graphics system so that offscreen rendering works. This makes it unsuitable for being a unit test ran after compilation though.
Description of the change
To post a comment you must log in.
Revision history for this message
SirVer (sirver) : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/graphic/CMakeLists.txt' | |||
2 | --- src/graphic/CMakeLists.txt 2014-11-08 14:59:03 +0000 | |||
3 | +++ src/graphic/CMakeLists.txt 2014-11-23 12:03:00 +0000 | |||
4 | @@ -36,21 +36,22 @@ | |||
5 | 36 | graphic_surface | 36 | graphic_surface |
6 | 37 | ) | 37 | ) |
7 | 38 | 38 | ||
8 | 39 | wl_library(graphic_sdl_utils | ||
9 | 40 | SRCS | ||
10 | 41 | sdl_utils.h | ||
11 | 42 | sdl_utils.cc | ||
12 | 43 | USES_SDL2 | ||
13 | 44 | ) | ||
14 | 45 | |||
15 | 39 | wl_library(graphic_surface | 46 | wl_library(graphic_surface |
16 | 40 | SRCS | 47 | SRCS |
17 | 41 | compositemode.h | 48 | compositemode.h |
18 | 42 | gl/surface.cc | ||
19 | 43 | gl/surface.h | ||
20 | 44 | gl/surface_screen.cc | 49 | gl/surface_screen.cc |
21 | 45 | gl/surface_screen.h | 50 | gl/surface_screen.h |
22 | 46 | gl/surface_texture.cc | 51 | gl/surface_texture.cc |
23 | 47 | gl/surface_texture.h | 52 | gl/surface_texture.h |
24 | 48 | gl/utils.cc | 53 | gl/utils.cc |
25 | 49 | gl/utils.h | 54 | gl/utils.h |
26 | 50 | sdl/surface.cc | ||
27 | 51 | sdl/surface.h | ||
28 | 52 | sdl/utils.cc | ||
29 | 53 | sdl/utils.h | ||
30 | 54 | surface.cc | 55 | surface.cc |
31 | 55 | surface.h | 56 | surface.h |
32 | 56 | surface_cache.cc | 57 | surface_cache.cc |
33 | @@ -58,12 +59,13 @@ | |||
34 | 58 | USES_OPENGL | 59 | USES_OPENGL |
35 | 59 | USES_SDL2 | 60 | USES_SDL2 |
36 | 60 | DEPENDS | 61 | DEPENDS |
37 | 61 | base_macros | ||
38 | 62 | base_exceptions | 62 | base_exceptions |
39 | 63 | base_geometry | 63 | base_geometry |
40 | 64 | base_log | 64 | base_log |
41 | 65 | base_macros | ||
42 | 65 | graphic | 66 | graphic |
43 | 66 | graphic_color | 67 | graphic_color |
44 | 68 | graphic_sdl_utils | ||
45 | 67 | ) | 69 | ) |
46 | 68 | 70 | ||
47 | 69 | wl_library(graphic | 71 | wl_library(graphic |
48 | @@ -114,11 +116,6 @@ | |||
49 | 114 | rendertarget.h | 116 | rendertarget.h |
50 | 115 | richtext.cc | 117 | richtext.cc |
51 | 116 | richtext.h | 118 | richtext.h |
52 | 117 | sdl/game_renderer.cc | ||
53 | 118 | sdl/game_renderer.h | ||
54 | 119 | sdl/terrain.cc | ||
55 | 120 | sdl/terrain.h | ||
56 | 121 | sdl/vertex.h | ||
57 | 122 | text_parser.cc | 119 | text_parser.cc |
58 | 123 | text_parser.h | 120 | text_parser.h |
59 | 124 | texture.cc | 121 | texture.cc |
60 | @@ -150,7 +147,6 @@ | |||
61 | 150 | io_stream | 147 | io_stream |
62 | 151 | logic | 148 | logic |
63 | 152 | profile | 149 | profile |
64 | 153 | random | ||
65 | 154 | scripting | 150 | scripting |
66 | 155 | sound | 151 | sound |
67 | 156 | ui_basic | 152 | ui_basic |
68 | 157 | 153 | ||
69 | === modified file 'src/graphic/gl/game_renderer.cc' | |||
70 | --- src/graphic/gl/game_renderer.cc 2014-11-22 11:59:34 +0000 | |||
71 | +++ src/graphic/gl/game_renderer.cc 2014-11-23 12:03:00 +0000 | |||
72 | @@ -24,10 +24,10 @@ | |||
73 | 24 | #include "graphic/gl/dither_program.h" | 24 | #include "graphic/gl/dither_program.h" |
74 | 25 | #include "graphic/gl/fields_to_draw.h" | 25 | #include "graphic/gl/fields_to_draw.h" |
75 | 26 | #include "graphic/gl/road_program.h" | 26 | #include "graphic/gl/road_program.h" |
76 | 27 | #include "graphic/gl/surface.h" | ||
77 | 28 | #include "graphic/gl/terrain_program.h" | 27 | #include "graphic/gl/terrain_program.h" |
78 | 29 | #include "graphic/graphic.h" | 28 | #include "graphic/graphic.h" |
79 | 30 | #include "graphic/rendertarget.h" | 29 | #include "graphic/rendertarget.h" |
80 | 30 | #include "graphic/surface.h" | ||
81 | 31 | #include "graphic/texture.h" | 31 | #include "graphic/texture.h" |
82 | 32 | #include "logic/editor_game_base.h" | 32 | #include "logic/editor_game_base.h" |
83 | 33 | #include "logic/player.h" | 33 | #include "logic/player.h" |
84 | @@ -133,7 +133,7 @@ | |||
85 | 133 | road_program_.reset(new RoadProgram()); | 133 | road_program_.reset(new RoadProgram()); |
86 | 134 | } | 134 | } |
87 | 135 | 135 | ||
89 | 136 | GLSurface* surface = dynamic_cast<GLSurface*>(m_dst->get_surface()); | 136 | Surface* surface = m_dst->get_surface(); |
90 | 137 | if (!surface) | 137 | if (!surface) |
91 | 138 | return; | 138 | return; |
92 | 139 | 139 | ||
93 | 140 | 140 | ||
94 | === modified file 'src/graphic/gl/road_program.cc' | |||
95 | --- src/graphic/gl/road_program.cc 2014-11-09 14:20:59 +0000 | |||
96 | +++ src/graphic/gl/road_program.cc 2014-11-23 12:03:00 +0000 | |||
97 | @@ -87,7 +87,7 @@ | |||
98 | 87 | u_busy_road_texture_ = glGetUniformLocation(gl_program_.object(), "u_busy_road_texture"); | 87 | u_busy_road_texture_ = glGetUniformLocation(gl_program_.object(), "u_busy_road_texture"); |
99 | 88 | } | 88 | } |
100 | 89 | 89 | ||
102 | 90 | void RoadProgram::add_road(const GLSurface& surface, | 90 | void RoadProgram::add_road(const Surface& surface, |
103 | 91 | const FieldsToDraw::Field& start, | 91 | const FieldsToDraw::Field& start, |
104 | 92 | const FieldsToDraw::Field& end, | 92 | const FieldsToDraw::Field& end, |
105 | 93 | const Widelands::RoadType road_type) { | 93 | const Widelands::RoadType road_type) { |
106 | @@ -146,7 +146,7 @@ | |||
107 | 146 | vertices_.emplace_back(p4); | 146 | vertices_.emplace_back(p4); |
108 | 147 | } | 147 | } |
109 | 148 | 148 | ||
111 | 149 | void RoadProgram::draw(const GLSurface& surface, const FieldsToDraw& fields_to_draw) { | 149 | void RoadProgram::draw(const Surface& surface, const FieldsToDraw& fields_to_draw) { |
112 | 150 | vertices_.clear(); | 150 | vertices_.clear(); |
113 | 151 | 151 | ||
114 | 152 | for (size_t current_index = 0; current_index < fields_to_draw.size(); ++current_index) { | 152 | for (size_t current_index = 0; current_index < fields_to_draw.size(); ++current_index) { |
115 | 153 | 153 | ||
116 | === modified file 'src/graphic/gl/road_program.h' | |||
117 | --- src/graphic/gl/road_program.h 2014-11-08 18:06:17 +0000 | |||
118 | +++ src/graphic/gl/road_program.h 2014-11-23 12:03:00 +0000 | |||
119 | @@ -24,8 +24,8 @@ | |||
120 | 24 | 24 | ||
121 | 25 | #include "base/macros.h" | 25 | #include "base/macros.h" |
122 | 26 | #include "graphic/gl/fields_to_draw.h" | 26 | #include "graphic/gl/fields_to_draw.h" |
123 | 27 | #include "graphic/gl/surface.h" | ||
124 | 28 | #include "graphic/gl/utils.h" | 27 | #include "graphic/gl/utils.h" |
125 | 28 | #include "graphic/surface.h" | ||
126 | 29 | #include "logic/roadtype.h" | 29 | #include "logic/roadtype.h" |
127 | 30 | 30 | ||
128 | 31 | class RoadProgram { | 31 | class RoadProgram { |
129 | @@ -35,7 +35,7 @@ | |||
130 | 35 | 35 | ||
131 | 36 | // Draws the roads. The 'surface' is needed to convert from pixel space to | 36 | // Draws the roads. The 'surface' is needed to convert from pixel space to |
132 | 37 | // GL space. | 37 | // GL space. |
134 | 38 | void draw(const GLSurface& surface, const FieldsToDraw& fields_to_draw); | 38 | void draw(const Surface& surface, const FieldsToDraw& fields_to_draw); |
135 | 39 | 39 | ||
136 | 40 | private: | 40 | private: |
137 | 41 | struct PerVertexData { | 41 | struct PerVertexData { |
138 | @@ -55,7 +55,7 @@ | |||
139 | 55 | 55 | ||
140 | 56 | // Adds a road from 'start' to 'end' to be rendered in this frame using the | 56 | // Adds a road from 'start' to 'end' to be rendered in this frame using the |
141 | 57 | // correct texture for 'road_type'. | 57 | // correct texture for 'road_type'. |
143 | 58 | void add_road(const GLSurface& surface, | 58 | void add_road(const Surface& surface, |
144 | 59 | const FieldsToDraw::Field& start, | 59 | const FieldsToDraw::Field& start, |
145 | 60 | const FieldsToDraw::Field& end, | 60 | const FieldsToDraw::Field& end, |
146 | 61 | const Widelands::RoadType road_type); | 61 | const Widelands::RoadType road_type); |
147 | 62 | 62 | ||
148 | === removed file 'src/graphic/gl/surface.cc' | |||
149 | --- src/graphic/gl/surface.cc 2014-11-22 11:59:34 +0000 | |||
150 | +++ src/graphic/gl/surface.cc 1970-01-01 00:00:00 +0000 | |||
151 | @@ -1,171 +0,0 @@ | |||
152 | 1 | /* | ||
153 | 2 | * Copyright (C) 2006-2012 by the Widelands Development Team | ||
154 | 3 | * | ||
155 | 4 | * This program is free software; you can redistribute it and/or | ||
156 | 5 | * modify it under the terms of the GNU General Public License | ||
157 | 6 | * as published by the Free Software Foundation; either version 2 | ||
158 | 7 | * of the License, or (at your option) any later version. | ||
159 | 8 | * | ||
160 | 9 | * This program is distributed in the hope that it will be useful, | ||
161 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
162 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
163 | 12 | * GNU General Public License for more details. | ||
164 | 13 | * | ||
165 | 14 | * You should have received a copy of the GNU General Public License | ||
166 | 15 | * along with this program; if not, write to the Free Software | ||
167 | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
168 | 17 | * | ||
169 | 18 | */ | ||
170 | 19 | |||
171 | 20 | #include "graphic/gl/surface.h" | ||
172 | 21 | |||
173 | 22 | #include <cassert> | ||
174 | 23 | #include <cmath> | ||
175 | 24 | #include <cstdlib> | ||
176 | 25 | |||
177 | 26 | #include "base/macros.h" | ||
178 | 27 | #include "graphic/gl/blit_program.h" | ||
179 | 28 | #include "graphic/gl/draw_line_program.h" | ||
180 | 29 | #include "graphic/gl/draw_rect_program.h" | ||
181 | 30 | #include "graphic/gl/fill_rect_program.h" | ||
182 | 31 | #include "graphic/gl/surface_texture.h" | ||
183 | 32 | #include "graphic/graphic.h" | ||
184 | 33 | |||
185 | 34 | uint16_t GLSurface::width() const { | ||
186 | 35 | return m_w; | ||
187 | 36 | } | ||
188 | 37 | |||
189 | 38 | uint16_t GLSurface::height() const { | ||
190 | 39 | return m_h; | ||
191 | 40 | } | ||
192 | 41 | |||
193 | 42 | uint8_t * GLSurface::get_pixels() const | ||
194 | 43 | { | ||
195 | 44 | return m_pixels.get(); | ||
196 | 45 | } | ||
197 | 46 | |||
198 | 47 | uint32_t GLSurface::get_pixel(uint16_t x, uint16_t y) { | ||
199 | 48 | assert(m_pixels); | ||
200 | 49 | assert(x < m_w); | ||
201 | 50 | assert(y < m_h); | ||
202 | 51 | |||
203 | 52 | uint8_t * data = &m_pixels[y * get_pitch() + 4 * x]; | ||
204 | 53 | return *(reinterpret_cast<uint32_t *>(data)); | ||
205 | 54 | } | ||
206 | 55 | |||
207 | 56 | void GLSurface::set_pixel(uint16_t x, uint16_t y, uint32_t clr) { | ||
208 | 57 | assert(m_pixels); | ||
209 | 58 | assert(x < m_w); | ||
210 | 59 | assert(y < m_h); | ||
211 | 60 | |||
212 | 61 | uint8_t * data = &m_pixels[y * get_pitch() + 4 * x]; | ||
213 | 62 | *(reinterpret_cast<uint32_t *>(data)) = clr; | ||
214 | 63 | } | ||
215 | 64 | |||
216 | 65 | FloatRect GLSurface::to_opengl(const Rect& rect, ConversionMode mode) { | ||
217 | 66 | const float delta = mode == ConversionMode::kExact ? 0. : 0.5; | ||
218 | 67 | float x1 = rect.x + delta; | ||
219 | 68 | float y1 = rect.y + delta; | ||
220 | 69 | pixel_to_gl(&x1, &y1); | ||
221 | 70 | float x2 = rect.x + rect.w - delta; | ||
222 | 71 | float y2 = rect.y + rect.h - delta; | ||
223 | 72 | pixel_to_gl(&x2, &y2); | ||
224 | 73 | |||
225 | 74 | return FloatRect(x1, y1, x2 - x1, y2 - y1); | ||
226 | 75 | } | ||
227 | 76 | |||
228 | 77 | void GLSurface::draw_rect(const Rect& rc, const RGBColor& clr) | ||
229 | 78 | { | ||
230 | 79 | glViewport(0, 0, width(), height()); | ||
231 | 80 | DrawRectProgram::instance().draw(to_opengl(rc, ConversionMode::kMidPoint), clr); | ||
232 | 81 | } | ||
233 | 82 | |||
234 | 83 | /** | ||
235 | 84 | * Draws a filled rectangle | ||
236 | 85 | */ | ||
237 | 86 | void GLSurface::fill_rect(const Rect& rc, const RGBAColor& clr) { | ||
238 | 87 | glViewport(0, 0, width(), height()); | ||
239 | 88 | |||
240 | 89 | glBlendFunc(GL_ONE, GL_ZERO); | ||
241 | 90 | |||
242 | 91 | FillRectProgram::instance().draw(to_opengl(rc, ConversionMode::kExact), clr); | ||
243 | 92 | |||
244 | 93 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
245 | 94 | } | ||
246 | 95 | |||
247 | 96 | /** | ||
248 | 97 | * Change the brightness of the given rectangle | ||
249 | 98 | */ | ||
250 | 99 | void GLSurface::brighten_rect(const Rect& rc, const int32_t factor) | ||
251 | 100 | { | ||
252 | 101 | if (!factor) | ||
253 | 102 | return; | ||
254 | 103 | |||
255 | 104 | glViewport(0, 0, width(), height()); | ||
256 | 105 | |||
257 | 106 | // The simple trick here is to fill the rect, but using a different glBlendFunc that will sum | ||
258 | 107 | // src and target (or subtract them if factor is negative). | ||
259 | 108 | if (factor < 0) { | ||
260 | 109 | glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); | ||
261 | 110 | } | ||
262 | 111 | |||
263 | 112 | glBlendFunc(GL_ONE, GL_ONE); | ||
264 | 113 | |||
265 | 114 | const int delta = std::abs(factor); | ||
266 | 115 | FillRectProgram::instance().draw( | ||
267 | 116 | to_opengl(rc, ConversionMode::kExact), RGBAColor(delta, delta, delta, 0)); | ||
268 | 117 | |||
269 | 118 | if (factor < 0) { | ||
270 | 119 | glBlendEquation(GL_FUNC_ADD); | ||
271 | 120 | } | ||
272 | 121 | |||
273 | 122 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
274 | 123 | } | ||
275 | 124 | |||
276 | 125 | void GLSurface::draw_line | ||
277 | 126 | (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth) | ||
278 | 127 | { | ||
279 | 128 | glViewport(0, 0, width(), height()); | ||
280 | 129 | |||
281 | 130 | float gl_x1 = x1 + 0.5; | ||
282 | 131 | float gl_y1 = y1 + 0.5; | ||
283 | 132 | pixel_to_gl(&gl_x1, &gl_y1); | ||
284 | 133 | |||
285 | 134 | float gl_x2 = x2 + 0.5; | ||
286 | 135 | float gl_y2 = y2 + 0.5; | ||
287 | 136 | pixel_to_gl(&gl_x2, &gl_y2); | ||
288 | 137 | |||
289 | 138 | DrawLineProgram::instance().draw(gl_x1, gl_y1, gl_x2, gl_y2, color, gwidth); | ||
290 | 139 | } | ||
291 | 140 | |||
292 | 141 | // Converts the pixel (x, y) in a texture to a gl coordinate in [0, 1]. | ||
293 | 142 | inline void pixel_to_gl_texture(const int width, const int height, float* x, float* y) { | ||
294 | 143 | *x = (*x / width); | ||
295 | 144 | *y = (*y / height); | ||
296 | 145 | } | ||
297 | 146 | |||
298 | 147 | void GLSurface::blit | ||
299 | 148 | (const Point& dst, const Surface* image, const Rect& srcrc, Composite cm) | ||
300 | 149 | { | ||
301 | 150 | glViewport(0, 0, width(), height()); | ||
302 | 151 | |||
303 | 152 | // Source Rectangle. | ||
304 | 153 | const GLSurfaceTexture* const texture = static_cast<const GLSurfaceTexture*>(image); | ||
305 | 154 | FloatRect gl_src_rect; | ||
306 | 155 | { | ||
307 | 156 | float x1 = srcrc.x; | ||
308 | 157 | float y1 = srcrc.y; | ||
309 | 158 | pixel_to_gl_texture(texture->width(), texture->height(), &x1, &y1); | ||
310 | 159 | float x2 = srcrc.x + srcrc.w; | ||
311 | 160 | float y2 = srcrc.y + srcrc.h; | ||
312 | 161 | pixel_to_gl_texture(texture->width(), texture->height(), &x2, &y2); | ||
313 | 162 | gl_src_rect.x = x1; | ||
314 | 163 | gl_src_rect.y = y1; | ||
315 | 164 | gl_src_rect.w = x2 - x1; | ||
316 | 165 | gl_src_rect.h = y2 - y1; | ||
317 | 166 | } | ||
318 | 167 | |||
319 | 168 | const FloatRect gl_dst_rect = to_opengl(Rect(dst.x, dst.y, srcrc.w, srcrc.h), ConversionMode::kExact); | ||
320 | 169 | |||
321 | 170 | BlitProgram::instance().draw(gl_dst_rect, gl_src_rect, texture->get_gl_texture(), cm); | ||
322 | 171 | } | ||
323 | 172 | 0 | ||
324 | === removed file 'src/graphic/gl/surface.h' | |||
325 | --- src/graphic/gl/surface.h 2014-11-08 18:06:17 +0000 | |||
326 | +++ src/graphic/gl/surface.h 1970-01-01 00:00:00 +0000 | |||
327 | @@ -1,68 +0,0 @@ | |||
328 | 1 | /* | ||
329 | 2 | * Copyright (C) 2006-2012 by the Widelands Development Team | ||
330 | 3 | * | ||
331 | 4 | * This program is free software; you can redistribute it and/or | ||
332 | 5 | * modify it under the terms of the GNU General Public License | ||
333 | 6 | * as published by the Free Software Foundation; either version 2 | ||
334 | 7 | * of the License, or (at your option) any later version. | ||
335 | 8 | * | ||
336 | 9 | * This program is distributed in the hope that it will be useful, | ||
337 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
338 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
339 | 12 | * GNU General Public License for more details. | ||
340 | 13 | * | ||
341 | 14 | * You should have received a copy of the GNU General Public License | ||
342 | 15 | * along with this program; if not, write to the Free Software | ||
343 | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
344 | 17 | * | ||
345 | 18 | */ | ||
346 | 19 | |||
347 | 20 | #ifndef WL_GRAPHIC_GL_SURFACE_H | ||
348 | 21 | #define WL_GRAPHIC_GL_SURFACE_H | ||
349 | 22 | |||
350 | 23 | #include <memory> | ||
351 | 24 | |||
352 | 25 | #include "graphic/gl/system_headers.h" | ||
353 | 26 | #include "graphic/surface.h" | ||
354 | 27 | |||
355 | 28 | class GLSurface : public Surface { | ||
356 | 29 | public: | ||
357 | 30 | virtual ~GLSurface() {} | ||
358 | 31 | |||
359 | 32 | /// Interface implementations | ||
360 | 33 | uint16_t width() const override; | ||
361 | 34 | uint16_t height() const override; | ||
362 | 35 | uint8_t * get_pixels() const override; | ||
363 | 36 | void set_pixel(uint16_t x, uint16_t y, uint32_t clr) override; | ||
364 | 37 | uint32_t get_pixel(uint16_t x, uint16_t y) override; | ||
365 | 38 | void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm) override; | ||
366 | 39 | void fill_rect(const Rect&, const RGBAColor&) override; | ||
367 | 40 | void draw_rect(const Rect&, const RGBColor&) override; | ||
368 | 41 | void brighten_rect(const Rect&, int32_t factor) override; | ||
369 | 42 | virtual void draw_line | ||
370 | 43 | (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor&, uint8_t width) override; | ||
371 | 44 | |||
372 | 45 | // Converts the given pixel into an OpenGl point. This might need some | ||
373 | 46 | // flipping of axis, depending if you want to render on the screen or not. | ||
374 | 47 | virtual void pixel_to_gl(float* x, float* y) const = 0; | ||
375 | 48 | |||
376 | 49 | protected: | ||
377 | 50 | // Convert the 'rect' in pixel space into opengl space. | ||
378 | 51 | enum class ConversionMode { | ||
379 | 52 | // Convert the rect as given. | ||
380 | 53 | kExact, | ||
381 | 54 | |||
382 | 55 | // Convert the rect so that the borders are in the center | ||
383 | 56 | // of the pixels. | ||
384 | 57 | kMidPoint, | ||
385 | 58 | }; | ||
386 | 59 | FloatRect to_opengl(const Rect& rect, ConversionMode mode); | ||
387 | 60 | |||
388 | 61 | /// Logical width and height of the surface | ||
389 | 62 | uint16_t m_w, m_h; | ||
390 | 63 | |||
391 | 64 | /// Pixel data, while the texture is locked | ||
392 | 65 | std::unique_ptr<uint8_t[]> m_pixels; | ||
393 | 66 | }; | ||
394 | 67 | |||
395 | 68 | #endif // end of include guard: WL_GRAPHIC_GL_SURFACE_H | ||
396 | 69 | 0 | ||
397 | === modified file 'src/graphic/gl/surface_screen.cc' | |||
398 | --- src/graphic/gl/surface_screen.cc 2014-11-08 18:06:17 +0000 | |||
399 | +++ src/graphic/gl/surface_screen.cc 2014-11-23 12:03:00 +0000 | |||
400 | @@ -52,10 +52,6 @@ | |||
401 | 52 | } | 52 | } |
402 | 53 | } | 53 | } |
403 | 54 | 54 | ||
404 | 55 | const SDL_PixelFormat & GLSurfaceScreen::format() const { | ||
405 | 56 | return Gl::gl_rgba_format(); | ||
406 | 57 | } | ||
407 | 58 | |||
408 | 59 | void GLSurfaceScreen::lock(Surface::LockMode mode) | 55 | void GLSurfaceScreen::lock(Surface::LockMode mode) |
409 | 60 | { | 56 | { |
410 | 61 | assert(!m_pixels); | 57 | assert(!m_pixels); |
411 | @@ -85,7 +81,3 @@ | |||
412 | 85 | 81 | ||
413 | 86 | m_pixels.reset(nullptr); | 82 | m_pixels.reset(nullptr); |
414 | 87 | } | 83 | } |
415 | 88 | |||
416 | 89 | uint16_t GLSurfaceScreen::get_pitch() const { | ||
417 | 90 | return 4 * m_w; | ||
418 | 91 | } | ||
419 | 92 | 84 | ||
420 | === modified file 'src/graphic/gl/surface_screen.h' | |||
421 | --- src/graphic/gl/surface_screen.h 2014-11-08 18:06:17 +0000 | |||
422 | +++ src/graphic/gl/surface_screen.h 2014-11-23 12:03:00 +0000 | |||
423 | @@ -19,12 +19,12 @@ | |||
424 | 19 | #ifndef WL_GRAPHIC_GL_SURFACE_SCREEN_H | 19 | #ifndef WL_GRAPHIC_GL_SURFACE_SCREEN_H |
425 | 20 | #define WL_GRAPHIC_GL_SURFACE_SCREEN_H | 20 | #define WL_GRAPHIC_GL_SURFACE_SCREEN_H |
426 | 21 | 21 | ||
428 | 22 | #include "graphic/gl/surface.h" | 22 | #include "graphic/surface.h" |
429 | 23 | 23 | ||
430 | 24 | /** | 24 | /** |
431 | 25 | * This surface represents the screen in OpenGL mode. | 25 | * This surface represents the screen in OpenGL mode. |
432 | 26 | */ | 26 | */ |
434 | 27 | class GLSurfaceScreen : public GLSurface { | 27 | class GLSurfaceScreen : public Surface { |
435 | 28 | public: | 28 | public: |
436 | 29 | GLSurfaceScreen(uint16_t w, uint16_t h); | 29 | GLSurfaceScreen(uint16_t w, uint16_t h); |
437 | 30 | virtual ~GLSurfaceScreen() {} | 30 | virtual ~GLSurfaceScreen() {} |
438 | @@ -32,8 +32,6 @@ | |||
439 | 32 | /// Interface implementations | 32 | /// Interface implementations |
440 | 33 | void lock(LockMode) override; | 33 | void lock(LockMode) override; |
441 | 34 | void unlock(UnlockMode) override; | 34 | void unlock(UnlockMode) override; |
442 | 35 | uint16_t get_pitch() const override; | ||
443 | 36 | const SDL_PixelFormat & format() const override; | ||
444 | 37 | 35 | ||
445 | 38 | private: | 36 | private: |
446 | 39 | void pixel_to_gl(float* x, float* y) const override; | 37 | void pixel_to_gl(float* x, float* y) const override; |
447 | 40 | 38 | ||
448 | === modified file 'src/graphic/gl/surface_texture.cc' | |||
449 | --- src/graphic/gl/surface_texture.cc 2014-11-08 18:06:17 +0000 | |||
450 | +++ src/graphic/gl/surface_texture.cc 2014-11-23 12:03:00 +0000 | |||
451 | @@ -24,10 +24,10 @@ | |||
452 | 24 | #include "base/macros.h" | 24 | #include "base/macros.h" |
453 | 25 | #include "base/wexception.h" | 25 | #include "base/wexception.h" |
454 | 26 | #include "graphic/gl/blit_program.h" | 26 | #include "graphic/gl/blit_program.h" |
455 | 27 | #include "graphic/gl/surface.h" | ||
456 | 28 | #include "graphic/gl/utils.h" | 27 | #include "graphic/gl/utils.h" |
457 | 29 | #include "graphic/graphic.h" | 28 | #include "graphic/graphic.h" |
459 | 30 | #include "graphic/sdl/utils.h" | 29 | #include "graphic/sdl_utils.h" |
460 | 30 | #include "graphic/surface.h" | ||
461 | 31 | 31 | ||
462 | 32 | namespace { | 32 | namespace { |
463 | 33 | 33 | ||
464 | @@ -160,10 +160,6 @@ | |||
465 | 160 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 160 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
466 | 161 | } | 161 | } |
467 | 162 | 162 | ||
468 | 163 | const SDL_PixelFormat & GLSurfaceTexture::format() const { | ||
469 | 164 | return Gl::gl_rgba_format(); | ||
470 | 165 | } | ||
471 | 166 | |||
472 | 167 | void GLSurfaceTexture::lock(LockMode mode) { | 163 | void GLSurfaceTexture::lock(LockMode mode) { |
473 | 168 | if (m_w <= 0 || m_h <= 0) { | 164 | if (m_w <= 0 || m_h <= 0) { |
474 | 169 | return; | 165 | return; |
475 | @@ -194,17 +190,13 @@ | |||
476 | 194 | m_pixels.reset(nullptr); | 190 | m_pixels.reset(nullptr); |
477 | 195 | } | 191 | } |
478 | 196 | 192 | ||
479 | 197 | uint16_t GLSurfaceTexture::get_pitch() const { | ||
480 | 198 | return 4 * m_w; | ||
481 | 199 | } | ||
482 | 200 | |||
483 | 201 | void GLSurfaceTexture::draw_rect(const Rect& rectangle, const RGBColor& clr) | 193 | void GLSurfaceTexture::draw_rect(const Rect& rectangle, const RGBColor& clr) |
484 | 202 | { | 194 | { |
485 | 203 | if (m_w <= 0 || m_h <= 0) { | 195 | if (m_w <= 0 || m_h <= 0) { |
486 | 204 | return; | 196 | return; |
487 | 205 | } | 197 | } |
488 | 206 | setup_gl(m_texture); | 198 | setup_gl(m_texture); |
490 | 207 | GLSurface::draw_rect(rectangle, clr); | 199 | Surface::draw_rect(rectangle, clr); |
491 | 208 | reset_gl(); | 200 | reset_gl(); |
492 | 209 | } | 201 | } |
493 | 210 | 202 | ||
494 | @@ -219,7 +211,7 @@ | |||
495 | 219 | } | 211 | } |
496 | 220 | 212 | ||
497 | 221 | setup_gl(m_texture); | 213 | setup_gl(m_texture); |
499 | 222 | GLSurface::fill_rect(rectangle, clr); | 214 | Surface::fill_rect(rectangle, clr); |
500 | 223 | reset_gl(); | 215 | reset_gl(); |
501 | 224 | } | 216 | } |
502 | 225 | 217 | ||
503 | @@ -233,7 +225,7 @@ | |||
504 | 233 | } | 225 | } |
505 | 234 | 226 | ||
506 | 235 | setup_gl(m_texture); | 227 | setup_gl(m_texture); |
508 | 236 | GLSurface::brighten_rect(rectangle, factor); | 228 | Surface::brighten_rect(rectangle, factor); |
509 | 237 | reset_gl(); | 229 | reset_gl(); |
510 | 238 | } | 230 | } |
511 | 239 | 231 | ||
512 | @@ -245,7 +237,7 @@ | |||
513 | 245 | } | 237 | } |
514 | 246 | 238 | ||
515 | 247 | setup_gl(m_texture); | 239 | setup_gl(m_texture); |
517 | 248 | GLSurface::draw_line(x1, y1, x2, y2, color, gwidth); | 240 | Surface::draw_line(x1, y1, x2, y2, color, gwidth); |
518 | 249 | reset_gl(); | 241 | reset_gl(); |
519 | 250 | } | 242 | } |
520 | 251 | 243 | ||
521 | @@ -257,6 +249,6 @@ | |||
522 | 257 | } | 249 | } |
523 | 258 | 250 | ||
524 | 259 | setup_gl(m_texture); | 251 | setup_gl(m_texture); |
526 | 260 | GLSurface::blit(dst, src, srcrc, cm); | 252 | Surface::blit(dst, src, srcrc, cm); |
527 | 261 | reset_gl(); | 253 | reset_gl(); |
528 | 262 | } | 254 | } |
529 | 263 | 255 | ||
530 | === modified file 'src/graphic/gl/surface_texture.h' | |||
531 | --- src/graphic/gl/surface_texture.h 2014-11-08 18:06:17 +0000 | |||
532 | +++ src/graphic/gl/surface_texture.h 2014-11-23 12:03:00 +0000 | |||
533 | @@ -19,11 +19,12 @@ | |||
534 | 19 | #ifndef WL_GRAPHIC_GL_SURFACE_TEXTURE_H | 19 | #ifndef WL_GRAPHIC_GL_SURFACE_TEXTURE_H |
535 | 20 | #define WL_GRAPHIC_GL_SURFACE_TEXTURE_H | 20 | #define WL_GRAPHIC_GL_SURFACE_TEXTURE_H |
536 | 21 | 21 | ||
538 | 22 | #include "graphic/gl/surface.h" | 22 | #include "graphic/gl/system_headers.h" |
539 | 23 | #include "graphic/surface.h" | ||
540 | 23 | 24 | ||
541 | 24 | struct SDL_Surface; | 25 | struct SDL_Surface; |
542 | 25 | 26 | ||
544 | 26 | class GLSurfaceTexture : public GLSurface { | 27 | class GLSurfaceTexture : public Surface { |
545 | 27 | public: | 28 | public: |
546 | 28 | GLSurfaceTexture(SDL_Surface * surface, bool intensity = false); | 29 | GLSurfaceTexture(SDL_Surface * surface, bool intensity = false); |
547 | 29 | GLSurfaceTexture(int w, int h); | 30 | GLSurfaceTexture(int w, int h); |
548 | @@ -34,13 +35,11 @@ | |||
549 | 34 | //@{ | 35 | //@{ |
550 | 35 | void lock(LockMode) override; | 36 | void lock(LockMode) override; |
551 | 36 | void unlock(UnlockMode) override; | 37 | void unlock(UnlockMode) override; |
552 | 37 | uint16_t get_pitch() const override; | ||
553 | 38 | const SDL_PixelFormat & format() const override; | ||
554 | 39 | 38 | ||
555 | 40 | // Note: the following functions are reimplemented here though they | 39 | // Note: the following functions are reimplemented here though they |
557 | 41 | // basically only call the functions in GLSurface wrapped in calls to | 40 | // basically only call the functions in Surface wrapped in calls to |
558 | 42 | // setup_gl(), reset_gl(). The same functionality can be achieved by making | 41 | // setup_gl(), reset_gl(). The same functionality can be achieved by making |
560 | 43 | // those two functions virtual and calling them in GLSurface. However, | 42 | // those two functions virtual and calling them in Surface. However, |
561 | 44 | // especially for blit which is called very often and mostly on the screen, | 43 | // especially for blit which is called very often and mostly on the screen, |
562 | 45 | // this costs two virtual function calls which makes a notable difference in | 44 | // this costs two virtual function calls which makes a notable difference in |
563 | 46 | // profiles. | 45 | // profiles. |
564 | 47 | 46 | ||
565 | === modified file 'src/graphic/graphic.cc' | |||
566 | --- src/graphic/graphic.cc 2014-11-22 10:18:20 +0000 | |||
567 | +++ src/graphic/graphic.cc 2014-11-23 12:03:00 +0000 | |||
568 | @@ -40,7 +40,6 @@ | |||
569 | 40 | #include "graphic/image_io.h" | 40 | #include "graphic/image_io.h" |
570 | 41 | #include "graphic/image_transformations.h" | 41 | #include "graphic/image_transformations.h" |
571 | 42 | #include "graphic/rendertarget.h" | 42 | #include "graphic/rendertarget.h" |
572 | 43 | #include "graphic/sdl/surface.h" | ||
573 | 44 | #include "graphic/surface_cache.h" | 43 | #include "graphic/surface_cache.h" |
574 | 45 | #include "graphic/texture.h" | 44 | #include "graphic/texture.h" |
575 | 46 | #include "io/fileread.h" | 45 | #include "io/fileread.h" |
576 | @@ -52,7 +51,6 @@ | |||
577 | 52 | using namespace std; | 51 | using namespace std; |
578 | 53 | 52 | ||
579 | 54 | Graphic * g_gr; | 53 | Graphic * g_gr; |
580 | 55 | bool g_opengl; | ||
581 | 56 | 54 | ||
582 | 57 | namespace { | 55 | namespace { |
583 | 58 | 56 | ||
584 | @@ -91,115 +89,81 @@ | |||
585 | 91 | ImageTransformations::initialize(); | 89 | ImageTransformations::initialize(); |
586 | 92 | 90 | ||
587 | 93 | m_sdl_window = nullptr; | 91 | m_sdl_window = nullptr; |
588 | 94 | m_sdl_screen = nullptr; | ||
589 | 95 | m_sdl_renderer = nullptr; | ||
590 | 96 | m_sdl_texture = nullptr; | ||
591 | 97 | m_glcontext = nullptr; | 92 | m_glcontext = nullptr; |
592 | 98 | } | 93 | } |
593 | 99 | 94 | ||
595 | 100 | void Graphic::initialize(int32_t w, int32_t h, bool fullscreen, bool opengl) { | 95 | void Graphic::initialize(int32_t w, int32_t h, bool fullscreen) { |
596 | 101 | cleanup(); | 96 | cleanup(); |
597 | 102 | 97 | ||
614 | 103 | // Set video mode using SDL. First collect the flags | 98 | // Request an OpenGL 2 context with double buffering. |
615 | 104 | int32_t flags = 0; | 99 | SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
616 | 105 | g_opengl = false; | 100 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
617 | 106 | 101 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); | |
618 | 107 | if (opengl) { | 102 | |
619 | 108 | log("Graphics: Trying opengl\n"); | 103 | int32_t flags = SDL_WINDOW_OPENGL; |
604 | 109 | |||
605 | 110 | SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | ||
606 | 111 | |||
607 | 112 | // Request an OpenGL 2 context. | ||
608 | 113 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); | ||
609 | 114 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); | ||
610 | 115 | |||
611 | 116 | flags |= SDL_WINDOW_OPENGL; | ||
612 | 117 | } | ||
613 | 118 | |||
620 | 119 | if (fullscreen) { | 104 | if (fullscreen) { |
621 | 120 | flags |= SDL_WINDOW_FULLSCREEN; | 105 | flags |= SDL_WINDOW_FULLSCREEN; |
622 | 121 | log("Graphics: Trying FULLSCREEN\n"); | 106 | log("Graphics: Trying FULLSCREEN\n"); |
623 | 122 | } | 107 | } |
624 | 123 | 108 | ||
625 | 124 | log("Graphics: Try to set Videomode %ux%u\n", w, h); | 109 | log("Graphics: Try to set Videomode %ux%u\n", w, h); |
630 | 125 | // Here we actually set the video mode | 110 | m_sdl_window = SDL_CreateWindow( |
631 | 126 | m_sdl_window = SDL_CreateWindow("Widelands Window", | 111 | "Widelands Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags); |
628 | 127 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags); | ||
629 | 128 | |||
632 | 129 | if (!m_sdl_window) { | 112 | if (!m_sdl_window) { |
636 | 130 | log | 113 | log("Graphics: Could not set Videomode: %s, trying minimum graphics settings\n", |
637 | 131 | ("Graphics: Could not set videomode: %s, trying minimum graphics settings\n", | 114 | SDL_GetError()); |
635 | 132 | SDL_GetError()); | ||
638 | 133 | flags &= ~SDL_WINDOW_FULLSCREEN; | 115 | flags &= ~SDL_WINDOW_FULLSCREEN; |
639 | 134 | m_sdl_window = SDL_CreateWindow("Widelands Window", | 116 | m_sdl_window = SDL_CreateWindow("Widelands Window", |
640 | 135 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, | 117 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, |
641 | 136 | kFallbackGraphicsWidth, kFallbackGraphicsHeight, flags); | 118 | kFallbackGraphicsWidth, kFallbackGraphicsHeight, flags); |
642 | 137 | m_fallback_settings_in_effect = true; | 119 | m_fallback_settings_in_effect = true; |
643 | 138 | if (!m_sdl_window) { | 120 | if (!m_sdl_window) { |
646 | 139 | throw wexception | 121 | throw wexception("Graphics: could not set video mode: %s", SDL_GetError()); |
645 | 140 | ("Graphics: could not set video mode: %s", SDL_GetError()); | ||
647 | 141 | } | 122 | } |
648 | 142 | } | 123 | } |
649 | 143 | 124 | ||
650 | 144 | SDL_SetWindowTitle(m_sdl_window, ("Widelands " + build_id() + '(' + build_type() + ')').c_str()); | 125 | SDL_SetWindowTitle(m_sdl_window, ("Widelands " + build_id() + '(' + build_type() + ')').c_str()); |
651 | 145 | |||
652 | 146 | if (opengl) { | ||
653 | 147 | m_glcontext = SDL_GL_CreateContext(m_sdl_window); | ||
654 | 148 | if (m_glcontext) { | ||
655 | 149 | SDL_GL_MakeCurrent(m_sdl_window, m_glcontext); | ||
656 | 150 | } | ||
657 | 151 | |||
658 | 152 | // We now really have a working opengl screen... | ||
659 | 153 | g_opengl = true; | ||
660 | 154 | |||
661 | 155 | // See graphic/gl/system_headers.h for an explanation of the | ||
662 | 156 | // next line. | ||
663 | 157 | glewExperimental = GL_TRUE; | ||
664 | 158 | GLenum err = glewInit(); | ||
665 | 159 | if (err != GLEW_OK) { | ||
666 | 160 | log("glewInit returns %i\nYour OpenGL installation must be __very__ broken. %s\n", | ||
667 | 161 | err, glewGetErrorString(err)); | ||
668 | 162 | throw wexception("glewInit returns %i: Broken OpenGL installation.", err); | ||
669 | 163 | } | ||
670 | 164 | |||
671 | 165 | log("Graphics: OpenGL: Version \"%s\"\n", | ||
672 | 166 | reinterpret_cast<const char*>(glGetString(GL_VERSION))); | ||
673 | 167 | |||
674 | 168 | GLboolean glBool; | ||
675 | 169 | glGetBooleanv(GL_DOUBLEBUFFER, &glBool); | ||
676 | 170 | log("Graphics: OpenGL: Double buffering %s\n", (glBool == GL_TRUE) ? "enabled" : "disabled"); | ||
677 | 171 | |||
678 | 172 | GLint glInt; | ||
679 | 173 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glInt); | ||
680 | 174 | log("Graphics: OpenGL: Max texture size: %u\n", glInt); | ||
681 | 175 | |||
682 | 176 | SDL_GL_SetSwapInterval(1); | ||
683 | 177 | SDL_GL_SwapWindow(m_sdl_window); | ||
684 | 178 | |||
685 | 179 | glDrawBuffer(GL_BACK); | ||
686 | 180 | |||
687 | 181 | glDisable(GL_DEPTH_TEST); | ||
688 | 182 | glEnable(GL_TEXTURE_2D); | ||
689 | 183 | glEnable(GL_BLEND); | ||
690 | 184 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
691 | 185 | |||
692 | 186 | glClear(GL_COLOR_BUFFER_BIT); | ||
693 | 187 | |||
694 | 188 | screen_.reset(new GLSurfaceScreen(w, h)); | ||
695 | 189 | } else { | ||
696 | 190 | m_sdl_renderer = SDL_CreateRenderer(m_sdl_window, -1, 0); | ||
697 | 191 | uint32_t rmask, gmask, bmask, amask; | ||
698 | 192 | int bpp; | ||
699 | 193 | SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB8888, &bpp, &rmask, &gmask, &bmask, &amask); | ||
700 | 194 | m_sdl_screen = SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask); | ||
701 | 195 | m_sdl_texture = SDL_CreateTexture(m_sdl_renderer, | ||
702 | 196 | SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, | ||
703 | 197 | w, h); | ||
704 | 198 | screen_.reset(new SDLSurface(m_sdl_screen, false)); | ||
705 | 199 | } | ||
706 | 200 | |||
707 | 201 | set_icon(m_sdl_window); | 126 | set_icon(m_sdl_window); |
708 | 202 | 127 | ||
709 | 128 | m_glcontext = SDL_GL_CreateContext(m_sdl_window); | ||
710 | 129 | SDL_GL_MakeCurrent(m_sdl_window, m_glcontext); | ||
711 | 130 | |||
712 | 131 | // See graphic/gl/system_headers.h for an explanation of the | ||
713 | 132 | // next line. | ||
714 | 133 | glewExperimental = GL_TRUE; | ||
715 | 134 | GLenum err = glewInit(); | ||
716 | 135 | if (err != GLEW_OK) { | ||
717 | 136 | log("glewInit returns %i\nYour OpenGL installation must be __very__ broken. %s\n", | ||
718 | 137 | err, glewGetErrorString(err)); | ||
719 | 138 | throw wexception("glewInit returns %i: Broken OpenGL installation.", err); | ||
720 | 139 | } | ||
721 | 140 | |||
722 | 141 | log("Graphics: OpenGL: Version \"%s\"\n", | ||
723 | 142 | reinterpret_cast<const char*>(glGetString(GL_VERSION))); | ||
724 | 143 | |||
725 | 144 | GLboolean glBool; | ||
726 | 145 | glGetBooleanv(GL_DOUBLEBUFFER, &glBool); | ||
727 | 146 | log("Graphics: OpenGL: Double buffering %s\n", (glBool == GL_TRUE) ? "enabled" : "disabled"); | ||
728 | 147 | |||
729 | 148 | GLint glInt; | ||
730 | 149 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glInt); | ||
731 | 150 | log("Graphics: OpenGL: Max texture size: %u\n", glInt); | ||
732 | 151 | |||
733 | 152 | SDL_GL_SetSwapInterval(1); | ||
734 | 153 | |||
735 | 154 | glDrawBuffer(GL_BACK); | ||
736 | 155 | |||
737 | 156 | glDisable(GL_DEPTH_TEST); | ||
738 | 157 | glEnable(GL_TEXTURE_2D); | ||
739 | 158 | glEnable(GL_BLEND); | ||
740 | 159 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
741 | 160 | |||
742 | 161 | glClear(GL_COLOR_BUFFER_BIT); | ||
743 | 162 | |||
744 | 163 | SDL_GL_SwapWindow(m_sdl_window); | ||
745 | 164 | |||
746 | 165 | screen_.reset(new GLSurfaceScreen(w, h)); | ||
747 | 166 | |||
748 | 203 | /* Information about the video capabilities. */ | 167 | /* Information about the video capabilities. */ |
749 | 204 | { | 168 | { |
750 | 205 | SDL_DisplayMode disp_mode; | 169 | SDL_DisplayMode disp_mode; |
751 | @@ -216,8 +180,6 @@ | |||
752 | 216 | assert(SDL_BYTESPERPIXEL(disp_mode.format) == 4); | 180 | assert(SDL_BYTESPERPIXEL(disp_mode.format) == 4); |
753 | 217 | } | 181 | } |
754 | 218 | 182 | ||
755 | 219 | Surface::display_format_is_now_defined(); | ||
756 | 220 | |||
757 | 221 | m_rendertarget.reset(new RenderTarget(screen_.get())); | 183 | m_rendertarget.reset(new RenderTarget(screen_.get())); |
758 | 222 | 184 | ||
759 | 223 | pic_road_normal_.reset(load_image("world/pics/roadt_normal.png")); | 185 | pic_road_normal_.reset(load_image("world/pics/roadt_normal.png")); |
760 | @@ -236,14 +198,6 @@ | |||
761 | 236 | if (UI::g_fh) | 198 | if (UI::g_fh) |
762 | 237 | UI::g_fh->flush(); | 199 | UI::g_fh->flush(); |
763 | 238 | 200 | ||
764 | 239 | if (m_sdl_texture) { | ||
765 | 240 | SDL_DestroyTexture(m_sdl_texture); | ||
766 | 241 | m_sdl_texture = nullptr; | ||
767 | 242 | } | ||
768 | 243 | if (m_sdl_screen) { | ||
769 | 244 | SDL_FreeSurface(m_sdl_screen); | ||
770 | 245 | m_sdl_screen = nullptr; | ||
771 | 246 | } | ||
772 | 247 | if (m_sdl_window) { | 201 | if (m_sdl_window) { |
773 | 248 | SDL_DestroyWindow(m_sdl_window); | 202 | SDL_DestroyWindow(m_sdl_window); |
774 | 249 | m_sdl_window = nullptr; | 203 | m_sdl_window = nullptr; |
775 | @@ -329,16 +283,7 @@ | |||
776 | 329 | */ | 283 | */ |
777 | 330 | void Graphic::refresh() | 284 | void Graphic::refresh() |
778 | 331 | { | 285 | { |
789 | 332 | if (g_opengl) { | 286 | SDL_GL_SwapWindow(m_sdl_window); |
780 | 333 | SDL_GL_SwapWindow(m_sdl_window); | ||
781 | 334 | m_update = false; | ||
782 | 335 | return; | ||
783 | 336 | } | ||
784 | 337 | |||
785 | 338 | SDL_UpdateTexture(m_sdl_texture, nullptr, m_sdl_screen->pixels, m_sdl_screen->pitch); | ||
786 | 339 | SDL_RenderClear(m_sdl_renderer); | ||
787 | 340 | SDL_RenderCopy(m_sdl_renderer, m_sdl_texture, nullptr, nullptr); | ||
788 | 341 | SDL_RenderPresent(m_sdl_renderer); | ||
790 | 342 | m_update = false; | 287 | m_update = false; |
791 | 343 | } | 288 | } |
792 | 344 | 289 | ||
793 | @@ -355,11 +300,7 @@ | |||
794 | 355 | 300 | ||
795 | 356 | uint32_t Graphic::new_maptexture(const std::vector<std::string>& texture_files, const uint32_t frametime) | 301 | uint32_t Graphic::new_maptexture(const std::vector<std::string>& texture_files, const uint32_t frametime) |
796 | 357 | { | 302 | { |
802 | 358 | SDL_PixelFormat* pixel_fmt = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888); | 303 | m_maptextures.emplace_back(new Texture(texture_files, frametime)); |
798 | 359 | m_maptextures.emplace_back(new Texture(texture_files, frametime, *pixel_fmt)); | ||
799 | 360 | if (pixel_fmt) { | ||
800 | 361 | SDL_FreeFormat(pixel_fmt); | ||
801 | 362 | } | ||
803 | 363 | return m_maptextures.size(); // ID 1 is at m_maptextures[0] | 304 | return m_maptextures.size(); // ID 1 is at m_maptextures[0] |
804 | 364 | } | 305 | } |
805 | 365 | 306 | ||
806 | 366 | 307 | ||
807 | === modified file 'src/graphic/graphic.h' | |||
808 | --- src/graphic/graphic.h 2014-11-13 06:45:36 +0000 | |||
809 | +++ src/graphic/graphic.h 2014-11-23 12:03:00 +0000 | |||
810 | @@ -35,7 +35,6 @@ | |||
811 | 35 | class RenderTarget; | 35 | class RenderTarget; |
812 | 36 | class Surface; | 36 | class Surface; |
813 | 37 | class SurfaceCache; | 37 | class SurfaceCache; |
814 | 38 | struct SDL_Surface; | ||
815 | 39 | class StreamWrite; | 38 | class StreamWrite; |
816 | 40 | struct Texture; | 39 | struct Texture; |
817 | 41 | 40 | ||
818 | @@ -51,8 +50,7 @@ | |||
819 | 51 | ~Graphic(); | 50 | ~Graphic(); |
820 | 52 | 51 | ||
821 | 53 | // Initialize or reinitialize the graphics system. Throws on error. | 52 | // Initialize or reinitialize the graphics system. Throws on error. |
824 | 54 | void initialize | 53 | void initialize(int32_t w, int32_t h, bool fullscreen); |
823 | 55 | (int32_t w, int32_t h, bool fullscreen, bool opengl); | ||
825 | 56 | 54 | ||
826 | 57 | int32_t get_xres(); | 55 | int32_t get_xres(); |
827 | 58 | int32_t get_yres(); | 56 | int32_t get_yres(); |
828 | @@ -94,10 +92,7 @@ | |||
829 | 94 | /// This saves a copy of the screen SDL_Surface. This is needed for | 92 | /// This saves a copy of the screen SDL_Surface. This is needed for |
830 | 95 | /// opengl rendering as the SurfaceOpenGL does not use it. It allows | 93 | /// opengl rendering as the SurfaceOpenGL does not use it. It allows |
831 | 96 | /// manipulation the screen context. | 94 | /// manipulation the screen context. |
832 | 97 | SDL_Surface * m_sdl_screen; | ||
833 | 98 | SDL_Renderer * m_sdl_renderer; | ||
834 | 99 | SDL_Window * m_sdl_window; | 95 | SDL_Window * m_sdl_window; |
835 | 100 | SDL_Texture * m_sdl_texture; | ||
836 | 101 | SDL_GLContext m_glcontext; | 96 | SDL_GLContext m_glcontext; |
837 | 102 | /// A RenderTarget for screen_. This is initialized during init() | 97 | /// A RenderTarget for screen_. This is initialized during init() |
838 | 103 | std::unique_ptr<RenderTarget> m_rendertarget; | 98 | std::unique_ptr<RenderTarget> m_rendertarget; |
839 | @@ -120,6 +115,5 @@ | |||
840 | 120 | }; | 115 | }; |
841 | 121 | 116 | ||
842 | 122 | extern Graphic * g_gr; | 117 | extern Graphic * g_gr; |
843 | 123 | extern bool g_opengl; | ||
844 | 124 | 118 | ||
845 | 125 | #endif // end of include guard: WL_GRAPHIC_GRAPHIC_H | 119 | #endif // end of include guard: WL_GRAPHIC_GRAPHIC_H |
846 | 126 | 120 | ||
847 | === modified file 'src/graphic/image_transformations.cc' | |||
848 | --- src/graphic/image_transformations.cc 2014-11-02 20:15:01 +0000 | |||
849 | +++ src/graphic/image_transformations.cc 2014-11-23 12:03:00 +0000 | |||
850 | @@ -28,7 +28,6 @@ | |||
851 | 28 | #include "base/macros.h" | 28 | #include "base/macros.h" |
852 | 29 | #include "graphic/color.h" | 29 | #include "graphic/color.h" |
853 | 30 | #include "graphic/graphic.h" | 30 | #include "graphic/graphic.h" |
854 | 31 | #include "graphic/sdl/surface.h" | ||
855 | 32 | #include "graphic/surface.h" | 31 | #include "graphic/surface.h" |
856 | 33 | #include "graphic/surface_cache.h" | 32 | #include "graphic/surface_cache.h" |
857 | 34 | 33 | ||
858 | @@ -87,15 +86,8 @@ | |||
859 | 87 | Rect srcrect = Rect(Point(0, 0), src->width(), src->height()); | 86 | Rect srcrect = Rect(Point(0, 0), src->width(), src->height()); |
860 | 88 | 87 | ||
861 | 89 | // Second step: get source material | 88 | // Second step: get source material |
863 | 90 | SDL_Surface * srcsdl = nullptr; | 89 | SDL_Surface * srcsdl = extract_sdl_surface(*src, srcrect); |
864 | 91 | bool free_source = true; | 90 | bool free_source = true; |
865 | 92 | if (upcast(const SDLSurface, sdlsrcsurf, src)) { | ||
866 | 93 | srcsdl = sdlsrcsurf->get_sdl_surface(); | ||
867 | 94 | free_source = false; | ||
868 | 95 | } else { | ||
869 | 96 | // This is in OpenGL | ||
870 | 97 | srcsdl = extract_sdl_surface(*src, srcrect); | ||
871 | 98 | } | ||
872 | 99 | 91 | ||
873 | 100 | // If we actually shrink a surface, ballpark the zoom so that the shrinking | 92 | // If we actually shrink a surface, ballpark the zoom so that the shrinking |
874 | 101 | // effect is weakened. | 93 | // effect is weakened. |
875 | 102 | 94 | ||
876 | === removed directory 'src/graphic/sdl' | |||
877 | === removed file 'src/graphic/sdl/game_renderer.cc' | |||
878 | --- src/graphic/sdl/game_renderer.cc 2014-09-27 18:53:55 +0000 | |||
879 | +++ src/graphic/sdl/game_renderer.cc 1970-01-01 00:00:00 +0000 | |||
880 | @@ -1,279 +0,0 @@ | |||
881 | 1 | /* | ||
882 | 2 | * Copyright (C) 2010-2013 by the Widelands Development Team | ||
883 | 3 | * | ||
884 | 4 | * This program is free software; you can redistribute it and/or | ||
885 | 5 | * modify it under the terms of the GNU General Public License | ||
886 | 6 | * as published by the Free Software Foundation; either version 2 | ||
887 | 7 | * of the License, or (at your option) any later version. | ||
888 | 8 | * | ||
889 | 9 | * This program is distributed in the hope that it will be useful, | ||
890 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
891 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
892 | 12 | * GNU General Public License for more details. | ||
893 | 13 | * | ||
894 | 14 | * You should have received a copy of the GNU General Public License | ||
895 | 15 | * along with this program; if not, write to the Free Software | ||
896 | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
897 | 17 | * | ||
898 | 18 | */ | ||
899 | 19 | |||
900 | 20 | #include "graphic/sdl/game_renderer.h" | ||
901 | 21 | |||
902 | 22 | #include "graphic/rendertarget.h" | ||
903 | 23 | #include "graphic/sdl/terrain.h" | ||
904 | 24 | #include "logic/field.h" | ||
905 | 25 | #include "logic/map.h" | ||
906 | 26 | #include "logic/player.h" | ||
907 | 27 | #include "logic/world/terrain_description.h" | ||
908 | 28 | #include "logic/world/world.h" | ||
909 | 29 | #include "wui/overlay_manager.h" | ||
910 | 30 | |||
911 | 31 | |||
912 | 32 | using namespace Widelands; | ||
913 | 33 | |||
914 | 34 | ///This is used by rendermap to calculate the brightness of the terrain. | ||
915 | 35 | inline static int8_t node_brightness | ||
916 | 36 | (Widelands::Time const gametime, | ||
917 | 37 | Widelands::Time const last_seen, | ||
918 | 38 | Widelands::Vision const vision, | ||
919 | 39 | int8_t result) | ||
920 | 40 | { | ||
921 | 41 | if (vision == 0) | ||
922 | 42 | result = -128; | ||
923 | 43 | else if (vision == 1) { | ||
924 | 44 | assert(last_seen <= gametime); | ||
925 | 45 | Widelands::Duration const time_ago = gametime - last_seen; | ||
926 | 46 | result = | ||
927 | 47 | static_cast<int16_t> | ||
928 | 48 | (((static_cast<int16_t>(result) + 128) >> 1) | ||
929 | 49 | * | ||
930 | 50 | (1.0 + (time_ago < 45000 ? expf(-8.46126929e-5 * time_ago) : 0))) | ||
931 | 51 | - | ||
932 | 52 | 128; | ||
933 | 53 | } | ||
934 | 54 | |||
935 | 55 | return result; | ||
936 | 56 | } | ||
937 | 57 | |||
938 | 58 | |||
939 | 59 | void SdlGameRenderer::draw() | ||
940 | 60 | { | ||
941 | 61 | draw_terrain(); | ||
942 | 62 | draw_objects(); | ||
943 | 63 | } | ||
944 | 64 | |||
945 | 65 | void SdlGameRenderer::draw_terrain() | ||
946 | 66 | { | ||
947 | 67 | if (m_player && !m_player->see_all()) | ||
948 | 68 | m_dst->get_surface()->fill_rect(m_dst->get_rect(), RGBAColor(0, 0, 0, 255)); | ||
949 | 69 | |||
950 | 70 | const Map & map = m_egbase->map(); | ||
951 | 71 | const World & world = m_egbase->world(); | ||
952 | 72 | uint32_t const mapwidth = map.get_width(); | ||
953 | 73 | |||
954 | 74 | #define get_terrain_texture(ter) \ | ||
955 | 75 | (g_gr->get_maptexture_data(world.terrain_descr((ter)).get_texture())) | ||
956 | 76 | |||
957 | 77 | int32_t dx = m_maxfx - m_minfx + 1; | ||
958 | 78 | int32_t dy = m_maxfy - m_minfy + 1; | ||
959 | 79 | int32_t linear_fy = m_minfy; | ||
960 | 80 | int32_t b_posy = linear_fy * TRIANGLE_HEIGHT + m_dst_offset.y; | ||
961 | 81 | |||
962 | 82 | Widelands::Time const gametime = m_egbase->get_gametime(); | ||
963 | 83 | |||
964 | 84 | while (dy--) { | ||
965 | 85 | const int32_t posy = b_posy; | ||
966 | 86 | b_posy += TRIANGLE_HEIGHT; | ||
967 | 87 | const int32_t linear_fx = m_minfx; | ||
968 | 88 | FCoords r(Coords(linear_fx, linear_fy)); | ||
969 | 89 | FCoords br(Coords(linear_fx + (linear_fy & 1) - 1, linear_fy + 1)); | ||
970 | 90 | int32_t r_posx = | ||
971 | 91 | r.x * TRIANGLE_WIDTH | ||
972 | 92 | + | ||
973 | 93 | (linear_fy & 1) * (TRIANGLE_WIDTH / 2) | ||
974 | 94 | + | ||
975 | 95 | m_dst_offset.x; | ||
976 | 96 | int32_t br_posx = r_posx - TRIANGLE_WIDTH / 2; | ||
977 | 97 | |||
978 | 98 | // Calculate safe (bounded) field coordinates and get field pointers | ||
979 | 99 | map.normalize_coords(r); | ||
980 | 100 | map.normalize_coords(br); | ||
981 | 101 | MapIndex r_index = Map::get_index (r, mapwidth); | ||
982 | 102 | r.field = &map[r_index]; | ||
983 | 103 | MapIndex br_index = Map::get_index(br, mapwidth); | ||
984 | 104 | br.field = &map[br_index]; | ||
985 | 105 | FCoords tr; | ||
986 | 106 | map.get_tln(r, &tr); | ||
987 | 107 | MapIndex tr_index = tr.field - &map[0]; | ||
988 | 108 | |||
989 | 109 | const Texture * f_r_texture; | ||
990 | 110 | |||
991 | 111 | if (m_player && !m_player->see_all()) { | ||
992 | 112 | const Player::Field & l_pf = m_player->fields()[Map::get_index(map.l_n(r), mapwidth)]; | ||
993 | 113 | f_r_texture = get_terrain_texture(l_pf.terrains.r); | ||
994 | 114 | } else { | ||
995 | 115 | f_r_texture = get_terrain_texture(map.l_n(r).field->get_terrains().r); | ||
996 | 116 | } | ||
997 | 117 | |||
998 | 118 | uint32_t count = dx; | ||
999 | 119 | |||
1000 | 120 | while (count--) { | ||
1001 | 121 | const FCoords bl = br; | ||
1002 | 122 | const FCoords f = r; | ||
1003 | 123 | const int32_t f_posx = r_posx; | ||
1004 | 124 | const int32_t bl_posx = br_posx; | ||
1005 | 125 | MapIndex f_index = r_index; | ||
1006 | 126 | MapIndex bl_index = br_index; | ||
1007 | 127 | move_r(mapwidth, tr, tr_index); | ||
1008 | 128 | move_r(mapwidth, r, r_index); | ||
1009 | 129 | move_r(mapwidth, br, br_index); | ||
1010 | 130 | r_posx += TRIANGLE_WIDTH; | ||
1011 | 131 | br_posx += TRIANGLE_WIDTH; | ||
1012 | 132 | |||
1013 | 133 | const Texture * l_r_texture = f_r_texture; | ||
1014 | 134 | const Texture * f_d_texture; | ||
1015 | 135 | const Texture * tr_d_texture; | ||
1016 | 136 | uint8_t roads; | ||
1017 | 137 | int8_t f_brightness; | ||
1018 | 138 | int8_t r_brightness; | ||
1019 | 139 | int8_t bl_brightness; | ||
1020 | 140 | int8_t br_brightness; | ||
1021 | 141 | |||
1022 | 142 | if (m_player && !m_player->see_all()) { | ||
1023 | 143 | const Player::Field & f_pf = m_player->fields()[f_index]; | ||
1024 | 144 | const Player::Field & r_pf = m_player->fields()[r_index]; | ||
1025 | 145 | const Player::Field & bl_pf = m_player->fields()[bl_index]; | ||
1026 | 146 | const Player::Field & br_pf = m_player->fields()[br_index]; | ||
1027 | 147 | const Player::Field & tr_pf = m_player->fields()[tr_index]; | ||
1028 | 148 | |||
1029 | 149 | f_r_texture = get_terrain_texture(f_pf.terrains.r); | ||
1030 | 150 | f_d_texture = get_terrain_texture(f_pf.terrains.d); | ||
1031 | 151 | tr_d_texture = get_terrain_texture(tr_pf.terrains.d); | ||
1032 | 152 | |||
1033 | 153 | roads = f_pf.roads; | ||
1034 | 154 | |||
1035 | 155 | f_brightness = node_brightness | ||
1036 | 156 | (gametime, f_pf.time_node_last_unseen, | ||
1037 | 157 | f_pf.vision, f.field->get_brightness()); | ||
1038 | 158 | r_brightness = node_brightness | ||
1039 | 159 | (gametime, r_pf.time_node_last_unseen, | ||
1040 | 160 | r_pf.vision, r.field->get_brightness()); | ||
1041 | 161 | bl_brightness = node_brightness | ||
1042 | 162 | (gametime, bl_pf.time_node_last_unseen, | ||
1043 | 163 | bl_pf.vision, bl.field->get_brightness()); | ||
1044 | 164 | br_brightness = node_brightness | ||
1045 | 165 | (gametime, br_pf.time_node_last_unseen, | ||
1046 | 166 | br_pf.vision, br.field->get_brightness()); | ||
1047 | 167 | } else { | ||
1048 | 168 | f_r_texture = get_terrain_texture(f.field->get_terrains().r); | ||
1049 | 169 | f_d_texture = get_terrain_texture(f.field->get_terrains().d); | ||
1050 | 170 | tr_d_texture = get_terrain_texture(tr.field->get_terrains().d); | ||
1051 | 171 | |||
1052 | 172 | roads = f.field->get_roads(); | ||
1053 | 173 | |||
1054 | 174 | f_brightness = f.field->get_brightness(); | ||
1055 | 175 | r_brightness = r.field->get_brightness(); | ||
1056 | 176 | bl_brightness = bl.field->get_brightness(); | ||
1057 | 177 | br_brightness = br.field->get_brightness(); | ||
1058 | 178 | } | ||
1059 | 179 | roads |= map.overlay_manager().get_road_overlay(f); | ||
1060 | 180 | |||
1061 | 181 | Vertex f_vert | ||
1062 | 182 | (f_posx, posy - f.field->get_height() * HEIGHT_FACTOR, | ||
1063 | 183 | f_brightness, 0, 0); | ||
1064 | 184 | Vertex r_vert | ||
1065 | 185 | (r_posx, posy - r.field->get_height() * HEIGHT_FACTOR, | ||
1066 | 186 | r_brightness, TRIANGLE_WIDTH, 0); | ||
1067 | 187 | Vertex bl_vert | ||
1068 | 188 | (bl_posx, b_posy - bl.field->get_height() * HEIGHT_FACTOR, | ||
1069 | 189 | bl_brightness, 0, 64); | ||
1070 | 190 | Vertex br_vert | ||
1071 | 191 | (br_posx, b_posy - br.field->get_height() * HEIGHT_FACTOR, | ||
1072 | 192 | br_brightness, TRIANGLE_WIDTH, 64); | ||
1073 | 193 | |||
1074 | 194 | if (linear_fy & 1) { | ||
1075 | 195 | f_vert.tx += TRIANGLE_WIDTH / 2; | ||
1076 | 196 | r_vert.tx += TRIANGLE_WIDTH / 2; | ||
1077 | 197 | } else { | ||
1078 | 198 | f_vert.tx += TRIANGLE_WIDTH; | ||
1079 | 199 | r_vert.tx += TRIANGLE_WIDTH; | ||
1080 | 200 | bl_vert.tx += TRIANGLE_WIDTH / 2; | ||
1081 | 201 | br_vert.tx += TRIANGLE_WIDTH / 2; | ||
1082 | 202 | } | ||
1083 | 203 | |||
1084 | 204 | draw_field // Render ground | ||
1085 | 205 | (*m_dst, | ||
1086 | 206 | f_vert, r_vert, bl_vert, br_vert, | ||
1087 | 207 | roads, | ||
1088 | 208 | *tr_d_texture, *l_r_texture, *f_d_texture, *f_r_texture); | ||
1089 | 209 | } | ||
1090 | 210 | |||
1091 | 211 | ++linear_fy; | ||
1092 | 212 | } | ||
1093 | 213 | |||
1094 | 214 | #undef get_terrain_texture | ||
1095 | 215 | } | ||
1096 | 216 | |||
1097 | 217 | |||
1098 | 218 | /** | ||
1099 | 219 | * Draw ground textures and roads for the given parallelogram (two triangles) | ||
1100 | 220 | * into the bitmap. | ||
1101 | 221 | * | ||
1102 | 222 | * Vertices: | ||
1103 | 223 | * - f_vert vertex of the field | ||
1104 | 224 | * - r_vert vertex right of the field | ||
1105 | 225 | * - bl_vert vertex bottom left of the field | ||
1106 | 226 | * - br_vert vertex bottom right of the field | ||
1107 | 227 | * | ||
1108 | 228 | * Textures: | ||
1109 | 229 | * - f_r_texture Terrain of the triangle right of the field | ||
1110 | 230 | * - f_d_texture Terrain of the triangle under of the field | ||
1111 | 231 | * - tr_d_texture Terrain of the triangle top of the right triangle ?? | ||
1112 | 232 | * - l_r_texture Terrain of the triangle left of the down triangle ?? | ||
1113 | 233 | * | ||
1114 | 234 | * (tr_d) | ||
1115 | 235 | * | ||
1116 | 236 | * (f) *------* (r) | ||
1117 | 237 | * / \ r / | ||
1118 | 238 | * (l_r) / \ / | ||
1119 | 239 | * / d \/ | ||
1120 | 240 | * (bl) *------* (br) | ||
1121 | 241 | */ | ||
1122 | 242 | void SdlGameRenderer::draw_field | ||
1123 | 243 | (RenderTarget & dst, | ||
1124 | 244 | const Vertex & f_vert, | ||
1125 | 245 | const Vertex & r_vert, | ||
1126 | 246 | const Vertex & bl_vert, | ||
1127 | 247 | const Vertex & br_vert, | ||
1128 | 248 | uint8_t roads, | ||
1129 | 249 | const Texture & tr_d_texture, | ||
1130 | 250 | const Texture & l_r_texture, | ||
1131 | 251 | const Texture & f_d_texture, | ||
1132 | 252 | const Texture & f_r_texture) | ||
1133 | 253 | { | ||
1134 | 254 | upcast(SDLSurface, sdlsurf, dst.get_surface()); | ||
1135 | 255 | if (sdlsurf) | ||
1136 | 256 | { | ||
1137 | 257 | sdlsurf->set_subwin(dst.get_rect()); | ||
1138 | 258 | switch (sdlsurf->format().BytesPerPixel) { | ||
1139 | 259 | case 2: | ||
1140 | 260 | draw_field_int<uint16_t> | ||
1141 | 261 | (*sdlsurf, | ||
1142 | 262 | f_vert, r_vert, bl_vert, br_vert, | ||
1143 | 263 | roads, | ||
1144 | 264 | tr_d_texture, l_r_texture, f_d_texture, f_r_texture); | ||
1145 | 265 | break; | ||
1146 | 266 | case 4: | ||
1147 | 267 | draw_field_int<uint32_t> | ||
1148 | 268 | (*sdlsurf, | ||
1149 | 269 | f_vert, r_vert, bl_vert, br_vert, | ||
1150 | 270 | roads, | ||
1151 | 271 | tr_d_texture, l_r_texture, f_d_texture, f_r_texture); | ||
1152 | 272 | break; | ||
1153 | 273 | default: | ||
1154 | 274 | assert(false); | ||
1155 | 275 | break; | ||
1156 | 276 | } | ||
1157 | 277 | sdlsurf->unset_subwin(); | ||
1158 | 278 | } | ||
1159 | 279 | } | ||
1160 | 280 | 0 | ||
1161 | === removed file 'src/graphic/sdl/game_renderer.h' | |||
1162 | --- src/graphic/sdl/game_renderer.h 2014-09-27 18:53:55 +0000 | |||
1163 | +++ src/graphic/sdl/game_renderer.h 1970-01-01 00:00:00 +0000 | |||
1164 | @@ -1,55 +0,0 @@ | |||
1165 | 1 | /* | ||
1166 | 2 | * Copyright (C) 2010-2013 by the Widelands Development Team | ||
1167 | 3 | * | ||
1168 | 4 | * This program is free software; you can redistribute it and/or | ||
1169 | 5 | * modify it under the terms of the GNU General Public License | ||
1170 | 6 | * as published by the Free Software Foundation; either version 2 | ||
1171 | 7 | * of the License, or (at your option) any later version. | ||
1172 | 8 | * | ||
1173 | 9 | * This program is distributed in the hope that it will be useful, | ||
1174 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1175 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1176 | 12 | * GNU General Public License for more details. | ||
1177 | 13 | * | ||
1178 | 14 | * You should have received a copy of the GNU General Public License | ||
1179 | 15 | * along with this program; if not, write to the Free Software | ||
1180 | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
1181 | 17 | * | ||
1182 | 18 | */ | ||
1183 | 19 | |||
1184 | 20 | #ifndef WL_GRAPHIC_SDL_GAME_RENDERER_H | ||
1185 | 21 | #define WL_GRAPHIC_SDL_GAME_RENDERER_H | ||
1186 | 22 | |||
1187 | 23 | #include "graphic/game_renderer.h" | ||
1188 | 24 | |||
1189 | 25 | struct Texture; | ||
1190 | 26 | struct Vertex; | ||
1191 | 27 | |||
1192 | 28 | /** | ||
1193 | 29 | * Software-rendering implementation of @ref GameRenderer. | ||
1194 | 30 | */ | ||
1195 | 31 | class SdlGameRenderer : public GameRenderer { | ||
1196 | 32 | protected: | ||
1197 | 33 | void draw() override; | ||
1198 | 34 | |||
1199 | 35 | private: | ||
1200 | 36 | void draw_terrain(); | ||
1201 | 37 | |||
1202 | 38 | /** | ||
1203 | 39 | * Helper function to draw two terrain triangles. This is called from the | ||
1204 | 40 | * rendermap() functions. | ||
1205 | 41 | */ | ||
1206 | 42 | void draw_field | ||
1207 | 43 | (RenderTarget & dst, | ||
1208 | 44 | const Vertex & f_vert, | ||
1209 | 45 | const Vertex & r_vert, | ||
1210 | 46 | const Vertex & bl_vert, | ||
1211 | 47 | const Vertex & br_vert, | ||
1212 | 48 | uint8_t roads, | ||
1213 | 49 | const Texture & tr_d_texture, | ||
1214 | 50 | const Texture & l_r_texture, | ||
1215 | 51 | const Texture & f_d_texture, | ||
1216 | 52 | const Texture & f_r_texture); | ||
1217 | 53 | }; | ||
1218 | 54 | |||
1219 | 55 | #endif // end of include guard: WL_GRAPHIC_SDL_GAME_RENDERER_H | ||
1220 | 56 | 0 | ||
1221 | === removed file 'src/graphic/sdl/surface.cc' | |||
1222 | --- src/graphic/sdl/surface.cc 2014-11-02 20:31:40 +0000 | |||
1223 | +++ src/graphic/sdl/surface.cc 1970-01-01 00:00:00 +0000 | |||
1224 | @@ -1,355 +0,0 @@ | |||
1225 | 1 | /* | ||
1226 | 2 | * Copyright (C) 2002-2004, 2007-2013 by the Widelands Development Team | ||
1227 | 3 | * | ||
1228 | 4 | * This program is free software; you can redistribute it and/or | ||
1229 | 5 | * modify it under the terms of the GNU General Public License | ||
1230 | 6 | * as published by the Free Software Foundation; either version 2 | ||
1231 | 7 | * of the License, or (at your option) any later version. | ||
1232 | 8 | * | ||
1233 | 9 | * This program is distributed in the hope that it will be useful, | ||
1234 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1235 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1236 | 12 | * GNU General Public License for more details. | ||
1237 | 13 | * | ||
1238 | 14 | * You should have received a copy of the GNU General Public License | ||
1239 | 15 | * along with this program; if not, write to the Free Software | ||
1240 | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
1241 | 17 | * | ||
1242 | 18 | */ | ||
1243 | 19 | |||
1244 | 20 | #include "graphic/sdl/surface.h" | ||
1245 | 21 | |||
1246 | 22 | #include <cassert> | ||
1247 | 23 | |||
1248 | 24 | #include <SDL.h> | ||
1249 | 25 | |||
1250 | 26 | SDLSurface::SDLSurface(SDL_Surface* surface, bool free_surface_on_delete) : | ||
1251 | 27 | m_surface(surface), | ||
1252 | 28 | m_offsx(0), m_offsy(0), | ||
1253 | 29 | m_w(surface->w), m_h(surface->h), | ||
1254 | 30 | m_free_surface_on_delete(free_surface_on_delete) | ||
1255 | 31 | {} | ||
1256 | 32 | |||
1257 | 33 | SDLSurface::~SDLSurface() { | ||
1258 | 34 | assert(m_surface); | ||
1259 | 35 | |||
1260 | 36 | if (m_free_surface_on_delete) | ||
1261 | 37 | SDL_FreeSurface(m_surface); | ||
1262 | 38 | } | ||
1263 | 39 | |||
1264 | 40 | const SDL_PixelFormat & SDLSurface::format() const { | ||
1265 | 41 | assert(m_surface); | ||
1266 | 42 | return *m_surface->format; | ||
1267 | 43 | } | ||
1268 | 44 | |||
1269 | 45 | uint8_t * SDLSurface::get_pixels() const { | ||
1270 | 46 | assert(m_surface); | ||
1271 | 47 | |||
1272 | 48 | return | ||
1273 | 49 | static_cast<uint8_t *>(m_surface->pixels) | ||
1274 | 50 | + | ||
1275 | 51 | m_offsy * m_surface->pitch | ||
1276 | 52 | + | ||
1277 | 53 | m_offsx * m_surface->format->BytesPerPixel; | ||
1278 | 54 | } | ||
1279 | 55 | |||
1280 | 56 | void SDLSurface::lock(LockMode) { | ||
1281 | 57 | if (SDL_MUSTLOCK(m_surface)) | ||
1282 | 58 | SDL_LockSurface(m_surface); | ||
1283 | 59 | } | ||
1284 | 60 | |||
1285 | 61 | void SDLSurface::unlock(UnlockMode) { | ||
1286 | 62 | if (SDL_MUSTLOCK(m_surface)) | ||
1287 | 63 | SDL_UnlockSurface(m_surface); | ||
1288 | 64 | } | ||
1289 | 65 | |||
1290 | 66 | uint32_t SDLSurface::get_pixel(uint16_t x, uint16_t y) { | ||
1291 | 67 | x += m_offsx; | ||
1292 | 68 | y += m_offsy; | ||
1293 | 69 | |||
1294 | 70 | assert(x < width()); | ||
1295 | 71 | assert(y < height()); | ||
1296 | 72 | assert(m_surface); | ||
1297 | 73 | |||
1298 | 74 | // Locking not needed: reading only | ||
1299 | 75 | const uint8_t bytes_per_pixel = m_surface->format->BytesPerPixel; | ||
1300 | 76 | uint8_t * const pix = | ||
1301 | 77 | static_cast<uint8_t *>(m_surface->pixels) + | ||
1302 | 78 | y * m_surface->pitch + x * bytes_per_pixel; | ||
1303 | 79 | |||
1304 | 80 | switch (bytes_per_pixel) { | ||
1305 | 81 | case 1: | ||
1306 | 82 | return *pix; // Maybe needed for save_png. | ||
1307 | 83 | case 2: | ||
1308 | 84 | return *reinterpret_cast<const uint16_t *>(pix); | ||
1309 | 85 | case 3: //Needed for save_png. | ||
1310 | 86 | // We can not dereference a pointer to a size 4 object in this case | ||
1311 | 87 | // since that would casue a read beyond the end of the block pointed to | ||
1312 | 88 | // by m_surface. Furthermore it would not be properly aligned to a 4 | ||
1313 | 89 | // byte boundary. | ||
1314 | 90 | // | ||
1315 | 91 | // Suppose that the image is 2 * 2 pixels. Then m_surface points to a | ||
1316 | 92 | // block of size 2 * 2 * 3 = 12. The values for the last pixel are at | ||
1317 | 93 | // m_surface[9], m_surface[10] and m_surface[11]. But m_surface[12] is | ||
1318 | 94 | // beyond the end of the block, so we can not read 4 bytes starting at | ||
1319 | 95 | // m_surface[9] (even if unaligned access is allowed). | ||
1320 | 96 | // | ||
1321 | 97 | // Therefore we read the 3 bytes separately and get the result by | ||
1322 | 98 | // shifting the values. It is alignment safe. | ||
1323 | 99 | return pix[0] << 0x00 | pix[1] << 0x08 | pix[2] << 0x10; | ||
1324 | 100 | case 4: | ||
1325 | 101 | return *reinterpret_cast<const uint32_t *>(pix); | ||
1326 | 102 | default: | ||
1327 | 103 | assert(false); | ||
1328 | 104 | } | ||
1329 | 105 | |||
1330 | 106 | return 0; // Should never be here | ||
1331 | 107 | } | ||
1332 | 108 | |||
1333 | 109 | void SDLSurface::set_pixel(uint16_t x, uint16_t y, const uint32_t clr) { | ||
1334 | 110 | x += m_offsx; | ||
1335 | 111 | y += m_offsy; | ||
1336 | 112 | |||
1337 | 113 | if (x >= width() || y >= height()) | ||
1338 | 114 | return; | ||
1339 | 115 | assert(m_surface); | ||
1340 | 116 | |||
1341 | 117 | if (SDL_MUSTLOCK(m_surface)) | ||
1342 | 118 | SDL_LockSurface(m_surface); | ||
1343 | 119 | |||
1344 | 120 | const uint8_t bytes_per_pixel = m_surface->format->BytesPerPixel; | ||
1345 | 121 | uint8_t * const pix = | ||
1346 | 122 | static_cast<uint8_t *>(m_surface->pixels) + | ||
1347 | 123 | y * m_surface->pitch + x * bytes_per_pixel; | ||
1348 | 124 | switch (bytes_per_pixel) { | ||
1349 | 125 | case 2: *reinterpret_cast<uint16_t *>(pix) = static_cast<uint16_t>(clr); break; | ||
1350 | 126 | case 4: *reinterpret_cast<uint32_t *>(pix) = clr; break; | ||
1351 | 127 | default: break; | ||
1352 | 128 | }; | ||
1353 | 129 | |||
1354 | 130 | if (SDL_MUSTLOCK(m_surface)) | ||
1355 | 131 | SDL_UnlockSurface(m_surface); | ||
1356 | 132 | } | ||
1357 | 133 | |||
1358 | 134 | void SDLSurface::set_subwin(const Rect& r) { | ||
1359 | 135 | m_offsx = r.x; | ||
1360 | 136 | m_offsy = r.y; | ||
1361 | 137 | m_w = r.w; | ||
1362 | 138 | m_h = r.h; | ||
1363 | 139 | } | ||
1364 | 140 | |||
1365 | 141 | void SDLSurface::unset_subwin() { | ||
1366 | 142 | m_offsx = 0; | ||
1367 | 143 | m_offsy = 0; | ||
1368 | 144 | m_w = m_surface->w; | ||
1369 | 145 | m_h = m_surface->h; | ||
1370 | 146 | } | ||
1371 | 147 | |||
1372 | 148 | /* | ||
1373 | 149 | =============== | ||
1374 | 150 | Draws the outline of a rectangle | ||
1375 | 151 | =============== | ||
1376 | 152 | */ | ||
1377 | 153 | void SDLSurface::draw_rect(const Rect& rc, const RGBColor& clr) { | ||
1378 | 154 | assert(m_surface); | ||
1379 | 155 | assert(rc.x >= 0); | ||
1380 | 156 | assert(rc.y >= 0); | ||
1381 | 157 | |||
1382 | 158 | const uint32_t color = clr.map(format()); | ||
1383 | 159 | |||
1384 | 160 | const Point bl = rc.bottom_right() - Point(1, 1); | ||
1385 | 161 | |||
1386 | 162 | for (int32_t x = rc.x + 1; x < bl.x; ++x) { | ||
1387 | 163 | set_pixel(x, rc.y, color); | ||
1388 | 164 | set_pixel(x, bl.y, color); | ||
1389 | 165 | } | ||
1390 | 166 | for (int32_t y = rc.y; y <= bl.y; ++y) { | ||
1391 | 167 | set_pixel(rc.x, y, color); | ||
1392 | 168 | set_pixel(bl.x, y, color); | ||
1393 | 169 | } | ||
1394 | 170 | } | ||
1395 | 171 | |||
1396 | 172 | |||
1397 | 173 | /* | ||
1398 | 174 | =============== | ||
1399 | 175 | Draws a filled rectangle | ||
1400 | 176 | =============== | ||
1401 | 177 | */ | ||
1402 | 178 | void SDLSurface::fill_rect(const Rect& rc, const RGBAColor& clr) { | ||
1403 | 179 | assert(m_surface); | ||
1404 | 180 | assert(rc.x >= 0); | ||
1405 | 181 | assert(rc.y >= 0); | ||
1406 | 182 | |||
1407 | 183 | const uint32_t color = clr.map(format()); | ||
1408 | 184 | |||
1409 | 185 | SDL_Rect r = { | ||
1410 | 186 | static_cast<int16_t>(rc.x), static_cast<int16_t>(rc.y), | ||
1411 | 187 | static_cast<uint16_t>(rc.w), static_cast<uint16_t>(rc.h) | ||
1412 | 188 | }; | ||
1413 | 189 | SDL_FillRect(m_surface, &r, color); | ||
1414 | 190 | } | ||
1415 | 191 | |||
1416 | 192 | |||
1417 | 193 | /* | ||
1418 | 194 | =============== | ||
1419 | 195 | Change the brightness of the given rectangle | ||
1420 | 196 | This function is slow as hell. | ||
1421 | 197 | |||
1422 | 198 | * This function is a possible point to optimize on | ||
1423 | 199 | slow system. It takes a lot of cpu time atm and is | ||
1424 | 200 | not needed. It is used by the ui_basic stuff to | ||
1425 | 201 | highlight things. | ||
1426 | 202 | =============== | ||
1427 | 203 | */ | ||
1428 | 204 | void SDLSurface::brighten_rect(const Rect& rc, const int32_t factor) { | ||
1429 | 205 | if (!factor) | ||
1430 | 206 | return; | ||
1431 | 207 | assert(rc.x >= 0); | ||
1432 | 208 | assert(rc.y >= 0); | ||
1433 | 209 | assert(rc.w >= 1); | ||
1434 | 210 | assert(rc.h >= 1); | ||
1435 | 211 | |||
1436 | 212 | const Point bl = rc.bottom_right(); | ||
1437 | 213 | |||
1438 | 214 | lock(Surface::Lock_Normal); | ||
1439 | 215 | |||
1440 | 216 | if (m_surface->format->BytesPerPixel == 4) | ||
1441 | 217 | { | ||
1442 | 218 | for (int32_t y = rc.y; y < bl.y; ++y) | ||
1443 | 219 | for (int32_t x = rc.x; x < bl.x; ++x) | ||
1444 | 220 | { | ||
1445 | 221 | |||
1446 | 222 | uint8_t * const pix = | ||
1447 | 223 | static_cast<uint8_t *>(m_surface->pixels) + | ||
1448 | 224 | (y + m_offsy) * m_surface->pitch + (x + m_offsx) * 4; | ||
1449 | 225 | |||
1450 | 226 | uint32_t const clr = *reinterpret_cast<const uint32_t *>(pix); | ||
1451 | 227 | uint8_t gr, gg, gb; | ||
1452 | 228 | SDL_GetRGB(clr, m_surface->format, &gr, &gg, &gb); | ||
1453 | 229 | int16_t r = gr + factor; | ||
1454 | 230 | int16_t g = gg + factor; | ||
1455 | 231 | int16_t b = gb + factor; | ||
1456 | 232 | |||
1457 | 233 | if (b & 0xFF00) | ||
1458 | 234 | b = ~b >> 24; | ||
1459 | 235 | if (g & 0xFF00) | ||
1460 | 236 | g = ~g >> 24; | ||
1461 | 237 | if (r & 0xFF00) | ||
1462 | 238 | r = ~r >> 24; | ||
1463 | 239 | |||
1464 | 240 | *reinterpret_cast<uint32_t *>(pix) = | ||
1465 | 241 | SDL_MapRGB(m_surface->format, r, g, b); | ||
1466 | 242 | } | ||
1467 | 243 | } else if (m_surface->format->BytesPerPixel == 2) { | ||
1468 | 244 | for (int32_t y = rc.y; y < bl.y; ++y) | ||
1469 | 245 | for (int32_t x = rc.x; x < bl.x; ++x) | ||
1470 | 246 | { | ||
1471 | 247 | uint8_t * const pix = | ||
1472 | 248 | static_cast<uint8_t *>(m_surface->pixels) + | ||
1473 | 249 | (y + m_offsy) * m_surface->pitch + (x + m_offsx) * 2; | ||
1474 | 250 | |||
1475 | 251 | uint32_t const clr = *reinterpret_cast<const uint16_t *>(pix); | ||
1476 | 252 | uint8_t gr, gg, gb; | ||
1477 | 253 | SDL_GetRGB(clr, m_surface->format, &gr, &gg, &gb); | ||
1478 | 254 | int16_t r = gr + factor; | ||
1479 | 255 | int16_t g = gg + factor; | ||
1480 | 256 | int16_t b = gb + factor; | ||
1481 | 257 | |||
1482 | 258 | if (b & 0xFF00) | ||
1483 | 259 | b = ~b >> 24; | ||
1484 | 260 | if (g & 0xFF00) | ||
1485 | 261 | g = ~g >> 24; | ||
1486 | 262 | if (r & 0xFF00) | ||
1487 | 263 | r = ~r >> 24; | ||
1488 | 264 | |||
1489 | 265 | *reinterpret_cast<uint16_t *>(pix) = | ||
1490 | 266 | SDL_MapRGB(m_surface->format, r, g, b); | ||
1491 | 267 | } | ||
1492 | 268 | } | ||
1493 | 269 | unlock(Surface::Unlock_Update); | ||
1494 | 270 | } | ||
1495 | 271 | |||
1496 | 272 | /** | ||
1497 | 273 | * This functions draws a (not horizontal or vertical) | ||
1498 | 274 | * line in the target, using Bresenham's algorithm | ||
1499 | 275 | * | ||
1500 | 276 | * This function could be faster by using direct pixel | ||
1501 | 277 | * access instead of the set_pixel() function | ||
1502 | 278 | */ | ||
1503 | 279 | void SDLSurface::draw_line | ||
1504 | 280 | (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth) | ||
1505 | 281 | { | ||
1506 | 282 | int32_t dx = x2 - x1; /* the horizontal distance of the line */ | ||
1507 | 283 | int32_t dy = y2 - y1; /* the vertical distance of the line */ | ||
1508 | 284 | const uint32_t dxabs = abs(dx); | ||
1509 | 285 | const uint32_t dyabs = abs(dy); | ||
1510 | 286 | int32_t sdx = dx < 0 ? -1 : 1; | ||
1511 | 287 | int32_t sdy = dy < 0 ? -1 : 1; | ||
1512 | 288 | uint32_t x = dyabs / 2; | ||
1513 | 289 | uint32_t y = dxabs / 2; | ||
1514 | 290 | Point p(x1, y1); | ||
1515 | 291 | |||
1516 | 292 | set_pixel(p.x, p.y, color.map(format())); | ||
1517 | 293 | |||
1518 | 294 | if (dxabs >= dyabs) // the line is more horizontal than vertical | ||
1519 | 295 | for (uint32_t i = 0; i < dxabs; ++i) { | ||
1520 | 296 | y += dyabs; | ||
1521 | 297 | |||
1522 | 298 | if (y >= dxabs) { | ||
1523 | 299 | y -= dxabs; | ||
1524 | 300 | p.y += sdy; | ||
1525 | 301 | } | ||
1526 | 302 | |||
1527 | 303 | p.x += sdx; | ||
1528 | 304 | for (int32_t w = 0; w < gwidth; ++w) { | ||
1529 | 305 | set_pixel(p.x, p.y + w, color.map(format())); | ||
1530 | 306 | } | ||
1531 | 307 | } | ||
1532 | 308 | else // the line is more vertical than horizontal | ||
1533 | 309 | for (uint32_t i = 0; i < dyabs; ++i) { | ||
1534 | 310 | x += dxabs; | ||
1535 | 311 | |||
1536 | 312 | if (x >= dyabs) { | ||
1537 | 313 | x -= dyabs; | ||
1538 | 314 | p.x += sdx; | ||
1539 | 315 | } | ||
1540 | 316 | |||
1541 | 317 | p.y += sdy; | ||
1542 | 318 | for (int32_t w = 0; w < gwidth; ++w) { | ||
1543 | 319 | set_pixel(p.x + w, p.y, color.map(format())); | ||
1544 | 320 | } | ||
1545 | 321 | } | ||
1546 | 322 | } | ||
1547 | 323 | |||
1548 | 324 | |||
1549 | 325 | void SDLSurface::blit | ||
1550 | 326 | (const Point& dst, const Surface* src, const Rect& srcrc, Composite cm) | ||
1551 | 327 | { | ||
1552 | 328 | SDL_Surface* sdlsurf = static_cast<const SDLSurface*>(src)->get_sdl_surface(); | ||
1553 | 329 | SDL_Rect srcrect = { | ||
1554 | 330 | static_cast<int16_t>(srcrc.x), static_cast<int16_t>(srcrc.y), | ||
1555 | 331 | static_cast<uint16_t>(srcrc.w), static_cast<uint16_t>(srcrc.h) | ||
1556 | 332 | }; | ||
1557 | 333 | SDL_Rect dstrect = { | ||
1558 | 334 | static_cast<int16_t>(dst.x), static_cast<int16_t>(dst.y), | ||
1559 | 335 | 0, 0 | ||
1560 | 336 | }; | ||
1561 | 337 | |||
1562 | 338 | bool alpha = false; | ||
1563 | 339 | uint8_t alphaval = 0; | ||
1564 | 340 | if (cm == CM_Copy) { | ||
1565 | 341 | SDL_BlendMode bm; | ||
1566 | 342 | SDL_GetSurfaceBlendMode(sdlsurf, &bm); | ||
1567 | 343 | alpha = bm & SDL_BLENDMODE_BLEND; | ||
1568 | 344 | SDL_GetSurfaceAlphaMod(sdlsurf, &alphaval); | ||
1569 | 345 | SDL_SetSurfaceAlphaMod(sdlsurf, 255); | ||
1570 | 346 | SDL_SetSurfaceBlendMode(sdlsurf, SDL_BLENDMODE_NONE); | ||
1571 | 347 | } | ||
1572 | 348 | |||
1573 | 349 | SDL_BlitSurface(sdlsurf, &srcrect, m_surface, &dstrect); | ||
1574 | 350 | |||
1575 | 351 | if (cm == CM_Copy) { | ||
1576 | 352 | SDL_SetSurfaceAlphaMod(sdlsurf, alphaval); | ||
1577 | 353 | SDL_SetSurfaceBlendMode(sdlsurf, alpha ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE); | ||
1578 | 354 | } | ||
1579 | 355 | } | ||
1580 | 356 | 0 | ||
1581 | === removed file 'src/graphic/sdl/surface.h' | |||
1582 | --- src/graphic/sdl/surface.h 2014-11-02 20:31:40 +0000 | |||
1583 | +++ src/graphic/sdl/surface.h 1970-01-01 00:00:00 +0000 | |||
1584 | @@ -1,77 +0,0 @@ | |||
1585 | 1 | /* | ||
1586 | 2 | * Copyright (C) 2010-2011 by the Widelands Development Team | ||
1587 | 3 | * | ||
1588 | 4 | * This program is free software; you can redistribute it and/or | ||
1589 | 5 | * modify it under the terms of the GNU General Public License | ||
1590 | 6 | * as published by the Free Software Foundation; either version 2 | ||
1591 | 7 | * of the License, or (at your option) any later version. | ||
1592 | 8 | * | ||
1593 | 9 | * This program is distributed in the hope that it will be useful, | ||
1594 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1595 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1596 | 12 | * GNU General Public License for more details. | ||
1597 | 13 | * | ||
1598 | 14 | * You should have received a copy of the GNU General Public License | ||
1599 | 15 | * along with this program; if not, write to the Free Software | ||
1600 | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
1601 | 17 | * | ||
1602 | 18 | */ | ||
1603 | 19 | |||
1604 | 20 | #ifndef WL_GRAPHIC_SDL_SURFACE_H | ||
1605 | 21 | #define WL_GRAPHIC_SDL_SURFACE_H | ||
1606 | 22 | |||
1607 | 23 | #include <SDL_render.h> | ||
1608 | 24 | |||
1609 | 25 | #include "base/rect.h" | ||
1610 | 26 | #include "graphic/color.h" | ||
1611 | 27 | #include "graphic/surface.h" | ||
1612 | 28 | |||
1613 | 29 | /** | ||
1614 | 30 | * This implements SDL rendering. Do not use this class directly. The right | ||
1615 | 31 | * way is to use the base struct Surface wherever possible. Everything which | ||
1616 | 32 | * needs to know about the underlying renderer should go to the graphics | ||
1617 | 33 | * subdirectory. | ||
1618 | 34 | */ | ||
1619 | 35 | class SDLSurface : public Surface { | ||
1620 | 36 | public: | ||
1621 | 37 | // The surface set by SetVideoMode must not be freed according to the SDL | ||
1622 | 38 | // docs, so we need 'free_surface_on_delete'. | ||
1623 | 39 | SDLSurface(SDL_Surface* surface, bool free_surface_on_delete = true); | ||
1624 | 40 | virtual ~SDLSurface(); | ||
1625 | 41 | |||
1626 | 42 | // Implements Image | ||
1627 | 43 | uint16_t width() const override {return m_w;} | ||
1628 | 44 | uint16_t height() const override {return m_h;} | ||
1629 | 45 | |||
1630 | 46 | // Implements Surface | ||
1631 | 47 | void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm) override; | ||
1632 | 48 | void fill_rect(const Rect&, const RGBAColor&) override; | ||
1633 | 49 | |||
1634 | 50 | // Implements Surface | ||
1635 | 51 | void draw_rect(const Rect&, const RGBColor&) override; | ||
1636 | 52 | virtual void draw_line | ||
1637 | 53 | (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor&, uint8_t width) override; | ||
1638 | 54 | void brighten_rect(const Rect&, int32_t factor) override; | ||
1639 | 55 | |||
1640 | 56 | const SDL_PixelFormat & format() const override; | ||
1641 | 57 | void lock(LockMode) override; | ||
1642 | 58 | void unlock(UnlockMode) override; | ||
1643 | 59 | uint32_t get_pixel(uint16_t x, uint16_t y) override; | ||
1644 | 60 | void set_pixel(uint16_t x, uint16_t y, uint32_t clr) override; | ||
1645 | 61 | uint16_t get_pitch() const override {return m_surface->pitch;} | ||
1646 | 62 | uint8_t * get_pixels() const override; | ||
1647 | 63 | |||
1648 | 64 | SDL_Surface * get_sdl_surface() const {return m_surface;} | ||
1649 | 65 | |||
1650 | 66 | void set_subwin(const Rect& r); | ||
1651 | 67 | void unset_subwin(); | ||
1652 | 68 | |||
1653 | 69 | protected: | ||
1654 | 70 | SDL_Surface * m_surface; | ||
1655 | 71 | int32_t m_offsx; | ||
1656 | 72 | int32_t m_offsy; | ||
1657 | 73 | uint16_t m_w, m_h; | ||
1658 | 74 | bool m_free_surface_on_delete; | ||
1659 | 75 | }; | ||
1660 | 76 | |||
1661 | 77 | #endif // end of include guard: WL_GRAPHIC_SDL_SURFACE_H | ||
1662 | 78 | 0 | ||
1663 | === removed file 'src/graphic/sdl/terrain.cc' | |||
1664 | --- src/graphic/sdl/terrain.cc 2014-09-27 18:53:55 +0000 | |||
1665 | +++ src/graphic/sdl/terrain.cc 1970-01-01 00:00:00 +0000 | |||
1666 | @@ -1,34 +0,0 @@ | |||
1667 | 1 | /* | ||
1668 | 2 | * Copyright (C) 2002-2004, 2006, 2009-2010 by the Widelands Development Team | ||
1669 | 3 | * | ||
1670 | 4 | * This program is free software; you can redistribute it and/or | ||
1671 | 5 | * modify it under the terms of the GNU General Public License | ||
1672 | 6 | * as published by the Free Software Foundation; either version 2 | ||
1673 | 7 | * of the License, or (at your option) any later version. | ||
1674 | 8 | * | ||
1675 | 9 | * This program is distributed in the hope that it will be useful, | ||
1676 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1677 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1678 | 12 | * GNU General Public License for more details. | ||
1679 | 13 | * | ||
1680 | 14 | * You should have received a copy of the GNU General Public License | ||
1681 | 15 | * along with this program; if not, write to the Free Software | ||
1682 | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
1683 | 17 | * | ||
1684 | 18 | */ | ||
1685 | 19 | |||
1686 | 20 | #include "graphic/sdl/terrain.h" | ||
1687 | 21 | |||
1688 | 22 | /// get lambda and mu so that | ||
1689 | 23 | /// lambda * u + mu * v = (1 0)^T with u = (u1 u2)^T and v = (v1 v2)^T | ||
1690 | 24 | void get_horiz_linearcomb | ||
1691 | 25 | (int32_t const u1, int32_t const u2, int32_t const v1, int32_t const v2, | ||
1692 | 26 | float & lambda, float & mu) | ||
1693 | 27 | { | ||
1694 | 28 | float det; | ||
1695 | 29 | |||
1696 | 30 | det = u1 * v2 - u2 * v1; // determinant of (u v) | ||
1697 | 31 | |||
1698 | 32 | lambda = v2 / det; // by Cramer's rule | ||
1699 | 33 | mu = -u2 / det; | ||
1700 | 34 | } | ||
1701 | 35 | 0 | ||
1702 | === removed file 'src/graphic/sdl/terrain.h' | |||
1703 | --- src/graphic/sdl/terrain.h 2014-09-27 18:53:55 +0000 | |||
1704 | +++ src/graphic/sdl/terrain.h 1970-01-01 00:00:00 +0000 | |||
1705 | @@ -1,668 +0,0 @@ | |||
1706 | 1 | /* | ||
1707 | 2 | * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team | ||
1708 | 3 | * | ||
1709 | 4 | * This program is free software; you can redistribute it and/or | ||
1710 | 5 | * modify it under the terms of the GNU General Public License | ||
1711 | 6 | * as published by the Free Software Foundation; either version 2 | ||
1712 | 7 | * of the License, or (at your option) any later version. | ||
1713 | 8 | * | ||
1714 | 9 | * This program is distributed in the hope that it will be useful, | ||
1715 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1716 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1717 | 12 | * GNU General Public License for more details. | ||
1718 | 13 | * | ||
1719 | 14 | * You should have received a copy of the GNU General Public License | ||
1720 | 15 | * along with this program; if not, write to the Free Software | ||
1721 | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
1722 | 17 | * | ||
1723 | 18 | */ | ||
1724 | 19 | |||
1725 | 20 | #ifndef WL_GRAPHIC_SDL_TERRAIN_H | ||
1726 | 21 | #define WL_GRAPHIC_SDL_TERRAIN_H | ||
1727 | 22 | |||
1728 | 23 | #include <cassert> | ||
1729 | 24 | |||
1730 | 25 | #include "base/log.h" | ||
1731 | 26 | #include "base/macros.h" | ||
1732 | 27 | #include "graphic/graphic.h" | ||
1733 | 28 | #include "graphic/sdl/surface.h" | ||
1734 | 29 | #include "graphic/sdl/vertex.h" | ||
1735 | 30 | #include "graphic/texture.h" | ||
1736 | 31 | #include "logic/roadtype.h" | ||
1737 | 32 | #include "random/random.h" | ||
1738 | 33 | #include "wui/mapviewpixelconstants.h" | ||
1739 | 34 | |||
1740 | 35 | ///Must be a power of two | ||
1741 | 36 | #define DITHER_WIDTH 4 | ||
1742 | 37 | |||
1743 | 38 | #define DITHER_RAND_MASK (DITHER_WIDTH * 2 - 1) | ||
1744 | 39 | #define DITHER_RAND_SHIFT (16 / DITHER_WIDTH) | ||
1745 | 40 | |||
1746 | 41 | // TODO(unknown): Dangerous: casting, assumptions for sizeof(X), bitshifting | ||
1747 | 42 | #define FTOFIX(f) (static_cast<int32_t>((f) * 0x10000)) | ||
1748 | 43 | #define ITOFIX(i) ((i)<<16) | ||
1749 | 44 | #define FIXTOI(f) ((f)>>16) | ||
1750 | 45 | |||
1751 | 46 | void get_horiz_linearcomb | ||
1752 | 47 | (int32_t u1, int32_t u2, int32_t v1, int32_t v2, | ||
1753 | 48 | float & lambda, float & mu); | ||
1754 | 49 | |||
1755 | 50 | |||
1756 | 51 | struct LeftEdge { | ||
1757 | 52 | /** | ||
1758 | 53 | * Height of the edge. | ||
1759 | 54 | * | ||
1760 | 55 | * This is the number of pixels spanned by the edge in a vertical direction | ||
1761 | 56 | */ | ||
1762 | 57 | uint32_t height; | ||
1763 | 58 | |||
1764 | 59 | // the following are all fixed point | ||
1765 | 60 | int32_t x0; | ||
1766 | 61 | int32_t tx0; | ||
1767 | 62 | int32_t ty0; | ||
1768 | 63 | int32_t b0; | ||
1769 | 64 | int32_t dx; | ||
1770 | 65 | int32_t dtx; | ||
1771 | 66 | int32_t dty; | ||
1772 | 67 | int32_t db; | ||
1773 | 68 | }; | ||
1774 | 69 | |||
1775 | 70 | struct RightEdge { | ||
1776 | 71 | uint32_t height; | ||
1777 | 72 | |||
1778 | 73 | int32_t x0; | ||
1779 | 74 | int32_t dx; | ||
1780 | 75 | }; | ||
1781 | 76 | |||
1782 | 77 | |||
1783 | 78 | /** | ||
1784 | 79 | * Render a polygon based on the given edge lists. | ||
1785 | 80 | * | ||
1786 | 81 | * The edge lists will be overwritten with undefined values. | ||
1787 | 82 | */ | ||
1788 | 83 | template<typename T> static void render_edge_lists | ||
1789 | 84 | (SDLSurface & dst, const Texture & tex, | ||
1790 | 85 | int32_t y, int32_t height, | ||
1791 | 86 | LeftEdge * left, RightEdge * right, | ||
1792 | 87 | int32_t dbdx, int32_t dtydx) | ||
1793 | 88 | { | ||
1794 | 89 | if (-y >= height) | ||
1795 | 90 | return; // completely above screen | ||
1796 | 91 | |||
1797 | 92 | uint8_t * texpixels; | ||
1798 | 93 | T * texcolormap; | ||
1799 | 94 | |||
1800 | 95 | texpixels = tex.get_curpixels(); | ||
1801 | 96 | texcolormap = static_cast<T *>(tex.get_colormap()); | ||
1802 | 97 | |||
1803 | 98 | // Skip lines that are above the screen | ||
1804 | 99 | while (y < 0) { | ||
1805 | 100 | int32_t skip = -y; | ||
1806 | 101 | if (skip > static_cast<int32_t>(left->height)) | ||
1807 | 102 | skip = left->height; | ||
1808 | 103 | if (skip > static_cast<int32_t>(right->height)) | ||
1809 | 104 | skip = right->height; | ||
1810 | 105 | |||
1811 | 106 | if (skip < static_cast<int32_t>(left->height)) { | ||
1812 | 107 | left->x0 += skip * left->dx; | ||
1813 | 108 | left->tx0 += skip * left->dtx; | ||
1814 | 109 | left->ty0 += skip * left->dty; | ||
1815 | 110 | left->b0 += skip * left->db; | ||
1816 | 111 | left->height -= skip; | ||
1817 | 112 | } else { | ||
1818 | 113 | ++left; | ||
1819 | 114 | } | ||
1820 | 115 | |||
1821 | 116 | if (skip < static_cast<int32_t>(right->height)) { | ||
1822 | 117 | right->x0 += skip * right->dx; | ||
1823 | 118 | right->height -= skip; | ||
1824 | 119 | } else { | ||
1825 | 120 | ++right; | ||
1826 | 121 | } | ||
1827 | 122 | |||
1828 | 123 | height -= skip; | ||
1829 | 124 | y += skip; | ||
1830 | 125 | } | ||
1831 | 126 | |||
1832 | 127 | // Cut off lines below screen | ||
1833 | 128 | if (y + height > static_cast<int32_t>(dst.height())) | ||
1834 | 129 | height = dst.height() - y; | ||
1835 | 130 | |||
1836 | 131 | int32_t dstw = dst.width(); | ||
1837 | 132 | while (height > 0) { | ||
1838 | 133 | int32_t leftx = FIXTOI(left->x0); | ||
1839 | 134 | int32_t rightx = FIXTOI(right->x0); | ||
1840 | 135 | |||
1841 | 136 | if (leftx < 0) | ||
1842 | 137 | leftx = 0; | ||
1843 | 138 | if (rightx > dstw) | ||
1844 | 139 | rightx = dstw; | ||
1845 | 140 | |||
1846 | 141 | if (leftx < rightx) { | ||
1847 | 142 | int32_t tx = left->tx0; | ||
1848 | 143 | int32_t ty = left->ty0; | ||
1849 | 144 | int32_t b = left->b0; | ||
1850 | 145 | |||
1851 | 146 | int32_t adjust = ITOFIX(leftx) - left->x0; | ||
1852 | 147 | tx += adjust; // note: dtx/dx = 1 | ||
1853 | 148 | ty += FIXTOI(static_cast<long long>(adjust) * dtydx); | ||
1854 | 149 | b += FIXTOI(static_cast<long long>(adjust) * dbdx); | ||
1855 | 150 | |||
1856 | 151 | // Technically, we should clamp b at every pixel, but that's too | ||
1857 | 152 | // expensive. The following seems to be enough to get rid of | ||
1858 | 153 | // artifacts along the border between seen and unseen fields. | ||
1859 | 154 | if (b < ITOFIX(-128)) | ||
1860 | 155 | b = ITOFIX(-128); | ||
1861 | 156 | |||
1862 | 157 | tx = FIXTOI(tx); | ||
1863 | 158 | |||
1864 | 159 | T * scanline = | ||
1865 | 160 | reinterpret_cast<T *> | ||
1866 | 161 | (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch()) | ||
1867 | 162 | + | ||
1868 | 163 | leftx; | ||
1869 | 164 | |||
1870 | 165 | uint32_t count = rightx - leftx; | ||
1871 | 166 | while (count--) { | ||
1872 | 167 | *scanline++ = | ||
1873 | 168 | texcolormap | ||
1874 | 169 | [texpixels | ||
1875 | 170 | [(tx & (TEXTURE_WIDTH - 1)) | | ||
1876 | 171 | ((ty >> 10) & ((TEXTURE_HEIGHT - 1) << 6))] | ||
1877 | 172 | | | ||
1878 | 173 | ((b >> 8) & 0xFF00)]; | ||
1879 | 174 | |||
1880 | 175 | b += dbdx; | ||
1881 | 176 | ++tx; | ||
1882 | 177 | ty += dtydx; | ||
1883 | 178 | } | ||
1884 | 179 | } | ||
1885 | 180 | |||
1886 | 181 | // Advance the line | ||
1887 | 182 | ++y; | ||
1888 | 183 | left->x0 += left->dx; | ||
1889 | 184 | left->tx0 += left->dtx; | ||
1890 | 185 | left->ty0 += left->dty; | ||
1891 | 186 | left->b0 += left->db; | ||
1892 | 187 | right->x0 += right->dx; | ||
1893 | 188 | |||
1894 | 189 | if (--left->height == 0) | ||
1895 | 190 | ++left; | ||
1896 | 191 | if (--right->height == 0) | ||
1897 | 192 | ++right; | ||
1898 | 193 | --height; | ||
1899 | 194 | } | ||
1900 | 195 | } | ||
1901 | 196 | |||
1902 | 197 | struct WLPolygon { | ||
1903 | 198 | Point p[3]; | ||
1904 | 199 | uint8_t nrpoints; | ||
1905 | 200 | }; | ||
1906 | 201 | |||
1907 | 202 | |||
1908 | 203 | /** | ||
1909 | 204 | * Render a triangle into the given destination surface. | ||
1910 | 205 | * | ||
1911 | 206 | * \note It is assumed that p1, p2, p3 are sorted in counter-clockwise order. | ||
1912 | 207 | * | ||
1913 | 208 | * \note The rendering code assumes that d(tx)/d(x) = 1. This can be achieved | ||
1914 | 209 | * by making sure that there is a 1:1 relation between x coordinates and | ||
1915 | 210 | * texture x coordinates. | ||
1916 | 211 | */ | ||
1917 | 212 | template<typename T> static void render_triangle | ||
1918 | 213 | (SDLSurface & dst, | ||
1919 | 214 | const Vertex & p1, const Vertex & p2, const Vertex & p3, | ||
1920 | 215 | const Texture & tex) | ||
1921 | 216 | { | ||
1922 | 217 | if (p1.y == p2.y && p2.y == p3.y) | ||
1923 | 218 | return; // degenerate triangle | ||
1924 | 219 | |||
1925 | 220 | // Clip the triangle | ||
1926 | 221 | WLPolygon polygon; | ||
1927 | 222 | |||
1928 | 223 | polygon.p[0] = p1; | ||
1929 | 224 | polygon.p[1] = p2; | ||
1930 | 225 | polygon.p[2] = p3; | ||
1931 | 226 | polygon.nrpoints = 3; | ||
1932 | 227 | |||
1933 | 228 | // Determine a top vertex | ||
1934 | 229 | int32_t top = 0, topy = 0; | ||
1935 | 230 | |||
1936 | 231 | topy = 0x7fffffff; | ||
1937 | 232 | for (uint8_t i = 0; i < polygon.nrpoints; ++i) { | ||
1938 | 233 | if (polygon.p[i].y < topy) { | ||
1939 | 234 | top = i; | ||
1940 | 235 | topy = polygon.p[i].y; | ||
1941 | 236 | } | ||
1942 | 237 | } | ||
1943 | 238 | |||
1944 | 239 | // Calculate d(b) / d(x) etc. as fixed point variables. | ||
1945 | 240 | // Remember that we assume d(tx) / d(x) == 1 and d(tx) / d(y) == 0. | ||
1946 | 241 | |||
1947 | 242 | // lA * (p2 - p1) + lB * (p3 - p1) = (1, 0) | ||
1948 | 243 | // mA * (p2 - p1) + mB * (p3 - p1) = (0, 1) | ||
1949 | 244 | int32_t const det = | ||
1950 | 245 | (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); | ||
1951 | 246 | int32_t const lA = ITOFIX(p3.y - p1.y) / det; | ||
1952 | 247 | int32_t const lB = -ITOFIX(p2.y - p1.y) / det; | ||
1953 | 248 | int32_t const mA = -ITOFIX(p3.x - p1.x) / det; | ||
1954 | 249 | int32_t const mB = ITOFIX(p2.x - p1.x) / det; | ||
1955 | 250 | int32_t const dbdx = lA * (p2.b - p1.b) + lB * (p3.b - p1.b); | ||
1956 | 251 | int32_t const dbdy = mA * (p2.b - p1.b) + mB * (p3.b - p1.b); | ||
1957 | 252 | int32_t const dtydx = lA * (p2.ty - p1.ty) + lB * (p3.ty - p1.ty); | ||
1958 | 253 | int32_t const dtydy = mA * (p2.ty - p1.ty) + mB * (p3.ty - p1.ty); | ||
1959 | 254 | |||
1960 | 255 | // Build left edges | ||
1961 | 256 | int32_t boty = topy; | ||
1962 | 257 | LeftEdge leftedges[3]; | ||
1963 | 258 | |||
1964 | 259 | { | ||
1965 | 260 | uint8_t nrleftedges = 0; | ||
1966 | 261 | uint8_t start = top; | ||
1967 | 262 | uint8_t end = (top + 1) % polygon.nrpoints; | ||
1968 | 263 | do { | ||
1969 | 264 | if (polygon.p[end].y > polygon.p[start].y) { | ||
1970 | 265 | boty = polygon.p[end].y; | ||
1971 | 266 | |||
1972 | 267 | LeftEdge & edge = leftedges[nrleftedges++]; | ||
1973 | 268 | assert(nrleftedges <= 3); | ||
1974 | 269 | |||
1975 | 270 | edge.height = polygon.p[end].y - polygon.p[start].y; | ||
1976 | 271 | edge.x0 = ITOFIX(polygon.p[start].x); | ||
1977 | 272 | edge.dx = | ||
1978 | 273 | ITOFIX(polygon.p[end].x - polygon.p[start].x) | ||
1979 | 274 | / | ||
1980 | 275 | static_cast<int32_t>(edge.height); | ||
1981 | 276 | |||
1982 | 277 | int32_t startdx = polygon.p[start].x - p1.x; | ||
1983 | 278 | int32_t startdy = polygon.p[start].y - p1.y; | ||
1984 | 279 | int32_t dx = polygon.p[end].x - polygon.p[start].x; | ||
1985 | 280 | int32_t dy = polygon.p[end].y - polygon.p[start].y; | ||
1986 | 281 | |||
1987 | 282 | edge.tx0 = ITOFIX(p1.tx + startdx); | ||
1988 | 283 | edge.ty0 = ITOFIX(p1.ty) + startdx * dtydx + startdy * dtydy; | ||
1989 | 284 | edge.b0 = ITOFIX(p1.b) + startdx * dbdx + startdy * dbdy; | ||
1990 | 285 | edge.dtx = ITOFIX(dx) / static_cast<int32_t>(edge.height); | ||
1991 | 286 | edge.dty = | ||
1992 | 287 | (dx * dtydx + dy * dtydy) / static_cast<int32_t>(edge.height); | ||
1993 | 288 | edge.db = | ||
1994 | 289 | (dx * dbdx + dy * dbdy) / static_cast<int32_t>(edge.height); | ||
1995 | 290 | } | ||
1996 | 291 | |||
1997 | 292 | start = end; | ||
1998 | 293 | end = (start + 1) % polygon.nrpoints; | ||
1999 | 294 | } while (polygon.p[end].y >= polygon.p[start].y); | ||
2000 | 295 | } | ||
2001 | 296 | |||
2002 | 297 | // Build right edges | ||
2003 | 298 | RightEdge rightedges[3]; | ||
2004 | 299 | |||
2005 | 300 | { | ||
2006 | 301 | uint8_t nrrightedges = 0; | ||
2007 | 302 | uint8_t start = top; | ||
2008 | 303 | uint8_t end = (polygon.nrpoints + top - 1) % polygon.nrpoints; | ||
2009 | 304 | do { | ||
2010 | 305 | if (polygon.p[end].y > polygon.p[start].y) { | ||
2011 | 306 | RightEdge & edge = rightedges[nrrightedges++]; | ||
2012 | 307 | assert(nrrightedges <= 3); | ||
2013 | 308 | |||
2014 | 309 | edge.height = polygon.p[end].y - polygon.p[start].y; | ||
2015 | 310 | edge.x0 = ITOFIX(polygon.p[start].x); | ||
2016 | 311 | edge.dx = | ||
2017 | 312 | ITOFIX(polygon.p[end].x - polygon.p[start].x) | ||
2018 | 313 | / | ||
2019 | 314 | static_cast<int32_t>(edge.height); | ||
2020 | 315 | } | ||
2021 | 316 | |||
2022 | 317 | start = end; | ||
2023 | 318 | end = (polygon.nrpoints + start - 1) % polygon.nrpoints; | ||
2024 | 319 | } while (polygon.p[end].y >= polygon.p[start].y); | ||
2025 | 320 | } | ||
2026 | 321 | |||
2027 | 322 | render_edge_lists<T> | ||
2028 | 323 | (dst, tex, topy, boty - topy, leftedges, rightedges, dbdx, dtydx); | ||
2029 | 324 | } | ||
2030 | 325 | |||
2031 | 326 | /** | ||
2032 | 327 | * Blur the polygon edge between vertices start and end. | ||
2033 | 328 | * | ||
2034 | 329 | * It is dithered by randomly placing points taken from the texture of the | ||
2035 | 330 | * adjacent polygon. The blend area is a few pixels wide, and the chance for | ||
2036 | 331 | * replacing a pixel depends on the distance from the center line. Texture | ||
2037 | 332 | * coordinates and brightness are interpolated across the center line (outer | ||
2038 | 333 | * loop). To the sides these are approximated (inner loop): Brightness is kept | ||
2039 | 334 | * constant, and the texture is mapped orthogonally to the center line. It is | ||
2040 | 335 | * important that only those pixels are drawn whose texture actually changes in | ||
2041 | 336 | * order to minimize artifacts. | ||
2042 | 337 | * | ||
2043 | 338 | * \note All this is preliminary and subject to change. For example, a special | ||
2044 | 339 | * edge texture could be used instead of stochastically dithering. Road | ||
2045 | 340 | * rendering could be handled as a special case then. | ||
2046 | 341 | */ | ||
2047 | 342 | template<typename T> static void dither_edge_horiz | ||
2048 | 343 | (SDLSurface & dst, | ||
2049 | 344 | const Vertex & start, const Vertex & end, | ||
2050 | 345 | const Texture & ttex, const Texture & btex) | ||
2051 | 346 | { | ||
2052 | 347 | uint8_t * tpixels, * bpixels; | ||
2053 | 348 | T * tcolormap, * bcolormap; | ||
2054 | 349 | |||
2055 | 350 | tpixels = ttex.get_curpixels(); | ||
2056 | 351 | tcolormap = static_cast<T *>(ttex.get_colormap()); | ||
2057 | 352 | bpixels = btex.get_curpixels(); | ||
2058 | 353 | bcolormap = static_cast<T *>(btex.get_colormap()); | ||
2059 | 354 | |||
2060 | 355 | int32_t tx, ty, b, dtx, dty, db, tx0, ty0; | ||
2061 | 356 | |||
2062 | 357 | tx = ITOFIX(start.tx); | ||
2063 | 358 | ty = ITOFIX(start.ty); | ||
2064 | 359 | b = ITOFIX(start.b); | ||
2065 | 360 | dtx = (ITOFIX(end.tx) - tx) / (end.x - start.x + 1); | ||
2066 | 361 | dty = (ITOFIX(end.ty) - ty) / (end.x - start.x + 1); | ||
2067 | 362 | db = (ITOFIX(end.b) - b) / (end.x - start.x + 1); | ||
2068 | 363 | |||
2069 | 364 | // TODO(unknown): seed this depending on field coordinates | ||
2070 | 365 | uint32_t rnd = 0; | ||
2071 | 366 | |||
2072 | 367 | const int32_t dstw = dst.width(); | ||
2073 | 368 | const int32_t dsth = dst.height(); | ||
2074 | 369 | |||
2075 | 370 | int32_t ydiff = ITOFIX(end.y - start.y) / (end.x - start.x); | ||
2076 | 371 | int32_t centery = ITOFIX(start.y); | ||
2077 | 372 | |||
2078 | 373 | for (int32_t x = start.x; x < end.x; x++, centery += ydiff) { | ||
2079 | 374 | rnd = SIMPLE_RAND(rnd); | ||
2080 | 375 | |||
2081 | 376 | if (x >= 0 && x < dstw) { | ||
2082 | 377 | int32_t y = FIXTOI(centery) - DITHER_WIDTH; | ||
2083 | 378 | |||
2084 | 379 | tx0 = tx - DITHER_WIDTH * dty; | ||
2085 | 380 | ty0 = ty + DITHER_WIDTH * dtx; | ||
2086 | 381 | |||
2087 | 382 | uint32_t rnd0 = rnd; | ||
2088 | 383 | |||
2089 | 384 | // dither above the edge | ||
2090 | 385 | for (uint32_t i = 0; i < DITHER_WIDTH; i++, y++) { | ||
2091 | 386 | if ((rnd0 & DITHER_RAND_MASK) <= i && y >= 0 && y < dsth) { | ||
2092 | 387 | T * const pix = | ||
2093 | 388 | reinterpret_cast<T *> | ||
2094 | 389 | (static_cast<uint8_t *>(dst.get_pixels()) | ||
2095 | 390 | + | ||
2096 | 391 | y * dst.get_pitch()) | ||
2097 | 392 | + | ||
2098 | 393 | x; | ||
2099 | 394 | *pix = | ||
2100 | 395 | tcolormap | ||
2101 | 396 | [tpixels | ||
2102 | 397 | [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) | | ||
2103 | 398 | ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))] | ||
2104 | 399 | | | ||
2105 | 400 | ((b >> 8) & 0xFF00)]; | ||
2106 | 401 | } | ||
2107 | 402 | |||
2108 | 403 | tx0 += dty; | ||
2109 | 404 | ty0 -= dtx; | ||
2110 | 405 | rnd0 >>= DITHER_RAND_SHIFT; | ||
2111 | 406 | } | ||
2112 | 407 | |||
2113 | 408 | // dither below the edge | ||
2114 | 409 | for | ||
2115 | 410 | (uint32_t i = 0; | ||
2116 | 411 | i < DITHER_WIDTH; | ||
2117 | 412 | ++i, ++y, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT) | ||
2118 | 413 | if | ||
2119 | 414 | ((rnd0 & DITHER_RAND_MASK) >= i + DITHER_WIDTH && | ||
2120 | 415 | y >= 0 && y < dsth) | ||
2121 | 416 | reinterpret_cast<T *> | ||
2122 | 417 | (static_cast<uint8_t *>(dst.get_pixels()) | ||
2123 | 418 | + | ||
2124 | 419 | y * dst.get_pitch()) | ||
2125 | 420 | [x] | ||
2126 | 421 | = | ||
2127 | 422 | bcolormap | ||
2128 | 423 | [bpixels | ||
2129 | 424 | [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) | | ||
2130 | 425 | ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))] | ||
2131 | 426 | | | ||
2132 | 427 | ((b >> 8) & 0xFF00)]; | ||
2133 | 428 | } | ||
2134 | 429 | |||
2135 | 430 | tx += dtx; | ||
2136 | 431 | ty += dty; | ||
2137 | 432 | b += db; | ||
2138 | 433 | } | ||
2139 | 434 | } | ||
2140 | 435 | |||
2141 | 436 | /** | ||
2142 | 437 | * \see dither_edge_horiz | ||
2143 | 438 | */ | ||
2144 | 439 | template<typename T> static void dither_edge_vert | ||
2145 | 440 | (SDLSurface & dst, | ||
2146 | 441 | const Vertex & start, const Vertex & end, | ||
2147 | 442 | const Texture & ltex, const Texture & rtex) | ||
2148 | 443 | { | ||
2149 | 444 | uint8_t * lpixels, * rpixels; | ||
2150 | 445 | T * lcolormap, * rcolormap; | ||
2151 | 446 | |||
2152 | 447 | lpixels = ltex.get_curpixels(); | ||
2153 | 448 | lcolormap = static_cast<T *>(ltex.get_colormap()); | ||
2154 | 449 | rpixels = rtex.get_curpixels(); | ||
2155 | 450 | rcolormap = static_cast<T *>(rtex.get_colormap()); | ||
2156 | 451 | |||
2157 | 452 | int32_t tx, ty, b, dtx, dty, db, tx0, ty0; | ||
2158 | 453 | |||
2159 | 454 | tx = ITOFIX(start.tx); | ||
2160 | 455 | ty = ITOFIX(start.ty); | ||
2161 | 456 | b = ITOFIX(start.b); | ||
2162 | 457 | dtx = (ITOFIX(end.tx) - tx) / (end.y - start.y + 1); | ||
2163 | 458 | dty = (ITOFIX(end.ty) - ty) / (end.y - start.y + 1); | ||
2164 | 459 | db = (ITOFIX(end.b) - b) / (end.y - start.y + 1); | ||
2165 | 460 | |||
2166 | 461 | // TODO(unknown): seed this depending on field coordinates | ||
2167 | 462 | uint32_t rnd = 0; | ||
2168 | 463 | |||
2169 | 464 | const int32_t dstw = dst.width(); | ||
2170 | 465 | const int32_t dsth = dst.height(); | ||
2171 | 466 | |||
2172 | 467 | int32_t xdiff = ITOFIX(end.x - start.x) / (end.y - start.y); | ||
2173 | 468 | int32_t centerx = ITOFIX(start.x); | ||
2174 | 469 | |||
2175 | 470 | for (int32_t y = start.y; y < end.y; y++, centerx += xdiff) { | ||
2176 | 471 | rnd = SIMPLE_RAND(rnd); | ||
2177 | 472 | |||
2178 | 473 | if (y >= 0 && y < dsth) { | ||
2179 | 474 | int32_t x = FIXTOI(centerx) - DITHER_WIDTH; | ||
2180 | 475 | |||
2181 | 476 | tx0 = tx - DITHER_WIDTH * dty; | ||
2182 | 477 | ty0 = ty + DITHER_WIDTH * dtx; | ||
2183 | 478 | |||
2184 | 479 | uint32_t rnd0 = rnd; | ||
2185 | 480 | |||
2186 | 481 | // dither on left side | ||
2187 | 482 | for | ||
2188 | 483 | (uint32_t i = 0; | ||
2189 | 484 | i < DITHER_WIDTH; | ||
2190 | 485 | ++i, ++x, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT) | ||
2191 | 486 | if ((rnd0 & DITHER_RAND_MASK) <= i && x >= 0 && x < dstw) | ||
2192 | 487 | reinterpret_cast<T *> | ||
2193 | 488 | (static_cast<uint8_t *>(dst.get_pixels()) | ||
2194 | 489 | + | ||
2195 | 490 | y * dst.get_pitch()) | ||
2196 | 491 | [x] | ||
2197 | 492 | = | ||
2198 | 493 | lcolormap | ||
2199 | 494 | [lpixels | ||
2200 | 495 | [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) | | ||
2201 | 496 | ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))] | ||
2202 | 497 | | | ||
2203 | 498 | ((b >> 8) & 0xFF00)]; | ||
2204 | 499 | |||
2205 | 500 | // dither on right side | ||
2206 | 501 | for | ||
2207 | 502 | (uint32_t i = 0; | ||
2208 | 503 | i < DITHER_WIDTH; | ||
2209 | 504 | ++i, ++x, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT) | ||
2210 | 505 | if | ||
2211 | 506 | ((rnd0 & DITHER_RAND_MASK) >= i + DITHER_WIDTH | ||
2212 | 507 | && | ||
2213 | 508 | x >= 0 && x < dstw) | ||
2214 | 509 | reinterpret_cast<T *> | ||
2215 | 510 | (static_cast<uint8_t *>(dst.get_pixels()) | ||
2216 | 511 | + | ||
2217 | 512 | y * dst.get_pitch()) | ||
2218 | 513 | [x] | ||
2219 | 514 | = | ||
2220 | 515 | rcolormap | ||
2221 | 516 | [rpixels | ||
2222 | 517 | [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) | | ||
2223 | 518 | ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))] | ||
2224 | 519 | | | ||
2225 | 520 | ((b >> 8) & 0xFF00)]; | ||
2226 | 521 | } | ||
2227 | 522 | |||
2228 | 523 | tx += dtx; | ||
2229 | 524 | ty += dty; | ||
2230 | 525 | b += db; | ||
2231 | 526 | } | ||
2232 | 527 | } | ||
2233 | 528 | |||
2234 | 529 | template<typename T> static void render_road_horiz | ||
2235 | 530 | (SDLSurface & dst, Point const start, Point const end, const SDLSurface & src) | ||
2236 | 531 | { | ||
2237 | 532 | int32_t const dstw = dst.width(); | ||
2238 | 533 | int32_t const dsth = dst.height(); | ||
2239 | 534 | |||
2240 | 535 | int32_t const ydiff = ((end.y - start.y) << 16) / (end.x - start.x); | ||
2241 | 536 | int32_t centery = start.y << 16; | ||
2242 | 537 | |||
2243 | 538 | for (int32_t x = start.x, sx = 0; x < end.x; ++x, centery += ydiff, ++sx) { | ||
2244 | 539 | if (x < 0 || x >= dstw) | ||
2245 | 540 | continue; | ||
2246 | 541 | |||
2247 | 542 | for (int32_t i = 0, y = (centery >> 16) - 2; i < 5; ++i, ++y) | ||
2248 | 543 | if (0 < y && y < dsth) | ||
2249 | 544 | reinterpret_cast<T *> | ||
2250 | 545 | (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch()) | ||
2251 | 546 | [x] | ||
2252 | 547 | = | ||
2253 | 548 | reinterpret_cast<T const *> | ||
2254 | 549 | (static_cast<uint8_t const *>(src.get_pixels()) | ||
2255 | 550 | + | ||
2256 | 551 | i * src.get_pitch()) | ||
2257 | 552 | [sx]; | ||
2258 | 553 | } | ||
2259 | 554 | } | ||
2260 | 555 | |||
2261 | 556 | template<typename T> static void render_road_vert | ||
2262 | 557 | (SDLSurface & dst, Point const start, Point const end, const SDLSurface & src) | ||
2263 | 558 | { | ||
2264 | 559 | int32_t const dstw = dst.width(); | ||
2265 | 560 | int32_t const dsth = dst.height(); | ||
2266 | 561 | |||
2267 | 562 | int32_t const xdiff = ((end.x - start.x) << 16) / (end.y - start.y); | ||
2268 | 563 | int32_t centerx = start.x << 16; | ||
2269 | 564 | |||
2270 | 565 | for (int32_t y = start.y, sy = 0; y < end.y; ++y, centerx += xdiff, ++sy) { | ||
2271 | 566 | if (y < 0 || y >= dsth) | ||
2272 | 567 | continue; | ||
2273 | 568 | |||
2274 | 569 | for (int32_t i = 0, x = (centerx >> 16) - 2; i < 5; ++i, ++x) | ||
2275 | 570 | if (0 < x && x < dstw) | ||
2276 | 571 | reinterpret_cast<T *> | ||
2277 | 572 | (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch()) | ||
2278 | 573 | [x] | ||
2279 | 574 | = | ||
2280 | 575 | reinterpret_cast<T const *> | ||
2281 | 576 | (static_cast<uint8_t const *>(src.get_pixels()) | ||
2282 | 577 | + | ||
2283 | 578 | sy * src.get_pitch()) | ||
2284 | 579 | [i]; | ||
2285 | 580 | } | ||
2286 | 581 | } | ||
2287 | 582 | |||
2288 | 583 | template<typename T> static void draw_field_int | ||
2289 | 584 | (SDLSurface & dst, | ||
2290 | 585 | const Vertex & f_vert, | ||
2291 | 586 | const Vertex & r_vert, | ||
2292 | 587 | const Vertex & bl_vert, | ||
2293 | 588 | const Vertex & br_vert, | ||
2294 | 589 | uint8_t roads, | ||
2295 | 590 | const Texture & tr_d_texture, | ||
2296 | 591 | const Texture & l_r_texture, | ||
2297 | 592 | const Texture & f_d_texture, | ||
2298 | 593 | const Texture & f_r_texture) | ||
2299 | 594 | { | ||
2300 | 595 | SDLSurface& rt_busy = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Busy)); | ||
2301 | 596 | SDLSurface& rt_normal = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Normal)); | ||
2302 | 597 | |||
2303 | 598 | dst.lock(Surface::Lock_Normal); | ||
2304 | 599 | |||
2305 | 600 | render_triangle<T> (dst, f_vert, br_vert, r_vert, f_r_texture); | ||
2306 | 601 | render_triangle<T> (dst, f_vert, bl_vert, br_vert, f_d_texture); | ||
2307 | 602 | |||
2308 | 603 | // Render roads and dither polygon edges | ||
2309 | 604 | uint8_t road; | ||
2310 | 605 | |||
2311 | 606 | road = (roads >> Widelands::Road_East) & Widelands::Road_Mask; | ||
2312 | 607 | if (-128 < f_vert.b || -128 < r_vert.b) { | ||
2313 | 608 | if (road) { | ||
2314 | 609 | switch (road) { | ||
2315 | 610 | case Widelands::Road_Normal: | ||
2316 | 611 | render_road_horiz<T> (dst, f_vert, r_vert, rt_normal); | ||
2317 | 612 | break; | ||
2318 | 613 | case Widelands::Road_Busy: | ||
2319 | 614 | render_road_horiz<T> (dst, f_vert, r_vert, rt_busy); | ||
2320 | 615 | break; | ||
2321 | 616 | default: | ||
2322 | 617 | assert(false); | ||
2323 | 618 | break; | ||
2324 | 619 | } | ||
2325 | 620 | } else if (&f_r_texture != &tr_d_texture) { | ||
2326 | 621 | dither_edge_horiz<T>(dst, f_vert, r_vert, f_r_texture, tr_d_texture); | ||
2327 | 622 | } | ||
2328 | 623 | } | ||
2329 | 624 | |||
2330 | 625 | road = (roads >> Widelands::Road_SouthEast) & Widelands::Road_Mask; | ||
2331 | 626 | if (-128 < f_vert.b || -128 < br_vert.b) { | ||
2332 | 627 | if (road) { | ||
2333 | 628 | switch (road) { | ||
2334 | 629 | case Widelands::Road_Normal: | ||
2335 | 630 | render_road_vert<T> (dst, f_vert, br_vert, rt_normal); | ||
2336 | 631 | break; | ||
2337 | 632 | case Widelands::Road_Busy: | ||
2338 | 633 | render_road_vert<T> (dst, f_vert, br_vert, rt_busy); | ||
2339 | 634 | break; | ||
2340 | 635 | default: | ||
2341 | 636 | assert(false); | ||
2342 | 637 | break; | ||
2343 | 638 | } | ||
2344 | 639 | } else if (&f_r_texture != &f_d_texture) { | ||
2345 | 640 | dither_edge_vert<T>(dst, f_vert, br_vert, f_r_texture, f_d_texture); | ||
2346 | 641 | } | ||
2347 | 642 | } | ||
2348 | 643 | |||
2349 | 644 | road = (roads >> Widelands::Road_SouthWest) & Widelands::Road_Mask; | ||
2350 | 645 | if (-128 < f_vert.b || -128 < bl_vert.b) { | ||
2351 | 646 | if (road) { | ||
2352 | 647 | switch (road) { | ||
2353 | 648 | case Widelands::Road_Normal: | ||
2354 | 649 | render_road_vert<T> (dst, f_vert, bl_vert, rt_normal); | ||
2355 | 650 | break; | ||
2356 | 651 | case Widelands::Road_Busy: | ||
2357 | 652 | render_road_vert<T> (dst, f_vert, bl_vert, rt_busy); | ||
2358 | 653 | break; | ||
2359 | 654 | default: | ||
2360 | 655 | assert(false); | ||
2361 | 656 | break; | ||
2362 | 657 | } | ||
2363 | 658 | } else if (&l_r_texture != &f_d_texture) { | ||
2364 | 659 | dither_edge_vert<T>(dst, f_vert, bl_vert, f_d_texture, l_r_texture); | ||
2365 | 660 | } | ||
2366 | 661 | } | ||
2367 | 662 | |||
2368 | 663 | dst.unlock(Surface::Unlock_Update); | ||
2369 | 664 | |||
2370 | 665 | // TODO(unknown): similar textures may not need dithering | ||
2371 | 666 | } | ||
2372 | 667 | |||
2373 | 668 | #endif // end of include guard: WL_GRAPHIC_SDL_TERRAIN_H | ||
2374 | 669 | 0 | ||
2375 | === removed file 'src/graphic/sdl/utils.cc' | |||
2376 | --- src/graphic/sdl/utils.cc 2014-11-08 15:47:38 +0000 | |||
2377 | +++ src/graphic/sdl/utils.cc 1970-01-01 00:00:00 +0000 | |||
2378 | @@ -1,30 +0,0 @@ | |||
2379 | 1 | /* | ||
2380 | 2 | * Copyright (C) 2006-2012 by the Widelands Development Team | ||
2381 | 3 | * | ||
2382 | 4 | * This program is free software; you can redistribute it and/or | ||
2383 | 5 | * modify it under the terms of the GNU General Public License | ||
2384 | 6 | * as published by the Free Software Foundation; either version 2 | ||
2385 | 7 | * of the License, or (at your option) any later version. | ||
2386 | 8 | * | ||
2387 | 9 | * This program is distributed in the hope that it will be useful, | ||
2388 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2389 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2390 | 12 | * GNU General Public License for more details. | ||
2391 | 13 | * | ||
2392 | 14 | * You should have received a copy of the GNU General Public License | ||
2393 | 15 | * along with this program; if not, write to the Free Software | ||
2394 | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
2395 | 17 | * | ||
2396 | 18 | */ | ||
2397 | 19 | |||
2398 | 20 | #include "graphic/sdl/utils.h" | ||
2399 | 21 | |||
2400 | 22 | #include <cassert> | ||
2401 | 23 | |||
2402 | 24 | #include <SDL.h> | ||
2403 | 25 | |||
2404 | 26 | SDL_Surface * empty_sdl_surface(int16_t w, int16_t h) { | ||
2405 | 27 | SDL_Surface* const surface = | ||
2406 | 28 | SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); | ||
2407 | 29 | return surface; | ||
2408 | 30 | } | ||
2409 | 31 | 0 | ||
2410 | === removed file 'src/graphic/sdl/utils.h' | |||
2411 | --- src/graphic/sdl/utils.h 2014-09-27 18:53:55 +0000 | |||
2412 | +++ src/graphic/sdl/utils.h 1970-01-01 00:00:00 +0000 | |||
2413 | @@ -1,29 +0,0 @@ | |||
2414 | 1 | /* | ||
2415 | 2 | * Copyright (C) 2006-2012 by the Widelands Development Team | ||
2416 | 3 | * | ||
2417 | 4 | * This program is free software; you can redistribute it and/or | ||
2418 | 5 | * modify it under the terms of the GNU General Public License | ||
2419 | 6 | * as published by the Free Software Foundation; either version 2 | ||
2420 | 7 | * of the License, or (at your option) any later version. | ||
2421 | 8 | * | ||
2422 | 9 | * This program is distributed in the hope that it will be useful, | ||
2423 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2424 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2425 | 12 | * GNU General Public License for more details. | ||
2426 | 13 | * | ||
2427 | 14 | * You should have received a copy of the GNU General Public License | ||
2428 | 15 | * along with this program; if not, write to the Free Software | ||
2429 | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
2430 | 17 | * | ||
2431 | 18 | */ | ||
2432 | 19 | |||
2433 | 20 | #ifndef WL_GRAPHIC_SDL_UTILS_H | ||
2434 | 21 | #define WL_GRAPHIC_SDL_UTILS_H | ||
2435 | 22 | |||
2436 | 23 | #include <stdint.h> | ||
2437 | 24 | |||
2438 | 25 | struct SDL_Surface; | ||
2439 | 26 | |||
2440 | 27 | SDL_Surface * empty_sdl_surface(int16_t w, int16_t h); | ||
2441 | 28 | |||
2442 | 29 | #endif // end of include guard: WL_GRAPHIC_SDL_UTILS_H | ||
2443 | 30 | 0 | ||
2444 | === removed file 'src/graphic/sdl/vertex.h' | |||
2445 | --- src/graphic/sdl/vertex.h 2014-09-27 18:53:55 +0000 | |||
2446 | +++ src/graphic/sdl/vertex.h 1970-01-01 00:00:00 +0000 | |||
2447 | @@ -1,39 +0,0 @@ | |||
2448 | 1 | /* | ||
2449 | 2 | * Copyright (C) 2002-2004, 2006-2007 by the Widelands Development Team | ||
2450 | 3 | * | ||
2451 | 4 | * This program is free software; you can redistribute it and/or | ||
2452 | 5 | * modify it under the terms of the GNU General Public License | ||
2453 | 6 | * as published by the Free Software Foundation; either version 2 | ||
2454 | 7 | * of the License, or (at your option) any later version. | ||
2455 | 8 | * | ||
2456 | 9 | * This program is distributed in the hope that it will be useful, | ||
2457 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2458 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2459 | 12 | * GNU General Public License for more details. | ||
2460 | 13 | * | ||
2461 | 14 | * You should have received a copy of the GNU General Public License | ||
2462 | 15 | * along with this program; if not, write to the Free Software | ||
2463 | 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
2464 | 17 | * | ||
2465 | 18 | */ | ||
2466 | 19 | |||
2467 | 20 | #ifndef WL_GRAPHIC_SDL_VERTEX_H | ||
2468 | 21 | #define WL_GRAPHIC_SDL_VERTEX_H | ||
2469 | 22 | |||
2470 | 23 | #include "base/point.h" | ||
2471 | 24 | |||
2472 | 25 | /// Like a point but with an additional bright factor and texture coordinates. | ||
2473 | 26 | struct Vertex:public Point { | ||
2474 | 27 | Vertex() : Point (0, 0), b(0), tx(0), ty(0) {} | ||
2475 | 28 | Vertex | ||
2476 | 29 | (const int32_t vx, const int32_t vy, | ||
2477 | 30 | const int32_t vb, | ||
2478 | 31 | const int32_t vtx, const int32_t vty) | ||
2479 | 32 | |||
2480 | 33 | : Point(vx, vy), b(vb), tx(vtx), ty(vty) | ||
2481 | 34 | {} | ||
2482 | 35 | |||
2483 | 36 | int32_t b, tx, ty; | ||
2484 | 37 | }; | ||
2485 | 38 | |||
2486 | 39 | #endif // end of include guard: WL_GRAPHIC_SDL_VERTEX_H | ||
2487 | 40 | 0 | ||
2488 | === added file 'src/graphic/sdl_utils.cc' | |||
2489 | --- src/graphic/sdl_utils.cc 1970-01-01 00:00:00 +0000 | |||
2490 | +++ src/graphic/sdl_utils.cc 2014-11-23 12:03:00 +0000 | |||
2491 | @@ -0,0 +1,28 @@ | |||
2492 | 1 | /* | ||
2493 | 2 | * Copyright (C) 2006-2014 by the Widelands Development Team | ||
2494 | 3 | * | ||
2495 | 4 | * This program is free software; you can redistribute it and/or | ||
2496 | 5 | * modify it under the terms of the GNU General Public License | ||
2497 | 6 | * as published by the Free Software Foundation; either version 2 | ||
2498 | 7 | * of the License, or (at your option) any later version. | ||
2499 | 8 | * | ||
2500 | 9 | * This program is distributed in the hope that it will be useful, | ||
2501 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2502 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2503 | 12 | * GNU General Public License for more details. | ||
2504 | 13 | * | ||
2505 | 14 | * You should have received a copy of the GNU General Public License | ||
2506 | 15 | * along with this program; if not, write to the Free Software | ||
2507 | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
2508 | 17 | * | ||
2509 | 18 | */ | ||
2510 | 19 | |||
2511 | 20 | #include "graphic/sdl_utils.h" | ||
2512 | 21 | |||
2513 | 22 | #include <SDL.h> | ||
2514 | 23 | |||
2515 | 24 | SDL_Surface* empty_sdl_surface(int16_t w, int16_t h) { | ||
2516 | 25 | SDL_Surface* const surface = | ||
2517 | 26 | SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); | ||
2518 | 27 | return surface; | ||
2519 | 28 | } | ||
2520 | 0 | 29 | ||
2521 | === added file 'src/graphic/sdl_utils.h' | |||
2522 | --- src/graphic/sdl_utils.h 1970-01-01 00:00:00 +0000 | |||
2523 | +++ src/graphic/sdl_utils.h 2014-11-23 12:03:00 +0000 | |||
2524 | @@ -0,0 +1,29 @@ | |||
2525 | 1 | /* | ||
2526 | 2 | * Copyright (C) 2006-2014 by the Widelands Development Team | ||
2527 | 3 | * | ||
2528 | 4 | * This program is free software; you can redistribute it and/or | ||
2529 | 5 | * modify it under the terms of the GNU General Public License | ||
2530 | 6 | * as published by the Free Software Foundation; either version 2 | ||
2531 | 7 | * of the License, or (at your option) any later version. | ||
2532 | 8 | * | ||
2533 | 9 | * This program is distributed in the hope that it will be useful, | ||
2534 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2535 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2536 | 12 | * GNU General Public License for more details. | ||
2537 | 13 | * | ||
2538 | 14 | * You should have received a copy of the GNU General Public License | ||
2539 | 15 | * along with this program; if not, write to the Free Software | ||
2540 | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
2541 | 17 | * | ||
2542 | 18 | */ | ||
2543 | 19 | |||
2544 | 20 | #ifndef WL_GRAPHIC_SDL_UTILS_H | ||
2545 | 21 | #define WL_GRAPHIC_SDL_UTILS_H | ||
2546 | 22 | |||
2547 | 23 | #include <stdint.h> | ||
2548 | 24 | |||
2549 | 25 | struct SDL_Surface; | ||
2550 | 26 | |||
2551 | 27 | SDL_Surface * empty_sdl_surface(int16_t w, int16_t h); | ||
2552 | 28 | |||
2553 | 29 | #endif // end of include guard: | ||
2554 | 0 | 30 | ||
2555 | === modified file 'src/graphic/surface.cc' | |||
2556 | --- src/graphic/surface.cc 2014-11-02 20:15:01 +0000 | |||
2557 | +++ src/graphic/surface.cc 2014-11-23 12:03:00 +0000 | |||
2558 | @@ -19,43 +19,175 @@ | |||
2559 | 19 | 19 | ||
2560 | 20 | #include "graphic/surface.h" | 20 | #include "graphic/surface.h" |
2561 | 21 | 21 | ||
2562 | 22 | #include <cassert> | ||
2563 | 23 | #include <cmath> | ||
2564 | 24 | #include <cstdlib> | ||
2565 | 25 | |||
2566 | 22 | #include <SDL.h> | 26 | #include <SDL.h> |
2567 | 23 | 27 | ||
2568 | 28 | #include "base/macros.h" | ||
2569 | 29 | #include "graphic/gl/blit_program.h" | ||
2570 | 30 | #include "graphic/gl/draw_line_program.h" | ||
2571 | 31 | #include "graphic/gl/draw_rect_program.h" | ||
2572 | 32 | #include "graphic/gl/fill_rect_program.h" | ||
2573 | 24 | #include "graphic/gl/surface_texture.h" | 33 | #include "graphic/gl/surface_texture.h" |
2597 | 25 | #include "graphic/sdl/surface.h" | 34 | #include "graphic/gl/utils.h" |
2598 | 26 | #include "graphic/sdl/utils.h" | 35 | #include "graphic/graphic.h" |
2599 | 27 | 36 | ||
2577 | 28 | extern bool g_opengl; | ||
2578 | 29 | |||
2579 | 30 | namespace { | ||
2580 | 31 | |||
2581 | 32 | bool s_is_diplay_format_defined = false; | ||
2582 | 33 | |||
2583 | 34 | SDL_Surface* maybe_convert_to_diplay_format(SDL_Surface* surface) { | ||
2584 | 35 | if (!s_is_diplay_format_defined) { | ||
2585 | 36 | return surface; | ||
2586 | 37 | } | ||
2587 | 38 | SDL_Surface * converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0); | ||
2588 | 39 | SDL_FreeSurface(surface); | ||
2589 | 40 | return converted; | ||
2590 | 41 | } | ||
2591 | 42 | |||
2592 | 43 | } // namespace | ||
2593 | 44 | |||
2594 | 45 | void Surface::display_format_is_now_defined() { | ||
2595 | 46 | s_is_diplay_format_defined = true; | ||
2596 | 47 | } | ||
2600 | 48 | 37 | ||
2601 | 49 | Surface* Surface::create(SDL_Surface* surf) { | 38 | Surface* Surface::create(SDL_Surface* surf) { |
2606 | 50 | if (g_opengl) { | 39 | return new GLSurfaceTexture(surf); |
2603 | 51 | return new GLSurfaceTexture(surf); | ||
2604 | 52 | } | ||
2605 | 53 | return new SDLSurface(maybe_convert_to_diplay_format(surf)); | ||
2607 | 54 | } | 40 | } |
2608 | 55 | 41 | ||
2609 | 56 | Surface* Surface::create(uint16_t w, uint16_t h) { | 42 | Surface* Surface::create(uint16_t w, uint16_t h) { |
2614 | 57 | if (g_opengl) { | 43 | return new GLSurfaceTexture(w, h); |
2615 | 58 | return new GLSurfaceTexture(w, h); | 44 | } |
2616 | 59 | } | 45 | |
2617 | 60 | return new SDLSurface(empty_sdl_surface(w, h)); | 46 | |
2618 | 47 | uint16_t Surface::width() const { | ||
2619 | 48 | return m_w; | ||
2620 | 49 | } | ||
2621 | 50 | |||
2622 | 51 | uint16_t Surface::height() const { | ||
2623 | 52 | return m_h; | ||
2624 | 53 | } | ||
2625 | 54 | |||
2626 | 55 | uint8_t * Surface::get_pixels() const | ||
2627 | 56 | { | ||
2628 | 57 | return m_pixels.get(); | ||
2629 | 58 | } | ||
2630 | 59 | |||
2631 | 60 | uint32_t Surface::get_pixel(uint16_t x, uint16_t y) { | ||
2632 | 61 | assert(m_pixels); | ||
2633 | 62 | assert(x < m_w); | ||
2634 | 63 | assert(y < m_h); | ||
2635 | 64 | |||
2636 | 65 | uint8_t * data = &m_pixels[y * get_pitch() + 4 * x]; | ||
2637 | 66 | return *(reinterpret_cast<uint32_t *>(data)); | ||
2638 | 67 | } | ||
2639 | 68 | |||
2640 | 69 | uint16_t Surface::get_pitch() const { | ||
2641 | 70 | return 4 * m_w; | ||
2642 | 71 | } | ||
2643 | 72 | |||
2644 | 73 | const SDL_PixelFormat & Surface::format() const { | ||
2645 | 74 | return Gl::gl_rgba_format(); | ||
2646 | 75 | } | ||
2647 | 76 | |||
2648 | 77 | |||
2649 | 78 | void Surface::set_pixel(uint16_t x, uint16_t y, uint32_t clr) { | ||
2650 | 79 | assert(m_pixels); | ||
2651 | 80 | assert(x < m_w); | ||
2652 | 81 | assert(y < m_h); | ||
2653 | 82 | |||
2654 | 83 | uint8_t * data = &m_pixels[y * get_pitch() + 4 * x]; | ||
2655 | 84 | *(reinterpret_cast<uint32_t *>(data)) = clr; | ||
2656 | 85 | } | ||
2657 | 86 | |||
2658 | 87 | FloatRect Surface::to_opengl(const Rect& rect, ConversionMode mode) { | ||
2659 | 88 | const float delta = mode == ConversionMode::kExact ? 0. : 0.5; | ||
2660 | 89 | float x1 = rect.x + delta; | ||
2661 | 90 | float y1 = rect.y + delta; | ||
2662 | 91 | pixel_to_gl(&x1, &y1); | ||
2663 | 92 | float x2 = rect.x + rect.w - delta; | ||
2664 | 93 | float y2 = rect.y + rect.h - delta; | ||
2665 | 94 | pixel_to_gl(&x2, &y2); | ||
2666 | 95 | |||
2667 | 96 | return FloatRect(x1, y1, x2 - x1, y2 - y1); | ||
2668 | 97 | } | ||
2669 | 98 | |||
2670 | 99 | void Surface::draw_rect(const Rect& rc, const RGBColor& clr) | ||
2671 | 100 | { | ||
2672 | 101 | glViewport(0, 0, width(), height()); | ||
2673 | 102 | DrawRectProgram::instance().draw(to_opengl(rc, ConversionMode::kMidPoint), clr); | ||
2674 | 103 | } | ||
2675 | 104 | |||
2676 | 105 | /** | ||
2677 | 106 | * Draws a filled rectangle | ||
2678 | 107 | */ | ||
2679 | 108 | void Surface::fill_rect(const Rect& rc, const RGBAColor& clr) { | ||
2680 | 109 | glViewport(0, 0, width(), height()); | ||
2681 | 110 | |||
2682 | 111 | glBlendFunc(GL_ONE, GL_ZERO); | ||
2683 | 112 | |||
2684 | 113 | FillRectProgram::instance().draw(to_opengl(rc, ConversionMode::kExact), clr); | ||
2685 | 114 | |||
2686 | 115 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
2687 | 116 | } | ||
2688 | 117 | |||
2689 | 118 | /** | ||
2690 | 119 | * Change the brightness of the given rectangle | ||
2691 | 120 | */ | ||
2692 | 121 | void Surface::brighten_rect(const Rect& rc, const int32_t factor) | ||
2693 | 122 | { | ||
2694 | 123 | if (!factor) | ||
2695 | 124 | return; | ||
2696 | 125 | |||
2697 | 126 | glViewport(0, 0, width(), height()); | ||
2698 | 127 | |||
2699 | 128 | // The simple trick here is to fill the rect, but using a different glBlendFunc that will sum | ||
2700 | 129 | // src and target (or subtract them if factor is negative). | ||
2701 | 130 | if (factor < 0) { | ||
2702 | 131 | glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); | ||
2703 | 132 | } | ||
2704 | 133 | |||
2705 | 134 | glBlendFunc(GL_ONE, GL_ONE); | ||
2706 | 135 | |||
2707 | 136 | const int delta = std::abs(factor); | ||
2708 | 137 | FillRectProgram::instance().draw( | ||
2709 | 138 | to_opengl(rc, ConversionMode::kExact), RGBAColor(delta, delta, delta, 0)); | ||
2710 | 139 | |||
2711 | 140 | if (factor < 0) { | ||
2712 | 141 | glBlendEquation(GL_FUNC_ADD); | ||
2713 | 142 | } | ||
2714 | 143 | |||
2715 | 144 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
2716 | 145 | } | ||
2717 | 146 | |||
2718 | 147 | void Surface::draw_line | ||
2719 | 148 | (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth) | ||
2720 | 149 | { | ||
2721 | 150 | glViewport(0, 0, width(), height()); | ||
2722 | 151 | |||
2723 | 152 | float gl_x1 = x1 + 0.5; | ||
2724 | 153 | float gl_y1 = y1 + 0.5; | ||
2725 | 154 | pixel_to_gl(&gl_x1, &gl_y1); | ||
2726 | 155 | |||
2727 | 156 | float gl_x2 = x2 + 0.5; | ||
2728 | 157 | float gl_y2 = y2 + 0.5; | ||
2729 | 158 | pixel_to_gl(&gl_x2, &gl_y2); | ||
2730 | 159 | |||
2731 | 160 | DrawLineProgram::instance().draw(gl_x1, gl_y1, gl_x2, gl_y2, color, gwidth); | ||
2732 | 161 | } | ||
2733 | 162 | |||
2734 | 163 | // Converts the pixel (x, y) in a texture to a gl coordinate in [0, 1]. | ||
2735 | 164 | inline void pixel_to_gl_texture(const int width, const int height, float* x, float* y) { | ||
2736 | 165 | *x = (*x / width); | ||
2737 | 166 | *y = (*y / height); | ||
2738 | 167 | } | ||
2739 | 168 | |||
2740 | 169 | void Surface::blit | ||
2741 | 170 | (const Point& dst, const Surface* image, const Rect& srcrc, Composite cm) | ||
2742 | 171 | { | ||
2743 | 172 | glViewport(0, 0, width(), height()); | ||
2744 | 173 | |||
2745 | 174 | // Source Rectangle. | ||
2746 | 175 | const GLSurfaceTexture* const texture = static_cast<const GLSurfaceTexture*>(image); | ||
2747 | 176 | FloatRect gl_src_rect; | ||
2748 | 177 | { | ||
2749 | 178 | float x1 = srcrc.x; | ||
2750 | 179 | float y1 = srcrc.y; | ||
2751 | 180 | pixel_to_gl_texture(texture->width(), texture->height(), &x1, &y1); | ||
2752 | 181 | float x2 = srcrc.x + srcrc.w; | ||
2753 | 182 | float y2 = srcrc.y + srcrc.h; | ||
2754 | 183 | pixel_to_gl_texture(texture->width(), texture->height(), &x2, &y2); | ||
2755 | 184 | gl_src_rect.x = x1; | ||
2756 | 185 | gl_src_rect.y = y1; | ||
2757 | 186 | gl_src_rect.w = x2 - x1; | ||
2758 | 187 | gl_src_rect.h = y2 - y1; | ||
2759 | 188 | } | ||
2760 | 189 | |||
2761 | 190 | const FloatRect gl_dst_rect = to_opengl(Rect(dst.x, dst.y, srcrc.w, srcrc.h), ConversionMode::kExact); | ||
2762 | 191 | |||
2763 | 192 | BlitProgram::instance().draw(gl_dst_rect, gl_src_rect, texture->get_gl_texture(), cm); | ||
2764 | 61 | } | 193 | } |
2765 | 62 | 194 | ||
2766 | === modified file 'src/graphic/surface.h' | |||
2767 | --- src/graphic/surface.h 2014-11-08 16:02:07 +0000 | |||
2768 | +++ src/graphic/surface.h 2014-11-23 12:03:00 +0000 | |||
2769 | @@ -20,6 +20,8 @@ | |||
2770 | 20 | #ifndef WL_GRAPHIC_SURFACE_H | 20 | #ifndef WL_GRAPHIC_SURFACE_H |
2771 | 21 | #define WL_GRAPHIC_SURFACE_H | 21 | #define WL_GRAPHIC_SURFACE_H |
2772 | 22 | 22 | ||
2773 | 23 | #include <memory> | ||
2774 | 24 | |||
2775 | 23 | #include "base/macros.h" | 25 | #include "base/macros.h" |
2776 | 24 | #include "base/rect.h" | 26 | #include "base/rect.h" |
2777 | 25 | #include "graphic/color.h" | 27 | #include "graphic/color.h" |
2778 | @@ -31,13 +33,6 @@ | |||
2779 | 31 | */ | 33 | */ |
2780 | 32 | class Surface { | 34 | class Surface { |
2781 | 33 | public: | 35 | public: |
2782 | 34 | // Surfaces can either be converted to display format on creation or kept in | ||
2783 | 35 | // the format they were created. The only reason not to convert to display | ||
2784 | 36 | // format is when no display format is defined - trying will then crash the | ||
2785 | 37 | // program. This is only the case when SDL_SetVideoMode() has never been | ||
2786 | 38 | // called, so call this method after you called SDL_SetVideoMode. | ||
2787 | 39 | static void display_format_is_now_defined(); | ||
2788 | 40 | |||
2789 | 41 | // Create a new surface from an SDL_Surface. Ownership is taken. | 36 | // Create a new surface from an SDL_Surface. Ownership is taken. |
2790 | 42 | static Surface* create(SDL_Surface*); | 37 | static Surface* create(SDL_Surface*); |
2791 | 43 | 38 | ||
2792 | @@ -49,26 +44,26 @@ | |||
2793 | 49 | virtual ~Surface() {} | 44 | virtual ~Surface() {} |
2794 | 50 | 45 | ||
2795 | 51 | /// Dimensions. | 46 | /// Dimensions. |
2798 | 52 | virtual uint16_t width() const = 0; | 47 | uint16_t width() const; |
2799 | 53 | virtual uint16_t height() const = 0; | 48 | uint16_t height() const; |
2800 | 54 | 49 | ||
2801 | 55 | /// This draws a part of another surface to this surface | 50 | /// This draws a part of another surface to this surface |
2803 | 56 | virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm = CM_UseAlpha) = 0; | 51 | virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm = CM_UseAlpha); |
2804 | 57 | 52 | ||
2805 | 58 | /// Draws a filled rect to the surface. No blending takes place, the values | 53 | /// Draws a filled rect to the surface. No blending takes place, the values |
2806 | 59 | //in the target are just replaced (i.e. / Composite would be CM_Copy). | 54 | //in the target are just replaced (i.e. / Composite would be CM_Copy). |
2808 | 60 | virtual void fill_rect(const Rect&, const RGBAColor&) = 0; | 55 | virtual void fill_rect(const Rect&, const RGBAColor&); |
2809 | 61 | 56 | ||
2810 | 62 | /// Draws a rect (frame only) to the surface. | 57 | /// Draws a rect (frame only) to the surface. |
2812 | 63 | virtual void draw_rect(const Rect&, const RGBColor&) = 0; | 58 | virtual void draw_rect(const Rect&, const RGBColor&); |
2813 | 64 | 59 | ||
2814 | 65 | /// draw a line to the surface | 60 | /// draw a line to the surface |
2815 | 66 | virtual void draw_line | 61 | virtual void draw_line |
2817 | 67 | (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t width = 1) = 0; | 62 | (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t width = 1); |
2818 | 68 | 63 | ||
2819 | 69 | /// makes a rectangle on the surface brighter (or darker). | 64 | /// makes a rectangle on the surface brighter (or darker). |
2820 | 70 | /// @note this is slow in SDL mode. Use with care | 65 | /// @note this is slow in SDL mode. Use with care |
2822 | 71 | virtual void brighten_rect(const Rect&, int32_t factor) = 0; | 66 | virtual void brighten_rect(const Rect&, int32_t factor); |
2823 | 72 | 67 | ||
2824 | 73 | /// The functions below are for direct pixel access. This should be used | 68 | /// The functions below are for direct pixel access. This should be used |
2825 | 74 | /// only very sparingly as / it is potentially expensive (especially for | 69 | /// only very sparingly as / it is potentially expensive (especially for |
2826 | @@ -105,7 +100,21 @@ | |||
2827 | 105 | }; | 100 | }; |
2828 | 106 | 101 | ||
2829 | 107 | /// This returns the pixel format for direct pixel access. | 102 | /// This returns the pixel format for direct pixel access. |
2831 | 108 | virtual const SDL_PixelFormat & format() const = 0; | 103 | const SDL_PixelFormat & format() const; |
2832 | 104 | |||
2833 | 105 | /** | ||
2834 | 106 | * \return Pitch of the raw pixel data, i.e. the number of bytes | ||
2835 | 107 | * contained in each image row. This can be strictly larger than | ||
2836 | 108 | * bytes per pixel times the width. | ||
2837 | 109 | */ | ||
2838 | 110 | uint16_t get_pitch() const; | ||
2839 | 111 | |||
2840 | 112 | /** | ||
2841 | 113 | * \return Pointer to the raw pixel data. | ||
2842 | 114 | * | ||
2843 | 115 | * \warning May only be called inside lock/unlock pairs. | ||
2844 | 116 | */ | ||
2845 | 117 | uint8_t * get_pixels() const; | ||
2846 | 109 | 118 | ||
2847 | 110 | /** | 119 | /** |
2848 | 111 | * Lock/Unlock pairs must guard any of the direct pixel access using the | 120 | * Lock/Unlock pairs must guard any of the direct pixel access using the |
2849 | @@ -113,29 +122,34 @@ | |||
2850 | 113 | * | 122 | * |
2851 | 114 | * \note Lock/Unlock pairs cannot be nested. | 123 | * \note Lock/Unlock pairs cannot be nested. |
2852 | 115 | */ | 124 | */ |
2853 | 116 | //@{ | ||
2854 | 117 | virtual void lock(LockMode) = 0; | 125 | virtual void lock(LockMode) = 0; |
2855 | 118 | virtual void unlock(UnlockMode) = 0; | 126 | virtual void unlock(UnlockMode) = 0; |
2876 | 119 | //@} | 127 | |
2877 | 120 | 128 | uint32_t get_pixel(uint16_t x, uint16_t y); | |
2878 | 121 | //@{ | 129 | void set_pixel(uint16_t x, uint16_t y, uint32_t clr); |
2879 | 122 | virtual uint32_t get_pixel(uint16_t x, uint16_t y) = 0; | 130 | |
2880 | 123 | virtual void set_pixel(uint16_t x, uint16_t y, uint32_t clr) = 0; | 131 | // Converts the given pixel into an OpenGl point. This might |
2881 | 124 | //@} | 132 | // need some flipping of axis, depending if you want to render |
2882 | 125 | 133 | // on the screen or not. | |
2883 | 126 | /** | 134 | virtual void pixel_to_gl(float* x, float* y) const = 0; |
2884 | 127 | * \return Pitch of the raw pixel data, i.e. the number of bytes | 135 | |
2885 | 128 | * contained in each image row. This can be strictly larger than | 136 | protected: |
2886 | 129 | * bytes per pixel times the width. | 137 | // Convert the 'rect' in pixel space into opengl space. |
2887 | 130 | */ | 138 | enum class ConversionMode { |
2888 | 131 | virtual uint16_t get_pitch() const = 0; | 139 | // Convert the rect as given. |
2889 | 132 | 140 | kExact, | |
2890 | 133 | /** | 141 | |
2891 | 134 | * \return Pointer to the raw pixel data. | 142 | // Convert the rect so that the borders are in the center |
2892 | 135 | * | 143 | // of the pixels. |
2893 | 136 | * \warning May only be called inside lock/unlock pairs. | 144 | kMidPoint, |
2894 | 137 | */ | 145 | }; |
2895 | 138 | virtual uint8_t * get_pixels() const = 0; | 146 | FloatRect to_opengl(const Rect& rect, ConversionMode mode); |
2896 | 147 | |||
2897 | 148 | /// Logical width and height of the surface | ||
2898 | 149 | uint16_t m_w, m_h; | ||
2899 | 150 | |||
2900 | 151 | /// Pixel data, while the texture is locked | ||
2901 | 152 | std::unique_ptr<uint8_t[]> m_pixels; | ||
2902 | 139 | 153 | ||
2903 | 140 | private: | 154 | private: |
2904 | 141 | DISALLOW_COPY_AND_ASSIGN(Surface); | 155 | DISALLOW_COPY_AND_ASSIGN(Surface); |
2905 | 142 | 156 | ||
2906 | === modified file 'src/graphic/text/CMakeLists.txt' | |||
2907 | --- src/graphic/text/CMakeLists.txt 2014-10-13 15:04:50 +0000 | |||
2908 | +++ src/graphic/text/CMakeLists.txt 2014-11-23 12:03:00 +0000 | |||
2909 | @@ -18,6 +18,7 @@ | |||
2910 | 18 | USES_SDL2_TTF | 18 | USES_SDL2_TTF |
2911 | 19 | USES_SDL2_GFX | 19 | USES_SDL2_GFX |
2912 | 20 | DEPENDS | 20 | DEPENDS |
2913 | 21 | graphic_sdl_utils | ||
2914 | 21 | base_exceptions | 22 | base_exceptions |
2915 | 22 | base_geometry | 23 | base_geometry |
2916 | 23 | graphic_color | 24 | graphic_color |
2917 | 24 | 25 | ||
2918 | === modified file 'src/graphic/text/sdl_ttf_font.cc' | |||
2919 | --- src/graphic/text/sdl_ttf_font.cc 2014-11-02 20:15:01 +0000 | |||
2920 | +++ src/graphic/text/sdl_ttf_font.cc 2014-11-23 12:03:00 +0000 | |||
2921 | @@ -23,7 +23,7 @@ | |||
2922 | 23 | #include <SDL_ttf.h> | 23 | #include <SDL_ttf.h> |
2923 | 24 | #include <boost/format.hpp> | 24 | #include <boost/format.hpp> |
2924 | 25 | 25 | ||
2926 | 26 | #include "graphic/sdl/utils.h" | 26 | #include "graphic/sdl_utils.h" |
2927 | 27 | #include "graphic/surface.h" | 27 | #include "graphic/surface.h" |
2928 | 28 | #include "graphic/surface_cache.h" | 28 | #include "graphic/surface_cache.h" |
2929 | 29 | #include "graphic/text/rt_errors.h" | 29 | #include "graphic/text/rt_errors.h" |
2930 | 30 | 30 | ||
2931 | === modified file 'src/graphic/text/test/CMakeLists.txt' | |||
2932 | --- src/graphic/text/test/CMakeLists.txt 2014-07-17 14:34:32 +0000 | |||
2933 | +++ src/graphic/text/test/CMakeLists.txt 2014-11-23 12:03:00 +0000 | |||
2934 | @@ -7,6 +7,7 @@ | |||
2935 | 7 | render_richtext.cc | 7 | render_richtext.cc |
2936 | 8 | DEPENDS | 8 | DEPENDS |
2937 | 9 | base_log | 9 | base_log |
2938 | 10 | graphic | ||
2939 | 10 | graphic_image_io | 11 | graphic_image_io |
2940 | 11 | graphic_surface | 12 | graphic_surface |
2941 | 12 | graphic_text | 13 | graphic_text |
2942 | 13 | 14 | ||
2943 | === modified file 'src/graphic/text/test/render_richtext.cc' | |||
2944 | --- src/graphic/text/test/render_richtext.cc 2014-10-11 13:26:59 +0000 | |||
2945 | +++ src/graphic/text/test/render_richtext.cc 2014-11-23 12:03:00 +0000 | |||
2946 | @@ -30,11 +30,14 @@ | |||
2947 | 30 | #undef main // No, we do not want SDL_main | 30 | #undef main // No, we do not want SDL_main |
2948 | 31 | 31 | ||
2949 | 32 | #include "base/log.h" | 32 | #include "base/log.h" |
2950 | 33 | #include "config.h" | ||
2951 | 34 | #include "graphic/graphic.h" | ||
2952 | 33 | #include "graphic/image_io.h" | 35 | #include "graphic/image_io.h" |
2954 | 34 | #include "graphic/sdl/surface.h" | 36 | #include "graphic/surface.h" |
2955 | 35 | #include "graphic/text/rt_errors.h" | 37 | #include "graphic/text/rt_errors.h" |
2956 | 36 | #include "graphic/text/test/render.h" | 38 | #include "graphic/text/test/render.h" |
2957 | 37 | #include "io/filesystem/filesystem.h" | 39 | #include "io/filesystem/filesystem.h" |
2958 | 40 | #include "io/filesystem/layered_filesystem.h" | ||
2959 | 38 | #include "io/streamwrite.h" | 41 | #include "io/streamwrite.h" |
2960 | 39 | 42 | ||
2961 | 40 | namespace { | 43 | namespace { |
2962 | @@ -88,6 +91,17 @@ | |||
2963 | 88 | return 0; | 91 | return 0; |
2964 | 89 | } | 92 | } |
2965 | 90 | 93 | ||
2966 | 94 | // Setup the static objects Widelands needs to operate and initializes systems. | ||
2967 | 95 | void initialize() { | ||
2968 | 96 | SDL_Init(SDL_INIT_VIDEO); | ||
2969 | 97 | |||
2970 | 98 | g_fs = new LayeredFileSystem(); | ||
2971 | 99 | g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR)); | ||
2972 | 100 | |||
2973 | 101 | g_gr = new Graphic(); | ||
2974 | 102 | g_gr->initialize(1, 1, false); | ||
2975 | 103 | } | ||
2976 | 104 | |||
2977 | 91 | } // namespace | 105 | } // namespace |
2978 | 92 | 106 | ||
2979 | 93 | int main(int argc, char** argv) { | 107 | int main(int argc, char** argv) { |
2980 | @@ -117,19 +131,19 @@ | |||
2981 | 117 | return 1; | 131 | return 1; |
2982 | 118 | } | 132 | } |
2983 | 119 | 133 | ||
2984 | 134 | initialize(); | ||
2985 | 135 | |||
2986 | 120 | StandaloneRenderer standalone_renderer; | 136 | StandaloneRenderer standalone_renderer; |
2987 | 121 | 137 | ||
2988 | 122 | try { | 138 | try { |
2991 | 123 | std::unique_ptr<SDLSurface> surf( | 139 | std::unique_ptr<Surface> surf(standalone_renderer.renderer()->render(txt, w, allowed_tags)); |
2990 | 124 | static_cast<SDLSurface*>(standalone_renderer.renderer()->render(txt, w, allowed_tags))); | ||
2992 | 125 | 140 | ||
2993 | 126 | std::unique_ptr<FileSystem> fs(&FileSystem::create(".")); | 141 | std::unique_ptr<FileSystem> fs(&FileSystem::create(".")); |
2994 | 127 | std::unique_ptr<StreamWrite> sw(fs->open_stream_write(outname)); | 142 | std::unique_ptr<StreamWrite> sw(fs->open_stream_write(outname)); |
2995 | 128 | if (!save_surface_to_png(surf.get(), sw.get())) { | 143 | if (!save_surface_to_png(surf.get(), sw.get())) { |
2996 | 129 | std::cout << "Could not encode PNG." << std::endl; | 144 | std::cout << "Could not encode PNG." << std::endl; |
2997 | 130 | } | 145 | } |
3000 | 131 | } | 146 | } catch (RT::Exception& e) { |
2999 | 132 | catch (RT::Exception& e) { | ||
3001 | 133 | std::cout << e.what() << std::endl; | 147 | std::cout << e.what() << std::endl; |
3002 | 134 | } | 148 | } |
3003 | 135 | 149 | ||
3004 | 136 | 150 | ||
3005 | === modified file 'src/graphic/texture.cc' | |||
3006 | --- src/graphic/texture.cc 2014-09-20 09:37:47 +0000 | |||
3007 | +++ src/graphic/texture.cc 2014-11-23 12:03:00 +0000 | |||
3008 | @@ -28,8 +28,6 @@ | |||
3009 | 28 | #include "io/fileread.h" | 28 | #include "io/fileread.h" |
3010 | 29 | #include "io/filesystem/layered_filesystem.h" | 29 | #include "io/filesystem/layered_filesystem.h" |
3011 | 30 | 30 | ||
3012 | 31 | extern bool g_opengl; | ||
3013 | 32 | |||
3014 | 33 | using namespace std; | 31 | using namespace std; |
3015 | 34 | 32 | ||
3016 | 35 | /** | 33 | /** |
3017 | @@ -37,15 +35,8 @@ | |||
3018 | 37 | * Currently it converts a 16 bit image to a 8 bit texture. This should | 35 | * Currently it converts a 16 bit image to a 8 bit texture. This should |
3019 | 38 | * be changed to load a 8 bit file directly, however. | 36 | * be changed to load a 8 bit file directly, however. |
3020 | 39 | */ | 37 | */ |
3030 | 40 | Texture::Texture(const std::vector<std::string>& texture_files, | 38 | Texture::Texture(const std::vector<std::string>& texture_files, const uint32_t frametime) |
3031 | 41 | const uint32_t frametime, | 39 | : m_frame_num(0), m_frametime(frametime) { |
3023 | 42 | const SDL_PixelFormat& format) | ||
3024 | 43 | : m_colormap(nullptr), | ||
3025 | 44 | m_pixels(nullptr), | ||
3026 | 45 | m_curframe(nullptr), | ||
3027 | 46 | m_frame_num(0), | ||
3028 | 47 | m_nrframes(0), | ||
3029 | 48 | m_frametime(frametime) { | ||
3032 | 49 | if (texture_files.empty()) { | 40 | if (texture_files.empty()) { |
3033 | 50 | throw wexception("No images for texture."); | 41 | throw wexception("No images for texture."); |
3034 | 51 | } | 42 | } |
3035 | @@ -58,7 +49,8 @@ | |||
3036 | 58 | m_texture_image = fname; | 49 | m_texture_image = fname; |
3037 | 59 | SDL_Surface* surf = load_image_as_sdl_surface(fname, g_fs); | 50 | SDL_Surface* surf = load_image_as_sdl_surface(fname, g_fs); |
3038 | 60 | if (!surf) { | 51 | if (!surf) { |
3040 | 61 | throw wexception("WARNING: Failed to load texture frame %s: %s\n", fname.c_str(), IMG_GetError()); | 52 | throw wexception( |
3041 | 53 | "WARNING: Failed to load texture frame %s: %s\n", fname.c_str(), IMG_GetError()); | ||
3042 | 62 | } | 54 | } |
3043 | 63 | if (surf->w != TEXTURE_WIDTH || surf->h != TEXTURE_HEIGHT) { | 55 | if (surf->w != TEXTURE_WIDTH || surf->h != TEXTURE_HEIGHT) { |
3044 | 64 | SDL_FreeSurface(surf); | 56 | SDL_FreeSurface(surf); |
3045 | @@ -69,7 +61,7 @@ | |||
3046 | 69 | } | 61 | } |
3047 | 70 | 62 | ||
3048 | 71 | // calculate shades on the first frame | 63 | // calculate shades on the first frame |
3050 | 72 | if (!m_nrframes) { | 64 | if (m_gl_textures.empty()) { |
3051 | 73 | uint8_t top_left_pixel = static_cast<uint8_t*>(surf->pixels)[0]; | 65 | uint8_t top_left_pixel = static_cast<uint8_t*>(surf->pixels)[0]; |
3052 | 74 | SDL_Color top_left_pixel_color = surf->format->palette->colors[top_left_pixel]; | 66 | SDL_Color top_left_pixel_color = surf->format->palette->colors[top_left_pixel]; |
3053 | 75 | for (int i = -128; i < 128; i++) { | 67 | for (int i = -128; i < 128; i++) { |
3054 | @@ -80,73 +72,13 @@ | |||
3055 | 80 | m_minimap_colors[shade] = RGBColor(r, g, b); | 72 | m_minimap_colors[shade] = RGBColor(r, g, b); |
3056 | 81 | } | 73 | } |
3057 | 82 | } | 74 | } |
3113 | 83 | 75 | m_gl_textures.emplace_back(new GLSurfaceTexture(surf)); | |
3059 | 84 | if (g_opengl) { | ||
3060 | 85 | // Note: we except the constructor to free the SDL surface | ||
3061 | 86 | GLSurfaceTexture* surface = new GLSurfaceTexture(surf); | ||
3062 | 87 | m_glFrames.emplace_back(surface); | ||
3063 | 88 | |||
3064 | 89 | ++m_nrframes; | ||
3065 | 90 | continue; | ||
3066 | 91 | } | ||
3067 | 92 | |||
3068 | 93 | // Determine color map if it's the first frame | ||
3069 | 94 | if (!m_nrframes) { | ||
3070 | 95 | if (surf->format->BitsPerPixel != 8) { | ||
3071 | 96 | throw wexception("Terrain %s is not 8 bits per pixel.", fname.c_str()); | ||
3072 | 97 | } | ||
3073 | 98 | m_colormap.reset(new Colormap(*surf->format->palette->colors, format)); | ||
3074 | 99 | } | ||
3075 | 100 | |||
3076 | 101 | // Convert to our palette | ||
3077 | 102 | SDL_Palette palette; | ||
3078 | 103 | SDL_PixelFormat fmt; | ||
3079 | 104 | |||
3080 | 105 | palette.ncolors = 256; | ||
3081 | 106 | palette.colors = m_colormap->get_palette(); | ||
3082 | 107 | |||
3083 | 108 | memset(&fmt, 0, sizeof(fmt)); | ||
3084 | 109 | fmt.BitsPerPixel = 8; | ||
3085 | 110 | fmt.BytesPerPixel = 1; | ||
3086 | 111 | fmt.palette = &palette; | ||
3087 | 112 | |||
3088 | 113 | SDL_Surface * const cv = SDL_ConvertSurface(surf, &fmt, 0); | ||
3089 | 114 | |||
3090 | 115 | // Add the frame | ||
3091 | 116 | uint8_t* new_ptr = | ||
3092 | 117 | static_cast<uint8_t *> | ||
3093 | 118 | (realloc | ||
3094 | 119 | (m_pixels, TEXTURE_WIDTH * TEXTURE_HEIGHT * (m_nrframes + 1))); | ||
3095 | 120 | if (!new_ptr) | ||
3096 | 121 | throw wexception("Out of memory."); | ||
3097 | 122 | m_pixels = new_ptr; | ||
3098 | 123 | |||
3099 | 124 | |||
3100 | 125 | m_curframe = &m_pixels[TEXTURE_WIDTH * TEXTURE_HEIGHT * m_nrframes]; | ||
3101 | 126 | ++m_nrframes; | ||
3102 | 127 | |||
3103 | 128 | SDL_LockSurface(cv); | ||
3104 | 129 | |||
3105 | 130 | for (int32_t y = 0; y < TEXTURE_HEIGHT; ++y) | ||
3106 | 131 | memcpy | ||
3107 | 132 | (m_curframe + y * TEXTURE_WIDTH, | ||
3108 | 133 | static_cast<uint8_t *>(cv->pixels) + y * cv->pitch, | ||
3109 | 134 | TEXTURE_WIDTH); | ||
3110 | 135 | SDL_UnlockSurface(cv); | ||
3111 | 136 | SDL_FreeSurface(cv); | ||
3112 | 137 | SDL_FreeSurface(surf); | ||
3114 | 138 | } | 76 | } |
3115 | 139 | 77 | ||
3117 | 140 | if (!m_nrframes) | 78 | if (m_gl_textures.empty()) |
3118 | 141 | throw wexception("Texture has no frames"); | 79 | throw wexception("Texture has no frames"); |
3119 | 142 | } | 80 | } |
3120 | 143 | 81 | ||
3121 | 144 | |||
3122 | 145 | Texture::~Texture () | ||
3123 | 146 | { | ||
3124 | 147 | free(m_pixels); | ||
3125 | 148 | } | ||
3126 | 149 | |||
3127 | 150 | /** | 82 | /** |
3128 | 151 | * Return the basic terrain colour to be used in the minimap. | 83 | * Return the basic terrain colour to be used in the minimap. |
3129 | 152 | */ | 84 | */ |
3130 | @@ -159,8 +91,5 @@ | |||
3131 | 159 | */ | 91 | */ |
3132 | 160 | void Texture::animate(uint32_t time) | 92 | void Texture::animate(uint32_t time) |
3133 | 161 | { | 93 | { |
3138 | 162 | m_frame_num = (time / m_frametime) % m_nrframes; | 94 | m_frame_num = (time / m_frametime) % m_gl_textures.size(); |
3135 | 163 | if (g_opengl) | ||
3136 | 164 | return; | ||
3137 | 165 | m_curframe = &m_pixels[TEXTURE_WIDTH * TEXTURE_HEIGHT * m_frame_num]; | ||
3139 | 166 | } | 95 | } |
3140 | 167 | 96 | ||
3141 | === modified file 'src/graphic/texture.h' | |||
3142 | --- src/graphic/texture.h 2014-10-11 13:26:59 +0000 | |||
3143 | +++ src/graphic/texture.h 2014-11-23 12:03:00 +0000 | |||
3144 | @@ -45,33 +45,25 @@ | |||
3145 | 45 | * changed to load 8 bit bitmaps directly. | 45 | * changed to load 8 bit bitmaps directly. |
3146 | 46 | */ | 46 | */ |
3147 | 47 | struct Texture { | 47 | struct Texture { |
3158 | 48 | Texture(const std::vector<std::string>& texture_files, | 48 | Texture(const std::vector<std::string>& texture_files, uint32_t frametime); |
3159 | 49 | uint32_t frametime, | 49 | |
3160 | 50 | const SDL_PixelFormat&); | 50 | const std::string& get_texture_image() const { |
3161 | 51 | ~Texture(); | 51 | return m_texture_image; |
3162 | 52 | 52 | } | |
3163 | 53 | const std::string & get_texture_image() const {return m_texture_image;} | 53 | uint32_t get_texture() const { |
3164 | 54 | 54 | return m_gl_textures.at(m_frame_num)->get_gl_texture(); | |
3165 | 55 | uint8_t * get_pixels () const {return m_pixels;} | 55 | } |
3156 | 56 | uint8_t * get_curpixels() const {return m_curframe;} | ||
3157 | 57 | void * get_colormap () const {return m_colormap->get_colormap();} | ||
3166 | 58 | 56 | ||
3167 | 59 | RGBColor get_minimap_color(int8_t shade); | 57 | RGBColor get_minimap_color(int8_t shade); |
3168 | 60 | 58 | ||
3169 | 61 | void animate(uint32_t time); | 59 | void animate(uint32_t time); |
3170 | 62 | uint32_t get_texture() const | ||
3171 | 63 | {return m_glFrames.at(m_frame_num)->get_gl_texture();} | ||
3172 | 64 | 60 | ||
3173 | 65 | private: | 61 | private: |
3174 | 66 | std::unique_ptr<Colormap> m_colormap; | ||
3175 | 67 | uint8_t * m_pixels; | ||
3176 | 68 | RGBColor m_minimap_colors[256]; | 62 | RGBColor m_minimap_colors[256]; |
3177 | 69 | uint8_t * m_curframe; | ||
3178 | 70 | int32_t m_frame_num; | 63 | int32_t m_frame_num; |
3179 | 71 | std::string m_texture_image; | 64 | std::string m_texture_image; |
3180 | 72 | uint32_t m_nrframes; | ||
3181 | 73 | uint32_t m_frametime; | 65 | uint32_t m_frametime; |
3183 | 74 | std::vector<std::unique_ptr<GLSurfaceTexture>> m_glFrames; | 66 | std::vector<std::unique_ptr<GLSurfaceTexture>> m_gl_textures; |
3184 | 75 | }; | 67 | }; |
3185 | 76 | 68 | ||
3186 | 77 | #endif // end of include guard: WL_GRAPHIC_TEXTURE_H | 69 | #endif // end of include guard: WL_GRAPHIC_TEXTURE_H |
3187 | 78 | 70 | ||
3188 | === modified file 'src/logic/map_info.cc' | |||
3189 | --- src/logic/map_info.cc 2014-11-12 20:12:48 +0000 | |||
3190 | +++ src/logic/map_info.cc 2014-11-23 12:03:00 +0000 | |||
3191 | @@ -43,19 +43,14 @@ | |||
3192 | 43 | namespace { | 43 | namespace { |
3193 | 44 | 44 | ||
3194 | 45 | // Setup the static objects Widelands needs to operate and initializes systems. | 45 | // Setup the static objects Widelands needs to operate and initializes systems. |
3196 | 46 | void initialize(bool use_opengl) { | 46 | void initialize() { |
3197 | 47 | SDL_Init(SDL_INIT_VIDEO); | 47 | SDL_Init(SDL_INIT_VIDEO); |
3198 | 48 | 48 | ||
3199 | 49 | g_fs = new LayeredFileSystem(); | 49 | g_fs = new LayeredFileSystem(); |
3200 | 50 | g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR)); | 50 | g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR)); |
3201 | 51 | 51 | ||
3202 | 52 | #ifdef HAS_GETENV | ||
3203 | 53 | char dummy_video_env[] = "SDL_VIDEODRIVER=dummy"; | ||
3204 | 54 | putenv(dummy_video_env); | ||
3205 | 55 | #endif | ||
3206 | 56 | |||
3207 | 57 | g_gr = new Graphic(); | 52 | g_gr = new Graphic(); |
3209 | 58 | g_gr->initialize(1, 1, false, use_opengl); | 53 | g_gr->initialize(1, 1, false); |
3210 | 59 | } | 54 | } |
3211 | 60 | 55 | ||
3212 | 61 | } // namespace | 56 | } // namespace |
3213 | @@ -63,21 +58,14 @@ | |||
3214 | 63 | int main(int argc, char ** argv) | 58 | int main(int argc, char ** argv) |
3215 | 64 | { | 59 | { |
3216 | 65 | if (!(2 <= argc && argc <= 3)) { | 60 | if (!(2 <= argc && argc <= 3)) { |
3218 | 66 | log("Usage: %s [--opengl] <map file>\n", argv[0]); | 61 | log("Usage: %s <map file>\n", argv[0]); |
3219 | 67 | return 1; | 62 | return 1; |
3220 | 68 | } | 63 | } |
3221 | 69 | 64 | ||
3222 | 70 | bool use_opengl = false; | ||
3223 | 71 | for (int i = 0; i < argc; ++i) { | ||
3224 | 72 | if (std::string(argv[i]) == "--opengl") { | ||
3225 | 73 | use_opengl = true; | ||
3226 | 74 | } | ||
3227 | 75 | } | ||
3228 | 76 | |||
3229 | 77 | const std::string map_path = argv[argc - 1]; | 65 | const std::string map_path = argv[argc - 1]; |
3230 | 78 | 66 | ||
3231 | 79 | try { | 67 | try { |
3233 | 80 | initialize(use_opengl); | 68 | initialize(); |
3234 | 81 | 69 | ||
3235 | 82 | std::string map_dir = FileSystem::fs_dirname(map_path); | 70 | std::string map_dir = FileSystem::fs_dirname(map_path); |
3236 | 83 | if (map_dir.empty()) { | 71 | if (map_dir.empty()) { |
3237 | 84 | 72 | ||
3238 | === modified file 'src/ui_fsmenu/options.cc' | |||
3239 | --- src/ui_fsmenu/options.cc 2014-11-22 22:11:36 +0000 | |||
3240 | +++ src/ui_fsmenu/options.cc 2014-11-23 12:03:00 +0000 | |||
3241 | @@ -555,14 +555,6 @@ | |||
3242 | 555 | get_w() - 2 * m_hmargin - m_remove_syncstreams.get_w() - m_padding, 40, | 555 | get_w() - 2 * m_hmargin - m_remove_syncstreams.get_w() - m_padding, 40, |
3243 | 556 | _("Remove Syncstream dumps on startup"), UI::Align_VCenter), | 556 | _("Remove Syncstream dumps on startup"), UI::Align_VCenter), |
3244 | 557 | 557 | ||
3245 | 558 | m_opengl (this, Point(m_hmargin, | ||
3246 | 559 | m_label_remove_syncstreams.get_y() + | ||
3247 | 560 | m_label_remove_syncstreams.get_h() + m_padding)), | ||
3248 | 561 | m_label_opengl | ||
3249 | 562 | (this, | ||
3250 | 563 | m_hmargin + m_opengl.get_w() + m_padding, m_opengl.get_y(), | ||
3251 | 564 | get_w() - 2 * m_hmargin - m_opengl.get_w() - m_padding, 40, | ||
3252 | 565 | _("OpenGL rendering"), UI::Align_VCenter), | ||
3253 | 566 | os(opt) | 558 | os(opt) |
3254 | 567 | { | 559 | { |
3255 | 568 | for (UI::Button* temp_button : m_sb_dis_panel.get_buttons()) { | 560 | for (UI::Button* temp_button : m_sb_dis_panel.get_buttons()) { |
3256 | @@ -594,7 +586,6 @@ | |||
3257 | 594 | m_message_sound .set_state(opt.message_sound); | 586 | m_message_sound .set_state(opt.message_sound); |
3258 | 595 | m_nozip .set_state(opt.nozip); | 587 | m_nozip .set_state(opt.nozip); |
3259 | 596 | m_remove_syncstreams .set_state(opt.remove_syncstreams); | 588 | m_remove_syncstreams .set_state(opt.remove_syncstreams); |
3260 | 597 | m_opengl .set_state(opt.opengl); | ||
3261 | 598 | m_transparent_chat .set_state(opt.transparent_chat); | 589 | m_transparent_chat .set_state(opt.transparent_chat); |
3262 | 599 | 590 | ||
3263 | 600 | // Fill the font list. | 591 | // Fill the font list. |
3264 | @@ -678,7 +669,6 @@ | |||
3265 | 678 | os.panel_snap_distance = m_sb_dis_panel.get_value(); | 669 | os.panel_snap_distance = m_sb_dis_panel.get_value(); |
3266 | 679 | os.border_snap_distance = m_sb_dis_border.get_value(); | 670 | os.border_snap_distance = m_sb_dis_border.get_value(); |
3267 | 680 | os.remove_syncstreams = m_remove_syncstreams.get_state(); | 671 | os.remove_syncstreams = m_remove_syncstreams.get_state(); |
3268 | 681 | os.opengl = m_opengl.get_state(); | ||
3269 | 682 | os.transparent_chat = m_transparent_chat.get_state(); | 672 | os.transparent_chat = m_transparent_chat.get_state(); |
3270 | 683 | return os; | 673 | return os; |
3271 | 684 | } | 674 | } |
3272 | @@ -734,7 +724,6 @@ | |||
3273 | 734 | opt.panel_snap_distance = m_opt_section.get_int("panel_snap_distance", 0); | 724 | opt.panel_snap_distance = m_opt_section.get_int("panel_snap_distance", 0); |
3274 | 735 | opt.remove_replays = m_opt_section.get_int("remove_replays", 0); | 725 | opt.remove_replays = m_opt_section.get_int("remove_replays", 0); |
3275 | 736 | opt.remove_syncstreams = m_opt_section.get_bool("remove_syncstreams", true); | 726 | opt.remove_syncstreams = m_opt_section.get_bool("remove_syncstreams", true); |
3276 | 737 | opt.opengl = m_opt_section.get_bool("opengl", true); | ||
3277 | 738 | opt.transparent_chat = m_opt_section.get_bool("transparent_chat", true); | 727 | opt.transparent_chat = m_opt_section.get_bool("transparent_chat", true); |
3278 | 739 | return opt; | 728 | return opt; |
3279 | 740 | } | 729 | } |
3280 | @@ -766,7 +755,6 @@ | |||
3281 | 766 | 755 | ||
3282 | 767 | m_opt_section.set_int("remove_replays", opt.remove_replays); | 756 | m_opt_section.set_int("remove_replays", opt.remove_replays); |
3283 | 768 | m_opt_section.set_bool("remove_syncstreams", opt.remove_syncstreams); | 757 | m_opt_section.set_bool("remove_syncstreams", opt.remove_syncstreams); |
3284 | 769 | m_opt_section.set_bool("opengl", opt.opengl); | ||
3285 | 770 | m_opt_section.set_bool("transparent_chat", opt.transparent_chat); | 758 | m_opt_section.set_bool("transparent_chat", opt.transparent_chat); |
3286 | 771 | 759 | ||
3287 | 772 | WLApplication::get()->set_input_grab(opt.inputgrab); | 760 | WLApplication::get()->set_input_grab(opt.inputgrab); |
3288 | 773 | 761 | ||
3289 | === modified file 'src/ui_fsmenu/options.h' | |||
3290 | --- src/ui_fsmenu/options.h 2014-10-14 06:30:20 +0000 | |||
3291 | +++ src/ui_fsmenu/options.h 2014-11-23 12:03:00 +0000 | |||
3292 | @@ -54,7 +54,6 @@ | |||
3293 | 54 | uint32_t maxfps; | 54 | uint32_t maxfps; |
3294 | 55 | uint32_t remove_replays; | 55 | uint32_t remove_replays; |
3295 | 56 | bool remove_syncstreams; | 56 | bool remove_syncstreams; |
3296 | 57 | bool opengl; | ||
3297 | 58 | bool transparent_chat; | 57 | bool transparent_chat; |
3298 | 59 | 58 | ||
3299 | 60 | // advanced options | 59 | // advanced options |
3300 | @@ -197,8 +196,6 @@ | |||
3301 | 197 | UI::MultilineTextarea m_label_nozip; | 196 | UI::MultilineTextarea m_label_nozip; |
3302 | 198 | UI::Checkbox m_remove_syncstreams; | 197 | UI::Checkbox m_remove_syncstreams; |
3303 | 199 | UI::MultilineTextarea m_label_remove_syncstreams; | 198 | UI::MultilineTextarea m_label_remove_syncstreams; |
3304 | 200 | UI::Checkbox m_opengl; | ||
3305 | 201 | UI::MultilineTextarea m_label_opengl; | ||
3306 | 202 | 199 | ||
3307 | 203 | OptionsCtrl::OptionsStruct os; | 200 | OptionsCtrl::OptionsStruct os; |
3308 | 204 | }; | 201 | }; |
3309 | 205 | 202 | ||
3310 | === modified file 'src/wlapplication.cc' | |||
3311 | --- src/wlapplication.cc 2014-11-22 10:18:20 +0000 | |||
3312 | +++ src/wlapplication.cc 2014-11-23 12:03:00 +0000 | |||
3313 | @@ -676,7 +676,7 @@ | |||
3314 | 676 | * with the given resolution. | 676 | * with the given resolution. |
3315 | 677 | * Throws an exception on failure. | 677 | * Throws an exception on failure. |
3316 | 678 | */ | 678 | */ |
3318 | 679 | void WLApplication::init_graphics(int32_t w, int32_t h, bool fullscreen, bool opengl) | 679 | void WLApplication::init_graphics(int32_t w, int32_t h, bool fullscreen) |
3319 | 680 | { | 680 | { |
3320 | 681 | if (!w && !h) { // shutdown. | 681 | if (!w && !h) { // shutdown. |
3321 | 682 | delete g_gr; | 682 | delete g_gr; |
3322 | @@ -687,13 +687,10 @@ | |||
3323 | 687 | 687 | ||
3324 | 688 | if (!g_gr) { | 688 | if (!g_gr) { |
3325 | 689 | g_gr = new Graphic(); | 689 | g_gr = new Graphic(); |
3327 | 690 | g_gr->initialize(w, h, fullscreen, opengl); | 690 | g_gr->initialize(w, h, fullscreen); |
3328 | 691 | } else { | 691 | } else { |
3334 | 692 | if | 692 | if (g_gr->get_xres() != w || g_gr->get_yres() != h || g_gr->is_fullscreen() != fullscreen) { |
3335 | 693 | (g_gr->get_xres() != w || g_gr->get_yres() != h | 693 | g_gr->initialize(w, h, fullscreen); |
3331 | 694 | || g_gr->is_fullscreen() != fullscreen || g_opengl != opengl) | ||
3332 | 695 | { | ||
3333 | 696 | g_gr->initialize(w, h, fullscreen, opengl); | ||
3336 | 697 | } | 694 | } |
3337 | 698 | } | 695 | } |
3338 | 699 | } | 696 | } |
3339 | @@ -703,11 +700,9 @@ | |||
3340 | 703 | Section & s = g_options.pull_section("global"); | 700 | Section & s = g_options.pull_section("global"); |
3341 | 704 | 701 | ||
3342 | 705 | // Switch to the new graphics system now, if necessary. | 702 | // Switch to the new graphics system now, if necessary. |
3348 | 706 | init_graphics | 703 | init_graphics(s.get_int("xres", DEFAULT_RESOLUTION_W), |
3349 | 707 | (s.get_int("xres", DEFAULT_RESOLUTION_W), | 704 | s.get_int("yres", DEFAULT_RESOLUTION_H), |
3350 | 708 | s.get_int("yres", DEFAULT_RESOLUTION_H), | 705 | s.get_bool("fullscreen", false)); |
3346 | 709 | s.get_bool("fullscreen", false), | ||
3347 | 710 | s.get_bool("opengl", true)); | ||
3351 | 711 | // does only work with a window | 706 | // does only work with a window |
3352 | 712 | set_input_grab(s.get_bool("inputgrab", false)); | 707 | set_input_grab(s.get_bool("inputgrab", false)); |
3353 | 713 | } | 708 | } |
3354 | @@ -732,7 +727,6 @@ | |||
3355 | 732 | // Profile needs support for a Syntax definition to solve this in a | 727 | // Profile needs support for a Syntax definition to solve this in a |
3356 | 733 | // sensible way | 728 | // sensible way |
3357 | 734 | s.get_bool("fullscreen"); | 729 | s.get_bool("fullscreen"); |
3358 | 735 | s.get_bool("opengl"); | ||
3359 | 736 | s.get_int("xres"); | 730 | s.get_int("xres"); |
3360 | 737 | s.get_int("yres"); | 731 | s.get_int("yres"); |
3361 | 738 | s.get_int("border_snap_distance"); | 732 | s.get_int("border_snap_distance"); |
3362 | @@ -851,7 +845,7 @@ | |||
3363 | 851 | "alive!" | 845 | "alive!" |
3364 | 852 | << std::endl; | 846 | << std::endl; |
3365 | 853 | 847 | ||
3367 | 854 | init_graphics(0, 0, false, false); | 848 | init_graphics(0, 0, false); |
3368 | 855 | SDL_QuitSubSystem(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK); | 849 | SDL_QuitSubSystem(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK); |
3369 | 856 | 850 | ||
3370 | 857 | #ifndef _WIN32 | 851 | #ifndef _WIN32 |
3371 | 858 | 852 | ||
3372 | === modified file 'src/wlapplication.h' | |||
3373 | --- src/wlapplication.h 2014-11-22 10:18:20 +0000 | |||
3374 | +++ src/wlapplication.h 2014-11-23 12:03:00 +0000 | |||
3375 | @@ -164,7 +164,7 @@ | |||
3376 | 164 | void set_mouse_lock(const bool locked) {m_mouse_locked = locked;} | 164 | void set_mouse_lock(const bool locked) {m_mouse_locked = locked;} |
3377 | 165 | //@} | 165 | //@} |
3378 | 166 | 166 | ||
3380 | 167 | void init_graphics(int32_t w, int32_t h, bool fullscreen, bool opengl); | 167 | void init_graphics(int32_t w, int32_t h, bool fullscreen); |
3381 | 168 | 168 | ||
3382 | 169 | /** | 169 | /** |
3383 | 170 | * Refresh the graphics from the latest options. | 170 | * Refresh the graphics from the latest options. |
3384 | 171 | 171 | ||
3385 | === modified file 'src/wlapplication_messages.cc' | |||
3386 | --- src/wlapplication_messages.cc 2014-11-03 19:51:45 +0000 | |||
3387 | +++ src/wlapplication_messages.cc 2014-11-23 12:03:00 +0000 | |||
3388 | @@ -99,8 +99,7 @@ | |||
3389 | 99 | << _(" --yres=[...] Height of the window in pixel.") << endl | 99 | << _(" --yres=[...] Height of the window in pixel.") << endl |
3390 | 100 | /** TRANSLATORS: You may translate true/false, also as on/off or yes/no, but */ | 100 | /** TRANSLATORS: You may translate true/false, also as on/off or yes/no, but */ |
3391 | 101 | /** TRANSLATORS: it HAS TO BE CONSISTENT with the translation in the widelands textdomain */ | 101 | /** TRANSLATORS: it HAS TO BE CONSISTENT with the translation in the widelands textdomain */ |
3394 | 102 | << _(" --opengl=[true|false]\n" | 102 | << endl |
3393 | 103 | " Enables OpenGL rendering") << endl << endl | ||
3395 | 104 | << _("Options for the internal window manager:") << endl | 103 | << _("Options for the internal window manager:") << endl |
3396 | 105 | << _(" --border_snap_distance=[0 ...]\n" | 104 | << _(" --border_snap_distance=[0 ...]\n" |
3397 | 106 | " Move a window to the edge of the screen\n" | 105 | " Move a window to the edge of the screen\n" |
3398 | 107 | 106 | ||
3399 | === modified file 'src/wui/mapview.cc' | |||
3400 | --- src/wui/mapview.cc 2014-11-13 08:25:45 +0000 | |||
3401 | +++ src/wui/mapview.cc 2014-11-23 12:03:00 +0000 | |||
3402 | @@ -23,7 +23,6 @@ | |||
3403 | 23 | #include "graphic/gl/game_renderer.h" | 23 | #include "graphic/gl/game_renderer.h" |
3404 | 24 | #include "graphic/graphic.h" | 24 | #include "graphic/graphic.h" |
3405 | 25 | #include "graphic/rendertarget.h" | 25 | #include "graphic/rendertarget.h" |
3406 | 26 | #include "graphic/sdl/game_renderer.h" | ||
3407 | 27 | #include "logic/map.h" | 26 | #include "logic/map.h" |
3408 | 28 | #include "logic/player.h" | 27 | #include "logic/player.h" |
3409 | 29 | #include "wlapplication.h" | 28 | #include "wlapplication.h" |
3410 | @@ -92,12 +91,7 @@ | |||
3411 | 92 | egbase.map().overlay_manager().load_graphics(); | 91 | egbase.map().overlay_manager().load_graphics(); |
3412 | 93 | 92 | ||
3413 | 94 | if (!m_renderer) { | 93 | if (!m_renderer) { |
3420 | 95 | if (g_opengl) { | 94 | m_renderer.reset(new GlGameRenderer()); |
3415 | 96 | m_renderer.reset(new GlGameRenderer()); | ||
3416 | 97 | } else | ||
3417 | 98 | { | ||
3418 | 99 | m_renderer.reset(new SdlGameRenderer()); | ||
3419 | 100 | } | ||
3421 | 101 | } | 95 | } |
3422 | 102 | if (upcast(InteractivePlayer const, interactive_player, &intbase())) { | 96 | if (upcast(InteractivePlayer const, interactive_player, &intbase())) { |
3423 | 103 | m_renderer->rendermap(dst, egbase, interactive_player->player(), m_viewpoint); | 97 | m_renderer->rendermap(dst, egbase, interactive_player->player(), m_viewpoint); |
You inherited a strange comment in line 3112 that you might want to fix as well.
Otherwise, LGTM and tested.