Merge lp:~widelands-dev/widelands/remove_software_rendering into lp:widelands

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
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.

To post a comment you must log in.
Revision history for this message
GunChleoc (gunchleoc) wrote :

You inherited a strange comment in line 3112 that you might want to fix as well.

Otherwise, LGTM and tested.

review: Approve
Revision history for this message
SirVer (sirver) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt 2014-11-08 14:59:03 +0000
+++ src/graphic/CMakeLists.txt 2014-11-23 12:03:00 +0000
@@ -36,21 +36,22 @@
36 graphic_surface36 graphic_surface
37)37)
3838
39wl_library(graphic_sdl_utils
40 SRCS
41 sdl_utils.h
42 sdl_utils.cc
43 USES_SDL2
44)
45
39wl_library(graphic_surface46wl_library(graphic_surface
40 SRCS47 SRCS
41 compositemode.h48 compositemode.h
42 gl/surface.cc
43 gl/surface.h
44 gl/surface_screen.cc49 gl/surface_screen.cc
45 gl/surface_screen.h50 gl/surface_screen.h
46 gl/surface_texture.cc51 gl/surface_texture.cc
47 gl/surface_texture.h52 gl/surface_texture.h
48 gl/utils.cc53 gl/utils.cc
49 gl/utils.h54 gl/utils.h
50 sdl/surface.cc
51 sdl/surface.h
52 sdl/utils.cc
53 sdl/utils.h
54 surface.cc55 surface.cc
55 surface.h56 surface.h
56 surface_cache.cc57 surface_cache.cc
@@ -58,12 +59,13 @@
58 USES_OPENGL59 USES_OPENGL
59 USES_SDL260 USES_SDL2
60 DEPENDS61 DEPENDS
61 base_macros
62 base_exceptions62 base_exceptions
63 base_geometry63 base_geometry
64 base_log64 base_log
65 base_macros
65 graphic66 graphic
66 graphic_color67 graphic_color
68 graphic_sdl_utils
67)69)
6870
69wl_library(graphic71wl_library(graphic
@@ -114,11 +116,6 @@
114 rendertarget.h116 rendertarget.h
115 richtext.cc117 richtext.cc
116 richtext.h118 richtext.h
117 sdl/game_renderer.cc
118 sdl/game_renderer.h
119 sdl/terrain.cc
120 sdl/terrain.h
121 sdl/vertex.h
122 text_parser.cc119 text_parser.cc
123 text_parser.h120 text_parser.h
124 texture.cc121 texture.cc
@@ -150,7 +147,6 @@
150 io_stream147 io_stream
151 logic148 logic
152 profile149 profile
153 random
154 scripting150 scripting
155 sound151 sound
156 ui_basic152 ui_basic
157153
=== modified file 'src/graphic/gl/game_renderer.cc'
--- src/graphic/gl/game_renderer.cc 2014-11-22 11:59:34 +0000
+++ src/graphic/gl/game_renderer.cc 2014-11-23 12:03:00 +0000
@@ -24,10 +24,10 @@
24#include "graphic/gl/dither_program.h"24#include "graphic/gl/dither_program.h"
25#include "graphic/gl/fields_to_draw.h"25#include "graphic/gl/fields_to_draw.h"
26#include "graphic/gl/road_program.h"26#include "graphic/gl/road_program.h"
27#include "graphic/gl/surface.h"
28#include "graphic/gl/terrain_program.h"27#include "graphic/gl/terrain_program.h"
29#include "graphic/graphic.h"28#include "graphic/graphic.h"
30#include "graphic/rendertarget.h"29#include "graphic/rendertarget.h"
30#include "graphic/surface.h"
31#include "graphic/texture.h"31#include "graphic/texture.h"
32#include "logic/editor_game_base.h"32#include "logic/editor_game_base.h"
33#include "logic/player.h"33#include "logic/player.h"
@@ -133,7 +133,7 @@
133 road_program_.reset(new RoadProgram());133 road_program_.reset(new RoadProgram());
134 }134 }
135135
136 GLSurface* surface = dynamic_cast<GLSurface*>(m_dst->get_surface());136 Surface* surface = m_dst->get_surface();
137 if (!surface)137 if (!surface)
138 return;138 return;
139139
140140
=== modified file 'src/graphic/gl/road_program.cc'
--- src/graphic/gl/road_program.cc 2014-11-09 14:20:59 +0000
+++ src/graphic/gl/road_program.cc 2014-11-23 12:03:00 +0000
@@ -87,7 +87,7 @@
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");
88}88}
8989
90void RoadProgram::add_road(const GLSurface& surface,90void RoadProgram::add_road(const Surface& surface,
91 const FieldsToDraw::Field& start,91 const FieldsToDraw::Field& start,
92 const FieldsToDraw::Field& end,92 const FieldsToDraw::Field& end,
93 const Widelands::RoadType road_type) {93 const Widelands::RoadType road_type) {
@@ -146,7 +146,7 @@
146 vertices_.emplace_back(p4);146 vertices_.emplace_back(p4);
147}147}
148148
149void RoadProgram::draw(const GLSurface& surface, const FieldsToDraw& fields_to_draw) {149void RoadProgram::draw(const Surface& surface, const FieldsToDraw& fields_to_draw) {
150 vertices_.clear();150 vertices_.clear();
151151
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) {
153153
=== modified file 'src/graphic/gl/road_program.h'
--- src/graphic/gl/road_program.h 2014-11-08 18:06:17 +0000
+++ src/graphic/gl/road_program.h 2014-11-23 12:03:00 +0000
@@ -24,8 +24,8 @@
2424
25#include "base/macros.h"25#include "base/macros.h"
26#include "graphic/gl/fields_to_draw.h"26#include "graphic/gl/fields_to_draw.h"
27#include "graphic/gl/surface.h"
28#include "graphic/gl/utils.h"27#include "graphic/gl/utils.h"
28#include "graphic/surface.h"
29#include "logic/roadtype.h"29#include "logic/roadtype.h"
3030
31class RoadProgram {31class RoadProgram {
@@ -35,7 +35,7 @@
3535
36 // Draws the roads. The 'surface' is needed to convert from pixel space to36 // Draws the roads. The 'surface' is needed to convert from pixel space to
37 // GL space.37 // GL space.
38 void draw(const GLSurface& surface, const FieldsToDraw& fields_to_draw);38 void draw(const Surface& surface, const FieldsToDraw& fields_to_draw);
3939
40private:40private:
41 struct PerVertexData {41 struct PerVertexData {
@@ -55,7 +55,7 @@
5555
56 // Adds a road from 'start' to 'end' to be rendered in this frame using the56 // Adds a road from 'start' to 'end' to be rendered in this frame using the
57 // correct texture for 'road_type'.57 // correct texture for 'road_type'.
58 void add_road(const GLSurface& surface,58 void add_road(const Surface& surface,
59 const FieldsToDraw::Field& start,59 const FieldsToDraw::Field& start,
60 const FieldsToDraw::Field& end,60 const FieldsToDraw::Field& end,
61 const Widelands::RoadType road_type);61 const Widelands::RoadType road_type);
6262
=== removed file 'src/graphic/gl/surface.cc'
--- src/graphic/gl/surface.cc 2014-11-22 11:59:34 +0000
+++ src/graphic/gl/surface.cc 1970-01-01 00:00:00 +0000
@@ -1,171 +0,0 @@
1/*
2 * Copyright (C) 2006-2012 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#include "graphic/gl/surface.h"
21
22#include <cassert>
23#include <cmath>
24#include <cstdlib>
25
26#include "base/macros.h"
27#include "graphic/gl/blit_program.h"
28#include "graphic/gl/draw_line_program.h"
29#include "graphic/gl/draw_rect_program.h"
30#include "graphic/gl/fill_rect_program.h"
31#include "graphic/gl/surface_texture.h"
32#include "graphic/graphic.h"
33
34uint16_t GLSurface::width() const {
35 return m_w;
36}
37
38uint16_t GLSurface::height() const {
39 return m_h;
40}
41
42uint8_t * GLSurface::get_pixels() const
43{
44 return m_pixels.get();
45}
46
47uint32_t GLSurface::get_pixel(uint16_t x, uint16_t y) {
48 assert(m_pixels);
49 assert(x < m_w);
50 assert(y < m_h);
51
52 uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
53 return *(reinterpret_cast<uint32_t *>(data));
54}
55
56void GLSurface::set_pixel(uint16_t x, uint16_t y, uint32_t clr) {
57 assert(m_pixels);
58 assert(x < m_w);
59 assert(y < m_h);
60
61 uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
62 *(reinterpret_cast<uint32_t *>(data)) = clr;
63}
64
65FloatRect GLSurface::to_opengl(const Rect& rect, ConversionMode mode) {
66 const float delta = mode == ConversionMode::kExact ? 0. : 0.5;
67 float x1 = rect.x + delta;
68 float y1 = rect.y + delta;
69 pixel_to_gl(&x1, &y1);
70 float x2 = rect.x + rect.w - delta;
71 float y2 = rect.y + rect.h - delta;
72 pixel_to_gl(&x2, &y2);
73
74 return FloatRect(x1, y1, x2 - x1, y2 - y1);
75}
76
77void GLSurface::draw_rect(const Rect& rc, const RGBColor& clr)
78{
79 glViewport(0, 0, width(), height());
80 DrawRectProgram::instance().draw(to_opengl(rc, ConversionMode::kMidPoint), clr);
81}
82
83/**
84 * Draws a filled rectangle
85 */
86void GLSurface::fill_rect(const Rect& rc, const RGBAColor& clr) {
87 glViewport(0, 0, width(), height());
88
89 glBlendFunc(GL_ONE, GL_ZERO);
90
91 FillRectProgram::instance().draw(to_opengl(rc, ConversionMode::kExact), clr);
92
93 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
94}
95
96/**
97 * Change the brightness of the given rectangle
98 */
99void GLSurface::brighten_rect(const Rect& rc, const int32_t factor)
100{
101 if (!factor)
102 return;
103
104 glViewport(0, 0, width(), height());
105
106 // The simple trick here is to fill the rect, but using a different glBlendFunc that will sum
107 // src and target (or subtract them if factor is negative).
108 if (factor < 0) {
109 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
110 }
111
112 glBlendFunc(GL_ONE, GL_ONE);
113
114 const int delta = std::abs(factor);
115 FillRectProgram::instance().draw(
116 to_opengl(rc, ConversionMode::kExact), RGBAColor(delta, delta, delta, 0));
117
118 if (factor < 0) {
119 glBlendEquation(GL_FUNC_ADD);
120 }
121
122 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
123}
124
125void GLSurface::draw_line
126 (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth)
127{
128 glViewport(0, 0, width(), height());
129
130 float gl_x1 = x1 + 0.5;
131 float gl_y1 = y1 + 0.5;
132 pixel_to_gl(&gl_x1, &gl_y1);
133
134 float gl_x2 = x2 + 0.5;
135 float gl_y2 = y2 + 0.5;
136 pixel_to_gl(&gl_x2, &gl_y2);
137
138 DrawLineProgram::instance().draw(gl_x1, gl_y1, gl_x2, gl_y2, color, gwidth);
139}
140
141// Converts the pixel (x, y) in a texture to a gl coordinate in [0, 1].
142inline void pixel_to_gl_texture(const int width, const int height, float* x, float* y) {
143 *x = (*x / width);
144 *y = (*y / height);
145}
146
147void GLSurface::blit
148 (const Point& dst, const Surface* image, const Rect& srcrc, Composite cm)
149{
150 glViewport(0, 0, width(), height());
151
152 // Source Rectangle.
153 const GLSurfaceTexture* const texture = static_cast<const GLSurfaceTexture*>(image);
154 FloatRect gl_src_rect;
155 {
156 float x1 = srcrc.x;
157 float y1 = srcrc.y;
158 pixel_to_gl_texture(texture->width(), texture->height(), &x1, &y1);
159 float x2 = srcrc.x + srcrc.w;
160 float y2 = srcrc.y + srcrc.h;
161 pixel_to_gl_texture(texture->width(), texture->height(), &x2, &y2);
162 gl_src_rect.x = x1;
163 gl_src_rect.y = y1;
164 gl_src_rect.w = x2 - x1;
165 gl_src_rect.h = y2 - y1;
166 }
167
168 const FloatRect gl_dst_rect = to_opengl(Rect(dst.x, dst.y, srcrc.w, srcrc.h), ConversionMode::kExact);
169
170 BlitProgram::instance().draw(gl_dst_rect, gl_src_rect, texture->get_gl_texture(), cm);
171}
1720
=== removed file 'src/graphic/gl/surface.h'
--- src/graphic/gl/surface.h 2014-11-08 18:06:17 +0000
+++ src/graphic/gl/surface.h 1970-01-01 00:00:00 +0000
@@ -1,68 +0,0 @@
1/*
2 * Copyright (C) 2006-2012 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_GL_SURFACE_H
21#define WL_GRAPHIC_GL_SURFACE_H
22
23#include <memory>
24
25#include "graphic/gl/system_headers.h"
26#include "graphic/surface.h"
27
28class GLSurface : public Surface {
29public:
30 virtual ~GLSurface() {}
31
32 /// Interface implementations
33 uint16_t width() const override;
34 uint16_t height() const override;
35 uint8_t * get_pixels() const override;
36 void set_pixel(uint16_t x, uint16_t y, uint32_t clr) override;
37 uint32_t get_pixel(uint16_t x, uint16_t y) override;
38 void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm) override;
39 void fill_rect(const Rect&, const RGBAColor&) override;
40 void draw_rect(const Rect&, const RGBColor&) override;
41 void brighten_rect(const Rect&, int32_t factor) override;
42 virtual void draw_line
43 (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor&, uint8_t width) override;
44
45 // Converts the given pixel into an OpenGl point. This might need some
46 // flipping of axis, depending if you want to render on the screen or not.
47 virtual void pixel_to_gl(float* x, float* y) const = 0;
48
49protected:
50 // Convert the 'rect' in pixel space into opengl space.
51 enum class ConversionMode {
52 // Convert the rect as given.
53 kExact,
54
55 // Convert the rect so that the borders are in the center
56 // of the pixels.
57 kMidPoint,
58 };
59 FloatRect to_opengl(const Rect& rect, ConversionMode mode);
60
61 /// Logical width and height of the surface
62 uint16_t m_w, m_h;
63
64 /// Pixel data, while the texture is locked
65 std::unique_ptr<uint8_t[]> m_pixels;
66};
67
68#endif // end of include guard: WL_GRAPHIC_GL_SURFACE_H
690
=== modified file 'src/graphic/gl/surface_screen.cc'
--- src/graphic/gl/surface_screen.cc 2014-11-08 18:06:17 +0000
+++ src/graphic/gl/surface_screen.cc 2014-11-23 12:03:00 +0000
@@ -52,10 +52,6 @@
52 }52 }
53}53}
5454
55const SDL_PixelFormat & GLSurfaceScreen::format() const {
56 return Gl::gl_rgba_format();
57}
58
59void GLSurfaceScreen::lock(Surface::LockMode mode)55void GLSurfaceScreen::lock(Surface::LockMode mode)
60{56{
61 assert(!m_pixels);57 assert(!m_pixels);
@@ -85,7 +81,3 @@
8581
86 m_pixels.reset(nullptr);82 m_pixels.reset(nullptr);
87}83}
88
89uint16_t GLSurfaceScreen::get_pitch() const {
90 return 4 * m_w;
91}
9284
=== modified file 'src/graphic/gl/surface_screen.h'
--- src/graphic/gl/surface_screen.h 2014-11-08 18:06:17 +0000
+++ src/graphic/gl/surface_screen.h 2014-11-23 12:03:00 +0000
@@ -19,12 +19,12 @@
19#ifndef WL_GRAPHIC_GL_SURFACE_SCREEN_H19#ifndef WL_GRAPHIC_GL_SURFACE_SCREEN_H
20#define WL_GRAPHIC_GL_SURFACE_SCREEN_H20#define WL_GRAPHIC_GL_SURFACE_SCREEN_H
2121
22#include "graphic/gl/surface.h"22#include "graphic/surface.h"
2323
24/**24/**
25 * This surface represents the screen in OpenGL mode.25 * This surface represents the screen in OpenGL mode.
26 */26 */
27class GLSurfaceScreen : public GLSurface {27class GLSurfaceScreen : public Surface {
28public:28public:
29 GLSurfaceScreen(uint16_t w, uint16_t h);29 GLSurfaceScreen(uint16_t w, uint16_t h);
30 virtual ~GLSurfaceScreen() {}30 virtual ~GLSurfaceScreen() {}
@@ -32,8 +32,6 @@
32 /// Interface implementations32 /// Interface implementations
33 void lock(LockMode) override;33 void lock(LockMode) override;
34 void unlock(UnlockMode) override;34 void unlock(UnlockMode) override;
35 uint16_t get_pitch() const override;
36 const SDL_PixelFormat & format() const override;
3735
38private:36private:
39 void pixel_to_gl(float* x, float* y) const override;37 void pixel_to_gl(float* x, float* y) const override;
4038
=== modified file 'src/graphic/gl/surface_texture.cc'
--- src/graphic/gl/surface_texture.cc 2014-11-08 18:06:17 +0000
+++ src/graphic/gl/surface_texture.cc 2014-11-23 12:03:00 +0000
@@ -24,10 +24,10 @@
24#include "base/macros.h"24#include "base/macros.h"
25#include "base/wexception.h"25#include "base/wexception.h"
26#include "graphic/gl/blit_program.h"26#include "graphic/gl/blit_program.h"
27#include "graphic/gl/surface.h"
28#include "graphic/gl/utils.h"27#include "graphic/gl/utils.h"
29#include "graphic/graphic.h"28#include "graphic/graphic.h"
30#include "graphic/sdl/utils.h"29#include "graphic/sdl_utils.h"
30#include "graphic/surface.h"
3131
32namespace {32namespace {
3333
@@ -160,10 +160,6 @@
160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
161}161}
162162
163const SDL_PixelFormat & GLSurfaceTexture::format() const {
164 return Gl::gl_rgba_format();
165}
166
167void GLSurfaceTexture::lock(LockMode mode) {163void GLSurfaceTexture::lock(LockMode mode) {
168 if (m_w <= 0 || m_h <= 0) {164 if (m_w <= 0 || m_h <= 0) {
169 return;165 return;
@@ -194,17 +190,13 @@
194 m_pixels.reset(nullptr);190 m_pixels.reset(nullptr);
195}191}
196192
197uint16_t GLSurfaceTexture::get_pitch() const {
198 return 4 * m_w;
199}
200
201void GLSurfaceTexture::draw_rect(const Rect& rectangle, const RGBColor& clr)193void GLSurfaceTexture::draw_rect(const Rect& rectangle, const RGBColor& clr)
202{194{
203 if (m_w <= 0 || m_h <= 0) {195 if (m_w <= 0 || m_h <= 0) {
204 return;196 return;
205 }197 }
206 setup_gl(m_texture);198 setup_gl(m_texture);
207 GLSurface::draw_rect(rectangle, clr);199 Surface::draw_rect(rectangle, clr);
208 reset_gl();200 reset_gl();
209}201}
210202
@@ -219,7 +211,7 @@
219 }211 }
220212
221 setup_gl(m_texture);213 setup_gl(m_texture);
222 GLSurface::fill_rect(rectangle, clr);214 Surface::fill_rect(rectangle, clr);
223 reset_gl();215 reset_gl();
224}216}
225217
@@ -233,7 +225,7 @@
233 }225 }
234226
235 setup_gl(m_texture);227 setup_gl(m_texture);
236 GLSurface::brighten_rect(rectangle, factor);228 Surface::brighten_rect(rectangle, factor);
237 reset_gl();229 reset_gl();
238}230}
239231
@@ -245,7 +237,7 @@
245 }237 }
246238
247 setup_gl(m_texture);239 setup_gl(m_texture);
248 GLSurface::draw_line(x1, y1, x2, y2, color, gwidth);240 Surface::draw_line(x1, y1, x2, y2, color, gwidth);
249 reset_gl();241 reset_gl();
250}242}
251243
@@ -257,6 +249,6 @@
257 }249 }
258250
259 setup_gl(m_texture);251 setup_gl(m_texture);
260 GLSurface::blit(dst, src, srcrc, cm);252 Surface::blit(dst, src, srcrc, cm);
261 reset_gl();253 reset_gl();
262}254}
263255
=== modified file 'src/graphic/gl/surface_texture.h'
--- src/graphic/gl/surface_texture.h 2014-11-08 18:06:17 +0000
+++ src/graphic/gl/surface_texture.h 2014-11-23 12:03:00 +0000
@@ -19,11 +19,12 @@
19#ifndef WL_GRAPHIC_GL_SURFACE_TEXTURE_H19#ifndef WL_GRAPHIC_GL_SURFACE_TEXTURE_H
20#define WL_GRAPHIC_GL_SURFACE_TEXTURE_H20#define WL_GRAPHIC_GL_SURFACE_TEXTURE_H
2121
22#include "graphic/gl/surface.h"22#include "graphic/gl/system_headers.h"
23#include "graphic/surface.h"
2324
24struct SDL_Surface;25struct SDL_Surface;
2526
26class GLSurfaceTexture : public GLSurface {27class GLSurfaceTexture : public Surface {
27public:28public:
28 GLSurfaceTexture(SDL_Surface * surface, bool intensity = false);29 GLSurfaceTexture(SDL_Surface * surface, bool intensity = false);
29 GLSurfaceTexture(int w, int h);30 GLSurfaceTexture(int w, int h);
@@ -34,13 +35,11 @@
34 //@{35 //@{
35 void lock(LockMode) override;36 void lock(LockMode) override;
36 void unlock(UnlockMode) override;37 void unlock(UnlockMode) override;
37 uint16_t get_pitch() const override;
38 const SDL_PixelFormat & format() const override;
3938
40 // Note: the following functions are reimplemented here though they39 // Note: the following functions are reimplemented here though they
41 // basically only call the functions in GLSurface wrapped in calls to40 // basically only call the functions in Surface wrapped in calls to
42 // setup_gl(), reset_gl(). The same functionality can be achieved by making41 // setup_gl(), reset_gl(). The same functionality can be achieved by making
43 // those two functions virtual and calling them in GLSurface. However,42 // those two functions virtual and calling them in Surface. However,
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,
45 // this costs two virtual function calls which makes a notable difference in44 // this costs two virtual function calls which makes a notable difference in
46 // profiles.45 // profiles.
4746
=== modified file 'src/graphic/graphic.cc'
--- src/graphic/graphic.cc 2014-11-22 10:18:20 +0000
+++ src/graphic/graphic.cc 2014-11-23 12:03:00 +0000
@@ -40,7 +40,6 @@
40#include "graphic/image_io.h"40#include "graphic/image_io.h"
41#include "graphic/image_transformations.h"41#include "graphic/image_transformations.h"
42#include "graphic/rendertarget.h"42#include "graphic/rendertarget.h"
43#include "graphic/sdl/surface.h"
44#include "graphic/surface_cache.h"43#include "graphic/surface_cache.h"
45#include "graphic/texture.h"44#include "graphic/texture.h"
46#include "io/fileread.h"45#include "io/fileread.h"
@@ -52,7 +51,6 @@
52using namespace std;51using namespace std;
5352
54Graphic * g_gr;53Graphic * g_gr;
55bool g_opengl;
5654
57namespace {55namespace {
5856
@@ -91,115 +89,81 @@
91 ImageTransformations::initialize();89 ImageTransformations::initialize();
9290
93 m_sdl_window = nullptr;91 m_sdl_window = nullptr;
94 m_sdl_screen = nullptr;
95 m_sdl_renderer = nullptr;
96 m_sdl_texture = nullptr;
97 m_glcontext = nullptr;92 m_glcontext = nullptr;
98}93}
9994
100void Graphic::initialize(int32_t w, int32_t h, bool fullscreen, bool opengl) {95void Graphic::initialize(int32_t w, int32_t h, bool fullscreen) {
101 cleanup();96 cleanup();
10297
103 // Set video mode using SDL. First collect the flags98 // Request an OpenGL 2 context with double buffering.
104 int32_t flags = 0;99 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
105 g_opengl = false;100 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
106101 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
107 if (opengl) {102
108 log("Graphics: Trying opengl\n");103 int32_t flags = SDL_WINDOW_OPENGL;
109
110 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
111
112 // Request an OpenGL 2 context.
113 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
114 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
115
116 flags |= SDL_WINDOW_OPENGL;
117 }
118
119 if (fullscreen) {104 if (fullscreen) {
120 flags |= SDL_WINDOW_FULLSCREEN;105 flags |= SDL_WINDOW_FULLSCREEN;
121 log("Graphics: Trying FULLSCREEN\n");106 log("Graphics: Trying FULLSCREEN\n");
122 }107 }
123108
124 log("Graphics: Try to set Videomode %ux%u\n", w, h);109 log("Graphics: Try to set Videomode %ux%u\n", w, h);
125 // Here we actually set the video mode110 m_sdl_window = SDL_CreateWindow(
126 m_sdl_window = SDL_CreateWindow("Widelands Window",111 "Widelands Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
127 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
128
129 if (!m_sdl_window) {112 if (!m_sdl_window) {
130 log113 log("Graphics: Could not set Videomode: %s, trying minimum graphics settings\n",
131 ("Graphics: Could not set videomode: %s, trying minimum graphics settings\n",114 SDL_GetError());
132 SDL_GetError());
133 flags &= ~SDL_WINDOW_FULLSCREEN;115 flags &= ~SDL_WINDOW_FULLSCREEN;
134 m_sdl_window = SDL_CreateWindow("Widelands Window",116 m_sdl_window = SDL_CreateWindow("Widelands Window",
135 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,117 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
136 kFallbackGraphicsWidth, kFallbackGraphicsHeight, flags);118 kFallbackGraphicsWidth, kFallbackGraphicsHeight, flags);
137 m_fallback_settings_in_effect = true;119 m_fallback_settings_in_effect = true;
138 if (!m_sdl_window) {120 if (!m_sdl_window) {
139 throw wexception121 throw wexception("Graphics: could not set video mode: %s", SDL_GetError());
140 ("Graphics: could not set video mode: %s", SDL_GetError());
141 }122 }
142 }123 }
143124
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());
145
146 if (opengl) {
147 m_glcontext = SDL_GL_CreateContext(m_sdl_window);
148 if (m_glcontext) {
149 SDL_GL_MakeCurrent(m_sdl_window, m_glcontext);
150 }
151
152 // We now really have a working opengl screen...
153 g_opengl = true;
154
155 // See graphic/gl/system_headers.h for an explanation of the
156 // next line.
157 glewExperimental = GL_TRUE;
158 GLenum err = glewInit();
159 if (err != GLEW_OK) {
160 log("glewInit returns %i\nYour OpenGL installation must be __very__ broken. %s\n",
161 err, glewGetErrorString(err));
162 throw wexception("glewInit returns %i: Broken OpenGL installation.", err);
163 }
164
165 log("Graphics: OpenGL: Version \"%s\"\n",
166 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
167
168 GLboolean glBool;
169 glGetBooleanv(GL_DOUBLEBUFFER, &glBool);
170 log("Graphics: OpenGL: Double buffering %s\n", (glBool == GL_TRUE) ? "enabled" : "disabled");
171
172 GLint glInt;
173 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glInt);
174 log("Graphics: OpenGL: Max texture size: %u\n", glInt);
175
176 SDL_GL_SetSwapInterval(1);
177 SDL_GL_SwapWindow(m_sdl_window);
178
179 glDrawBuffer(GL_BACK);
180
181 glDisable(GL_DEPTH_TEST);
182 glEnable(GL_TEXTURE_2D);
183 glEnable(GL_BLEND);
184 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
185
186 glClear(GL_COLOR_BUFFER_BIT);
187
188 screen_.reset(new GLSurfaceScreen(w, h));
189 } else {
190 m_sdl_renderer = SDL_CreateRenderer(m_sdl_window, -1, 0);
191 uint32_t rmask, gmask, bmask, amask;
192 int bpp;
193 SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB8888, &bpp, &rmask, &gmask, &bmask, &amask);
194 m_sdl_screen = SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);
195 m_sdl_texture = SDL_CreateTexture(m_sdl_renderer,
196 SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
197 w, h);
198 screen_.reset(new SDLSurface(m_sdl_screen, false));
199 }
200
201 set_icon(m_sdl_window);126 set_icon(m_sdl_window);
202127
128 m_glcontext = SDL_GL_CreateContext(m_sdl_window);
129 SDL_GL_MakeCurrent(m_sdl_window, m_glcontext);
130
131 // See graphic/gl/system_headers.h for an explanation of the
132 // next line.
133 glewExperimental = GL_TRUE;
134 GLenum err = glewInit();
135 if (err != GLEW_OK) {
136 log("glewInit returns %i\nYour OpenGL installation must be __very__ broken. %s\n",
137 err, glewGetErrorString(err));
138 throw wexception("glewInit returns %i: Broken OpenGL installation.", err);
139 }
140
141 log("Graphics: OpenGL: Version \"%s\"\n",
142 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
143
144 GLboolean glBool;
145 glGetBooleanv(GL_DOUBLEBUFFER, &glBool);
146 log("Graphics: OpenGL: Double buffering %s\n", (glBool == GL_TRUE) ? "enabled" : "disabled");
147
148 GLint glInt;
149 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glInt);
150 log("Graphics: OpenGL: Max texture size: %u\n", glInt);
151
152 SDL_GL_SetSwapInterval(1);
153
154 glDrawBuffer(GL_BACK);
155
156 glDisable(GL_DEPTH_TEST);
157 glEnable(GL_TEXTURE_2D);
158 glEnable(GL_BLEND);
159 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
160
161 glClear(GL_COLOR_BUFFER_BIT);
162
163 SDL_GL_SwapWindow(m_sdl_window);
164
165 screen_.reset(new GLSurfaceScreen(w, h));
166
203 /* Information about the video capabilities. */167 /* Information about the video capabilities. */
204 {168 {
205 SDL_DisplayMode disp_mode;169 SDL_DisplayMode disp_mode;
@@ -216,8 +180,6 @@
216 assert(SDL_BYTESPERPIXEL(disp_mode.format) == 4);180 assert(SDL_BYTESPERPIXEL(disp_mode.format) == 4);
217 }181 }
218182
219 Surface::display_format_is_now_defined();
220
221 m_rendertarget.reset(new RenderTarget(screen_.get()));183 m_rendertarget.reset(new RenderTarget(screen_.get()));
222184
223 pic_road_normal_.reset(load_image("world/pics/roadt_normal.png"));185 pic_road_normal_.reset(load_image("world/pics/roadt_normal.png"));
@@ -236,14 +198,6 @@
236 if (UI::g_fh)198 if (UI::g_fh)
237 UI::g_fh->flush();199 UI::g_fh->flush();
238200
239 if (m_sdl_texture) {
240 SDL_DestroyTexture(m_sdl_texture);
241 m_sdl_texture = nullptr;
242 }
243 if (m_sdl_screen) {
244 SDL_FreeSurface(m_sdl_screen);
245 m_sdl_screen = nullptr;
246 }
247 if (m_sdl_window) {201 if (m_sdl_window) {
248 SDL_DestroyWindow(m_sdl_window);202 SDL_DestroyWindow(m_sdl_window);
249 m_sdl_window = nullptr;203 m_sdl_window = nullptr;
@@ -329,16 +283,7 @@
329*/283*/
330void Graphic::refresh()284void Graphic::refresh()
331{285{
332 if (g_opengl) {286 SDL_GL_SwapWindow(m_sdl_window);
333 SDL_GL_SwapWindow(m_sdl_window);
334 m_update = false;
335 return;
336 }
337
338 SDL_UpdateTexture(m_sdl_texture, nullptr, m_sdl_screen->pixels, m_sdl_screen->pitch);
339 SDL_RenderClear(m_sdl_renderer);
340 SDL_RenderCopy(m_sdl_renderer, m_sdl_texture, nullptr, nullptr);
341 SDL_RenderPresent(m_sdl_renderer);
342 m_update = false;287 m_update = false;
343}288}
344289
@@ -355,11 +300,7 @@
355300
356uint32_t Graphic::new_maptexture(const std::vector<std::string>& texture_files, const uint32_t frametime)301uint32_t Graphic::new_maptexture(const std::vector<std::string>& texture_files, const uint32_t frametime)
357{302{
358 SDL_PixelFormat* pixel_fmt = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);303 m_maptextures.emplace_back(new Texture(texture_files, frametime));
359 m_maptextures.emplace_back(new Texture(texture_files, frametime, *pixel_fmt));
360 if (pixel_fmt) {
361 SDL_FreeFormat(pixel_fmt);
362 }
363 return m_maptextures.size(); // ID 1 is at m_maptextures[0]304 return m_maptextures.size(); // ID 1 is at m_maptextures[0]
364}305}
365306
366307
=== modified file 'src/graphic/graphic.h'
--- src/graphic/graphic.h 2014-11-13 06:45:36 +0000
+++ src/graphic/graphic.h 2014-11-23 12:03:00 +0000
@@ -35,7 +35,6 @@
35class RenderTarget;35class RenderTarget;
36class Surface;36class Surface;
37class SurfaceCache;37class SurfaceCache;
38struct SDL_Surface;
39class StreamWrite;38class StreamWrite;
40struct Texture;39struct Texture;
4140
@@ -51,8 +50,7 @@
51 ~Graphic();50 ~Graphic();
5251
53 // Initialize or reinitialize the graphics system. Throws on error.52 // Initialize or reinitialize the graphics system. Throws on error.
54 void initialize53 void initialize(int32_t w, int32_t h, bool fullscreen);
55 (int32_t w, int32_t h, bool fullscreen, bool opengl);
5654
57 int32_t get_xres();55 int32_t get_xres();
58 int32_t get_yres();56 int32_t get_yres();
@@ -94,10 +92,7 @@
94 /// This saves a copy of the screen SDL_Surface. This is needed for92 /// This saves a copy of the screen SDL_Surface. This is needed for
95 /// opengl rendering as the SurfaceOpenGL does not use it. It allows93 /// opengl rendering as the SurfaceOpenGL does not use it. It allows
96 /// manipulation the screen context.94 /// manipulation the screen context.
97 SDL_Surface * m_sdl_screen;
98 SDL_Renderer * m_sdl_renderer;
99 SDL_Window * m_sdl_window;95 SDL_Window * m_sdl_window;
100 SDL_Texture * m_sdl_texture;
101 SDL_GLContext m_glcontext;96 SDL_GLContext m_glcontext;
102 /// A RenderTarget for screen_. This is initialized during init()97 /// A RenderTarget for screen_. This is initialized during init()
103 std::unique_ptr<RenderTarget> m_rendertarget;98 std::unique_ptr<RenderTarget> m_rendertarget;
@@ -120,6 +115,5 @@
120};115};
121116
122extern Graphic * g_gr;117extern Graphic * g_gr;
123extern bool g_opengl;
124118
125#endif // end of include guard: WL_GRAPHIC_GRAPHIC_H119#endif // end of include guard: WL_GRAPHIC_GRAPHIC_H
126120
=== modified file 'src/graphic/image_transformations.cc'
--- src/graphic/image_transformations.cc 2014-11-02 20:15:01 +0000
+++ src/graphic/image_transformations.cc 2014-11-23 12:03:00 +0000
@@ -28,7 +28,6 @@
28#include "base/macros.h"28#include "base/macros.h"
29#include "graphic/color.h"29#include "graphic/color.h"
30#include "graphic/graphic.h"30#include "graphic/graphic.h"
31#include "graphic/sdl/surface.h"
32#include "graphic/surface.h"31#include "graphic/surface.h"
33#include "graphic/surface_cache.h"32#include "graphic/surface_cache.h"
3433
@@ -87,15 +86,8 @@
87 Rect srcrect = Rect(Point(0, 0), src->width(), src->height());86 Rect srcrect = Rect(Point(0, 0), src->width(), src->height());
8887
89 // Second step: get source material88 // Second step: get source material
90 SDL_Surface * srcsdl = nullptr;89 SDL_Surface * srcsdl = extract_sdl_surface(*src, srcrect);
91 bool free_source = true;90 bool free_source = true;
92 if (upcast(const SDLSurface, sdlsrcsurf, src)) {
93 srcsdl = sdlsrcsurf->get_sdl_surface();
94 free_source = false;
95 } else {
96 // This is in OpenGL
97 srcsdl = extract_sdl_surface(*src, srcrect);
98 }
9991
100 // If we actually shrink a surface, ballpark the zoom so that the shrinking92 // If we actually shrink a surface, ballpark the zoom so that the shrinking
101 // effect is weakened.93 // effect is weakened.
10294
=== removed directory 'src/graphic/sdl'
=== removed file 'src/graphic/sdl/game_renderer.cc'
--- src/graphic/sdl/game_renderer.cc 2014-09-27 18:53:55 +0000
+++ src/graphic/sdl/game_renderer.cc 1970-01-01 00:00:00 +0000
@@ -1,279 +0,0 @@
1/*
2 * Copyright (C) 2010-2013 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#include "graphic/sdl/game_renderer.h"
21
22#include "graphic/rendertarget.h"
23#include "graphic/sdl/terrain.h"
24#include "logic/field.h"
25#include "logic/map.h"
26#include "logic/player.h"
27#include "logic/world/terrain_description.h"
28#include "logic/world/world.h"
29#include "wui/overlay_manager.h"
30
31
32using namespace Widelands;
33
34///This is used by rendermap to calculate the brightness of the terrain.
35inline static int8_t node_brightness
36 (Widelands::Time const gametime,
37 Widelands::Time const last_seen,
38 Widelands::Vision const vision,
39 int8_t result)
40{
41 if (vision == 0)
42 result = -128;
43 else if (vision == 1) {
44 assert(last_seen <= gametime);
45 Widelands::Duration const time_ago = gametime - last_seen;
46 result =
47 static_cast<int16_t>
48 (((static_cast<int16_t>(result) + 128) >> 1)
49 *
50 (1.0 + (time_ago < 45000 ? expf(-8.46126929e-5 * time_ago) : 0)))
51 -
52 128;
53 }
54
55 return result;
56}
57
58
59void SdlGameRenderer::draw()
60{
61 draw_terrain();
62 draw_objects();
63}
64
65void SdlGameRenderer::draw_terrain()
66{
67 if (m_player && !m_player->see_all())
68 m_dst->get_surface()->fill_rect(m_dst->get_rect(), RGBAColor(0, 0, 0, 255));
69
70 const Map & map = m_egbase->map();
71 const World & world = m_egbase->world();
72 uint32_t const mapwidth = map.get_width();
73
74#define get_terrain_texture(ter) \
75 (g_gr->get_maptexture_data(world.terrain_descr((ter)).get_texture()))
76
77 int32_t dx = m_maxfx - m_minfx + 1;
78 int32_t dy = m_maxfy - m_minfy + 1;
79 int32_t linear_fy = m_minfy;
80 int32_t b_posy = linear_fy * TRIANGLE_HEIGHT + m_dst_offset.y;
81
82 Widelands::Time const gametime = m_egbase->get_gametime();
83
84 while (dy--) {
85 const int32_t posy = b_posy;
86 b_posy += TRIANGLE_HEIGHT;
87 const int32_t linear_fx = m_minfx;
88 FCoords r(Coords(linear_fx, linear_fy));
89 FCoords br(Coords(linear_fx + (linear_fy & 1) - 1, linear_fy + 1));
90 int32_t r_posx =
91 r.x * TRIANGLE_WIDTH
92 +
93 (linear_fy & 1) * (TRIANGLE_WIDTH / 2)
94 +
95 m_dst_offset.x;
96 int32_t br_posx = r_posx - TRIANGLE_WIDTH / 2;
97
98 // Calculate safe (bounded) field coordinates and get field pointers
99 map.normalize_coords(r);
100 map.normalize_coords(br);
101 MapIndex r_index = Map::get_index (r, mapwidth);
102 r.field = &map[r_index];
103 MapIndex br_index = Map::get_index(br, mapwidth);
104 br.field = &map[br_index];
105 FCoords tr;
106 map.get_tln(r, &tr);
107 MapIndex tr_index = tr.field - &map[0];
108
109 const Texture * f_r_texture;
110
111 if (m_player && !m_player->see_all()) {
112 const Player::Field & l_pf = m_player->fields()[Map::get_index(map.l_n(r), mapwidth)];
113 f_r_texture = get_terrain_texture(l_pf.terrains.r);
114 } else {
115 f_r_texture = get_terrain_texture(map.l_n(r).field->get_terrains().r);
116 }
117
118 uint32_t count = dx;
119
120 while (count--) {
121 const FCoords bl = br;
122 const FCoords f = r;
123 const int32_t f_posx = r_posx;
124 const int32_t bl_posx = br_posx;
125 MapIndex f_index = r_index;
126 MapIndex bl_index = br_index;
127 move_r(mapwidth, tr, tr_index);
128 move_r(mapwidth, r, r_index);
129 move_r(mapwidth, br, br_index);
130 r_posx += TRIANGLE_WIDTH;
131 br_posx += TRIANGLE_WIDTH;
132
133 const Texture * l_r_texture = f_r_texture;
134 const Texture * f_d_texture;
135 const Texture * tr_d_texture;
136 uint8_t roads;
137 int8_t f_brightness;
138 int8_t r_brightness;
139 int8_t bl_brightness;
140 int8_t br_brightness;
141
142 if (m_player && !m_player->see_all()) {
143 const Player::Field & f_pf = m_player->fields()[f_index];
144 const Player::Field & r_pf = m_player->fields()[r_index];
145 const Player::Field & bl_pf = m_player->fields()[bl_index];
146 const Player::Field & br_pf = m_player->fields()[br_index];
147 const Player::Field & tr_pf = m_player->fields()[tr_index];
148
149 f_r_texture = get_terrain_texture(f_pf.terrains.r);
150 f_d_texture = get_terrain_texture(f_pf.terrains.d);
151 tr_d_texture = get_terrain_texture(tr_pf.terrains.d);
152
153 roads = f_pf.roads;
154
155 f_brightness = node_brightness
156 (gametime, f_pf.time_node_last_unseen,
157 f_pf.vision, f.field->get_brightness());
158 r_brightness = node_brightness
159 (gametime, r_pf.time_node_last_unseen,
160 r_pf.vision, r.field->get_brightness());
161 bl_brightness = node_brightness
162 (gametime, bl_pf.time_node_last_unseen,
163 bl_pf.vision, bl.field->get_brightness());
164 br_brightness = node_brightness
165 (gametime, br_pf.time_node_last_unseen,
166 br_pf.vision, br.field->get_brightness());
167 } else {
168 f_r_texture = get_terrain_texture(f.field->get_terrains().r);
169 f_d_texture = get_terrain_texture(f.field->get_terrains().d);
170 tr_d_texture = get_terrain_texture(tr.field->get_terrains().d);
171
172 roads = f.field->get_roads();
173
174 f_brightness = f.field->get_brightness();
175 r_brightness = r.field->get_brightness();
176 bl_brightness = bl.field->get_brightness();
177 br_brightness = br.field->get_brightness();
178 }
179 roads |= map.overlay_manager().get_road_overlay(f);
180
181 Vertex f_vert
182 (f_posx, posy - f.field->get_height() * HEIGHT_FACTOR,
183 f_brightness, 0, 0);
184 Vertex r_vert
185 (r_posx, posy - r.field->get_height() * HEIGHT_FACTOR,
186 r_brightness, TRIANGLE_WIDTH, 0);
187 Vertex bl_vert
188 (bl_posx, b_posy - bl.field->get_height() * HEIGHT_FACTOR,
189 bl_brightness, 0, 64);
190 Vertex br_vert
191 (br_posx, b_posy - br.field->get_height() * HEIGHT_FACTOR,
192 br_brightness, TRIANGLE_WIDTH, 64);
193
194 if (linear_fy & 1) {
195 f_vert.tx += TRIANGLE_WIDTH / 2;
196 r_vert.tx += TRIANGLE_WIDTH / 2;
197 } else {
198 f_vert.tx += TRIANGLE_WIDTH;
199 r_vert.tx += TRIANGLE_WIDTH;
200 bl_vert.tx += TRIANGLE_WIDTH / 2;
201 br_vert.tx += TRIANGLE_WIDTH / 2;
202 }
203
204 draw_field // Render ground
205 (*m_dst,
206 f_vert, r_vert, bl_vert, br_vert,
207 roads,
208 *tr_d_texture, *l_r_texture, *f_d_texture, *f_r_texture);
209 }
210
211 ++linear_fy;
212 }
213
214#undef get_terrain_texture
215}
216
217
218/**
219 * Draw ground textures and roads for the given parallelogram (two triangles)
220 * into the bitmap.
221 *
222 * Vertices:
223 * - f_vert vertex of the field
224 * - r_vert vertex right of the field
225 * - bl_vert vertex bottom left of the field
226 * - br_vert vertex bottom right of the field
227 *
228 * Textures:
229 * - f_r_texture Terrain of the triangle right of the field
230 * - f_d_texture Terrain of the triangle under of the field
231 * - tr_d_texture Terrain of the triangle top of the right triangle ??
232 * - l_r_texture Terrain of the triangle left of the down triangle ??
233 *
234 * (tr_d)
235 *
236 * (f) *------* (r)
237 * / \ r /
238 * (l_r) / \ /
239 * / d \/
240 * (bl) *------* (br)
241 */
242void SdlGameRenderer::draw_field
243 (RenderTarget & dst,
244 const Vertex & f_vert,
245 const Vertex & r_vert,
246 const Vertex & bl_vert,
247 const Vertex & br_vert,
248 uint8_t roads,
249 const Texture & tr_d_texture,
250 const Texture & l_r_texture,
251 const Texture & f_d_texture,
252 const Texture & f_r_texture)
253{
254 upcast(SDLSurface, sdlsurf, dst.get_surface());
255 if (sdlsurf)
256 {
257 sdlsurf->set_subwin(dst.get_rect());
258 switch (sdlsurf->format().BytesPerPixel) {
259 case 2:
260 draw_field_int<uint16_t>
261 (*sdlsurf,
262 f_vert, r_vert, bl_vert, br_vert,
263 roads,
264 tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
265 break;
266 case 4:
267 draw_field_int<uint32_t>
268 (*sdlsurf,
269 f_vert, r_vert, bl_vert, br_vert,
270 roads,
271 tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
272 break;
273 default:
274 assert(false);
275 break;
276 }
277 sdlsurf->unset_subwin();
278 }
279}
2800
=== removed file 'src/graphic/sdl/game_renderer.h'
--- src/graphic/sdl/game_renderer.h 2014-09-27 18:53:55 +0000
+++ src/graphic/sdl/game_renderer.h 1970-01-01 00:00:00 +0000
@@ -1,55 +0,0 @@
1/*
2 * Copyright (C) 2010-2013 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_SDL_GAME_RENDERER_H
21#define WL_GRAPHIC_SDL_GAME_RENDERER_H
22
23#include "graphic/game_renderer.h"
24
25struct Texture;
26struct Vertex;
27
28/**
29 * Software-rendering implementation of @ref GameRenderer.
30 */
31class SdlGameRenderer : public GameRenderer {
32protected:
33 void draw() override;
34
35private:
36 void draw_terrain();
37
38 /**
39 * Helper function to draw two terrain triangles. This is called from the
40 * rendermap() functions.
41 */
42 void draw_field
43 (RenderTarget & dst,
44 const Vertex & f_vert,
45 const Vertex & r_vert,
46 const Vertex & bl_vert,
47 const Vertex & br_vert,
48 uint8_t roads,
49 const Texture & tr_d_texture,
50 const Texture & l_r_texture,
51 const Texture & f_d_texture,
52 const Texture & f_r_texture);
53};
54
55#endif // end of include guard: WL_GRAPHIC_SDL_GAME_RENDERER_H
560
=== removed file 'src/graphic/sdl/surface.cc'
--- src/graphic/sdl/surface.cc 2014-11-02 20:31:40 +0000
+++ src/graphic/sdl/surface.cc 1970-01-01 00:00:00 +0000
@@ -1,355 +0,0 @@
1/*
2 * Copyright (C) 2002-2004, 2007-2013 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#include "graphic/sdl/surface.h"
21
22#include <cassert>
23
24#include <SDL.h>
25
26SDLSurface::SDLSurface(SDL_Surface* surface, bool free_surface_on_delete) :
27 m_surface(surface),
28 m_offsx(0), m_offsy(0),
29 m_w(surface->w), m_h(surface->h),
30 m_free_surface_on_delete(free_surface_on_delete)
31{}
32
33SDLSurface::~SDLSurface() {
34 assert(m_surface);
35
36 if (m_free_surface_on_delete)
37 SDL_FreeSurface(m_surface);
38}
39
40const SDL_PixelFormat & SDLSurface::format() const {
41 assert(m_surface);
42 return *m_surface->format;
43}
44
45uint8_t * SDLSurface::get_pixels() const {
46 assert(m_surface);
47
48 return
49 static_cast<uint8_t *>(m_surface->pixels)
50 +
51 m_offsy * m_surface->pitch
52 +
53 m_offsx * m_surface->format->BytesPerPixel;
54}
55
56void SDLSurface::lock(LockMode) {
57 if (SDL_MUSTLOCK(m_surface))
58 SDL_LockSurface(m_surface);
59}
60
61void SDLSurface::unlock(UnlockMode) {
62 if (SDL_MUSTLOCK(m_surface))
63 SDL_UnlockSurface(m_surface);
64}
65
66uint32_t SDLSurface::get_pixel(uint16_t x, uint16_t y) {
67 x += m_offsx;
68 y += m_offsy;
69
70 assert(x < width());
71 assert(y < height());
72 assert(m_surface);
73
74 // Locking not needed: reading only
75 const uint8_t bytes_per_pixel = m_surface->format->BytesPerPixel;
76 uint8_t * const pix =
77 static_cast<uint8_t *>(m_surface->pixels) +
78 y * m_surface->pitch + x * bytes_per_pixel;
79
80 switch (bytes_per_pixel) {
81 case 1:
82 return *pix; // Maybe needed for save_png.
83 case 2:
84 return *reinterpret_cast<const uint16_t *>(pix);
85 case 3: //Needed for save_png.
86 // We can not dereference a pointer to a size 4 object in this case
87 // since that would casue a read beyond the end of the block pointed to
88 // by m_surface. Furthermore it would not be properly aligned to a 4
89 // byte boundary.
90 //
91 // Suppose that the image is 2 * 2 pixels. Then m_surface points to a
92 // block of size 2 * 2 * 3 = 12. The values for the last pixel are at
93 // m_surface[9], m_surface[10] and m_surface[11]. But m_surface[12] is
94 // beyond the end of the block, so we can not read 4 bytes starting at
95 // m_surface[9] (even if unaligned access is allowed).
96 //
97 // Therefore we read the 3 bytes separately and get the result by
98 // shifting the values. It is alignment safe.
99 return pix[0] << 0x00 | pix[1] << 0x08 | pix[2] << 0x10;
100 case 4:
101 return *reinterpret_cast<const uint32_t *>(pix);
102 default:
103 assert(false);
104 }
105
106 return 0; // Should never be here
107}
108
109void SDLSurface::set_pixel(uint16_t x, uint16_t y, const uint32_t clr) {
110 x += m_offsx;
111 y += m_offsy;
112
113 if (x >= width() || y >= height())
114 return;
115 assert(m_surface);
116
117 if (SDL_MUSTLOCK(m_surface))
118 SDL_LockSurface(m_surface);
119
120 const uint8_t bytes_per_pixel = m_surface->format->BytesPerPixel;
121 uint8_t * const pix =
122 static_cast<uint8_t *>(m_surface->pixels) +
123 y * m_surface->pitch + x * bytes_per_pixel;
124 switch (bytes_per_pixel) {
125 case 2: *reinterpret_cast<uint16_t *>(pix) = static_cast<uint16_t>(clr); break;
126 case 4: *reinterpret_cast<uint32_t *>(pix) = clr; break;
127 default: break;
128 };
129
130 if (SDL_MUSTLOCK(m_surface))
131 SDL_UnlockSurface(m_surface);
132}
133
134void SDLSurface::set_subwin(const Rect& r) {
135 m_offsx = r.x;
136 m_offsy = r.y;
137 m_w = r.w;
138 m_h = r.h;
139}
140
141void SDLSurface::unset_subwin() {
142 m_offsx = 0;
143 m_offsy = 0;
144 m_w = m_surface->w;
145 m_h = m_surface->h;
146}
147
148/*
149===============
150Draws the outline of a rectangle
151===============
152*/
153void SDLSurface::draw_rect(const Rect& rc, const RGBColor& clr) {
154 assert(m_surface);
155 assert(rc.x >= 0);
156 assert(rc.y >= 0);
157
158 const uint32_t color = clr.map(format());
159
160 const Point bl = rc.bottom_right() - Point(1, 1);
161
162 for (int32_t x = rc.x + 1; x < bl.x; ++x) {
163 set_pixel(x, rc.y, color);
164 set_pixel(x, bl.y, color);
165 }
166 for (int32_t y = rc.y; y <= bl.y; ++y) {
167 set_pixel(rc.x, y, color);
168 set_pixel(bl.x, y, color);
169 }
170}
171
172
173/*
174===============
175Draws a filled rectangle
176===============
177*/
178void SDLSurface::fill_rect(const Rect& rc, const RGBAColor& clr) {
179 assert(m_surface);
180 assert(rc.x >= 0);
181 assert(rc.y >= 0);
182
183 const uint32_t color = clr.map(format());
184
185 SDL_Rect r = {
186 static_cast<int16_t>(rc.x), static_cast<int16_t>(rc.y),
187 static_cast<uint16_t>(rc.w), static_cast<uint16_t>(rc.h)
188 };
189 SDL_FillRect(m_surface, &r, color);
190}
191
192
193/*
194===============
195Change the brightness of the given rectangle
196This function is slow as hell.
197
198* This function is a possible point to optimize on
199 slow system. It takes a lot of cpu time atm and is
200 not needed. It is used by the ui_basic stuff to
201 highlight things.
202===============
203*/
204void SDLSurface::brighten_rect(const Rect& rc, const int32_t factor) {
205 if (!factor)
206 return;
207 assert(rc.x >= 0);
208 assert(rc.y >= 0);
209 assert(rc.w >= 1);
210 assert(rc.h >= 1);
211
212 const Point bl = rc.bottom_right();
213
214 lock(Surface::Lock_Normal);
215
216 if (m_surface->format->BytesPerPixel == 4)
217 {
218 for (int32_t y = rc.y; y < bl.y; ++y)
219 for (int32_t x = rc.x; x < bl.x; ++x)
220 {
221
222 uint8_t * const pix =
223 static_cast<uint8_t *>(m_surface->pixels) +
224 (y + m_offsy) * m_surface->pitch + (x + m_offsx) * 4;
225
226 uint32_t const clr = *reinterpret_cast<const uint32_t *>(pix);
227 uint8_t gr, gg, gb;
228 SDL_GetRGB(clr, m_surface->format, &gr, &gg, &gb);
229 int16_t r = gr + factor;
230 int16_t g = gg + factor;
231 int16_t b = gb + factor;
232
233 if (b & 0xFF00)
234 b = ~b >> 24;
235 if (g & 0xFF00)
236 g = ~g >> 24;
237 if (r & 0xFF00)
238 r = ~r >> 24;
239
240 *reinterpret_cast<uint32_t *>(pix) =
241 SDL_MapRGB(m_surface->format, r, g, b);
242 }
243 } else if (m_surface->format->BytesPerPixel == 2) {
244 for (int32_t y = rc.y; y < bl.y; ++y)
245 for (int32_t x = rc.x; x < bl.x; ++x)
246 {
247 uint8_t * const pix =
248 static_cast<uint8_t *>(m_surface->pixels) +
249 (y + m_offsy) * m_surface->pitch + (x + m_offsx) * 2;
250
251 uint32_t const clr = *reinterpret_cast<const uint16_t *>(pix);
252 uint8_t gr, gg, gb;
253 SDL_GetRGB(clr, m_surface->format, &gr, &gg, &gb);
254 int16_t r = gr + factor;
255 int16_t g = gg + factor;
256 int16_t b = gb + factor;
257
258 if (b & 0xFF00)
259 b = ~b >> 24;
260 if (g & 0xFF00)
261 g = ~g >> 24;
262 if (r & 0xFF00)
263 r = ~r >> 24;
264
265 *reinterpret_cast<uint16_t *>(pix) =
266 SDL_MapRGB(m_surface->format, r, g, b);
267 }
268 }
269 unlock(Surface::Unlock_Update);
270}
271
272/**
273* This functions draws a (not horizontal or vertical)
274* line in the target, using Bresenham's algorithm
275*
276* This function could be faster by using direct pixel
277* access instead of the set_pixel() function
278*/
279void SDLSurface::draw_line
280 (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth)
281{
282 int32_t dx = x2 - x1; /* the horizontal distance of the line */
283 int32_t dy = y2 - y1; /* the vertical distance of the line */
284 const uint32_t dxabs = abs(dx);
285 const uint32_t dyabs = abs(dy);
286 int32_t sdx = dx < 0 ? -1 : 1;
287 int32_t sdy = dy < 0 ? -1 : 1;
288 uint32_t x = dyabs / 2;
289 uint32_t y = dxabs / 2;
290 Point p(x1, y1);
291
292 set_pixel(p.x, p.y, color.map(format()));
293
294 if (dxabs >= dyabs) // the line is more horizontal than vertical
295 for (uint32_t i = 0; i < dxabs; ++i) {
296 y += dyabs;
297
298 if (y >= dxabs) {
299 y -= dxabs;
300 p.y += sdy;
301 }
302
303 p.x += sdx;
304 for (int32_t w = 0; w < gwidth; ++w) {
305 set_pixel(p.x, p.y + w, color.map(format()));
306 }
307 }
308 else // the line is more vertical than horizontal
309 for (uint32_t i = 0; i < dyabs; ++i) {
310 x += dxabs;
311
312 if (x >= dyabs) {
313 x -= dyabs;
314 p.x += sdx;
315 }
316
317 p.y += sdy;
318 for (int32_t w = 0; w < gwidth; ++w) {
319 set_pixel(p.x + w, p.y, color.map(format()));
320 }
321 }
322}
323
324
325void SDLSurface::blit
326 (const Point& dst, const Surface* src, const Rect& srcrc, Composite cm)
327{
328 SDL_Surface* sdlsurf = static_cast<const SDLSurface*>(src)->get_sdl_surface();
329 SDL_Rect srcrect = {
330 static_cast<int16_t>(srcrc.x), static_cast<int16_t>(srcrc.y),
331 static_cast<uint16_t>(srcrc.w), static_cast<uint16_t>(srcrc.h)
332 };
333 SDL_Rect dstrect = {
334 static_cast<int16_t>(dst.x), static_cast<int16_t>(dst.y),
335 0, 0
336 };
337
338 bool alpha = false;
339 uint8_t alphaval = 0;
340 if (cm == CM_Copy) {
341 SDL_BlendMode bm;
342 SDL_GetSurfaceBlendMode(sdlsurf, &bm);
343 alpha = bm & SDL_BLENDMODE_BLEND;
344 SDL_GetSurfaceAlphaMod(sdlsurf, &alphaval);
345 SDL_SetSurfaceAlphaMod(sdlsurf, 255);
346 SDL_SetSurfaceBlendMode(sdlsurf, SDL_BLENDMODE_NONE);
347 }
348
349 SDL_BlitSurface(sdlsurf, &srcrect, m_surface, &dstrect);
350
351 if (cm == CM_Copy) {
352 SDL_SetSurfaceAlphaMod(sdlsurf, alphaval);
353 SDL_SetSurfaceBlendMode(sdlsurf, alpha ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
354 }
355}
3560
=== removed file 'src/graphic/sdl/surface.h'
--- src/graphic/sdl/surface.h 2014-11-02 20:31:40 +0000
+++ src/graphic/sdl/surface.h 1970-01-01 00:00:00 +0000
@@ -1,77 +0,0 @@
1/*
2 * Copyright (C) 2010-2011 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_SDL_SURFACE_H
21#define WL_GRAPHIC_SDL_SURFACE_H
22
23#include <SDL_render.h>
24
25#include "base/rect.h"
26#include "graphic/color.h"
27#include "graphic/surface.h"
28
29/**
30* This implements SDL rendering. Do not use this class directly. The right
31* way is to use the base struct Surface wherever possible. Everything which
32* needs to know about the underlying renderer should go to the graphics
33* subdirectory.
34*/
35class SDLSurface : public Surface {
36public:
37 // The surface set by SetVideoMode must not be freed according to the SDL
38 // docs, so we need 'free_surface_on_delete'.
39 SDLSurface(SDL_Surface* surface, bool free_surface_on_delete = true);
40 virtual ~SDLSurface();
41
42 // Implements Image
43 uint16_t width() const override {return m_w;}
44 uint16_t height() const override {return m_h;}
45
46 // Implements Surface
47 void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm) override;
48 void fill_rect(const Rect&, const RGBAColor&) override;
49
50 // Implements Surface
51 void draw_rect(const Rect&, const RGBColor&) override;
52 virtual void draw_line
53 (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor&, uint8_t width) override;
54 void brighten_rect(const Rect&, int32_t factor) override;
55
56 const SDL_PixelFormat & format() const override;
57 void lock(LockMode) override;
58 void unlock(UnlockMode) override;
59 uint32_t get_pixel(uint16_t x, uint16_t y) override;
60 void set_pixel(uint16_t x, uint16_t y, uint32_t clr) override;
61 uint16_t get_pitch() const override {return m_surface->pitch;}
62 uint8_t * get_pixels() const override;
63
64 SDL_Surface * get_sdl_surface() const {return m_surface;}
65
66 void set_subwin(const Rect& r);
67 void unset_subwin();
68
69protected:
70 SDL_Surface * m_surface;
71 int32_t m_offsx;
72 int32_t m_offsy;
73 uint16_t m_w, m_h;
74 bool m_free_surface_on_delete;
75};
76
77#endif // end of include guard: WL_GRAPHIC_SDL_SURFACE_H
780
=== removed file 'src/graphic/sdl/terrain.cc'
--- src/graphic/sdl/terrain.cc 2014-09-27 18:53:55 +0000
+++ src/graphic/sdl/terrain.cc 1970-01-01 00:00:00 +0000
@@ -1,34 +0,0 @@
1/*
2 * Copyright (C) 2002-2004, 2006, 2009-2010 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#include "graphic/sdl/terrain.h"
21
22/// get lambda and mu so that
23/// lambda * u + mu * v = (1 0)^T with u = (u1 u2)^T and v = (v1 v2)^T
24void get_horiz_linearcomb
25 (int32_t const u1, int32_t const u2, int32_t const v1, int32_t const v2,
26 float & lambda, float & mu)
27{
28 float det;
29
30 det = u1 * v2 - u2 * v1; // determinant of (u v)
31
32 lambda = v2 / det; // by Cramer's rule
33 mu = -u2 / det;
34}
350
=== removed file 'src/graphic/sdl/terrain.h'
--- src/graphic/sdl/terrain.h 2014-09-27 18:53:55 +0000
+++ src/graphic/sdl/terrain.h 1970-01-01 00:00:00 +0000
@@ -1,668 +0,0 @@
1/*
2 * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_SDL_TERRAIN_H
21#define WL_GRAPHIC_SDL_TERRAIN_H
22
23#include <cassert>
24
25#include "base/log.h"
26#include "base/macros.h"
27#include "graphic/graphic.h"
28#include "graphic/sdl/surface.h"
29#include "graphic/sdl/vertex.h"
30#include "graphic/texture.h"
31#include "logic/roadtype.h"
32#include "random/random.h"
33#include "wui/mapviewpixelconstants.h"
34
35///Must be a power of two
36#define DITHER_WIDTH 4
37
38#define DITHER_RAND_MASK (DITHER_WIDTH * 2 - 1)
39#define DITHER_RAND_SHIFT (16 / DITHER_WIDTH)
40
41// TODO(unknown): Dangerous: casting, assumptions for sizeof(X), bitshifting
42#define FTOFIX(f) (static_cast<int32_t>((f) * 0x10000))
43#define ITOFIX(i) ((i)<<16)
44#define FIXTOI(f) ((f)>>16)
45
46void get_horiz_linearcomb
47 (int32_t u1, int32_t u2, int32_t v1, int32_t v2,
48 float & lambda, float & mu);
49
50
51struct LeftEdge {
52 /**
53 * Height of the edge.
54 *
55 * This is the number of pixels spanned by the edge in a vertical direction
56 */
57 uint32_t height;
58
59 // the following are all fixed point
60 int32_t x0;
61 int32_t tx0;
62 int32_t ty0;
63 int32_t b0;
64 int32_t dx;
65 int32_t dtx;
66 int32_t dty;
67 int32_t db;
68};
69
70struct RightEdge {
71 uint32_t height;
72
73 int32_t x0;
74 int32_t dx;
75};
76
77
78/**
79 * Render a polygon based on the given edge lists.
80 *
81 * The edge lists will be overwritten with undefined values.
82 */
83template<typename T> static void render_edge_lists
84 (SDLSurface & dst, const Texture & tex,
85 int32_t y, int32_t height,
86 LeftEdge * left, RightEdge * right,
87 int32_t dbdx, int32_t dtydx)
88{
89 if (-y >= height)
90 return; // completely above screen
91
92 uint8_t * texpixels;
93 T * texcolormap;
94
95 texpixels = tex.get_curpixels();
96 texcolormap = static_cast<T *>(tex.get_colormap());
97
98 // Skip lines that are above the screen
99 while (y < 0) {
100 int32_t skip = -y;
101 if (skip > static_cast<int32_t>(left->height))
102 skip = left->height;
103 if (skip > static_cast<int32_t>(right->height))
104 skip = right->height;
105
106 if (skip < static_cast<int32_t>(left->height)) {
107 left->x0 += skip * left->dx;
108 left->tx0 += skip * left->dtx;
109 left->ty0 += skip * left->dty;
110 left->b0 += skip * left->db;
111 left->height -= skip;
112 } else {
113 ++left;
114 }
115
116 if (skip < static_cast<int32_t>(right->height)) {
117 right->x0 += skip * right->dx;
118 right->height -= skip;
119 } else {
120 ++right;
121 }
122
123 height -= skip;
124 y += skip;
125 }
126
127 // Cut off lines below screen
128 if (y + height > static_cast<int32_t>(dst.height()))
129 height = dst.height() - y;
130
131 int32_t dstw = dst.width();
132 while (height > 0) {
133 int32_t leftx = FIXTOI(left->x0);
134 int32_t rightx = FIXTOI(right->x0);
135
136 if (leftx < 0)
137 leftx = 0;
138 if (rightx > dstw)
139 rightx = dstw;
140
141 if (leftx < rightx) {
142 int32_t tx = left->tx0;
143 int32_t ty = left->ty0;
144 int32_t b = left->b0;
145
146 int32_t adjust = ITOFIX(leftx) - left->x0;
147 tx += adjust; // note: dtx/dx = 1
148 ty += FIXTOI(static_cast<long long>(adjust) * dtydx);
149 b += FIXTOI(static_cast<long long>(adjust) * dbdx);
150
151 // Technically, we should clamp b at every pixel, but that's too
152 // expensive. The following seems to be enough to get rid of
153 // artifacts along the border between seen and unseen fields.
154 if (b < ITOFIX(-128))
155 b = ITOFIX(-128);
156
157 tx = FIXTOI(tx);
158
159 T * scanline =
160 reinterpret_cast<T *>
161 (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch())
162 +
163 leftx;
164
165 uint32_t count = rightx - leftx;
166 while (count--) {
167 *scanline++ =
168 texcolormap
169 [texpixels
170 [(tx & (TEXTURE_WIDTH - 1)) |
171 ((ty >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
172 |
173 ((b >> 8) & 0xFF00)];
174
175 b += dbdx;
176 ++tx;
177 ty += dtydx;
178 }
179 }
180
181 // Advance the line
182 ++y;
183 left->x0 += left->dx;
184 left->tx0 += left->dtx;
185 left->ty0 += left->dty;
186 left->b0 += left->db;
187 right->x0 += right->dx;
188
189 if (--left->height == 0)
190 ++left;
191 if (--right->height == 0)
192 ++right;
193 --height;
194 }
195}
196
197struct WLPolygon {
198 Point p[3];
199 uint8_t nrpoints;
200};
201
202
203/**
204 * Render a triangle into the given destination surface.
205 *
206 * \note It is assumed that p1, p2, p3 are sorted in counter-clockwise order.
207 *
208 * \note The rendering code assumes that d(tx)/d(x) = 1. This can be achieved
209 * by making sure that there is a 1:1 relation between x coordinates and
210 * texture x coordinates.
211 */
212template<typename T> static void render_triangle
213 (SDLSurface & dst,
214 const Vertex & p1, const Vertex & p2, const Vertex & p3,
215 const Texture & tex)
216{
217 if (p1.y == p2.y && p2.y == p3.y)
218 return; // degenerate triangle
219
220 // Clip the triangle
221 WLPolygon polygon;
222
223 polygon.p[0] = p1;
224 polygon.p[1] = p2;
225 polygon.p[2] = p3;
226 polygon.nrpoints = 3;
227
228 // Determine a top vertex
229 int32_t top = 0, topy = 0;
230
231 topy = 0x7fffffff;
232 for (uint8_t i = 0; i < polygon.nrpoints; ++i) {
233 if (polygon.p[i].y < topy) {
234 top = i;
235 topy = polygon.p[i].y;
236 }
237 }
238
239 // Calculate d(b) / d(x) etc. as fixed point variables.
240 // Remember that we assume d(tx) / d(x) == 1 and d(tx) / d(y) == 0.
241
242 // lA * (p2 - p1) + lB * (p3 - p1) = (1, 0)
243 // mA * (p2 - p1) + mB * (p3 - p1) = (0, 1)
244 int32_t const det =
245 (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);
246 int32_t const lA = ITOFIX(p3.y - p1.y) / det;
247 int32_t const lB = -ITOFIX(p2.y - p1.y) / det;
248 int32_t const mA = -ITOFIX(p3.x - p1.x) / det;
249 int32_t const mB = ITOFIX(p2.x - p1.x) / det;
250 int32_t const dbdx = lA * (p2.b - p1.b) + lB * (p3.b - p1.b);
251 int32_t const dbdy = mA * (p2.b - p1.b) + mB * (p3.b - p1.b);
252 int32_t const dtydx = lA * (p2.ty - p1.ty) + lB * (p3.ty - p1.ty);
253 int32_t const dtydy = mA * (p2.ty - p1.ty) + mB * (p3.ty - p1.ty);
254
255 // Build left edges
256 int32_t boty = topy;
257 LeftEdge leftedges[3];
258
259 {
260 uint8_t nrleftedges = 0;
261 uint8_t start = top;
262 uint8_t end = (top + 1) % polygon.nrpoints;
263 do {
264 if (polygon.p[end].y > polygon.p[start].y) {
265 boty = polygon.p[end].y;
266
267 LeftEdge & edge = leftedges[nrleftedges++];
268 assert(nrleftedges <= 3);
269
270 edge.height = polygon.p[end].y - polygon.p[start].y;
271 edge.x0 = ITOFIX(polygon.p[start].x);
272 edge.dx =
273 ITOFIX(polygon.p[end].x - polygon.p[start].x)
274 /
275 static_cast<int32_t>(edge.height);
276
277 int32_t startdx = polygon.p[start].x - p1.x;
278 int32_t startdy = polygon.p[start].y - p1.y;
279 int32_t dx = polygon.p[end].x - polygon.p[start].x;
280 int32_t dy = polygon.p[end].y - polygon.p[start].y;
281
282 edge.tx0 = ITOFIX(p1.tx + startdx);
283 edge.ty0 = ITOFIX(p1.ty) + startdx * dtydx + startdy * dtydy;
284 edge.b0 = ITOFIX(p1.b) + startdx * dbdx + startdy * dbdy;
285 edge.dtx = ITOFIX(dx) / static_cast<int32_t>(edge.height);
286 edge.dty =
287 (dx * dtydx + dy * dtydy) / static_cast<int32_t>(edge.height);
288 edge.db =
289 (dx * dbdx + dy * dbdy) / static_cast<int32_t>(edge.height);
290 }
291
292 start = end;
293 end = (start + 1) % polygon.nrpoints;
294 } while (polygon.p[end].y >= polygon.p[start].y);
295 }
296
297 // Build right edges
298 RightEdge rightedges[3];
299
300 {
301 uint8_t nrrightedges = 0;
302 uint8_t start = top;
303 uint8_t end = (polygon.nrpoints + top - 1) % polygon.nrpoints;
304 do {
305 if (polygon.p[end].y > polygon.p[start].y) {
306 RightEdge & edge = rightedges[nrrightedges++];
307 assert(nrrightedges <= 3);
308
309 edge.height = polygon.p[end].y - polygon.p[start].y;
310 edge.x0 = ITOFIX(polygon.p[start].x);
311 edge.dx =
312 ITOFIX(polygon.p[end].x - polygon.p[start].x)
313 /
314 static_cast<int32_t>(edge.height);
315 }
316
317 start = end;
318 end = (polygon.nrpoints + start - 1) % polygon.nrpoints;
319 } while (polygon.p[end].y >= polygon.p[start].y);
320 }
321
322 render_edge_lists<T>
323 (dst, tex, topy, boty - topy, leftedges, rightedges, dbdx, dtydx);
324}
325
326/**
327 * Blur the polygon edge between vertices start and end.
328 *
329 * It is dithered by randomly placing points taken from the texture of the
330 * adjacent polygon. The blend area is a few pixels wide, and the chance for
331 * replacing a pixel depends on the distance from the center line. Texture
332 * coordinates and brightness are interpolated across the center line (outer
333 * loop). To the sides these are approximated (inner loop): Brightness is kept
334 * constant, and the texture is mapped orthogonally to the center line. It is
335 * important that only those pixels are drawn whose texture actually changes in
336 * order to minimize artifacts.
337 *
338 * \note All this is preliminary and subject to change. For example, a special
339 * edge texture could be used instead of stochastically dithering. Road
340 * rendering could be handled as a special case then.
341*/
342template<typename T> static void dither_edge_horiz
343 (SDLSurface & dst,
344 const Vertex & start, const Vertex & end,
345 const Texture & ttex, const Texture & btex)
346{
347 uint8_t * tpixels, * bpixels;
348 T * tcolormap, * bcolormap;
349
350 tpixels = ttex.get_curpixels();
351 tcolormap = static_cast<T *>(ttex.get_colormap());
352 bpixels = btex.get_curpixels();
353 bcolormap = static_cast<T *>(btex.get_colormap());
354
355 int32_t tx, ty, b, dtx, dty, db, tx0, ty0;
356
357 tx = ITOFIX(start.tx);
358 ty = ITOFIX(start.ty);
359 b = ITOFIX(start.b);
360 dtx = (ITOFIX(end.tx) - tx) / (end.x - start.x + 1);
361 dty = (ITOFIX(end.ty) - ty) / (end.x - start.x + 1);
362 db = (ITOFIX(end.b) - b) / (end.x - start.x + 1);
363
364 // TODO(unknown): seed this depending on field coordinates
365 uint32_t rnd = 0;
366
367 const int32_t dstw = dst.width();
368 const int32_t dsth = dst.height();
369
370 int32_t ydiff = ITOFIX(end.y - start.y) / (end.x - start.x);
371 int32_t centery = ITOFIX(start.y);
372
373 for (int32_t x = start.x; x < end.x; x++, centery += ydiff) {
374 rnd = SIMPLE_RAND(rnd);
375
376 if (x >= 0 && x < dstw) {
377 int32_t y = FIXTOI(centery) - DITHER_WIDTH;
378
379 tx0 = tx - DITHER_WIDTH * dty;
380 ty0 = ty + DITHER_WIDTH * dtx;
381
382 uint32_t rnd0 = rnd;
383
384 // dither above the edge
385 for (uint32_t i = 0; i < DITHER_WIDTH; i++, y++) {
386 if ((rnd0 & DITHER_RAND_MASK) <= i && y >= 0 && y < dsth) {
387 T * const pix =
388 reinterpret_cast<T *>
389 (static_cast<uint8_t *>(dst.get_pixels())
390 +
391 y * dst.get_pitch())
392 +
393 x;
394 *pix =
395 tcolormap
396 [tpixels
397 [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
398 ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
399 |
400 ((b >> 8) & 0xFF00)];
401 }
402
403 tx0 += dty;
404 ty0 -= dtx;
405 rnd0 >>= DITHER_RAND_SHIFT;
406 }
407
408 // dither below the edge
409 for
410 (uint32_t i = 0;
411 i < DITHER_WIDTH;
412 ++i, ++y, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT)
413 if
414 ((rnd0 & DITHER_RAND_MASK) >= i + DITHER_WIDTH &&
415 y >= 0 && y < dsth)
416 reinterpret_cast<T *>
417 (static_cast<uint8_t *>(dst.get_pixels())
418 +
419 y * dst.get_pitch())
420 [x]
421 =
422 bcolormap
423 [bpixels
424 [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
425 ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
426 |
427 ((b >> 8) & 0xFF00)];
428 }
429
430 tx += dtx;
431 ty += dty;
432 b += db;
433 }
434}
435
436/**
437 * \see dither_edge_horiz
438 */
439template<typename T> static void dither_edge_vert
440 (SDLSurface & dst,
441 const Vertex & start, const Vertex & end,
442 const Texture & ltex, const Texture & rtex)
443{
444 uint8_t * lpixels, * rpixels;
445 T * lcolormap, * rcolormap;
446
447 lpixels = ltex.get_curpixels();
448 lcolormap = static_cast<T *>(ltex.get_colormap());
449 rpixels = rtex.get_curpixels();
450 rcolormap = static_cast<T *>(rtex.get_colormap());
451
452 int32_t tx, ty, b, dtx, dty, db, tx0, ty0;
453
454 tx = ITOFIX(start.tx);
455 ty = ITOFIX(start.ty);
456 b = ITOFIX(start.b);
457 dtx = (ITOFIX(end.tx) - tx) / (end.y - start.y + 1);
458 dty = (ITOFIX(end.ty) - ty) / (end.y - start.y + 1);
459 db = (ITOFIX(end.b) - b) / (end.y - start.y + 1);
460
461 // TODO(unknown): seed this depending on field coordinates
462 uint32_t rnd = 0;
463
464 const int32_t dstw = dst.width();
465 const int32_t dsth = dst.height();
466
467 int32_t xdiff = ITOFIX(end.x - start.x) / (end.y - start.y);
468 int32_t centerx = ITOFIX(start.x);
469
470 for (int32_t y = start.y; y < end.y; y++, centerx += xdiff) {
471 rnd = SIMPLE_RAND(rnd);
472
473 if (y >= 0 && y < dsth) {
474 int32_t x = FIXTOI(centerx) - DITHER_WIDTH;
475
476 tx0 = tx - DITHER_WIDTH * dty;
477 ty0 = ty + DITHER_WIDTH * dtx;
478
479 uint32_t rnd0 = rnd;
480
481 // dither on left side
482 for
483 (uint32_t i = 0;
484 i < DITHER_WIDTH;
485 ++i, ++x, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT)
486 if ((rnd0 & DITHER_RAND_MASK) <= i && x >= 0 && x < dstw)
487 reinterpret_cast<T *>
488 (static_cast<uint8_t *>(dst.get_pixels())
489 +
490 y * dst.get_pitch())
491 [x]
492 =
493 lcolormap
494 [lpixels
495 [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
496 ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
497 |
498 ((b >> 8) & 0xFF00)];
499
500 // dither on right side
501 for
502 (uint32_t i = 0;
503 i < DITHER_WIDTH;
504 ++i, ++x, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT)
505 if
506 ((rnd0 & DITHER_RAND_MASK) >= i + DITHER_WIDTH
507 &&
508 x >= 0 && x < dstw)
509 reinterpret_cast<T *>
510 (static_cast<uint8_t *>(dst.get_pixels())
511 +
512 y * dst.get_pitch())
513 [x]
514 =
515 rcolormap
516 [rpixels
517 [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
518 ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
519 |
520 ((b >> 8) & 0xFF00)];
521 }
522
523 tx += dtx;
524 ty += dty;
525 b += db;
526 }
527}
528
529template<typename T> static void render_road_horiz
530 (SDLSurface & dst, Point const start, Point const end, const SDLSurface & src)
531{
532 int32_t const dstw = dst.width();
533 int32_t const dsth = dst.height();
534
535 int32_t const ydiff = ((end.y - start.y) << 16) / (end.x - start.x);
536 int32_t centery = start.y << 16;
537
538 for (int32_t x = start.x, sx = 0; x < end.x; ++x, centery += ydiff, ++sx) {
539 if (x < 0 || x >= dstw)
540 continue;
541
542 for (int32_t i = 0, y = (centery >> 16) - 2; i < 5; ++i, ++y)
543 if (0 < y && y < dsth)
544 reinterpret_cast<T *>
545 (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch())
546 [x]
547 =
548 reinterpret_cast<T const *>
549 (static_cast<uint8_t const *>(src.get_pixels())
550 +
551 i * src.get_pitch())
552 [sx];
553 }
554}
555
556template<typename T> static void render_road_vert
557 (SDLSurface & dst, Point const start, Point const end, const SDLSurface & src)
558{
559 int32_t const dstw = dst.width();
560 int32_t const dsth = dst.height();
561
562 int32_t const xdiff = ((end.x - start.x) << 16) / (end.y - start.y);
563 int32_t centerx = start.x << 16;
564
565 for (int32_t y = start.y, sy = 0; y < end.y; ++y, centerx += xdiff, ++sy) {
566 if (y < 0 || y >= dsth)
567 continue;
568
569 for (int32_t i = 0, x = (centerx >> 16) - 2; i < 5; ++i, ++x)
570 if (0 < x && x < dstw)
571 reinterpret_cast<T *>
572 (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch())
573 [x]
574 =
575 reinterpret_cast<T const *>
576 (static_cast<uint8_t const *>(src.get_pixels())
577 +
578 sy * src.get_pitch())
579 [i];
580 }
581}
582
583template<typename T> static void draw_field_int
584 (SDLSurface & dst,
585 const Vertex & f_vert,
586 const Vertex & r_vert,
587 const Vertex & bl_vert,
588 const Vertex & br_vert,
589 uint8_t roads,
590 const Texture & tr_d_texture,
591 const Texture & l_r_texture,
592 const Texture & f_d_texture,
593 const Texture & f_r_texture)
594{
595 SDLSurface& rt_busy = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Busy));
596 SDLSurface& rt_normal = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Normal));
597
598 dst.lock(Surface::Lock_Normal);
599
600 render_triangle<T> (dst, f_vert, br_vert, r_vert, f_r_texture);
601 render_triangle<T> (dst, f_vert, bl_vert, br_vert, f_d_texture);
602
603 // Render roads and dither polygon edges
604 uint8_t road;
605
606 road = (roads >> Widelands::Road_East) & Widelands::Road_Mask;
607 if (-128 < f_vert.b || -128 < r_vert.b) {
608 if (road) {
609 switch (road) {
610 case Widelands::Road_Normal:
611 render_road_horiz<T> (dst, f_vert, r_vert, rt_normal);
612 break;
613 case Widelands::Road_Busy:
614 render_road_horiz<T> (dst, f_vert, r_vert, rt_busy);
615 break;
616 default:
617 assert(false);
618 break;
619 }
620 } else if (&f_r_texture != &tr_d_texture) {
621 dither_edge_horiz<T>(dst, f_vert, r_vert, f_r_texture, tr_d_texture);
622 }
623 }
624
625 road = (roads >> Widelands::Road_SouthEast) & Widelands::Road_Mask;
626 if (-128 < f_vert.b || -128 < br_vert.b) {
627 if (road) {
628 switch (road) {
629 case Widelands::Road_Normal:
630 render_road_vert<T> (dst, f_vert, br_vert, rt_normal);
631 break;
632 case Widelands::Road_Busy:
633 render_road_vert<T> (dst, f_vert, br_vert, rt_busy);
634 break;
635 default:
636 assert(false);
637 break;
638 }
639 } else if (&f_r_texture != &f_d_texture) {
640 dither_edge_vert<T>(dst, f_vert, br_vert, f_r_texture, f_d_texture);
641 }
642 }
643
644 road = (roads >> Widelands::Road_SouthWest) & Widelands::Road_Mask;
645 if (-128 < f_vert.b || -128 < bl_vert.b) {
646 if (road) {
647 switch (road) {
648 case Widelands::Road_Normal:
649 render_road_vert<T> (dst, f_vert, bl_vert, rt_normal);
650 break;
651 case Widelands::Road_Busy:
652 render_road_vert<T> (dst, f_vert, bl_vert, rt_busy);
653 break;
654 default:
655 assert(false);
656 break;
657 }
658 } else if (&l_r_texture != &f_d_texture) {
659 dither_edge_vert<T>(dst, f_vert, bl_vert, f_d_texture, l_r_texture);
660 }
661 }
662
663 dst.unlock(Surface::Unlock_Update);
664
665 // TODO(unknown): similar textures may not need dithering
666}
667
668#endif // end of include guard: WL_GRAPHIC_SDL_TERRAIN_H
6690
=== removed file 'src/graphic/sdl/utils.cc'
--- src/graphic/sdl/utils.cc 2014-11-08 15:47:38 +0000
+++ src/graphic/sdl/utils.cc 1970-01-01 00:00:00 +0000
@@ -1,30 +0,0 @@
1/*
2 * Copyright (C) 2006-2012 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#include "graphic/sdl/utils.h"
21
22#include <cassert>
23
24#include <SDL.h>
25
26SDL_Surface * empty_sdl_surface(int16_t w, int16_t h) {
27 SDL_Surface* const surface =
28 SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
29 return surface;
30}
310
=== removed file 'src/graphic/sdl/utils.h'
--- src/graphic/sdl/utils.h 2014-09-27 18:53:55 +0000
+++ src/graphic/sdl/utils.h 1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
1/*
2 * Copyright (C) 2006-2012 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_SDL_UTILS_H
21#define WL_GRAPHIC_SDL_UTILS_H
22
23#include <stdint.h>
24
25struct SDL_Surface;
26
27SDL_Surface * empty_sdl_surface(int16_t w, int16_t h);
28
29#endif // end of include guard: WL_GRAPHIC_SDL_UTILS_H
300
=== removed file 'src/graphic/sdl/vertex.h'
--- src/graphic/sdl/vertex.h 2014-09-27 18:53:55 +0000
+++ src/graphic/sdl/vertex.h 1970-01-01 00:00:00 +0000
@@ -1,39 +0,0 @@
1/*
2 * Copyright (C) 2002-2004, 2006-2007 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_SDL_VERTEX_H
21#define WL_GRAPHIC_SDL_VERTEX_H
22
23#include "base/point.h"
24
25/// Like a point but with an additional bright factor and texture coordinates.
26struct Vertex:public Point {
27 Vertex() : Point (0, 0), b(0), tx(0), ty(0) {}
28 Vertex
29 (const int32_t vx, const int32_t vy,
30 const int32_t vb,
31 const int32_t vtx, const int32_t vty)
32
33 : Point(vx, vy), b(vb), tx(vtx), ty(vty)
34 {}
35
36 int32_t b, tx, ty;
37};
38
39#endif // end of include guard: WL_GRAPHIC_SDL_VERTEX_H
400
=== added file 'src/graphic/sdl_utils.cc'
--- src/graphic/sdl_utils.cc 1970-01-01 00:00:00 +0000
+++ src/graphic/sdl_utils.cc 2014-11-23 12:03:00 +0000
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2006-2014 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#include "graphic/sdl_utils.h"
21
22#include <SDL.h>
23
24SDL_Surface* empty_sdl_surface(int16_t w, int16_t h) {
25 SDL_Surface* const surface =
26 SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
27 return surface;
28}
029
=== added file 'src/graphic/sdl_utils.h'
--- src/graphic/sdl_utils.h 1970-01-01 00:00:00 +0000
+++ src/graphic/sdl_utils.h 2014-11-23 12:03:00 +0000
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2006-2014 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_SDL_UTILS_H
21#define WL_GRAPHIC_SDL_UTILS_H
22
23#include <stdint.h>
24
25struct SDL_Surface;
26
27SDL_Surface * empty_sdl_surface(int16_t w, int16_t h);
28
29#endif // end of include guard:
030
=== modified file 'src/graphic/surface.cc'
--- src/graphic/surface.cc 2014-11-02 20:15:01 +0000
+++ src/graphic/surface.cc 2014-11-23 12:03:00 +0000
@@ -19,43 +19,175 @@
1919
20#include "graphic/surface.h"20#include "graphic/surface.h"
2121
22#include <cassert>
23#include <cmath>
24#include <cstdlib>
25
22#include <SDL.h>26#include <SDL.h>
2327
28#include "base/macros.h"
29#include "graphic/gl/blit_program.h"
30#include "graphic/gl/draw_line_program.h"
31#include "graphic/gl/draw_rect_program.h"
32#include "graphic/gl/fill_rect_program.h"
24#include "graphic/gl/surface_texture.h"33#include "graphic/gl/surface_texture.h"
25#include "graphic/sdl/surface.h"34#include "graphic/gl/utils.h"
26#include "graphic/sdl/utils.h"35#include "graphic/graphic.h"
2736
28extern bool g_opengl;
29
30namespace {
31
32bool s_is_diplay_format_defined = false;
33
34SDL_Surface* maybe_convert_to_diplay_format(SDL_Surface* surface) {
35 if (!s_is_diplay_format_defined) {
36 return surface;
37 }
38 SDL_Surface * converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
39 SDL_FreeSurface(surface);
40 return converted;
41}
42
43} // namespace
44
45void Surface::display_format_is_now_defined() {
46 s_is_diplay_format_defined = true;
47}
4837
49Surface* Surface::create(SDL_Surface* surf) {38Surface* Surface::create(SDL_Surface* surf) {
50 if (g_opengl) {39 return new GLSurfaceTexture(surf);
51 return new GLSurfaceTexture(surf);
52 }
53 return new SDLSurface(maybe_convert_to_diplay_format(surf));
54}40}
5541
56Surface* Surface::create(uint16_t w, uint16_t h) {42Surface* Surface::create(uint16_t w, uint16_t h) {
57 if (g_opengl) {43 return new GLSurfaceTexture(w, h);
58 return new GLSurfaceTexture(w, h);44}
59 }45
60 return new SDLSurface(empty_sdl_surface(w, h));46
47uint16_t Surface::width() const {
48 return m_w;
49}
50
51uint16_t Surface::height() const {
52 return m_h;
53}
54
55uint8_t * Surface::get_pixels() const
56{
57 return m_pixels.get();
58}
59
60uint32_t Surface::get_pixel(uint16_t x, uint16_t y) {
61 assert(m_pixels);
62 assert(x < m_w);
63 assert(y < m_h);
64
65 uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
66 return *(reinterpret_cast<uint32_t *>(data));
67}
68
69uint16_t Surface::get_pitch() const {
70 return 4 * m_w;
71}
72
73const SDL_PixelFormat & Surface::format() const {
74 return Gl::gl_rgba_format();
75}
76
77
78void Surface::set_pixel(uint16_t x, uint16_t y, uint32_t clr) {
79 assert(m_pixels);
80 assert(x < m_w);
81 assert(y < m_h);
82
83 uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
84 *(reinterpret_cast<uint32_t *>(data)) = clr;
85}
86
87FloatRect Surface::to_opengl(const Rect& rect, ConversionMode mode) {
88 const float delta = mode == ConversionMode::kExact ? 0. : 0.5;
89 float x1 = rect.x + delta;
90 float y1 = rect.y + delta;
91 pixel_to_gl(&x1, &y1);
92 float x2 = rect.x + rect.w - delta;
93 float y2 = rect.y + rect.h - delta;
94 pixel_to_gl(&x2, &y2);
95
96 return FloatRect(x1, y1, x2 - x1, y2 - y1);
97}
98
99void Surface::draw_rect(const Rect& rc, const RGBColor& clr)
100{
101 glViewport(0, 0, width(), height());
102 DrawRectProgram::instance().draw(to_opengl(rc, ConversionMode::kMidPoint), clr);
103}
104
105/**
106 * Draws a filled rectangle
107 */
108void Surface::fill_rect(const Rect& rc, const RGBAColor& clr) {
109 glViewport(0, 0, width(), height());
110
111 glBlendFunc(GL_ONE, GL_ZERO);
112
113 FillRectProgram::instance().draw(to_opengl(rc, ConversionMode::kExact), clr);
114
115 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
116}
117
118/**
119 * Change the brightness of the given rectangle
120 */
121void Surface::brighten_rect(const Rect& rc, const int32_t factor)
122{
123 if (!factor)
124 return;
125
126 glViewport(0, 0, width(), height());
127
128 // The simple trick here is to fill the rect, but using a different glBlendFunc that will sum
129 // src and target (or subtract them if factor is negative).
130 if (factor < 0) {
131 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
132 }
133
134 glBlendFunc(GL_ONE, GL_ONE);
135
136 const int delta = std::abs(factor);
137 FillRectProgram::instance().draw(
138 to_opengl(rc, ConversionMode::kExact), RGBAColor(delta, delta, delta, 0));
139
140 if (factor < 0) {
141 glBlendEquation(GL_FUNC_ADD);
142 }
143
144 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
145}
146
147void Surface::draw_line
148 (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth)
149{
150 glViewport(0, 0, width(), height());
151
152 float gl_x1 = x1 + 0.5;
153 float gl_y1 = y1 + 0.5;
154 pixel_to_gl(&gl_x1, &gl_y1);
155
156 float gl_x2 = x2 + 0.5;
157 float gl_y2 = y2 + 0.5;
158 pixel_to_gl(&gl_x2, &gl_y2);
159
160 DrawLineProgram::instance().draw(gl_x1, gl_y1, gl_x2, gl_y2, color, gwidth);
161}
162
163// Converts the pixel (x, y) in a texture to a gl coordinate in [0, 1].
164inline void pixel_to_gl_texture(const int width, const int height, float* x, float* y) {
165 *x = (*x / width);
166 *y = (*y / height);
167}
168
169void Surface::blit
170 (const Point& dst, const Surface* image, const Rect& srcrc, Composite cm)
171{
172 glViewport(0, 0, width(), height());
173
174 // Source Rectangle.
175 const GLSurfaceTexture* const texture = static_cast<const GLSurfaceTexture*>(image);
176 FloatRect gl_src_rect;
177 {
178 float x1 = srcrc.x;
179 float y1 = srcrc.y;
180 pixel_to_gl_texture(texture->width(), texture->height(), &x1, &y1);
181 float x2 = srcrc.x + srcrc.w;
182 float y2 = srcrc.y + srcrc.h;
183 pixel_to_gl_texture(texture->width(), texture->height(), &x2, &y2);
184 gl_src_rect.x = x1;
185 gl_src_rect.y = y1;
186 gl_src_rect.w = x2 - x1;
187 gl_src_rect.h = y2 - y1;
188 }
189
190 const FloatRect gl_dst_rect = to_opengl(Rect(dst.x, dst.y, srcrc.w, srcrc.h), ConversionMode::kExact);
191
192 BlitProgram::instance().draw(gl_dst_rect, gl_src_rect, texture->get_gl_texture(), cm);
61}193}
62194
=== modified file 'src/graphic/surface.h'
--- src/graphic/surface.h 2014-11-08 16:02:07 +0000
+++ src/graphic/surface.h 2014-11-23 12:03:00 +0000
@@ -20,6 +20,8 @@
20#ifndef WL_GRAPHIC_SURFACE_H20#ifndef WL_GRAPHIC_SURFACE_H
21#define WL_GRAPHIC_SURFACE_H21#define WL_GRAPHIC_SURFACE_H
2222
23#include <memory>
24
23#include "base/macros.h"25#include "base/macros.h"
24#include "base/rect.h"26#include "base/rect.h"
25#include "graphic/color.h"27#include "graphic/color.h"
@@ -31,13 +33,6 @@
31 */33 */
32class Surface {34class Surface {
33public:35public:
34 // Surfaces can either be converted to display format on creation or kept in
35 // the format they were created. The only reason not to convert to display
36 // format is when no display format is defined - trying will then crash the
37 // program. This is only the case when SDL_SetVideoMode() has never been
38 // called, so call this method after you called SDL_SetVideoMode.
39 static void display_format_is_now_defined();
40
41 // Create a new surface from an SDL_Surface. Ownership is taken.36 // Create a new surface from an SDL_Surface. Ownership is taken.
42 static Surface* create(SDL_Surface*);37 static Surface* create(SDL_Surface*);
4338
@@ -49,26 +44,26 @@
49 virtual ~Surface() {}44 virtual ~Surface() {}
5045
51 /// Dimensions.46 /// Dimensions.
52 virtual uint16_t width() const = 0;47 uint16_t width() const;
53 virtual uint16_t height() const = 0;48 uint16_t height() const;
5449
55 /// This draws a part of another surface to this surface50 /// This draws a part of another surface to this surface
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);
5752
58 /// Draws a filled rect to the surface. No blending takes place, the values53 /// Draws a filled rect to the surface. No blending takes place, the values
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).
60 virtual void fill_rect(const Rect&, const RGBAColor&) = 0;55 virtual void fill_rect(const Rect&, const RGBAColor&);
6156
62 /// Draws a rect (frame only) to the surface.57 /// Draws a rect (frame only) to the surface.
63 virtual void draw_rect(const Rect&, const RGBColor&) = 0;58 virtual void draw_rect(const Rect&, const RGBColor&);
6459
65 /// draw a line to the surface60 /// draw a line to the surface
66 virtual void draw_line61 virtual void draw_line
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);
6863
69 /// makes a rectangle on the surface brighter (or darker).64 /// makes a rectangle on the surface brighter (or darker).
70 /// @note this is slow in SDL mode. Use with care65 /// @note this is slow in SDL mode. Use with care
71 virtual void brighten_rect(const Rect&, int32_t factor) = 0;66 virtual void brighten_rect(const Rect&, int32_t factor);
7267
73 /// The functions below are for direct pixel access. This should be used68 /// The functions below are for direct pixel access. This should be used
74 /// only very sparingly as / it is potentially expensive (especially for69 /// only very sparingly as / it is potentially expensive (especially for
@@ -105,7 +100,21 @@
105 };100 };
106101
107 /// This returns the pixel format for direct pixel access.102 /// This returns the pixel format for direct pixel access.
108 virtual const SDL_PixelFormat & format() const = 0;103 const SDL_PixelFormat & format() const;
104
105 /**
106 * \return Pitch of the raw pixel data, i.e. the number of bytes
107 * contained in each image row. This can be strictly larger than
108 * bytes per pixel times the width.
109 */
110 uint16_t get_pitch() const;
111
112 /**
113 * \return Pointer to the raw pixel data.
114 *
115 * \warning May only be called inside lock/unlock pairs.
116 */
117 uint8_t * get_pixels() const;
109118
110 /**119 /**
111 * Lock/Unlock pairs must guard any of the direct pixel access using the120 * Lock/Unlock pairs must guard any of the direct pixel access using the
@@ -113,29 +122,34 @@
113 *122 *
114 * \note Lock/Unlock pairs cannot be nested.123 * \note Lock/Unlock pairs cannot be nested.
115 */124 */
116 //@{
117 virtual void lock(LockMode) = 0;125 virtual void lock(LockMode) = 0;
118 virtual void unlock(UnlockMode) = 0;126 virtual void unlock(UnlockMode) = 0;
119 //@}127
120128 uint32_t get_pixel(uint16_t x, uint16_t y);
121 //@{129 void set_pixel(uint16_t x, uint16_t y, uint32_t clr);
122 virtual uint32_t get_pixel(uint16_t x, uint16_t y) = 0;130
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
124 //@}132 // need some flipping of axis, depending if you want to render
125133 // on the screen or not.
126 /**134 virtual void pixel_to_gl(float* x, float* y) const = 0;
127 * \return Pitch of the raw pixel data, i.e. the number of bytes135
128 * contained in each image row. This can be strictly larger than136protected:
129 * bytes per pixel times the width.137 // Convert the 'rect' in pixel space into opengl space.
130 */138 enum class ConversionMode {
131 virtual uint16_t get_pitch() const = 0;139 // Convert the rect as given.
132140 kExact,
133 /**141
134 * \return Pointer to the raw pixel data.142 // Convert the rect so that the borders are in the center
135 *143 // of the pixels.
136 * \warning May only be called inside lock/unlock pairs.144 kMidPoint,
137 */145 };
138 virtual uint8_t * get_pixels() const = 0;146 FloatRect to_opengl(const Rect& rect, ConversionMode mode);
147
148 /// Logical width and height of the surface
149 uint16_t m_w, m_h;
150
151 /// Pixel data, while the texture is locked
152 std::unique_ptr<uint8_t[]> m_pixels;
139153
140private:154private:
141 DISALLOW_COPY_AND_ASSIGN(Surface);155 DISALLOW_COPY_AND_ASSIGN(Surface);
142156
=== modified file 'src/graphic/text/CMakeLists.txt'
--- src/graphic/text/CMakeLists.txt 2014-10-13 15:04:50 +0000
+++ src/graphic/text/CMakeLists.txt 2014-11-23 12:03:00 +0000
@@ -18,6 +18,7 @@
18 USES_SDL2_TTF18 USES_SDL2_TTF
19 USES_SDL2_GFX19 USES_SDL2_GFX
20 DEPENDS20 DEPENDS
21 graphic_sdl_utils
21 base_exceptions22 base_exceptions
22 base_geometry23 base_geometry
23 graphic_color24 graphic_color
2425
=== modified file 'src/graphic/text/sdl_ttf_font.cc'
--- src/graphic/text/sdl_ttf_font.cc 2014-11-02 20:15:01 +0000
+++ src/graphic/text/sdl_ttf_font.cc 2014-11-23 12:03:00 +0000
@@ -23,7 +23,7 @@
23#include <SDL_ttf.h>23#include <SDL_ttf.h>
24#include <boost/format.hpp>24#include <boost/format.hpp>
2525
26#include "graphic/sdl/utils.h"26#include "graphic/sdl_utils.h"
27#include "graphic/surface.h"27#include "graphic/surface.h"
28#include "graphic/surface_cache.h"28#include "graphic/surface_cache.h"
29#include "graphic/text/rt_errors.h"29#include "graphic/text/rt_errors.h"
3030
=== modified file 'src/graphic/text/test/CMakeLists.txt'
--- src/graphic/text/test/CMakeLists.txt 2014-07-17 14:34:32 +0000
+++ src/graphic/text/test/CMakeLists.txt 2014-11-23 12:03:00 +0000
@@ -7,6 +7,7 @@
7 render_richtext.cc7 render_richtext.cc
8 DEPENDS8 DEPENDS
9 base_log9 base_log
10 graphic
10 graphic_image_io11 graphic_image_io
11 graphic_surface12 graphic_surface
12 graphic_text13 graphic_text
1314
=== modified file 'src/graphic/text/test/render_richtext.cc'
--- src/graphic/text/test/render_richtext.cc 2014-10-11 13:26:59 +0000
+++ src/graphic/text/test/render_richtext.cc 2014-11-23 12:03:00 +0000
@@ -30,11 +30,14 @@
30#undef main // No, we do not want SDL_main30#undef main // No, we do not want SDL_main
3131
32#include "base/log.h"32#include "base/log.h"
33#include "config.h"
34#include "graphic/graphic.h"
33#include "graphic/image_io.h"35#include "graphic/image_io.h"
34#include "graphic/sdl/surface.h"36#include "graphic/surface.h"
35#include "graphic/text/rt_errors.h"37#include "graphic/text/rt_errors.h"
36#include "graphic/text/test/render.h"38#include "graphic/text/test/render.h"
37#include "io/filesystem/filesystem.h"39#include "io/filesystem/filesystem.h"
40#include "io/filesystem/layered_filesystem.h"
38#include "io/streamwrite.h"41#include "io/streamwrite.h"
3942
40namespace {43namespace {
@@ -88,6 +91,17 @@
88 return 0;91 return 0;
89}92}
9093
94// Setup the static objects Widelands needs to operate and initializes systems.
95void initialize() {
96 SDL_Init(SDL_INIT_VIDEO);
97
98 g_fs = new LayeredFileSystem();
99 g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR));
100
101 g_gr = new Graphic();
102 g_gr->initialize(1, 1, false);
103}
104
91} // namespace105} // namespace
92106
93int main(int argc, char** argv) {107int main(int argc, char** argv) {
@@ -117,19 +131,19 @@
117 return 1;131 return 1;
118 }132 }
119133
134 initialize();
135
120 StandaloneRenderer standalone_renderer;136 StandaloneRenderer standalone_renderer;
121137
122 try {138 try {
123 std::unique_ptr<SDLSurface> surf(139 std::unique_ptr<Surface> surf(standalone_renderer.renderer()->render(txt, w, allowed_tags));
124 static_cast<SDLSurface*>(standalone_renderer.renderer()->render(txt, w, allowed_tags)));
125140
126 std::unique_ptr<FileSystem> fs(&FileSystem::create("."));141 std::unique_ptr<FileSystem> fs(&FileSystem::create("."));
127 std::unique_ptr<StreamWrite> sw(fs->open_stream_write(outname));142 std::unique_ptr<StreamWrite> sw(fs->open_stream_write(outname));
128 if (!save_surface_to_png(surf.get(), sw.get())) {143 if (!save_surface_to_png(surf.get(), sw.get())) {
129 std::cout << "Could not encode PNG." << std::endl;144 std::cout << "Could not encode PNG." << std::endl;
130 }145 }
131 }146 } catch (RT::Exception& e) {
132 catch (RT::Exception& e) {
133 std::cout << e.what() << std::endl;147 std::cout << e.what() << std::endl;
134 }148 }
135149
136150
=== modified file 'src/graphic/texture.cc'
--- src/graphic/texture.cc 2014-09-20 09:37:47 +0000
+++ src/graphic/texture.cc 2014-11-23 12:03:00 +0000
@@ -28,8 +28,6 @@
28#include "io/fileread.h"28#include "io/fileread.h"
29#include "io/filesystem/layered_filesystem.h"29#include "io/filesystem/layered_filesystem.h"
3030
31extern bool g_opengl;
32
33using namespace std;31using namespace std;
3432
35/**33/**
@@ -37,15 +35,8 @@
37 * Currently it converts a 16 bit image to a 8 bit texture. This should35 * Currently it converts a 16 bit image to a 8 bit texture. This should
38 * be changed to load a 8 bit file directly, however.36 * be changed to load a 8 bit file directly, however.
39 */37 */
40Texture::Texture(const std::vector<std::string>& texture_files,38Texture::Texture(const std::vector<std::string>& texture_files, const uint32_t frametime)
41 const uint32_t frametime,39 : m_frame_num(0), m_frametime(frametime) {
42 const SDL_PixelFormat& format)
43 : m_colormap(nullptr),
44 m_pixels(nullptr),
45 m_curframe(nullptr),
46 m_frame_num(0),
47 m_nrframes(0),
48 m_frametime(frametime) {
49 if (texture_files.empty()) {40 if (texture_files.empty()) {
50 throw wexception("No images for texture.");41 throw wexception("No images for texture.");
51 }42 }
@@ -58,7 +49,8 @@
58 m_texture_image = fname;49 m_texture_image = fname;
59 SDL_Surface* surf = load_image_as_sdl_surface(fname, g_fs);50 SDL_Surface* surf = load_image_as_sdl_surface(fname, g_fs);
60 if (!surf) {51 if (!surf) {
61 throw wexception("WARNING: Failed to load texture frame %s: %s\n", fname.c_str(), IMG_GetError());52 throw wexception(
53 "WARNING: Failed to load texture frame %s: %s\n", fname.c_str(), IMG_GetError());
62 }54 }
63 if (surf->w != TEXTURE_WIDTH || surf->h != TEXTURE_HEIGHT) {55 if (surf->w != TEXTURE_WIDTH || surf->h != TEXTURE_HEIGHT) {
64 SDL_FreeSurface(surf);56 SDL_FreeSurface(surf);
@@ -69,7 +61,7 @@
69 }61 }
7062
71 // calculate shades on the first frame63 // calculate shades on the first frame
72 if (!m_nrframes) {64 if (m_gl_textures.empty()) {
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];
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];
75 for (int i = -128; i < 128; i++) {67 for (int i = -128; i < 128; i++) {
@@ -80,73 +72,13 @@
80 m_minimap_colors[shade] = RGBColor(r, g, b);72 m_minimap_colors[shade] = RGBColor(r, g, b);
81 }73 }
82 }74 }
8375 m_gl_textures.emplace_back(new GLSurfaceTexture(surf));
84 if (g_opengl) {
85 // Note: we except the constructor to free the SDL surface
86 GLSurfaceTexture* surface = new GLSurfaceTexture(surf);
87 m_glFrames.emplace_back(surface);
88
89 ++m_nrframes;
90 continue;
91 }
92
93 // Determine color map if it's the first frame
94 if (!m_nrframes) {
95 if (surf->format->BitsPerPixel != 8) {
96 throw wexception("Terrain %s is not 8 bits per pixel.", fname.c_str());
97 }
98 m_colormap.reset(new Colormap(*surf->format->palette->colors, format));
99 }
100
101 // Convert to our palette
102 SDL_Palette palette;
103 SDL_PixelFormat fmt;
104
105 palette.ncolors = 256;
106 palette.colors = m_colormap->get_palette();
107
108 memset(&fmt, 0, sizeof(fmt));
109 fmt.BitsPerPixel = 8;
110 fmt.BytesPerPixel = 1;
111 fmt.palette = &palette;
112
113 SDL_Surface * const cv = SDL_ConvertSurface(surf, &fmt, 0);
114
115 // Add the frame
116 uint8_t* new_ptr =
117 static_cast<uint8_t *>
118 (realloc
119 (m_pixels, TEXTURE_WIDTH * TEXTURE_HEIGHT * (m_nrframes + 1)));
120 if (!new_ptr)
121 throw wexception("Out of memory.");
122 m_pixels = new_ptr;
123
124
125 m_curframe = &m_pixels[TEXTURE_WIDTH * TEXTURE_HEIGHT * m_nrframes];
126 ++m_nrframes;
127
128 SDL_LockSurface(cv);
129
130 for (int32_t y = 0; y < TEXTURE_HEIGHT; ++y)
131 memcpy
132 (m_curframe + y * TEXTURE_WIDTH,
133 static_cast<uint8_t *>(cv->pixels) + y * cv->pitch,
134 TEXTURE_WIDTH);
135 SDL_UnlockSurface(cv);
136 SDL_FreeSurface(cv);
137 SDL_FreeSurface(surf);
138 }76 }
13977
140 if (!m_nrframes)78 if (m_gl_textures.empty())
141 throw wexception("Texture has no frames");79 throw wexception("Texture has no frames");
142}80}
14381
144
145Texture::~Texture ()
146{
147 free(m_pixels);
148}
149
150/**82/**
151 * Return the basic terrain colour to be used in the minimap.83 * Return the basic terrain colour to be used in the minimap.
152*/84*/
@@ -159,8 +91,5 @@
159 */91 */
160void Texture::animate(uint32_t time)92void Texture::animate(uint32_t time)
161{93{
162 m_frame_num = (time / m_frametime) % m_nrframes;94 m_frame_num = (time / m_frametime) % m_gl_textures.size();
163 if (g_opengl)
164 return;
165 m_curframe = &m_pixels[TEXTURE_WIDTH * TEXTURE_HEIGHT * m_frame_num];
166}95}
16796
=== modified file 'src/graphic/texture.h'
--- src/graphic/texture.h 2014-10-11 13:26:59 +0000
+++ src/graphic/texture.h 2014-11-23 12:03:00 +0000
@@ -45,33 +45,25 @@
45* changed to load 8 bit bitmaps directly.45* changed to load 8 bit bitmaps directly.
46*/46*/
47struct Texture {47struct Texture {
48 Texture(const std::vector<std::string>& texture_files,48 Texture(const std::vector<std::string>& texture_files, uint32_t frametime);
49 uint32_t frametime,49
50 const SDL_PixelFormat&);50 const std::string& get_texture_image() const {
51 ~Texture();51 return m_texture_image;
5252 }
53 const std::string & get_texture_image() const {return m_texture_image;}53 uint32_t get_texture() const {
5454 return m_gl_textures.at(m_frame_num)->get_gl_texture();
55 uint8_t * get_pixels () const {return m_pixels;}55 }
56 uint8_t * get_curpixels() const {return m_curframe;}
57 void * get_colormap () const {return m_colormap->get_colormap();}
5856
59 RGBColor get_minimap_color(int8_t shade);57 RGBColor get_minimap_color(int8_t shade);
6058
61 void animate(uint32_t time);59 void animate(uint32_t time);
62 uint32_t get_texture() const
63 {return m_glFrames.at(m_frame_num)->get_gl_texture();}
6460
65private:61private:
66 std::unique_ptr<Colormap> m_colormap;
67 uint8_t * m_pixels;
68 RGBColor m_minimap_colors[256];62 RGBColor m_minimap_colors[256];
69 uint8_t * m_curframe;
70 int32_t m_frame_num;63 int32_t m_frame_num;
71 std::string m_texture_image;64 std::string m_texture_image;
72 uint32_t m_nrframes;
73 uint32_t m_frametime;65 uint32_t m_frametime;
74 std::vector<std::unique_ptr<GLSurfaceTexture>> m_glFrames;66 std::vector<std::unique_ptr<GLSurfaceTexture>> m_gl_textures;
75};67};
7668
77#endif // end of include guard: WL_GRAPHIC_TEXTURE_H69#endif // end of include guard: WL_GRAPHIC_TEXTURE_H
7870
=== modified file 'src/logic/map_info.cc'
--- src/logic/map_info.cc 2014-11-12 20:12:48 +0000
+++ src/logic/map_info.cc 2014-11-23 12:03:00 +0000
@@ -43,19 +43,14 @@
43namespace {43namespace {
4444
45// Setup the static objects Widelands needs to operate and initializes systems.45// Setup the static objects Widelands needs to operate and initializes systems.
46void initialize(bool use_opengl) {46void initialize() {
47 SDL_Init(SDL_INIT_VIDEO);47 SDL_Init(SDL_INIT_VIDEO);
4848
49 g_fs = new LayeredFileSystem();49 g_fs = new LayeredFileSystem();
50 g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR));50 g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR));
5151
52#ifdef HAS_GETENV
53 char dummy_video_env[] = "SDL_VIDEODRIVER=dummy";
54 putenv(dummy_video_env);
55#endif
56
57 g_gr = new Graphic();52 g_gr = new Graphic();
58 g_gr->initialize(1, 1, false, use_opengl);53 g_gr->initialize(1, 1, false);
59}54}
6055
61} // namespace56} // namespace
@@ -63,21 +58,14 @@
63int main(int argc, char ** argv)58int main(int argc, char ** argv)
64{59{
65 if (!(2 <= argc && argc <= 3)) {60 if (!(2 <= argc && argc <= 3)) {
66 log("Usage: %s [--opengl] <map file>\n", argv[0]);61 log("Usage: %s <map file>\n", argv[0]);
67 return 1;62 return 1;
68 }63 }
6964
70 bool use_opengl = false;
71 for (int i = 0; i < argc; ++i) {
72 if (std::string(argv[i]) == "--opengl") {
73 use_opengl = true;
74 }
75 }
76
77 const std::string map_path = argv[argc - 1];65 const std::string map_path = argv[argc - 1];
7866
79 try {67 try {
80 initialize(use_opengl);68 initialize();
8169
82 std::string map_dir = FileSystem::fs_dirname(map_path);70 std::string map_dir = FileSystem::fs_dirname(map_path);
83 if (map_dir.empty()) {71 if (map_dir.empty()) {
8472
=== modified file 'src/ui_fsmenu/options.cc'
--- src/ui_fsmenu/options.cc 2014-11-22 22:11:36 +0000
+++ src/ui_fsmenu/options.cc 2014-11-23 12:03:00 +0000
@@ -555,14 +555,6 @@
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,
556 _("Remove Syncstream dumps on startup"), UI::Align_VCenter),556 _("Remove Syncstream dumps on startup"), UI::Align_VCenter),
557557
558 m_opengl (this, Point(m_hmargin,
559 m_label_remove_syncstreams.get_y() +
560 m_label_remove_syncstreams.get_h() + m_padding)),
561 m_label_opengl
562 (this,
563 m_hmargin + m_opengl.get_w() + m_padding, m_opengl.get_y(),
564 get_w() - 2 * m_hmargin - m_opengl.get_w() - m_padding, 40,
565 _("OpenGL rendering"), UI::Align_VCenter),
566 os(opt)558 os(opt)
567{559{
568 for (UI::Button* temp_button : m_sb_dis_panel.get_buttons()) {560 for (UI::Button* temp_button : m_sb_dis_panel.get_buttons()) {
@@ -594,7 +586,6 @@
594 m_message_sound .set_state(opt.message_sound);586 m_message_sound .set_state(opt.message_sound);
595 m_nozip .set_state(opt.nozip);587 m_nozip .set_state(opt.nozip);
596 m_remove_syncstreams .set_state(opt.remove_syncstreams);588 m_remove_syncstreams .set_state(opt.remove_syncstreams);
597 m_opengl .set_state(opt.opengl);
598 m_transparent_chat .set_state(opt.transparent_chat);589 m_transparent_chat .set_state(opt.transparent_chat);
599590
600 // Fill the font list.591 // Fill the font list.
@@ -678,7 +669,6 @@
678 os.panel_snap_distance = m_sb_dis_panel.get_value();669 os.panel_snap_distance = m_sb_dis_panel.get_value();
679 os.border_snap_distance = m_sb_dis_border.get_value();670 os.border_snap_distance = m_sb_dis_border.get_value();
680 os.remove_syncstreams = m_remove_syncstreams.get_state();671 os.remove_syncstreams = m_remove_syncstreams.get_state();
681 os.opengl = m_opengl.get_state();
682 os.transparent_chat = m_transparent_chat.get_state();672 os.transparent_chat = m_transparent_chat.get_state();
683 return os;673 return os;
684}674}
@@ -734,7 +724,6 @@
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);
735 opt.remove_replays = m_opt_section.get_int("remove_replays", 0);725 opt.remove_replays = m_opt_section.get_int("remove_replays", 0);
736 opt.remove_syncstreams = m_opt_section.get_bool("remove_syncstreams", true);726 opt.remove_syncstreams = m_opt_section.get_bool("remove_syncstreams", true);
737 opt.opengl = m_opt_section.get_bool("opengl", true);
738 opt.transparent_chat = m_opt_section.get_bool("transparent_chat", true);727 opt.transparent_chat = m_opt_section.get_bool("transparent_chat", true);
739 return opt;728 return opt;
740}729}
@@ -766,7 +755,6 @@
766755
767 m_opt_section.set_int("remove_replays", opt.remove_replays);756 m_opt_section.set_int("remove_replays", opt.remove_replays);
768 m_opt_section.set_bool("remove_syncstreams", opt.remove_syncstreams);757 m_opt_section.set_bool("remove_syncstreams", opt.remove_syncstreams);
769 m_opt_section.set_bool("opengl", opt.opengl);
770 m_opt_section.set_bool("transparent_chat", opt.transparent_chat);758 m_opt_section.set_bool("transparent_chat", opt.transparent_chat);
771759
772 WLApplication::get()->set_input_grab(opt.inputgrab);760 WLApplication::get()->set_input_grab(opt.inputgrab);
773761
=== modified file 'src/ui_fsmenu/options.h'
--- src/ui_fsmenu/options.h 2014-10-14 06:30:20 +0000
+++ src/ui_fsmenu/options.h 2014-11-23 12:03:00 +0000
@@ -54,7 +54,6 @@
54 uint32_t maxfps;54 uint32_t maxfps;
55 uint32_t remove_replays;55 uint32_t remove_replays;
56 bool remove_syncstreams;56 bool remove_syncstreams;
57 bool opengl;
58 bool transparent_chat;57 bool transparent_chat;
5958
60 // advanced options59 // advanced options
@@ -197,8 +196,6 @@
197 UI::MultilineTextarea m_label_nozip;196 UI::MultilineTextarea m_label_nozip;
198 UI::Checkbox m_remove_syncstreams;197 UI::Checkbox m_remove_syncstreams;
199 UI::MultilineTextarea m_label_remove_syncstreams;198 UI::MultilineTextarea m_label_remove_syncstreams;
200 UI::Checkbox m_opengl;
201 UI::MultilineTextarea m_label_opengl;
202199
203 OptionsCtrl::OptionsStruct os;200 OptionsCtrl::OptionsStruct os;
204};201};
205202
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2014-11-22 10:18:20 +0000
+++ src/wlapplication.cc 2014-11-23 12:03:00 +0000
@@ -676,7 +676,7 @@
676 * with the given resolution.676 * with the given resolution.
677 * Throws an exception on failure.677 * Throws an exception on failure.
678 */678 */
679void WLApplication::init_graphics(int32_t w, int32_t h, bool fullscreen, bool opengl)679void WLApplication::init_graphics(int32_t w, int32_t h, bool fullscreen)
680{680{
681 if (!w && !h) { // shutdown.681 if (!w && !h) { // shutdown.
682 delete g_gr;682 delete g_gr;
@@ -687,13 +687,10 @@
687687
688 if (!g_gr) {688 if (!g_gr) {
689 g_gr = new Graphic();689 g_gr = new Graphic();
690 g_gr->initialize(w, h, fullscreen, opengl);690 g_gr->initialize(w, h, fullscreen);
691 } else {691 } else {
692 if692 if (g_gr->get_xres() != w || g_gr->get_yres() != h || g_gr->is_fullscreen() != fullscreen) {
693 (g_gr->get_xres() != w || g_gr->get_yres() != h693 g_gr->initialize(w, h, fullscreen);
694 || g_gr->is_fullscreen() != fullscreen || g_opengl != opengl)
695 {
696 g_gr->initialize(w, h, fullscreen, opengl);
697 }694 }
698 }695 }
699}696}
@@ -703,11 +700,9 @@
703 Section & s = g_options.pull_section("global");700 Section & s = g_options.pull_section("global");
704701
705 // Switch to the new graphics system now, if necessary.702 // Switch to the new graphics system now, if necessary.
706 init_graphics703 init_graphics(s.get_int("xres", DEFAULT_RESOLUTION_W),
707 (s.get_int("xres", DEFAULT_RESOLUTION_W),704 s.get_int("yres", DEFAULT_RESOLUTION_H),
708 s.get_int("yres", DEFAULT_RESOLUTION_H),705 s.get_bool("fullscreen", false));
709 s.get_bool("fullscreen", false),
710 s.get_bool("opengl", true));
711 // does only work with a window706 // does only work with a window
712 set_input_grab(s.get_bool("inputgrab", false));707 set_input_grab(s.get_bool("inputgrab", false));
713}708}
@@ -732,7 +727,6 @@
732 // Profile needs support for a Syntax definition to solve this in a727 // Profile needs support for a Syntax definition to solve this in a
733 // sensible way728 // sensible way
734 s.get_bool("fullscreen");729 s.get_bool("fullscreen");
735 s.get_bool("opengl");
736 s.get_int("xres");730 s.get_int("xres");
737 s.get_int("yres");731 s.get_int("yres");
738 s.get_int("border_snap_distance");732 s.get_int("border_snap_distance");
@@ -851,7 +845,7 @@
851 "alive!"845 "alive!"
852 << std::endl;846 << std::endl;
853847
854 init_graphics(0, 0, false, false);848 init_graphics(0, 0, false);
855 SDL_QuitSubSystem(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);849 SDL_QuitSubSystem(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
856850
857#ifndef _WIN32851#ifndef _WIN32
858852
=== modified file 'src/wlapplication.h'
--- src/wlapplication.h 2014-11-22 10:18:20 +0000
+++ src/wlapplication.h 2014-11-23 12:03:00 +0000
@@ -164,7 +164,7 @@
164 void set_mouse_lock(const bool locked) {m_mouse_locked = locked;}164 void set_mouse_lock(const bool locked) {m_mouse_locked = locked;}
165 //@}165 //@}
166166
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);
168168
169 /**169 /**
170 * Refresh the graphics from the latest options.170 * Refresh the graphics from the latest options.
171171
=== modified file 'src/wlapplication_messages.cc'
--- src/wlapplication_messages.cc 2014-11-03 19:51:45 +0000
+++ src/wlapplication_messages.cc 2014-11-23 12:03:00 +0000
@@ -99,8 +99,7 @@
99 << _(" --yres=[...] Height of the window in pixel.") << endl99 << _(" --yres=[...] Height of the window in pixel.") << endl
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 */
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 */
102 << _(" --opengl=[true|false]\n"102 << endl
103 " Enables OpenGL rendering") << endl << endl
104 << _("Options for the internal window manager:") << endl103 << _("Options for the internal window manager:") << endl
105 << _(" --border_snap_distance=[0 ...]\n"104 << _(" --border_snap_distance=[0 ...]\n"
106 " Move a window to the edge of the screen\n"105 " Move a window to the edge of the screen\n"
107106
=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc 2014-11-13 08:25:45 +0000
+++ src/wui/mapview.cc 2014-11-23 12:03:00 +0000
@@ -23,7 +23,6 @@
23#include "graphic/gl/game_renderer.h"23#include "graphic/gl/game_renderer.h"
24#include "graphic/graphic.h"24#include "graphic/graphic.h"
25#include "graphic/rendertarget.h"25#include "graphic/rendertarget.h"
26#include "graphic/sdl/game_renderer.h"
27#include "logic/map.h"26#include "logic/map.h"
28#include "logic/player.h"27#include "logic/player.h"
29#include "wlapplication.h"28#include "wlapplication.h"
@@ -92,12 +91,7 @@
92 egbase.map().overlay_manager().load_graphics();91 egbase.map().overlay_manager().load_graphics();
9392
94 if (!m_renderer) {93 if (!m_renderer) {
95 if (g_opengl) {94 m_renderer.reset(new GlGameRenderer());
96 m_renderer.reset(new GlGameRenderer());
97 } else
98 {
99 m_renderer.reset(new SdlGameRenderer());
100 }
101 }95 }
102 if (upcast(InteractivePlayer const, interactive_player, &intbase())) {96 if (upcast(InteractivePlayer const, interactive_player, &intbase())) {
103 m_renderer->rendermap(dst, egbase, interactive_player->player(), m_viewpoint);97 m_renderer->rendermap(dst, egbase, interactive_player->player(), m_viewpoint);

Subscribers

People subscribed via source and target branches

to status/vote changes: