widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #03150
[Merge] lp:~widelands-dev/widelands/remove_software_rendering into lp:widelands
SirVer has proposed merging lp:~widelands-dev/widelands/remove_software_rendering into lp:widelands.
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.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/remove_software_rendering/+merge/242587
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/remove_software_rendering into lp:widelands.
=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt 2014-11-08 14:59:03 +0000
+++ src/graphic/CMakeLists.txt 2014-11-23 10:15:33 +0000
@@ -36,21 +36,22 @@
graphic_surface
)
+wl_library(graphic_sdl_utils
+ SRCS
+ sdl_utils.h
+ sdl_utils.cc
+ USES_SDL2
+)
+
wl_library(graphic_surface
SRCS
compositemode.h
- gl/surface.cc
- gl/surface.h
gl/surface_screen.cc
gl/surface_screen.h
gl/surface_texture.cc
gl/surface_texture.h
gl/utils.cc
gl/utils.h
- sdl/surface.cc
- sdl/surface.h
- sdl/utils.cc
- sdl/utils.h
surface.cc
surface.h
surface_cache.cc
@@ -58,12 +59,13 @@
USES_OPENGL
USES_SDL2
DEPENDS
- base_macros
base_exceptions
base_geometry
base_log
+ base_macros
graphic
graphic_color
+ graphic_sdl_utils
)
wl_library(graphic
@@ -114,11 +116,6 @@
rendertarget.h
richtext.cc
richtext.h
- sdl/game_renderer.cc
- sdl/game_renderer.h
- sdl/terrain.cc
- sdl/terrain.h
- sdl/vertex.h
text_parser.cc
text_parser.h
texture.cc
@@ -150,7 +147,6 @@
io_stream
logic
profile
- random
scripting
sound
ui_basic
=== 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 10:15:33 +0000
@@ -24,10 +24,10 @@
#include "graphic/gl/dither_program.h"
#include "graphic/gl/fields_to_draw.h"
#include "graphic/gl/road_program.h"
-#include "graphic/gl/surface.h"
#include "graphic/gl/terrain_program.h"
#include "graphic/graphic.h"
#include "graphic/rendertarget.h"
+#include "graphic/surface.h"
#include "graphic/texture.h"
#include "logic/editor_game_base.h"
#include "logic/player.h"
@@ -133,7 +133,7 @@
road_program_.reset(new RoadProgram());
}
- GLSurface* surface = dynamic_cast<GLSurface*>(m_dst->get_surface());
+ Surface* surface = m_dst->get_surface();
if (!surface)
return;
=== 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 10:15:33 +0000
@@ -87,7 +87,7 @@
u_busy_road_texture_ = glGetUniformLocation(gl_program_.object(), "u_busy_road_texture");
}
-void RoadProgram::add_road(const GLSurface& surface,
+void RoadProgram::add_road(const Surface& surface,
const FieldsToDraw::Field& start,
const FieldsToDraw::Field& end,
const Widelands::RoadType road_type) {
@@ -146,7 +146,7 @@
vertices_.emplace_back(p4);
}
-void RoadProgram::draw(const GLSurface& surface, const FieldsToDraw& fields_to_draw) {
+void RoadProgram::draw(const Surface& surface, const FieldsToDraw& fields_to_draw) {
vertices_.clear();
for (size_t current_index = 0; current_index < fields_to_draw.size(); ++current_index) {
=== 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 10:15:33 +0000
@@ -24,8 +24,8 @@
#include "base/macros.h"
#include "graphic/gl/fields_to_draw.h"
-#include "graphic/gl/surface.h"
#include "graphic/gl/utils.h"
+#include "graphic/surface.h"
#include "logic/roadtype.h"
class RoadProgram {
@@ -35,7 +35,7 @@
// Draws the roads. The 'surface' is needed to convert from pixel space to
// GL space.
- void draw(const GLSurface& surface, const FieldsToDraw& fields_to_draw);
+ void draw(const Surface& surface, const FieldsToDraw& fields_to_draw);
private:
struct PerVertexData {
@@ -55,7 +55,7 @@
// Adds a road from 'start' to 'end' to be rendered in this frame using the
// correct texture for 'road_type'.
- void add_road(const GLSurface& surface,
+ void add_road(const Surface& surface,
const FieldsToDraw::Field& start,
const FieldsToDraw::Field& end,
const Widelands::RoadType road_type);
=== 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 @@
-/*
- * Copyright (C) 2006-2012 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "graphic/gl/surface.h"
-
-#include <cassert>
-#include <cmath>
-#include <cstdlib>
-
-#include "base/macros.h"
-#include "graphic/gl/blit_program.h"
-#include "graphic/gl/draw_line_program.h"
-#include "graphic/gl/draw_rect_program.h"
-#include "graphic/gl/fill_rect_program.h"
-#include "graphic/gl/surface_texture.h"
-#include "graphic/graphic.h"
-
-uint16_t GLSurface::width() const {
- return m_w;
-}
-
-uint16_t GLSurface::height() const {
- return m_h;
-}
-
-uint8_t * GLSurface::get_pixels() const
-{
- return m_pixels.get();
-}
-
-uint32_t GLSurface::get_pixel(uint16_t x, uint16_t y) {
- assert(m_pixels);
- assert(x < m_w);
- assert(y < m_h);
-
- uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
- return *(reinterpret_cast<uint32_t *>(data));
-}
-
-void GLSurface::set_pixel(uint16_t x, uint16_t y, uint32_t clr) {
- assert(m_pixels);
- assert(x < m_w);
- assert(y < m_h);
-
- uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
- *(reinterpret_cast<uint32_t *>(data)) = clr;
-}
-
-FloatRect GLSurface::to_opengl(const Rect& rect, ConversionMode mode) {
- const float delta = mode == ConversionMode::kExact ? 0. : 0.5;
- float x1 = rect.x + delta;
- float y1 = rect.y + delta;
- pixel_to_gl(&x1, &y1);
- float x2 = rect.x + rect.w - delta;
- float y2 = rect.y + rect.h - delta;
- pixel_to_gl(&x2, &y2);
-
- return FloatRect(x1, y1, x2 - x1, y2 - y1);
-}
-
-void GLSurface::draw_rect(const Rect& rc, const RGBColor& clr)
-{
- glViewport(0, 0, width(), height());
- DrawRectProgram::instance().draw(to_opengl(rc, ConversionMode::kMidPoint), clr);
-}
-
-/**
- * Draws a filled rectangle
- */
-void GLSurface::fill_rect(const Rect& rc, const RGBAColor& clr) {
- glViewport(0, 0, width(), height());
-
- glBlendFunc(GL_ONE, GL_ZERO);
-
- FillRectProgram::instance().draw(to_opengl(rc, ConversionMode::kExact), clr);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-/**
- * Change the brightness of the given rectangle
- */
-void GLSurface::brighten_rect(const Rect& rc, const int32_t factor)
-{
- if (!factor)
- return;
-
- glViewport(0, 0, width(), height());
-
- // The simple trick here is to fill the rect, but using a different glBlendFunc that will sum
- // src and target (or subtract them if factor is negative).
- if (factor < 0) {
- glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
- }
-
- glBlendFunc(GL_ONE, GL_ONE);
-
- const int delta = std::abs(factor);
- FillRectProgram::instance().draw(
- to_opengl(rc, ConversionMode::kExact), RGBAColor(delta, delta, delta, 0));
-
- if (factor < 0) {
- glBlendEquation(GL_FUNC_ADD);
- }
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-void GLSurface::draw_line
- (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth)
-{
- glViewport(0, 0, width(), height());
-
- float gl_x1 = x1 + 0.5;
- float gl_y1 = y1 + 0.5;
- pixel_to_gl(&gl_x1, &gl_y1);
-
- float gl_x2 = x2 + 0.5;
- float gl_y2 = y2 + 0.5;
- pixel_to_gl(&gl_x2, &gl_y2);
-
- DrawLineProgram::instance().draw(gl_x1, gl_y1, gl_x2, gl_y2, color, gwidth);
-}
-
-// Converts the pixel (x, y) in a texture to a gl coordinate in [0, 1].
-inline void pixel_to_gl_texture(const int width, const int height, float* x, float* y) {
- *x = (*x / width);
- *y = (*y / height);
-}
-
-void GLSurface::blit
- (const Point& dst, const Surface* image, const Rect& srcrc, Composite cm)
-{
- glViewport(0, 0, width(), height());
-
- // Source Rectangle.
- const GLSurfaceTexture* const texture = static_cast<const GLSurfaceTexture*>(image);
- FloatRect gl_src_rect;
- {
- float x1 = srcrc.x;
- float y1 = srcrc.y;
- pixel_to_gl_texture(texture->width(), texture->height(), &x1, &y1);
- float x2 = srcrc.x + srcrc.w;
- float y2 = srcrc.y + srcrc.h;
- pixel_to_gl_texture(texture->width(), texture->height(), &x2, &y2);
- gl_src_rect.x = x1;
- gl_src_rect.y = y1;
- gl_src_rect.w = x2 - x1;
- gl_src_rect.h = y2 - y1;
- }
-
- const FloatRect gl_dst_rect = to_opengl(Rect(dst.x, dst.y, srcrc.w, srcrc.h), ConversionMode::kExact);
-
- BlitProgram::instance().draw(gl_dst_rect, gl_src_rect, texture->get_gl_texture(), cm);
-}
=== 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 @@
-/*
- * Copyright (C) 2006-2012 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef WL_GRAPHIC_GL_SURFACE_H
-#define WL_GRAPHIC_GL_SURFACE_H
-
-#include <memory>
-
-#include "graphic/gl/system_headers.h"
-#include "graphic/surface.h"
-
-class GLSurface : public Surface {
-public:
- virtual ~GLSurface() {}
-
- /// Interface implementations
- uint16_t width() const override;
- uint16_t height() const override;
- uint8_t * get_pixels() const override;
- void set_pixel(uint16_t x, uint16_t y, uint32_t clr) override;
- uint32_t get_pixel(uint16_t x, uint16_t y) override;
- void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm) override;
- void fill_rect(const Rect&, const RGBAColor&) override;
- void draw_rect(const Rect&, const RGBColor&) override;
- void brighten_rect(const Rect&, int32_t factor) override;
- virtual void draw_line
- (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor&, uint8_t width) override;
-
- // Converts the given pixel into an OpenGl point. This might need some
- // flipping of axis, depending if you want to render on the screen or not.
- virtual void pixel_to_gl(float* x, float* y) const = 0;
-
-protected:
- // Convert the 'rect' in pixel space into opengl space.
- enum class ConversionMode {
- // Convert the rect as given.
- kExact,
-
- // Convert the rect so that the borders are in the center
- // of the pixels.
- kMidPoint,
- };
- FloatRect to_opengl(const Rect& rect, ConversionMode mode);
-
- /// Logical width and height of the surface
- uint16_t m_w, m_h;
-
- /// Pixel data, while the texture is locked
- std::unique_ptr<uint8_t[]> m_pixels;
-};
-
-#endif // end of include guard: WL_GRAPHIC_GL_SURFACE_H
=== 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 10:15:33 +0000
@@ -52,10 +52,6 @@
}
}
-const SDL_PixelFormat & GLSurfaceScreen::format() const {
- return Gl::gl_rgba_format();
-}
-
void GLSurfaceScreen::lock(Surface::LockMode mode)
{
assert(!m_pixels);
@@ -85,7 +81,3 @@
m_pixels.reset(nullptr);
}
-
-uint16_t GLSurfaceScreen::get_pitch() const {
- return 4 * m_w;
-}
=== 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 10:15:33 +0000
@@ -19,12 +19,12 @@
#ifndef WL_GRAPHIC_GL_SURFACE_SCREEN_H
#define WL_GRAPHIC_GL_SURFACE_SCREEN_H
-#include "graphic/gl/surface.h"
+#include "graphic/surface.h"
/**
* This surface represents the screen in OpenGL mode.
*/
-class GLSurfaceScreen : public GLSurface {
+class GLSurfaceScreen : public Surface {
public:
GLSurfaceScreen(uint16_t w, uint16_t h);
virtual ~GLSurfaceScreen() {}
@@ -32,8 +32,6 @@
/// Interface implementations
void lock(LockMode) override;
void unlock(UnlockMode) override;
- uint16_t get_pitch() const override;
- const SDL_PixelFormat & format() const override;
private:
void pixel_to_gl(float* x, float* y) const override;
=== 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 10:15:33 +0000
@@ -24,10 +24,10 @@
#include "base/macros.h"
#include "base/wexception.h"
#include "graphic/gl/blit_program.h"
-#include "graphic/gl/surface.h"
#include "graphic/gl/utils.h"
#include "graphic/graphic.h"
-#include "graphic/sdl/utils.h"
+#include "graphic/sdl_utils.h"
+#include "graphic/surface.h"
namespace {
@@ -160,10 +160,6 @@
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
-const SDL_PixelFormat & GLSurfaceTexture::format() const {
- return Gl::gl_rgba_format();
-}
-
void GLSurfaceTexture::lock(LockMode mode) {
if (m_w <= 0 || m_h <= 0) {
return;
@@ -194,17 +190,13 @@
m_pixels.reset(nullptr);
}
-uint16_t GLSurfaceTexture::get_pitch() const {
- return 4 * m_w;
-}
-
void GLSurfaceTexture::draw_rect(const Rect& rectangle, const RGBColor& clr)
{
if (m_w <= 0 || m_h <= 0) {
return;
}
setup_gl(m_texture);
- GLSurface::draw_rect(rectangle, clr);
+ Surface::draw_rect(rectangle, clr);
reset_gl();
}
@@ -219,7 +211,7 @@
}
setup_gl(m_texture);
- GLSurface::fill_rect(rectangle, clr);
+ Surface::fill_rect(rectangle, clr);
reset_gl();
}
@@ -233,7 +225,7 @@
}
setup_gl(m_texture);
- GLSurface::brighten_rect(rectangle, factor);
+ Surface::brighten_rect(rectangle, factor);
reset_gl();
}
@@ -245,7 +237,7 @@
}
setup_gl(m_texture);
- GLSurface::draw_line(x1, y1, x2, y2, color, gwidth);
+ Surface::draw_line(x1, y1, x2, y2, color, gwidth);
reset_gl();
}
@@ -257,6 +249,6 @@
}
setup_gl(m_texture);
- GLSurface::blit(dst, src, srcrc, cm);
+ Surface::blit(dst, src, srcrc, cm);
reset_gl();
}
=== 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 10:15:33 +0000
@@ -19,11 +19,12 @@
#ifndef WL_GRAPHIC_GL_SURFACE_TEXTURE_H
#define WL_GRAPHIC_GL_SURFACE_TEXTURE_H
-#include "graphic/gl/surface.h"
+#include "graphic/gl/system_headers.h"
+#include "graphic/surface.h"
struct SDL_Surface;
-class GLSurfaceTexture : public GLSurface {
+class GLSurfaceTexture : public Surface {
public:
GLSurfaceTexture(SDL_Surface * surface, bool intensity = false);
GLSurfaceTexture(int w, int h);
@@ -34,13 +35,11 @@
//@{
void lock(LockMode) override;
void unlock(UnlockMode) override;
- uint16_t get_pitch() const override;
- const SDL_PixelFormat & format() const override;
// Note: the following functions are reimplemented here though they
- // basically only call the functions in GLSurface wrapped in calls to
+ // basically only call the functions in Surface wrapped in calls to
// setup_gl(), reset_gl(). The same functionality can be achieved by making
- // those two functions virtual and calling them in GLSurface. However,
+ // those two functions virtual and calling them in Surface. However,
// especially for blit which is called very often and mostly on the screen,
// this costs two virtual function calls which makes a notable difference in
// profiles.
=== modified file 'src/graphic/graphic.cc'
--- src/graphic/graphic.cc 2014-11-22 10:18:20 +0000
+++ src/graphic/graphic.cc 2014-11-23 10:15:33 +0000
@@ -40,7 +40,6 @@
#include "graphic/image_io.h"
#include "graphic/image_transformations.h"
#include "graphic/rendertarget.h"
-#include "graphic/sdl/surface.h"
#include "graphic/surface_cache.h"
#include "graphic/texture.h"
#include "io/fileread.h"
@@ -52,7 +51,6 @@
using namespace std;
Graphic * g_gr;
-bool g_opengl;
namespace {
@@ -91,115 +89,81 @@
ImageTransformations::initialize();
m_sdl_window = nullptr;
- m_sdl_screen = nullptr;
- m_sdl_renderer = nullptr;
- m_sdl_texture = nullptr;
m_glcontext = nullptr;
}
-void Graphic::initialize(int32_t w, int32_t h, bool fullscreen, bool opengl) {
+void Graphic::initialize(int32_t w, int32_t h, bool fullscreen) {
cleanup();
- // Set video mode using SDL. First collect the flags
- int32_t flags = 0;
- g_opengl = false;
-
- if (opengl) {
- log("Graphics: Trying opengl\n");
-
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- // Request an OpenGL 2 context.
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
-
- flags |= SDL_WINDOW_OPENGL;
- }
-
+ // Request an OpenGL 2 context with double buffering.
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
+
+ int32_t flags = SDL_WINDOW_OPENGL;
if (fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN;
log("Graphics: Trying FULLSCREEN\n");
}
log("Graphics: Try to set Videomode %ux%u\n", w, h);
- // Here we actually set the video mode
- m_sdl_window = SDL_CreateWindow("Widelands Window",
- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
-
+ m_sdl_window = SDL_CreateWindow(
+ "Widelands Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
if (!m_sdl_window) {
- log
- ("Graphics: Could not set videomode: %s, trying minimum graphics settings\n",
- SDL_GetError());
+ log("Graphics: Could not set Videomode: %s, trying minimum graphics settings\n",
+ SDL_GetError());
flags &= ~SDL_WINDOW_FULLSCREEN;
m_sdl_window = SDL_CreateWindow("Widelands Window",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
kFallbackGraphicsWidth, kFallbackGraphicsHeight, flags);
m_fallback_settings_in_effect = true;
if (!m_sdl_window) {
- throw wexception
- ("Graphics: could not set video mode: %s", SDL_GetError());
+ throw wexception("Graphics: could not set video mode: %s", SDL_GetError());
}
}
SDL_SetWindowTitle(m_sdl_window, ("Widelands " + build_id() + '(' + build_type() + ')').c_str());
-
- if (opengl) {
- m_glcontext = SDL_GL_CreateContext(m_sdl_window);
- if (m_glcontext) {
- SDL_GL_MakeCurrent(m_sdl_window, m_glcontext);
- }
-
- // We now really have a working opengl screen...
- g_opengl = true;
-
- // See graphic/gl/system_headers.h for an explanation of the
- // next line.
- glewExperimental = GL_TRUE;
- GLenum err = glewInit();
- if (err != GLEW_OK) {
- log("glewInit returns %i\nYour OpenGL installation must be __very__ broken. %s\n",
- err, glewGetErrorString(err));
- throw wexception("glewInit returns %i: Broken OpenGL installation.", err);
- }
-
- log("Graphics: OpenGL: Version \"%s\"\n",
- reinterpret_cast<const char*>(glGetString(GL_VERSION)));
-
- GLboolean glBool;
- glGetBooleanv(GL_DOUBLEBUFFER, &glBool);
- log("Graphics: OpenGL: Double buffering %s\n", (glBool == GL_TRUE) ? "enabled" : "disabled");
-
- GLint glInt;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glInt);
- log("Graphics: OpenGL: Max texture size: %u\n", glInt);
-
- SDL_GL_SetSwapInterval(1);
- SDL_GL_SwapWindow(m_sdl_window);
-
- glDrawBuffer(GL_BACK);
-
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- screen_.reset(new GLSurfaceScreen(w, h));
- } else {
- m_sdl_renderer = SDL_CreateRenderer(m_sdl_window, -1, 0);
- uint32_t rmask, gmask, bmask, amask;
- int bpp;
- SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB8888, &bpp, &rmask, &gmask, &bmask, &amask);
- m_sdl_screen = SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);
- m_sdl_texture = SDL_CreateTexture(m_sdl_renderer,
- SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
- w, h);
- screen_.reset(new SDLSurface(m_sdl_screen, false));
- }
-
set_icon(m_sdl_window);
+ m_glcontext = SDL_GL_CreateContext(m_sdl_window);
+ SDL_GL_MakeCurrent(m_sdl_window, m_glcontext);
+
+ // See graphic/gl/system_headers.h for an explanation of the
+ // next line.
+ glewExperimental = GL_TRUE;
+ GLenum err = glewInit();
+ if (err != GLEW_OK) {
+ log("glewInit returns %i\nYour OpenGL installation must be __very__ broken. %s\n",
+ err, glewGetErrorString(err));
+ throw wexception("glewInit returns %i: Broken OpenGL installation.", err);
+ }
+
+ log("Graphics: OpenGL: Version \"%s\"\n",
+ reinterpret_cast<const char*>(glGetString(GL_VERSION)));
+
+ GLboolean glBool;
+ glGetBooleanv(GL_DOUBLEBUFFER, &glBool);
+ log("Graphics: OpenGL: Double buffering %s\n", (glBool == GL_TRUE) ? "enabled" : "disabled");
+
+ GLint glInt;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glInt);
+ log("Graphics: OpenGL: Max texture size: %u\n", glInt);
+
+ SDL_GL_SetSwapInterval(1);
+
+ glDrawBuffer(GL_BACK);
+
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ SDL_GL_SwapWindow(m_sdl_window);
+
+ screen_.reset(new GLSurfaceScreen(w, h));
+
/* Information about the video capabilities. */
{
SDL_DisplayMode disp_mode;
@@ -216,8 +180,6 @@
assert(SDL_BYTESPERPIXEL(disp_mode.format) == 4);
}
- Surface::display_format_is_now_defined();
-
m_rendertarget.reset(new RenderTarget(screen_.get()));
pic_road_normal_.reset(load_image("world/pics/roadt_normal.png"));
@@ -236,14 +198,6 @@
if (UI::g_fh)
UI::g_fh->flush();
- if (m_sdl_texture) {
- SDL_DestroyTexture(m_sdl_texture);
- m_sdl_texture = nullptr;
- }
- if (m_sdl_screen) {
- SDL_FreeSurface(m_sdl_screen);
- m_sdl_screen = nullptr;
- }
if (m_sdl_window) {
SDL_DestroyWindow(m_sdl_window);
m_sdl_window = nullptr;
@@ -329,16 +283,7 @@
*/
void Graphic::refresh()
{
- if (g_opengl) {
- SDL_GL_SwapWindow(m_sdl_window);
- m_update = false;
- return;
- }
-
- SDL_UpdateTexture(m_sdl_texture, nullptr, m_sdl_screen->pixels, m_sdl_screen->pitch);
- SDL_RenderClear(m_sdl_renderer);
- SDL_RenderCopy(m_sdl_renderer, m_sdl_texture, nullptr, nullptr);
- SDL_RenderPresent(m_sdl_renderer);
+ SDL_GL_SwapWindow(m_sdl_window);
m_update = false;
}
@@ -355,11 +300,7 @@
uint32_t Graphic::new_maptexture(const std::vector<std::string>& texture_files, const uint32_t frametime)
{
- SDL_PixelFormat* pixel_fmt = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);
- m_maptextures.emplace_back(new Texture(texture_files, frametime, *pixel_fmt));
- if (pixel_fmt) {
- SDL_FreeFormat(pixel_fmt);
- }
+ m_maptextures.emplace_back(new Texture(texture_files, frametime));
return m_maptextures.size(); // ID 1 is at m_maptextures[0]
}
=== modified file 'src/graphic/graphic.h'
--- src/graphic/graphic.h 2014-11-13 06:45:36 +0000
+++ src/graphic/graphic.h 2014-11-23 10:15:33 +0000
@@ -35,7 +35,6 @@
class RenderTarget;
class Surface;
class SurfaceCache;
-struct SDL_Surface;
class StreamWrite;
struct Texture;
@@ -51,8 +50,7 @@
~Graphic();
// Initialize or reinitialize the graphics system. Throws on error.
- void initialize
- (int32_t w, int32_t h, bool fullscreen, bool opengl);
+ void initialize(int32_t w, int32_t h, bool fullscreen);
int32_t get_xres();
int32_t get_yres();
@@ -94,10 +92,7 @@
/// This saves a copy of the screen SDL_Surface. This is needed for
/// opengl rendering as the SurfaceOpenGL does not use it. It allows
/// manipulation the screen context.
- SDL_Surface * m_sdl_screen;
- SDL_Renderer * m_sdl_renderer;
SDL_Window * m_sdl_window;
- SDL_Texture * m_sdl_texture;
SDL_GLContext m_glcontext;
/// A RenderTarget for screen_. This is initialized during init()
std::unique_ptr<RenderTarget> m_rendertarget;
@@ -120,6 +115,5 @@
};
extern Graphic * g_gr;
-extern bool g_opengl;
#endif // end of include guard: WL_GRAPHIC_GRAPHIC_H
=== 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 10:15:33 +0000
@@ -28,7 +28,6 @@
#include "base/macros.h"
#include "graphic/color.h"
#include "graphic/graphic.h"
-#include "graphic/sdl/surface.h"
#include "graphic/surface.h"
#include "graphic/surface_cache.h"
@@ -87,15 +86,8 @@
Rect srcrect = Rect(Point(0, 0), src->width(), src->height());
// Second step: get source material
- SDL_Surface * srcsdl = nullptr;
+ SDL_Surface * srcsdl = extract_sdl_surface(*src, srcrect);
bool free_source = true;
- if (upcast(const SDLSurface, sdlsrcsurf, src)) {
- srcsdl = sdlsrcsurf->get_sdl_surface();
- free_source = false;
- } else {
- // This is in OpenGL
- srcsdl = extract_sdl_surface(*src, srcrect);
- }
// If we actually shrink a surface, ballpark the zoom so that the shrinking
// effect is weakened.
=== 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 @@
-/*
- * Copyright (C) 2010-2013 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "graphic/sdl/game_renderer.h"
-
-#include "graphic/rendertarget.h"
-#include "graphic/sdl/terrain.h"
-#include "logic/field.h"
-#include "logic/map.h"
-#include "logic/player.h"
-#include "logic/world/terrain_description.h"
-#include "logic/world/world.h"
-#include "wui/overlay_manager.h"
-
-
-using namespace Widelands;
-
-///This is used by rendermap to calculate the brightness of the terrain.
-inline static int8_t node_brightness
- (Widelands::Time const gametime,
- Widelands::Time const last_seen,
- Widelands::Vision const vision,
- int8_t result)
-{
- if (vision == 0)
- result = -128;
- else if (vision == 1) {
- assert(last_seen <= gametime);
- Widelands::Duration const time_ago = gametime - last_seen;
- result =
- static_cast<int16_t>
- (((static_cast<int16_t>(result) + 128) >> 1)
- *
- (1.0 + (time_ago < 45000 ? expf(-8.46126929e-5 * time_ago) : 0)))
- -
- 128;
- }
-
- return result;
-}
-
-
-void SdlGameRenderer::draw()
-{
- draw_terrain();
- draw_objects();
-}
-
-void SdlGameRenderer::draw_terrain()
-{
- if (m_player && !m_player->see_all())
- m_dst->get_surface()->fill_rect(m_dst->get_rect(), RGBAColor(0, 0, 0, 255));
-
- const Map & map = m_egbase->map();
- const World & world = m_egbase->world();
- uint32_t const mapwidth = map.get_width();
-
-#define get_terrain_texture(ter) \
- (g_gr->get_maptexture_data(world.terrain_descr((ter)).get_texture()))
-
- int32_t dx = m_maxfx - m_minfx + 1;
- int32_t dy = m_maxfy - m_minfy + 1;
- int32_t linear_fy = m_minfy;
- int32_t b_posy = linear_fy * TRIANGLE_HEIGHT + m_dst_offset.y;
-
- Widelands::Time const gametime = m_egbase->get_gametime();
-
- while (dy--) {
- const int32_t posy = b_posy;
- b_posy += TRIANGLE_HEIGHT;
- const int32_t linear_fx = m_minfx;
- FCoords r(Coords(linear_fx, linear_fy));
- FCoords br(Coords(linear_fx + (linear_fy & 1) - 1, linear_fy + 1));
- int32_t r_posx =
- r.x * TRIANGLE_WIDTH
- +
- (linear_fy & 1) * (TRIANGLE_WIDTH / 2)
- +
- m_dst_offset.x;
- int32_t br_posx = r_posx - TRIANGLE_WIDTH / 2;
-
- // Calculate safe (bounded) field coordinates and get field pointers
- map.normalize_coords(r);
- map.normalize_coords(br);
- MapIndex r_index = Map::get_index (r, mapwidth);
- r.field = &map[r_index];
- MapIndex br_index = Map::get_index(br, mapwidth);
- br.field = &map[br_index];
- FCoords tr;
- map.get_tln(r, &tr);
- MapIndex tr_index = tr.field - &map[0];
-
- const Texture * f_r_texture;
-
- if (m_player && !m_player->see_all()) {
- const Player::Field & l_pf = m_player->fields()[Map::get_index(map.l_n(r), mapwidth)];
- f_r_texture = get_terrain_texture(l_pf.terrains.r);
- } else {
- f_r_texture = get_terrain_texture(map.l_n(r).field->get_terrains().r);
- }
-
- uint32_t count = dx;
-
- while (count--) {
- const FCoords bl = br;
- const FCoords f = r;
- const int32_t f_posx = r_posx;
- const int32_t bl_posx = br_posx;
- MapIndex f_index = r_index;
- MapIndex bl_index = br_index;
- move_r(mapwidth, tr, tr_index);
- move_r(mapwidth, r, r_index);
- move_r(mapwidth, br, br_index);
- r_posx += TRIANGLE_WIDTH;
- br_posx += TRIANGLE_WIDTH;
-
- const Texture * l_r_texture = f_r_texture;
- const Texture * f_d_texture;
- const Texture * tr_d_texture;
- uint8_t roads;
- int8_t f_brightness;
- int8_t r_brightness;
- int8_t bl_brightness;
- int8_t br_brightness;
-
- if (m_player && !m_player->see_all()) {
- const Player::Field & f_pf = m_player->fields()[f_index];
- const Player::Field & r_pf = m_player->fields()[r_index];
- const Player::Field & bl_pf = m_player->fields()[bl_index];
- const Player::Field & br_pf = m_player->fields()[br_index];
- const Player::Field & tr_pf = m_player->fields()[tr_index];
-
- f_r_texture = get_terrain_texture(f_pf.terrains.r);
- f_d_texture = get_terrain_texture(f_pf.terrains.d);
- tr_d_texture = get_terrain_texture(tr_pf.terrains.d);
-
- roads = f_pf.roads;
-
- f_brightness = node_brightness
- (gametime, f_pf.time_node_last_unseen,
- f_pf.vision, f.field->get_brightness());
- r_brightness = node_brightness
- (gametime, r_pf.time_node_last_unseen,
- r_pf.vision, r.field->get_brightness());
- bl_brightness = node_brightness
- (gametime, bl_pf.time_node_last_unseen,
- bl_pf.vision, bl.field->get_brightness());
- br_brightness = node_brightness
- (gametime, br_pf.time_node_last_unseen,
- br_pf.vision, br.field->get_brightness());
- } else {
- f_r_texture = get_terrain_texture(f.field->get_terrains().r);
- f_d_texture = get_terrain_texture(f.field->get_terrains().d);
- tr_d_texture = get_terrain_texture(tr.field->get_terrains().d);
-
- roads = f.field->get_roads();
-
- f_brightness = f.field->get_brightness();
- r_brightness = r.field->get_brightness();
- bl_brightness = bl.field->get_brightness();
- br_brightness = br.field->get_brightness();
- }
- roads |= map.overlay_manager().get_road_overlay(f);
-
- Vertex f_vert
- (f_posx, posy - f.field->get_height() * HEIGHT_FACTOR,
- f_brightness, 0, 0);
- Vertex r_vert
- (r_posx, posy - r.field->get_height() * HEIGHT_FACTOR,
- r_brightness, TRIANGLE_WIDTH, 0);
- Vertex bl_vert
- (bl_posx, b_posy - bl.field->get_height() * HEIGHT_FACTOR,
- bl_brightness, 0, 64);
- Vertex br_vert
- (br_posx, b_posy - br.field->get_height() * HEIGHT_FACTOR,
- br_brightness, TRIANGLE_WIDTH, 64);
-
- if (linear_fy & 1) {
- f_vert.tx += TRIANGLE_WIDTH / 2;
- r_vert.tx += TRIANGLE_WIDTH / 2;
- } else {
- f_vert.tx += TRIANGLE_WIDTH;
- r_vert.tx += TRIANGLE_WIDTH;
- bl_vert.tx += TRIANGLE_WIDTH / 2;
- br_vert.tx += TRIANGLE_WIDTH / 2;
- }
-
- draw_field // Render ground
- (*m_dst,
- f_vert, r_vert, bl_vert, br_vert,
- roads,
- *tr_d_texture, *l_r_texture, *f_d_texture, *f_r_texture);
- }
-
- ++linear_fy;
- }
-
-#undef get_terrain_texture
-}
-
-
-/**
- * Draw ground textures and roads for the given parallelogram (two triangles)
- * into the bitmap.
- *
- * Vertices:
- * - f_vert vertex of the field
- * - r_vert vertex right of the field
- * - bl_vert vertex bottom left of the field
- * - br_vert vertex bottom right of the field
- *
- * Textures:
- * - f_r_texture Terrain of the triangle right of the field
- * - f_d_texture Terrain of the triangle under of the field
- * - tr_d_texture Terrain of the triangle top of the right triangle ??
- * - l_r_texture Terrain of the triangle left of the down triangle ??
- *
- * (tr_d)
- *
- * (f) *------* (r)
- * / \ r /
- * (l_r) / \ /
- * / d \/
- * (bl) *------* (br)
- */
-void SdlGameRenderer::draw_field
- (RenderTarget & dst,
- const Vertex & f_vert,
- const Vertex & r_vert,
- const Vertex & bl_vert,
- const Vertex & br_vert,
- uint8_t roads,
- const Texture & tr_d_texture,
- const Texture & l_r_texture,
- const Texture & f_d_texture,
- const Texture & f_r_texture)
-{
- upcast(SDLSurface, sdlsurf, dst.get_surface());
- if (sdlsurf)
- {
- sdlsurf->set_subwin(dst.get_rect());
- switch (sdlsurf->format().BytesPerPixel) {
- case 2:
- draw_field_int<uint16_t>
- (*sdlsurf,
- f_vert, r_vert, bl_vert, br_vert,
- roads,
- tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
- break;
- case 4:
- draw_field_int<uint32_t>
- (*sdlsurf,
- f_vert, r_vert, bl_vert, br_vert,
- roads,
- tr_d_texture, l_r_texture, f_d_texture, f_r_texture);
- break;
- default:
- assert(false);
- break;
- }
- sdlsurf->unset_subwin();
- }
-}
=== 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 @@
-/*
- * Copyright (C) 2010-2013 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WL_GRAPHIC_SDL_GAME_RENDERER_H
-#define WL_GRAPHIC_SDL_GAME_RENDERER_H
-
-#include "graphic/game_renderer.h"
-
-struct Texture;
-struct Vertex;
-
-/**
- * Software-rendering implementation of @ref GameRenderer.
- */
-class SdlGameRenderer : public GameRenderer {
-protected:
- void draw() override;
-
-private:
- void draw_terrain();
-
- /**
- * Helper function to draw two terrain triangles. This is called from the
- * rendermap() functions.
- */
- void draw_field
- (RenderTarget & dst,
- const Vertex & f_vert,
- const Vertex & r_vert,
- const Vertex & bl_vert,
- const Vertex & br_vert,
- uint8_t roads,
- const Texture & tr_d_texture,
- const Texture & l_r_texture,
- const Texture & f_d_texture,
- const Texture & f_r_texture);
-};
-
-#endif // end of include guard: WL_GRAPHIC_SDL_GAME_RENDERER_H
=== 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 @@
-/*
- * Copyright (C) 2002-2004, 2007-2013 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "graphic/sdl/surface.h"
-
-#include <cassert>
-
-#include <SDL.h>
-
-SDLSurface::SDLSurface(SDL_Surface* surface, bool free_surface_on_delete) :
- m_surface(surface),
- m_offsx(0), m_offsy(0),
- m_w(surface->w), m_h(surface->h),
- m_free_surface_on_delete(free_surface_on_delete)
-{}
-
-SDLSurface::~SDLSurface() {
- assert(m_surface);
-
- if (m_free_surface_on_delete)
- SDL_FreeSurface(m_surface);
-}
-
-const SDL_PixelFormat & SDLSurface::format() const {
- assert(m_surface);
- return *m_surface->format;
-}
-
-uint8_t * SDLSurface::get_pixels() const {
- assert(m_surface);
-
- return
- static_cast<uint8_t *>(m_surface->pixels)
- +
- m_offsy * m_surface->pitch
- +
- m_offsx * m_surface->format->BytesPerPixel;
-}
-
-void SDLSurface::lock(LockMode) {
- if (SDL_MUSTLOCK(m_surface))
- SDL_LockSurface(m_surface);
-}
-
-void SDLSurface::unlock(UnlockMode) {
- if (SDL_MUSTLOCK(m_surface))
- SDL_UnlockSurface(m_surface);
-}
-
-uint32_t SDLSurface::get_pixel(uint16_t x, uint16_t y) {
- x += m_offsx;
- y += m_offsy;
-
- assert(x < width());
- assert(y < height());
- assert(m_surface);
-
- // Locking not needed: reading only
- const uint8_t bytes_per_pixel = m_surface->format->BytesPerPixel;
- uint8_t * const pix =
- static_cast<uint8_t *>(m_surface->pixels) +
- y * m_surface->pitch + x * bytes_per_pixel;
-
- switch (bytes_per_pixel) {
- case 1:
- return *pix; // Maybe needed for save_png.
- case 2:
- return *reinterpret_cast<const uint16_t *>(pix);
- case 3: //Needed for save_png.
- // We can not dereference a pointer to a size 4 object in this case
- // since that would casue a read beyond the end of the block pointed to
- // by m_surface. Furthermore it would not be properly aligned to a 4
- // byte boundary.
- //
- // Suppose that the image is 2 * 2 pixels. Then m_surface points to a
- // block of size 2 * 2 * 3 = 12. The values for the last pixel are at
- // m_surface[9], m_surface[10] and m_surface[11]. But m_surface[12] is
- // beyond the end of the block, so we can not read 4 bytes starting at
- // m_surface[9] (even if unaligned access is allowed).
- //
- // Therefore we read the 3 bytes separately and get the result by
- // shifting the values. It is alignment safe.
- return pix[0] << 0x00 | pix[1] << 0x08 | pix[2] << 0x10;
- case 4:
- return *reinterpret_cast<const uint32_t *>(pix);
- default:
- assert(false);
- }
-
- return 0; // Should never be here
-}
-
-void SDLSurface::set_pixel(uint16_t x, uint16_t y, const uint32_t clr) {
- x += m_offsx;
- y += m_offsy;
-
- if (x >= width() || y >= height())
- return;
- assert(m_surface);
-
- if (SDL_MUSTLOCK(m_surface))
- SDL_LockSurface(m_surface);
-
- const uint8_t bytes_per_pixel = m_surface->format->BytesPerPixel;
- uint8_t * const pix =
- static_cast<uint8_t *>(m_surface->pixels) +
- y * m_surface->pitch + x * bytes_per_pixel;
- switch (bytes_per_pixel) {
- case 2: *reinterpret_cast<uint16_t *>(pix) = static_cast<uint16_t>(clr); break;
- case 4: *reinterpret_cast<uint32_t *>(pix) = clr; break;
- default: break;
- };
-
- if (SDL_MUSTLOCK(m_surface))
- SDL_UnlockSurface(m_surface);
-}
-
-void SDLSurface::set_subwin(const Rect& r) {
- m_offsx = r.x;
- m_offsy = r.y;
- m_w = r.w;
- m_h = r.h;
-}
-
-void SDLSurface::unset_subwin() {
- m_offsx = 0;
- m_offsy = 0;
- m_w = m_surface->w;
- m_h = m_surface->h;
-}
-
-/*
-===============
-Draws the outline of a rectangle
-===============
-*/
-void SDLSurface::draw_rect(const Rect& rc, const RGBColor& clr) {
- assert(m_surface);
- assert(rc.x >= 0);
- assert(rc.y >= 0);
-
- const uint32_t color = clr.map(format());
-
- const Point bl = rc.bottom_right() - Point(1, 1);
-
- for (int32_t x = rc.x + 1; x < bl.x; ++x) {
- set_pixel(x, rc.y, color);
- set_pixel(x, bl.y, color);
- }
- for (int32_t y = rc.y; y <= bl.y; ++y) {
- set_pixel(rc.x, y, color);
- set_pixel(bl.x, y, color);
- }
-}
-
-
-/*
-===============
-Draws a filled rectangle
-===============
-*/
-void SDLSurface::fill_rect(const Rect& rc, const RGBAColor& clr) {
- assert(m_surface);
- assert(rc.x >= 0);
- assert(rc.y >= 0);
-
- const uint32_t color = clr.map(format());
-
- SDL_Rect r = {
- static_cast<int16_t>(rc.x), static_cast<int16_t>(rc.y),
- static_cast<uint16_t>(rc.w), static_cast<uint16_t>(rc.h)
- };
- SDL_FillRect(m_surface, &r, color);
-}
-
-
-/*
-===============
-Change the brightness of the given rectangle
-This function is slow as hell.
-
-* This function is a possible point to optimize on
- slow system. It takes a lot of cpu time atm and is
- not needed. It is used by the ui_basic stuff to
- highlight things.
-===============
-*/
-void SDLSurface::brighten_rect(const Rect& rc, const int32_t factor) {
- if (!factor)
- return;
- assert(rc.x >= 0);
- assert(rc.y >= 0);
- assert(rc.w >= 1);
- assert(rc.h >= 1);
-
- const Point bl = rc.bottom_right();
-
- lock(Surface::Lock_Normal);
-
- if (m_surface->format->BytesPerPixel == 4)
- {
- for (int32_t y = rc.y; y < bl.y; ++y)
- for (int32_t x = rc.x; x < bl.x; ++x)
- {
-
- uint8_t * const pix =
- static_cast<uint8_t *>(m_surface->pixels) +
- (y + m_offsy) * m_surface->pitch + (x + m_offsx) * 4;
-
- uint32_t const clr = *reinterpret_cast<const uint32_t *>(pix);
- uint8_t gr, gg, gb;
- SDL_GetRGB(clr, m_surface->format, &gr, &gg, &gb);
- int16_t r = gr + factor;
- int16_t g = gg + factor;
- int16_t b = gb + factor;
-
- if (b & 0xFF00)
- b = ~b >> 24;
- if (g & 0xFF00)
- g = ~g >> 24;
- if (r & 0xFF00)
- r = ~r >> 24;
-
- *reinterpret_cast<uint32_t *>(pix) =
- SDL_MapRGB(m_surface->format, r, g, b);
- }
- } else if (m_surface->format->BytesPerPixel == 2) {
- for (int32_t y = rc.y; y < bl.y; ++y)
- for (int32_t x = rc.x; x < bl.x; ++x)
- {
- uint8_t * const pix =
- static_cast<uint8_t *>(m_surface->pixels) +
- (y + m_offsy) * m_surface->pitch + (x + m_offsx) * 2;
-
- uint32_t const clr = *reinterpret_cast<const uint16_t *>(pix);
- uint8_t gr, gg, gb;
- SDL_GetRGB(clr, m_surface->format, &gr, &gg, &gb);
- int16_t r = gr + factor;
- int16_t g = gg + factor;
- int16_t b = gb + factor;
-
- if (b & 0xFF00)
- b = ~b >> 24;
- if (g & 0xFF00)
- g = ~g >> 24;
- if (r & 0xFF00)
- r = ~r >> 24;
-
- *reinterpret_cast<uint16_t *>(pix) =
- SDL_MapRGB(m_surface->format, r, g, b);
- }
- }
- unlock(Surface::Unlock_Update);
-}
-
-/**
-* This functions draws a (not horizontal or vertical)
-* line in the target, using Bresenham's algorithm
-*
-* This function could be faster by using direct pixel
-* access instead of the set_pixel() function
-*/
-void SDLSurface::draw_line
- (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth)
-{
- int32_t dx = x2 - x1; /* the horizontal distance of the line */
- int32_t dy = y2 - y1; /* the vertical distance of the line */
- const uint32_t dxabs = abs(dx);
- const uint32_t dyabs = abs(dy);
- int32_t sdx = dx < 0 ? -1 : 1;
- int32_t sdy = dy < 0 ? -1 : 1;
- uint32_t x = dyabs / 2;
- uint32_t y = dxabs / 2;
- Point p(x1, y1);
-
- set_pixel(p.x, p.y, color.map(format()));
-
- if (dxabs >= dyabs) // the line is more horizontal than vertical
- for (uint32_t i = 0; i < dxabs; ++i) {
- y += dyabs;
-
- if (y >= dxabs) {
- y -= dxabs;
- p.y += sdy;
- }
-
- p.x += sdx;
- for (int32_t w = 0; w < gwidth; ++w) {
- set_pixel(p.x, p.y + w, color.map(format()));
- }
- }
- else // the line is more vertical than horizontal
- for (uint32_t i = 0; i < dyabs; ++i) {
- x += dxabs;
-
- if (x >= dyabs) {
- x -= dyabs;
- p.x += sdx;
- }
-
- p.y += sdy;
- for (int32_t w = 0; w < gwidth; ++w) {
- set_pixel(p.x + w, p.y, color.map(format()));
- }
- }
-}
-
-
-void SDLSurface::blit
- (const Point& dst, const Surface* src, const Rect& srcrc, Composite cm)
-{
- SDL_Surface* sdlsurf = static_cast<const SDLSurface*>(src)->get_sdl_surface();
- SDL_Rect srcrect = {
- static_cast<int16_t>(srcrc.x), static_cast<int16_t>(srcrc.y),
- static_cast<uint16_t>(srcrc.w), static_cast<uint16_t>(srcrc.h)
- };
- SDL_Rect dstrect = {
- static_cast<int16_t>(dst.x), static_cast<int16_t>(dst.y),
- 0, 0
- };
-
- bool alpha = false;
- uint8_t alphaval = 0;
- if (cm == CM_Copy) {
- SDL_BlendMode bm;
- SDL_GetSurfaceBlendMode(sdlsurf, &bm);
- alpha = bm & SDL_BLENDMODE_BLEND;
- SDL_GetSurfaceAlphaMod(sdlsurf, &alphaval);
- SDL_SetSurfaceAlphaMod(sdlsurf, 255);
- SDL_SetSurfaceBlendMode(sdlsurf, SDL_BLENDMODE_NONE);
- }
-
- SDL_BlitSurface(sdlsurf, &srcrect, m_surface, &dstrect);
-
- if (cm == CM_Copy) {
- SDL_SetSurfaceAlphaMod(sdlsurf, alphaval);
- SDL_SetSurfaceBlendMode(sdlsurf, alpha ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
- }
-}
=== 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 @@
-/*
- * Copyright (C) 2010-2011 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WL_GRAPHIC_SDL_SURFACE_H
-#define WL_GRAPHIC_SDL_SURFACE_H
-
-#include <SDL_render.h>
-
-#include "base/rect.h"
-#include "graphic/color.h"
-#include "graphic/surface.h"
-
-/**
-* This implements SDL rendering. Do not use this class directly. The right
-* way is to use the base struct Surface wherever possible. Everything which
-* needs to know about the underlying renderer should go to the graphics
-* subdirectory.
-*/
-class SDLSurface : public Surface {
-public:
- // The surface set by SetVideoMode must not be freed according to the SDL
- // docs, so we need 'free_surface_on_delete'.
- SDLSurface(SDL_Surface* surface, bool free_surface_on_delete = true);
- virtual ~SDLSurface();
-
- // Implements Image
- uint16_t width() const override {return m_w;}
- uint16_t height() const override {return m_h;}
-
- // Implements Surface
- void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm) override;
- void fill_rect(const Rect&, const RGBAColor&) override;
-
- // Implements Surface
- void draw_rect(const Rect&, const RGBColor&) override;
- virtual void draw_line
- (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor&, uint8_t width) override;
- void brighten_rect(const Rect&, int32_t factor) override;
-
- const SDL_PixelFormat & format() const override;
- void lock(LockMode) override;
- void unlock(UnlockMode) override;
- uint32_t get_pixel(uint16_t x, uint16_t y) override;
- void set_pixel(uint16_t x, uint16_t y, uint32_t clr) override;
- uint16_t get_pitch() const override {return m_surface->pitch;}
- uint8_t * get_pixels() const override;
-
- SDL_Surface * get_sdl_surface() const {return m_surface;}
-
- void set_subwin(const Rect& r);
- void unset_subwin();
-
-protected:
- SDL_Surface * m_surface;
- int32_t m_offsx;
- int32_t m_offsy;
- uint16_t m_w, m_h;
- bool m_free_surface_on_delete;
-};
-
-#endif // end of include guard: WL_GRAPHIC_SDL_SURFACE_H
=== 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 @@
-/*
- * Copyright (C) 2002-2004, 2006, 2009-2010 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "graphic/sdl/terrain.h"
-
-/// get lambda and mu so that
-/// lambda * u + mu * v = (1 0)^T with u = (u1 u2)^T and v = (v1 v2)^T
-void get_horiz_linearcomb
- (int32_t const u1, int32_t const u2, int32_t const v1, int32_t const v2,
- float & lambda, float & mu)
-{
- float det;
-
- det = u1 * v2 - u2 * v1; // determinant of (u v)
-
- lambda = v2 / det; // by Cramer's rule
- mu = -u2 / det;
-}
=== 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 @@
-/*
- * Copyright (C) 2002-2004, 2006-2010 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WL_GRAPHIC_SDL_TERRAIN_H
-#define WL_GRAPHIC_SDL_TERRAIN_H
-
-#include <cassert>
-
-#include "base/log.h"
-#include "base/macros.h"
-#include "graphic/graphic.h"
-#include "graphic/sdl/surface.h"
-#include "graphic/sdl/vertex.h"
-#include "graphic/texture.h"
-#include "logic/roadtype.h"
-#include "random/random.h"
-#include "wui/mapviewpixelconstants.h"
-
-///Must be a power of two
-#define DITHER_WIDTH 4
-
-#define DITHER_RAND_MASK (DITHER_WIDTH * 2 - 1)
-#define DITHER_RAND_SHIFT (16 / DITHER_WIDTH)
-
-// TODO(unknown): Dangerous: casting, assumptions for sizeof(X), bitshifting
-#define FTOFIX(f) (static_cast<int32_t>((f) * 0x10000))
-#define ITOFIX(i) ((i)<<16)
-#define FIXTOI(f) ((f)>>16)
-
-void get_horiz_linearcomb
- (int32_t u1, int32_t u2, int32_t v1, int32_t v2,
- float & lambda, float & mu);
-
-
-struct LeftEdge {
- /**
- * Height of the edge.
- *
- * This is the number of pixels spanned by the edge in a vertical direction
- */
- uint32_t height;
-
- // the following are all fixed point
- int32_t x0;
- int32_t tx0;
- int32_t ty0;
- int32_t b0;
- int32_t dx;
- int32_t dtx;
- int32_t dty;
- int32_t db;
-};
-
-struct RightEdge {
- uint32_t height;
-
- int32_t x0;
- int32_t dx;
-};
-
-
-/**
- * Render a polygon based on the given edge lists.
- *
- * The edge lists will be overwritten with undefined values.
- */
-template<typename T> static void render_edge_lists
- (SDLSurface & dst, const Texture & tex,
- int32_t y, int32_t height,
- LeftEdge * left, RightEdge * right,
- int32_t dbdx, int32_t dtydx)
-{
- if (-y >= height)
- return; // completely above screen
-
- uint8_t * texpixels;
- T * texcolormap;
-
- texpixels = tex.get_curpixels();
- texcolormap = static_cast<T *>(tex.get_colormap());
-
- // Skip lines that are above the screen
- while (y < 0) {
- int32_t skip = -y;
- if (skip > static_cast<int32_t>(left->height))
- skip = left->height;
- if (skip > static_cast<int32_t>(right->height))
- skip = right->height;
-
- if (skip < static_cast<int32_t>(left->height)) {
- left->x0 += skip * left->dx;
- left->tx0 += skip * left->dtx;
- left->ty0 += skip * left->dty;
- left->b0 += skip * left->db;
- left->height -= skip;
- } else {
- ++left;
- }
-
- if (skip < static_cast<int32_t>(right->height)) {
- right->x0 += skip * right->dx;
- right->height -= skip;
- } else {
- ++right;
- }
-
- height -= skip;
- y += skip;
- }
-
- // Cut off lines below screen
- if (y + height > static_cast<int32_t>(dst.height()))
- height = dst.height() - y;
-
- int32_t dstw = dst.width();
- while (height > 0) {
- int32_t leftx = FIXTOI(left->x0);
- int32_t rightx = FIXTOI(right->x0);
-
- if (leftx < 0)
- leftx = 0;
- if (rightx > dstw)
- rightx = dstw;
-
- if (leftx < rightx) {
- int32_t tx = left->tx0;
- int32_t ty = left->ty0;
- int32_t b = left->b0;
-
- int32_t adjust = ITOFIX(leftx) - left->x0;
- tx += adjust; // note: dtx/dx = 1
- ty += FIXTOI(static_cast<long long>(adjust) * dtydx);
- b += FIXTOI(static_cast<long long>(adjust) * dbdx);
-
- // Technically, we should clamp b at every pixel, but that's too
- // expensive. The following seems to be enough to get rid of
- // artifacts along the border between seen and unseen fields.
- if (b < ITOFIX(-128))
- b = ITOFIX(-128);
-
- tx = FIXTOI(tx);
-
- T * scanline =
- reinterpret_cast<T *>
- (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch())
- +
- leftx;
-
- uint32_t count = rightx - leftx;
- while (count--) {
- *scanline++ =
- texcolormap
- [texpixels
- [(tx & (TEXTURE_WIDTH - 1)) |
- ((ty >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
- |
- ((b >> 8) & 0xFF00)];
-
- b += dbdx;
- ++tx;
- ty += dtydx;
- }
- }
-
- // Advance the line
- ++y;
- left->x0 += left->dx;
- left->tx0 += left->dtx;
- left->ty0 += left->dty;
- left->b0 += left->db;
- right->x0 += right->dx;
-
- if (--left->height == 0)
- ++left;
- if (--right->height == 0)
- ++right;
- --height;
- }
-}
-
-struct WLPolygon {
- Point p[3];
- uint8_t nrpoints;
-};
-
-
-/**
- * Render a triangle into the given destination surface.
- *
- * \note It is assumed that p1, p2, p3 are sorted in counter-clockwise order.
- *
- * \note The rendering code assumes that d(tx)/d(x) = 1. This can be achieved
- * by making sure that there is a 1:1 relation between x coordinates and
- * texture x coordinates.
- */
-template<typename T> static void render_triangle
- (SDLSurface & dst,
- const Vertex & p1, const Vertex & p2, const Vertex & p3,
- const Texture & tex)
-{
- if (p1.y == p2.y && p2.y == p3.y)
- return; // degenerate triangle
-
- // Clip the triangle
- WLPolygon polygon;
-
- polygon.p[0] = p1;
- polygon.p[1] = p2;
- polygon.p[2] = p3;
- polygon.nrpoints = 3;
-
- // Determine a top vertex
- int32_t top = 0, topy = 0;
-
- topy = 0x7fffffff;
- for (uint8_t i = 0; i < polygon.nrpoints; ++i) {
- if (polygon.p[i].y < topy) {
- top = i;
- topy = polygon.p[i].y;
- }
- }
-
- // Calculate d(b) / d(x) etc. as fixed point variables.
- // Remember that we assume d(tx) / d(x) == 1 and d(tx) / d(y) == 0.
-
- // lA * (p2 - p1) + lB * (p3 - p1) = (1, 0)
- // mA * (p2 - p1) + mB * (p3 - p1) = (0, 1)
- int32_t const det =
- (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);
- int32_t const lA = ITOFIX(p3.y - p1.y) / det;
- int32_t const lB = -ITOFIX(p2.y - p1.y) / det;
- int32_t const mA = -ITOFIX(p3.x - p1.x) / det;
- int32_t const mB = ITOFIX(p2.x - p1.x) / det;
- int32_t const dbdx = lA * (p2.b - p1.b) + lB * (p3.b - p1.b);
- int32_t const dbdy = mA * (p2.b - p1.b) + mB * (p3.b - p1.b);
- int32_t const dtydx = lA * (p2.ty - p1.ty) + lB * (p3.ty - p1.ty);
- int32_t const dtydy = mA * (p2.ty - p1.ty) + mB * (p3.ty - p1.ty);
-
- // Build left edges
- int32_t boty = topy;
- LeftEdge leftedges[3];
-
- {
- uint8_t nrleftedges = 0;
- uint8_t start = top;
- uint8_t end = (top + 1) % polygon.nrpoints;
- do {
- if (polygon.p[end].y > polygon.p[start].y) {
- boty = polygon.p[end].y;
-
- LeftEdge & edge = leftedges[nrleftedges++];
- assert(nrleftedges <= 3);
-
- edge.height = polygon.p[end].y - polygon.p[start].y;
- edge.x0 = ITOFIX(polygon.p[start].x);
- edge.dx =
- ITOFIX(polygon.p[end].x - polygon.p[start].x)
- /
- static_cast<int32_t>(edge.height);
-
- int32_t startdx = polygon.p[start].x - p1.x;
- int32_t startdy = polygon.p[start].y - p1.y;
- int32_t dx = polygon.p[end].x - polygon.p[start].x;
- int32_t dy = polygon.p[end].y - polygon.p[start].y;
-
- edge.tx0 = ITOFIX(p1.tx + startdx);
- edge.ty0 = ITOFIX(p1.ty) + startdx * dtydx + startdy * dtydy;
- edge.b0 = ITOFIX(p1.b) + startdx * dbdx + startdy * dbdy;
- edge.dtx = ITOFIX(dx) / static_cast<int32_t>(edge.height);
- edge.dty =
- (dx * dtydx + dy * dtydy) / static_cast<int32_t>(edge.height);
- edge.db =
- (dx * dbdx + dy * dbdy) / static_cast<int32_t>(edge.height);
- }
-
- start = end;
- end = (start + 1) % polygon.nrpoints;
- } while (polygon.p[end].y >= polygon.p[start].y);
- }
-
- // Build right edges
- RightEdge rightedges[3];
-
- {
- uint8_t nrrightedges = 0;
- uint8_t start = top;
- uint8_t end = (polygon.nrpoints + top - 1) % polygon.nrpoints;
- do {
- if (polygon.p[end].y > polygon.p[start].y) {
- RightEdge & edge = rightedges[nrrightedges++];
- assert(nrrightedges <= 3);
-
- edge.height = polygon.p[end].y - polygon.p[start].y;
- edge.x0 = ITOFIX(polygon.p[start].x);
- edge.dx =
- ITOFIX(polygon.p[end].x - polygon.p[start].x)
- /
- static_cast<int32_t>(edge.height);
- }
-
- start = end;
- end = (polygon.nrpoints + start - 1) % polygon.nrpoints;
- } while (polygon.p[end].y >= polygon.p[start].y);
- }
-
- render_edge_lists<T>
- (dst, tex, topy, boty - topy, leftedges, rightedges, dbdx, dtydx);
-}
-
-/**
- * Blur the polygon edge between vertices start and end.
- *
- * It is dithered by randomly placing points taken from the texture of the
- * adjacent polygon. The blend area is a few pixels wide, and the chance for
- * replacing a pixel depends on the distance from the center line. Texture
- * coordinates and brightness are interpolated across the center line (outer
- * loop). To the sides these are approximated (inner loop): Brightness is kept
- * constant, and the texture is mapped orthogonally to the center line. It is
- * important that only those pixels are drawn whose texture actually changes in
- * order to minimize artifacts.
- *
- * \note All this is preliminary and subject to change. For example, a special
- * edge texture could be used instead of stochastically dithering. Road
- * rendering could be handled as a special case then.
-*/
-template<typename T> static void dither_edge_horiz
- (SDLSurface & dst,
- const Vertex & start, const Vertex & end,
- const Texture & ttex, const Texture & btex)
-{
- uint8_t * tpixels, * bpixels;
- T * tcolormap, * bcolormap;
-
- tpixels = ttex.get_curpixels();
- tcolormap = static_cast<T *>(ttex.get_colormap());
- bpixels = btex.get_curpixels();
- bcolormap = static_cast<T *>(btex.get_colormap());
-
- int32_t tx, ty, b, dtx, dty, db, tx0, ty0;
-
- tx = ITOFIX(start.tx);
- ty = ITOFIX(start.ty);
- b = ITOFIX(start.b);
- dtx = (ITOFIX(end.tx) - tx) / (end.x - start.x + 1);
- dty = (ITOFIX(end.ty) - ty) / (end.x - start.x + 1);
- db = (ITOFIX(end.b) - b) / (end.x - start.x + 1);
-
- // TODO(unknown): seed this depending on field coordinates
- uint32_t rnd = 0;
-
- const int32_t dstw = dst.width();
- const int32_t dsth = dst.height();
-
- int32_t ydiff = ITOFIX(end.y - start.y) / (end.x - start.x);
- int32_t centery = ITOFIX(start.y);
-
- for (int32_t x = start.x; x < end.x; x++, centery += ydiff) {
- rnd = SIMPLE_RAND(rnd);
-
- if (x >= 0 && x < dstw) {
- int32_t y = FIXTOI(centery) - DITHER_WIDTH;
-
- tx0 = tx - DITHER_WIDTH * dty;
- ty0 = ty + DITHER_WIDTH * dtx;
-
- uint32_t rnd0 = rnd;
-
- // dither above the edge
- for (uint32_t i = 0; i < DITHER_WIDTH; i++, y++) {
- if ((rnd0 & DITHER_RAND_MASK) <= i && y >= 0 && y < dsth) {
- T * const pix =
- reinterpret_cast<T *>
- (static_cast<uint8_t *>(dst.get_pixels())
- +
- y * dst.get_pitch())
- +
- x;
- *pix =
- tcolormap
- [tpixels
- [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
- ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
- |
- ((b >> 8) & 0xFF00)];
- }
-
- tx0 += dty;
- ty0 -= dtx;
- rnd0 >>= DITHER_RAND_SHIFT;
- }
-
- // dither below the edge
- for
- (uint32_t i = 0;
- i < DITHER_WIDTH;
- ++i, ++y, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT)
- if
- ((rnd0 & DITHER_RAND_MASK) >= i + DITHER_WIDTH &&
- y >= 0 && y < dsth)
- reinterpret_cast<T *>
- (static_cast<uint8_t *>(dst.get_pixels())
- +
- y * dst.get_pitch())
- [x]
- =
- bcolormap
- [bpixels
- [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
- ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
- |
- ((b >> 8) & 0xFF00)];
- }
-
- tx += dtx;
- ty += dty;
- b += db;
- }
-}
-
-/**
- * \see dither_edge_horiz
- */
-template<typename T> static void dither_edge_vert
- (SDLSurface & dst,
- const Vertex & start, const Vertex & end,
- const Texture & ltex, const Texture & rtex)
-{
- uint8_t * lpixels, * rpixels;
- T * lcolormap, * rcolormap;
-
- lpixels = ltex.get_curpixels();
- lcolormap = static_cast<T *>(ltex.get_colormap());
- rpixels = rtex.get_curpixels();
- rcolormap = static_cast<T *>(rtex.get_colormap());
-
- int32_t tx, ty, b, dtx, dty, db, tx0, ty0;
-
- tx = ITOFIX(start.tx);
- ty = ITOFIX(start.ty);
- b = ITOFIX(start.b);
- dtx = (ITOFIX(end.tx) - tx) / (end.y - start.y + 1);
- dty = (ITOFIX(end.ty) - ty) / (end.y - start.y + 1);
- db = (ITOFIX(end.b) - b) / (end.y - start.y + 1);
-
- // TODO(unknown): seed this depending on field coordinates
- uint32_t rnd = 0;
-
- const int32_t dstw = dst.width();
- const int32_t dsth = dst.height();
-
- int32_t xdiff = ITOFIX(end.x - start.x) / (end.y - start.y);
- int32_t centerx = ITOFIX(start.x);
-
- for (int32_t y = start.y; y < end.y; y++, centerx += xdiff) {
- rnd = SIMPLE_RAND(rnd);
-
- if (y >= 0 && y < dsth) {
- int32_t x = FIXTOI(centerx) - DITHER_WIDTH;
-
- tx0 = tx - DITHER_WIDTH * dty;
- ty0 = ty + DITHER_WIDTH * dtx;
-
- uint32_t rnd0 = rnd;
-
- // dither on left side
- for
- (uint32_t i = 0;
- i < DITHER_WIDTH;
- ++i, ++x, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT)
- if ((rnd0 & DITHER_RAND_MASK) <= i && x >= 0 && x < dstw)
- reinterpret_cast<T *>
- (static_cast<uint8_t *>(dst.get_pixels())
- +
- y * dst.get_pitch())
- [x]
- =
- lcolormap
- [lpixels
- [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
- ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
- |
- ((b >> 8) & 0xFF00)];
-
- // dither on right side
- for
- (uint32_t i = 0;
- i < DITHER_WIDTH;
- ++i, ++x, tx0 += dty, ty0 -= dtx, rnd0 >>= DITHER_RAND_SHIFT)
- if
- ((rnd0 & DITHER_RAND_MASK) >= i + DITHER_WIDTH
- &&
- x >= 0 && x < dstw)
- reinterpret_cast<T *>
- (static_cast<uint8_t *>(dst.get_pixels())
- +
- y * dst.get_pitch())
- [x]
- =
- rcolormap
- [rpixels
- [((tx0 >> 16) & (TEXTURE_WIDTH - 1)) |
- ((ty0 >> 10) & ((TEXTURE_HEIGHT - 1) << 6))]
- |
- ((b >> 8) & 0xFF00)];
- }
-
- tx += dtx;
- ty += dty;
- b += db;
- }
-}
-
-template<typename T> static void render_road_horiz
- (SDLSurface & dst, Point const start, Point const end, const SDLSurface & src)
-{
- int32_t const dstw = dst.width();
- int32_t const dsth = dst.height();
-
- int32_t const ydiff = ((end.y - start.y) << 16) / (end.x - start.x);
- int32_t centery = start.y << 16;
-
- for (int32_t x = start.x, sx = 0; x < end.x; ++x, centery += ydiff, ++sx) {
- if (x < 0 || x >= dstw)
- continue;
-
- for (int32_t i = 0, y = (centery >> 16) - 2; i < 5; ++i, ++y)
- if (0 < y && y < dsth)
- reinterpret_cast<T *>
- (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch())
- [x]
- =
- reinterpret_cast<T const *>
- (static_cast<uint8_t const *>(src.get_pixels())
- +
- i * src.get_pitch())
- [sx];
- }
-}
-
-template<typename T> static void render_road_vert
- (SDLSurface & dst, Point const start, Point const end, const SDLSurface & src)
-{
- int32_t const dstw = dst.width();
- int32_t const dsth = dst.height();
-
- int32_t const xdiff = ((end.x - start.x) << 16) / (end.y - start.y);
- int32_t centerx = start.x << 16;
-
- for (int32_t y = start.y, sy = 0; y < end.y; ++y, centerx += xdiff, ++sy) {
- if (y < 0 || y >= dsth)
- continue;
-
- for (int32_t i = 0, x = (centerx >> 16) - 2; i < 5; ++i, ++x)
- if (0 < x && x < dstw)
- reinterpret_cast<T *>
- (static_cast<uint8_t *>(dst.get_pixels()) + y * dst.get_pitch())
- [x]
- =
- reinterpret_cast<T const *>
- (static_cast<uint8_t const *>(src.get_pixels())
- +
- sy * src.get_pitch())
- [i];
- }
-}
-
-template<typename T> static void draw_field_int
- (SDLSurface & dst,
- const Vertex & f_vert,
- const Vertex & r_vert,
- const Vertex & bl_vert,
- const Vertex & br_vert,
- uint8_t roads,
- const Texture & tr_d_texture,
- const Texture & l_r_texture,
- const Texture & f_d_texture,
- const Texture & f_r_texture)
-{
- SDLSurface& rt_busy = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Busy));
- SDLSurface& rt_normal = static_cast<SDLSurface&>(g_gr->get_road_texture(Widelands::Road_Normal));
-
- dst.lock(Surface::Lock_Normal);
-
- render_triangle<T> (dst, f_vert, br_vert, r_vert, f_r_texture);
- render_triangle<T> (dst, f_vert, bl_vert, br_vert, f_d_texture);
-
- // Render roads and dither polygon edges
- uint8_t road;
-
- road = (roads >> Widelands::Road_East) & Widelands::Road_Mask;
- if (-128 < f_vert.b || -128 < r_vert.b) {
- if (road) {
- switch (road) {
- case Widelands::Road_Normal:
- render_road_horiz<T> (dst, f_vert, r_vert, rt_normal);
- break;
- case Widelands::Road_Busy:
- render_road_horiz<T> (dst, f_vert, r_vert, rt_busy);
- break;
- default:
- assert(false);
- break;
- }
- } else if (&f_r_texture != &tr_d_texture) {
- dither_edge_horiz<T>(dst, f_vert, r_vert, f_r_texture, tr_d_texture);
- }
- }
-
- road = (roads >> Widelands::Road_SouthEast) & Widelands::Road_Mask;
- if (-128 < f_vert.b || -128 < br_vert.b) {
- if (road) {
- switch (road) {
- case Widelands::Road_Normal:
- render_road_vert<T> (dst, f_vert, br_vert, rt_normal);
- break;
- case Widelands::Road_Busy:
- render_road_vert<T> (dst, f_vert, br_vert, rt_busy);
- break;
- default:
- assert(false);
- break;
- }
- } else if (&f_r_texture != &f_d_texture) {
- dither_edge_vert<T>(dst, f_vert, br_vert, f_r_texture, f_d_texture);
- }
- }
-
- road = (roads >> Widelands::Road_SouthWest) & Widelands::Road_Mask;
- if (-128 < f_vert.b || -128 < bl_vert.b) {
- if (road) {
- switch (road) {
- case Widelands::Road_Normal:
- render_road_vert<T> (dst, f_vert, bl_vert, rt_normal);
- break;
- case Widelands::Road_Busy:
- render_road_vert<T> (dst, f_vert, bl_vert, rt_busy);
- break;
- default:
- assert(false);
- break;
- }
- } else if (&l_r_texture != &f_d_texture) {
- dither_edge_vert<T>(dst, f_vert, bl_vert, f_d_texture, l_r_texture);
- }
- }
-
- dst.unlock(Surface::Unlock_Update);
-
- // TODO(unknown): similar textures may not need dithering
-}
-
-#endif // end of include guard: WL_GRAPHIC_SDL_TERRAIN_H
=== 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 @@
-/*
- * Copyright (C) 2006-2012 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "graphic/sdl/utils.h"
-
-#include <cassert>
-
-#include <SDL.h>
-
-SDL_Surface * empty_sdl_surface(int16_t w, int16_t h) {
- SDL_Surface* const surface =
- SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
- return surface;
-}
=== 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 @@
-/*
- * Copyright (C) 2006-2012 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef WL_GRAPHIC_SDL_UTILS_H
-#define WL_GRAPHIC_SDL_UTILS_H
-
-#include <stdint.h>
-
-struct SDL_Surface;
-
-SDL_Surface * empty_sdl_surface(int16_t w, int16_t h);
-
-#endif // end of include guard: WL_GRAPHIC_SDL_UTILS_H
=== 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 @@
-/*
- * Copyright (C) 2002-2004, 2006-2007 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WL_GRAPHIC_SDL_VERTEX_H
-#define WL_GRAPHIC_SDL_VERTEX_H
-
-#include "base/point.h"
-
-/// Like a point but with an additional bright factor and texture coordinates.
-struct Vertex:public Point {
- Vertex() : Point (0, 0), b(0), tx(0), ty(0) {}
- Vertex
- (const int32_t vx, const int32_t vy,
- const int32_t vb,
- const int32_t vtx, const int32_t vty)
-
- : Point(vx, vy), b(vb), tx(vtx), ty(vty)
- {}
-
- int32_t b, tx, ty;
-};
-
-#endif // end of include guard: WL_GRAPHIC_SDL_VERTEX_H
=== 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 10:15:33 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2006-2014 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "graphic/sdl_utils.h"
+
+#include <SDL.h>
+
+SDL_Surface* empty_sdl_surface(int16_t w, int16_t h) {
+ SDL_Surface* const surface =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
+ return surface;
+}
=== 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 10:15:33 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006-2014 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef WL_GRAPHIC_SDL_UTILS_H
+#define WL_GRAPHIC_SDL_UTILS_H
+
+#include <stdint.h>
+
+struct SDL_Surface;
+
+SDL_Surface * empty_sdl_surface(int16_t w, int16_t h);
+
+#endif // end of include guard:
=== modified file 'src/graphic/surface.cc'
--- src/graphic/surface.cc 2014-11-02 20:15:01 +0000
+++ src/graphic/surface.cc 2014-11-23 10:15:33 +0000
@@ -19,43 +19,175 @@
#include "graphic/surface.h"
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
+
#include <SDL.h>
+#include "base/macros.h"
+#include "graphic/gl/blit_program.h"
+#include "graphic/gl/draw_line_program.h"
+#include "graphic/gl/draw_rect_program.h"
+#include "graphic/gl/fill_rect_program.h"
#include "graphic/gl/surface_texture.h"
-#include "graphic/sdl/surface.h"
-#include "graphic/sdl/utils.h"
-
-extern bool g_opengl;
-
-namespace {
-
-bool s_is_diplay_format_defined = false;
-
-SDL_Surface* maybe_convert_to_diplay_format(SDL_Surface* surface) {
- if (!s_is_diplay_format_defined) {
- return surface;
- }
- SDL_Surface * converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
- SDL_FreeSurface(surface);
- return converted;
-}
-
-} // namespace
-
-void Surface::display_format_is_now_defined() {
- s_is_diplay_format_defined = true;
-}
+#include "graphic/gl/utils.h"
+#include "graphic/graphic.h"
+
Surface* Surface::create(SDL_Surface* surf) {
- if (g_opengl) {
- return new GLSurfaceTexture(surf);
- }
- return new SDLSurface(maybe_convert_to_diplay_format(surf));
+ return new GLSurfaceTexture(surf);
}
Surface* Surface::create(uint16_t w, uint16_t h) {
- if (g_opengl) {
- return new GLSurfaceTexture(w, h);
- }
- return new SDLSurface(empty_sdl_surface(w, h));
+ return new GLSurfaceTexture(w, h);
+}
+
+
+uint16_t Surface::width() const {
+ return m_w;
+}
+
+uint16_t Surface::height() const {
+ return m_h;
+}
+
+uint8_t * Surface::get_pixels() const
+{
+ return m_pixels.get();
+}
+
+uint32_t Surface::get_pixel(uint16_t x, uint16_t y) {
+ assert(m_pixels);
+ assert(x < m_w);
+ assert(y < m_h);
+
+ uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
+ return *(reinterpret_cast<uint32_t *>(data));
+}
+
+uint16_t Surface::get_pitch() const {
+ return 4 * m_w;
+}
+
+const SDL_PixelFormat & Surface::format() const {
+ return Gl::gl_rgba_format();
+}
+
+
+void Surface::set_pixel(uint16_t x, uint16_t y, uint32_t clr) {
+ assert(m_pixels);
+ assert(x < m_w);
+ assert(y < m_h);
+
+ uint8_t * data = &m_pixels[y * get_pitch() + 4 * x];
+ *(reinterpret_cast<uint32_t *>(data)) = clr;
+}
+
+FloatRect Surface::to_opengl(const Rect& rect, ConversionMode mode) {
+ const float delta = mode == ConversionMode::kExact ? 0. : 0.5;
+ float x1 = rect.x + delta;
+ float y1 = rect.y + delta;
+ pixel_to_gl(&x1, &y1);
+ float x2 = rect.x + rect.w - delta;
+ float y2 = rect.y + rect.h - delta;
+ pixel_to_gl(&x2, &y2);
+
+ return FloatRect(x1, y1, x2 - x1, y2 - y1);
+}
+
+void Surface::draw_rect(const Rect& rc, const RGBColor& clr)
+{
+ glViewport(0, 0, width(), height());
+ DrawRectProgram::instance().draw(to_opengl(rc, ConversionMode::kMidPoint), clr);
+}
+
+/**
+ * Draws a filled rectangle
+ */
+void Surface::fill_rect(const Rect& rc, const RGBAColor& clr) {
+ glViewport(0, 0, width(), height());
+
+ glBlendFunc(GL_ONE, GL_ZERO);
+
+ FillRectProgram::instance().draw(to_opengl(rc, ConversionMode::kExact), clr);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+/**
+ * Change the brightness of the given rectangle
+ */
+void Surface::brighten_rect(const Rect& rc, const int32_t factor)
+{
+ if (!factor)
+ return;
+
+ glViewport(0, 0, width(), height());
+
+ // The simple trick here is to fill the rect, but using a different glBlendFunc that will sum
+ // src and target (or subtract them if factor is negative).
+ if (factor < 0) {
+ glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+ }
+
+ glBlendFunc(GL_ONE, GL_ONE);
+
+ const int delta = std::abs(factor);
+ FillRectProgram::instance().draw(
+ to_opengl(rc, ConversionMode::kExact), RGBAColor(delta, delta, delta, 0));
+
+ if (factor < 0) {
+ glBlendEquation(GL_FUNC_ADD);
+ }
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+void Surface::draw_line
+ (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t gwidth)
+{
+ glViewport(0, 0, width(), height());
+
+ float gl_x1 = x1 + 0.5;
+ float gl_y1 = y1 + 0.5;
+ pixel_to_gl(&gl_x1, &gl_y1);
+
+ float gl_x2 = x2 + 0.5;
+ float gl_y2 = y2 + 0.5;
+ pixel_to_gl(&gl_x2, &gl_y2);
+
+ DrawLineProgram::instance().draw(gl_x1, gl_y1, gl_x2, gl_y2, color, gwidth);
+}
+
+// Converts the pixel (x, y) in a texture to a gl coordinate in [0, 1].
+inline void pixel_to_gl_texture(const int width, const int height, float* x, float* y) {
+ *x = (*x / width);
+ *y = (*y / height);
+}
+
+void Surface::blit
+ (const Point& dst, const Surface* image, const Rect& srcrc, Composite cm)
+{
+ glViewport(0, 0, width(), height());
+
+ // Source Rectangle.
+ const GLSurfaceTexture* const texture = static_cast<const GLSurfaceTexture*>(image);
+ FloatRect gl_src_rect;
+ {
+ float x1 = srcrc.x;
+ float y1 = srcrc.y;
+ pixel_to_gl_texture(texture->width(), texture->height(), &x1, &y1);
+ float x2 = srcrc.x + srcrc.w;
+ float y2 = srcrc.y + srcrc.h;
+ pixel_to_gl_texture(texture->width(), texture->height(), &x2, &y2);
+ gl_src_rect.x = x1;
+ gl_src_rect.y = y1;
+ gl_src_rect.w = x2 - x1;
+ gl_src_rect.h = y2 - y1;
+ }
+
+ const FloatRect gl_dst_rect = to_opengl(Rect(dst.x, dst.y, srcrc.w, srcrc.h), ConversionMode::kExact);
+
+ BlitProgram::instance().draw(gl_dst_rect, gl_src_rect, texture->get_gl_texture(), cm);
}
=== modified file 'src/graphic/surface.h'
--- src/graphic/surface.h 2014-11-08 16:02:07 +0000
+++ src/graphic/surface.h 2014-11-23 10:15:33 +0000
@@ -20,6 +20,8 @@
#ifndef WL_GRAPHIC_SURFACE_H
#define WL_GRAPHIC_SURFACE_H
+#include <memory>
+
#include "base/macros.h"
#include "base/rect.h"
#include "graphic/color.h"
@@ -31,13 +33,6 @@
*/
class Surface {
public:
- // Surfaces can either be converted to display format on creation or kept in
- // the format they were created. The only reason not to convert to display
- // format is when no display format is defined - trying will then crash the
- // program. This is only the case when SDL_SetVideoMode() has never been
- // called, so call this method after you called SDL_SetVideoMode.
- static void display_format_is_now_defined();
-
// Create a new surface from an SDL_Surface. Ownership is taken.
static Surface* create(SDL_Surface*);
@@ -49,26 +44,26 @@
virtual ~Surface() {}
/// Dimensions.
- virtual uint16_t width() const = 0;
- virtual uint16_t height() const = 0;
+ uint16_t width() const;
+ uint16_t height() const;
/// This draws a part of another surface to this surface
- virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm = CM_UseAlpha) = 0;
+ virtual void blit(const Point&, const Surface*, const Rect& srcrc, Composite cm = CM_UseAlpha);
/// Draws a filled rect to the surface. No blending takes place, the values
//in the target are just replaced (i.e. / Composite would be CM_Copy).
- virtual void fill_rect(const Rect&, const RGBAColor&) = 0;
+ virtual void fill_rect(const Rect&, const RGBAColor&);
/// Draws a rect (frame only) to the surface.
- virtual void draw_rect(const Rect&, const RGBColor&) = 0;
+ virtual void draw_rect(const Rect&, const RGBColor&);
/// draw a line to the surface
virtual void draw_line
- (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t width = 1) = 0;
+ (int32_t x1, int32_t y1, int32_t x2, int32_t y2, const RGBColor& color, uint8_t width = 1);
/// makes a rectangle on the surface brighter (or darker).
/// @note this is slow in SDL mode. Use with care
- virtual void brighten_rect(const Rect&, int32_t factor) = 0;
+ virtual void brighten_rect(const Rect&, int32_t factor);
/// The functions below are for direct pixel access. This should be used
/// only very sparingly as / it is potentially expensive (especially for
@@ -105,7 +100,21 @@
};
/// This returns the pixel format for direct pixel access.
- virtual const SDL_PixelFormat & format() const = 0;
+ const SDL_PixelFormat & format() const;
+
+ /**
+ * \return Pitch of the raw pixel data, i.e. the number of bytes
+ * contained in each image row. This can be strictly larger than
+ * bytes per pixel times the width.
+ */
+ uint16_t get_pitch() const;
+
+ /**
+ * \return Pointer to the raw pixel data.
+ *
+ * \warning May only be called inside lock/unlock pairs.
+ */
+ uint8_t * get_pixels() const;
/**
* Lock/Unlock pairs must guard any of the direct pixel access using the
@@ -113,29 +122,34 @@
*
* \note Lock/Unlock pairs cannot be nested.
*/
- //@{
virtual void lock(LockMode) = 0;
virtual void unlock(UnlockMode) = 0;
- //@}
-
- //@{
- virtual uint32_t get_pixel(uint16_t x, uint16_t y) = 0;
- virtual void set_pixel(uint16_t x, uint16_t y, uint32_t clr) = 0;
- //@}
-
- /**
- * \return Pitch of the raw pixel data, i.e. the number of bytes
- * contained in each image row. This can be strictly larger than
- * bytes per pixel times the width.
- */
- virtual uint16_t get_pitch() const = 0;
-
- /**
- * \return Pointer to the raw pixel data.
- *
- * \warning May only be called inside lock/unlock pairs.
- */
- virtual uint8_t * get_pixels() const = 0;
+
+ uint32_t get_pixel(uint16_t x, uint16_t y);
+ void set_pixel(uint16_t x, uint16_t y, uint32_t clr);
+
+ // Converts the given pixel into an OpenGl point. This might
+ // need some flipping of axis, depending if you want to render
+ // on the screen or not.
+ virtual void pixel_to_gl(float* x, float* y) const = 0;
+
+protected:
+ // Convert the 'rect' in pixel space into opengl space.
+ enum class ConversionMode {
+ // Convert the rect as given.
+ kExact,
+
+ // Convert the rect so that the borders are in the center
+ // of the pixels.
+ kMidPoint,
+ };
+ FloatRect to_opengl(const Rect& rect, ConversionMode mode);
+
+ /// Logical width and height of the surface
+ uint16_t m_w, m_h;
+
+ /// Pixel data, while the texture is locked
+ std::unique_ptr<uint8_t[]> m_pixels;
private:
DISALLOW_COPY_AND_ASSIGN(Surface);
=== 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 10:15:33 +0000
@@ -18,6 +18,7 @@
USES_SDL2_TTF
USES_SDL2_GFX
DEPENDS
+ graphic_sdl_utils
base_exceptions
base_geometry
graphic_color
=== 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 10:15:33 +0000
@@ -23,7 +23,7 @@
#include <SDL_ttf.h>
#include <boost/format.hpp>
-#include "graphic/sdl/utils.h"
+#include "graphic/sdl_utils.h"
#include "graphic/surface.h"
#include "graphic/surface_cache.h"
#include "graphic/text/rt_errors.h"
=== 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 10:15:33 +0000
@@ -7,6 +7,7 @@
render_richtext.cc
DEPENDS
base_log
+ graphic
graphic_image_io
graphic_surface
graphic_text
=== 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 10:15:33 +0000
@@ -30,11 +30,14 @@
#undef main // No, we do not want SDL_main
#include "base/log.h"
+#include "config.h"
+#include "graphic/graphic.h"
#include "graphic/image_io.h"
-#include "graphic/sdl/surface.h"
+#include "graphic/surface.h"
#include "graphic/text/rt_errors.h"
#include "graphic/text/test/render.h"
#include "io/filesystem/filesystem.h"
+#include "io/filesystem/layered_filesystem.h"
#include "io/streamwrite.h"
namespace {
@@ -88,6 +91,17 @@
return 0;
}
+// Setup the static objects Widelands needs to operate and initializes systems.
+void initialize() {
+ SDL_Init(SDL_INIT_VIDEO);
+
+ g_fs = new LayeredFileSystem();
+ g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR));
+
+ g_gr = new Graphic();
+ g_gr->initialize(1, 1, false);
+}
+
} // namespace
int main(int argc, char** argv) {
@@ -117,19 +131,19 @@
return 1;
}
+ initialize();
+
StandaloneRenderer standalone_renderer;
try {
- std::unique_ptr<SDLSurface> surf(
- static_cast<SDLSurface*>(standalone_renderer.renderer()->render(txt, w, allowed_tags)));
+ std::unique_ptr<Surface> surf(standalone_renderer.renderer()->render(txt, w, allowed_tags));
std::unique_ptr<FileSystem> fs(&FileSystem::create("."));
std::unique_ptr<StreamWrite> sw(fs->open_stream_write(outname));
if (!save_surface_to_png(surf.get(), sw.get())) {
std::cout << "Could not encode PNG." << std::endl;
}
- }
- catch (RT::Exception& e) {
+ } catch (RT::Exception& e) {
std::cout << e.what() << std::endl;
}
=== modified file 'src/graphic/texture.cc'
--- src/graphic/texture.cc 2014-09-20 09:37:47 +0000
+++ src/graphic/texture.cc 2014-11-23 10:15:33 +0000
@@ -28,8 +28,6 @@
#include "io/fileread.h"
#include "io/filesystem/layered_filesystem.h"
-extern bool g_opengl;
-
using namespace std;
/**
@@ -37,15 +35,8 @@
* Currently it converts a 16 bit image to a 8 bit texture. This should
* be changed to load a 8 bit file directly, however.
*/
-Texture::Texture(const std::vector<std::string>& texture_files,
- const uint32_t frametime,
- const SDL_PixelFormat& format)
- : m_colormap(nullptr),
- m_pixels(nullptr),
- m_curframe(nullptr),
- m_frame_num(0),
- m_nrframes(0),
- m_frametime(frametime) {
+Texture::Texture(const std::vector<std::string>& texture_files, const uint32_t frametime)
+ : m_frame_num(0), m_frametime(frametime) {
if (texture_files.empty()) {
throw wexception("No images for texture.");
}
@@ -58,7 +49,8 @@
m_texture_image = fname;
SDL_Surface* surf = load_image_as_sdl_surface(fname, g_fs);
if (!surf) {
- throw wexception("WARNING: Failed to load texture frame %s: %s\n", fname.c_str(), IMG_GetError());
+ throw wexception(
+ "WARNING: Failed to load texture frame %s: %s\n", fname.c_str(), IMG_GetError());
}
if (surf->w != TEXTURE_WIDTH || surf->h != TEXTURE_HEIGHT) {
SDL_FreeSurface(surf);
@@ -69,7 +61,7 @@
}
// calculate shades on the first frame
- if (!m_nrframes) {
+ if (m_gl_textures.empty()) {
uint8_t top_left_pixel = static_cast<uint8_t*>(surf->pixels)[0];
SDL_Color top_left_pixel_color = surf->format->palette->colors[top_left_pixel];
for (int i = -128; i < 128; i++) {
@@ -81,72 +73,15 @@
}
}
- if (g_opengl) {
- // Note: we except the constructor to free the SDL surface
- GLSurfaceTexture* surface = new GLSurfaceTexture(surf);
- m_glFrames.emplace_back(surface);
-
- ++m_nrframes;
- continue;
- }
-
- // Determine color map if it's the first frame
- if (!m_nrframes) {
- if (surf->format->BitsPerPixel != 8) {
- throw wexception("Terrain %s is not 8 bits per pixel.", fname.c_str());
- }
- m_colormap.reset(new Colormap(*surf->format->palette->colors, format));
- }
-
- // Convert to our palette
- SDL_Palette palette;
- SDL_PixelFormat fmt;
-
- palette.ncolors = 256;
- palette.colors = m_colormap->get_palette();
-
- memset(&fmt, 0, sizeof(fmt));
- fmt.BitsPerPixel = 8;
- fmt.BytesPerPixel = 1;
- fmt.palette = &palette;
-
- SDL_Surface * const cv = SDL_ConvertSurface(surf, &fmt, 0);
-
- // Add the frame
- uint8_t* new_ptr =
- static_cast<uint8_t *>
- (realloc
- (m_pixels, TEXTURE_WIDTH * TEXTURE_HEIGHT * (m_nrframes + 1)));
- if (!new_ptr)
- throw wexception("Out of memory.");
- m_pixels = new_ptr;
-
-
- m_curframe = &m_pixels[TEXTURE_WIDTH * TEXTURE_HEIGHT * m_nrframes];
- ++m_nrframes;
-
- SDL_LockSurface(cv);
-
- for (int32_t y = 0; y < TEXTURE_HEIGHT; ++y)
- memcpy
- (m_curframe + y * TEXTURE_WIDTH,
- static_cast<uint8_t *>(cv->pixels) + y * cv->pitch,
- TEXTURE_WIDTH);
- SDL_UnlockSurface(cv);
- SDL_FreeSurface(cv);
- SDL_FreeSurface(surf);
+ // Note: we except the constructor to free the SDL surface
+ GLSurfaceTexture* surface = new GLSurfaceTexture(surf);
+ m_gl_textures.emplace_back(surface);
}
- if (!m_nrframes)
+ if (m_gl_textures.empty())
throw wexception("Texture has no frames");
}
-
-Texture::~Texture ()
-{
- free(m_pixels);
-}
-
/**
* Return the basic terrain colour to be used in the minimap.
*/
@@ -159,8 +94,5 @@
*/
void Texture::animate(uint32_t time)
{
- m_frame_num = (time / m_frametime) % m_nrframes;
- if (g_opengl)
- return;
- m_curframe = &m_pixels[TEXTURE_WIDTH * TEXTURE_HEIGHT * m_frame_num];
+ m_frame_num = (time / m_frametime) % m_gl_textures.size();
}
=== modified file 'src/graphic/texture.h'
--- src/graphic/texture.h 2014-10-11 13:26:59 +0000
+++ src/graphic/texture.h 2014-11-23 10:15:33 +0000
@@ -45,33 +45,25 @@
* changed to load 8 bit bitmaps directly.
*/
struct Texture {
- Texture(const std::vector<std::string>& texture_files,
- uint32_t frametime,
- const SDL_PixelFormat&);
- ~Texture();
-
- const std::string & get_texture_image() const {return m_texture_image;}
-
- uint8_t * get_pixels () const {return m_pixels;}
- uint8_t * get_curpixels() const {return m_curframe;}
- void * get_colormap () const {return m_colormap->get_colormap();}
+ Texture(const std::vector<std::string>& texture_files, uint32_t frametime);
+
+ const std::string& get_texture_image() const {
+ return m_texture_image;
+ }
+ uint32_t get_texture() const {
+ return m_gl_textures.at(m_frame_num)->get_gl_texture();
+ }
RGBColor get_minimap_color(int8_t shade);
void animate(uint32_t time);
- uint32_t get_texture() const
- {return m_glFrames.at(m_frame_num)->get_gl_texture();}
private:
- std::unique_ptr<Colormap> m_colormap;
- uint8_t * m_pixels;
RGBColor m_minimap_colors[256];
- uint8_t * m_curframe;
int32_t m_frame_num;
std::string m_texture_image;
- uint32_t m_nrframes;
uint32_t m_frametime;
- std::vector<std::unique_ptr<GLSurfaceTexture>> m_glFrames;
+ std::vector<std::unique_ptr<GLSurfaceTexture>> m_gl_textures;
};
#endif // end of include guard: WL_GRAPHIC_TEXTURE_H
=== 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 10:15:33 +0000
@@ -43,19 +43,14 @@
namespace {
// Setup the static objects Widelands needs to operate and initializes systems.
-void initialize(bool use_opengl) {
+void initialize() {
SDL_Init(SDL_INIT_VIDEO);
g_fs = new LayeredFileSystem();
g_fs->add_file_system(&FileSystem::create(INSTALL_DATADIR));
-#ifdef HAS_GETENV
- char dummy_video_env[] = "SDL_VIDEODRIVER=dummy";
- putenv(dummy_video_env);
-#endif
-
g_gr = new Graphic();
- g_gr->initialize(1, 1, false, use_opengl);
+ g_gr->initialize(1, 1, false);
}
} // namespace
@@ -63,21 +58,14 @@
int main(int argc, char ** argv)
{
if (!(2 <= argc && argc <= 3)) {
- log("Usage: %s [--opengl] <map file>\n", argv[0]);
+ log("Usage: %s <map file>\n", argv[0]);
return 1;
}
- bool use_opengl = false;
- for (int i = 0; i < argc; ++i) {
- if (std::string(argv[i]) == "--opengl") {
- use_opengl = true;
- }
- }
-
const std::string map_path = argv[argc - 1];
try {
- initialize(use_opengl);
+ initialize();
std::string map_dir = FileSystem::fs_dirname(map_path);
if (map_dir.empty()) {
=== 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 10:15:33 +0000
@@ -555,14 +555,6 @@
get_w() - 2 * m_hmargin - m_remove_syncstreams.get_w() - m_padding, 40,
_("Remove Syncstream dumps on startup"), UI::Align_VCenter),
- m_opengl (this, Point(m_hmargin,
- m_label_remove_syncstreams.get_y() +
- m_label_remove_syncstreams.get_h() + m_padding)),
- m_label_opengl
- (this,
- m_hmargin + m_opengl.get_w() + m_padding, m_opengl.get_y(),
- get_w() - 2 * m_hmargin - m_opengl.get_w() - m_padding, 40,
- _("OpenGL rendering"), UI::Align_VCenter),
os(opt)
{
for (UI::Button* temp_button : m_sb_dis_panel.get_buttons()) {
@@ -594,7 +586,6 @@
m_message_sound .set_state(opt.message_sound);
m_nozip .set_state(opt.nozip);
m_remove_syncstreams .set_state(opt.remove_syncstreams);
- m_opengl .set_state(opt.opengl);
m_transparent_chat .set_state(opt.transparent_chat);
// Fill the font list.
@@ -678,7 +669,6 @@
os.panel_snap_distance = m_sb_dis_panel.get_value();
os.border_snap_distance = m_sb_dis_border.get_value();
os.remove_syncstreams = m_remove_syncstreams.get_state();
- os.opengl = m_opengl.get_state();
os.transparent_chat = m_transparent_chat.get_state();
return os;
}
@@ -734,7 +724,6 @@
opt.panel_snap_distance = m_opt_section.get_int("panel_snap_distance", 0);
opt.remove_replays = m_opt_section.get_int("remove_replays", 0);
opt.remove_syncstreams = m_opt_section.get_bool("remove_syncstreams", true);
- opt.opengl = m_opt_section.get_bool("opengl", true);
opt.transparent_chat = m_opt_section.get_bool("transparent_chat", true);
return opt;
}
@@ -766,7 +755,6 @@
m_opt_section.set_int("remove_replays", opt.remove_replays);
m_opt_section.set_bool("remove_syncstreams", opt.remove_syncstreams);
- m_opt_section.set_bool("opengl", opt.opengl);
m_opt_section.set_bool("transparent_chat", opt.transparent_chat);
WLApplication::get()->set_input_grab(opt.inputgrab);
=== 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 10:15:33 +0000
@@ -54,7 +54,6 @@
uint32_t maxfps;
uint32_t remove_replays;
bool remove_syncstreams;
- bool opengl;
bool transparent_chat;
// advanced options
@@ -197,8 +196,6 @@
UI::MultilineTextarea m_label_nozip;
UI::Checkbox m_remove_syncstreams;
UI::MultilineTextarea m_label_remove_syncstreams;
- UI::Checkbox m_opengl;
- UI::MultilineTextarea m_label_opengl;
OptionsCtrl::OptionsStruct os;
};
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2014-11-22 10:18:20 +0000
+++ src/wlapplication.cc 2014-11-23 10:15:33 +0000
@@ -676,7 +676,7 @@
* with the given resolution.
* Throws an exception on failure.
*/
-void WLApplication::init_graphics(int32_t w, int32_t h, bool fullscreen, bool opengl)
+void WLApplication::init_graphics(int32_t w, int32_t h, bool fullscreen)
{
if (!w && !h) { // shutdown.
delete g_gr;
@@ -687,13 +687,10 @@
if (!g_gr) {
g_gr = new Graphic();
- g_gr->initialize(w, h, fullscreen, opengl);
+ g_gr->initialize(w, h, fullscreen);
} else {
- if
- (g_gr->get_xres() != w || g_gr->get_yres() != h
- || g_gr->is_fullscreen() != fullscreen || g_opengl != opengl)
- {
- g_gr->initialize(w, h, fullscreen, opengl);
+ if (g_gr->get_xres() != w || g_gr->get_yres() != h || g_gr->is_fullscreen() != fullscreen) {
+ g_gr->initialize(w, h, fullscreen);
}
}
}
@@ -703,11 +700,9 @@
Section & s = g_options.pull_section("global");
// Switch to the new graphics system now, if necessary.
- init_graphics
- (s.get_int("xres", DEFAULT_RESOLUTION_W),
- s.get_int("yres", DEFAULT_RESOLUTION_H),
- s.get_bool("fullscreen", false),
- s.get_bool("opengl", true));
+ init_graphics(s.get_int("xres", DEFAULT_RESOLUTION_W),
+ s.get_int("yres", DEFAULT_RESOLUTION_H),
+ s.get_bool("fullscreen", false));
// does only work with a window
set_input_grab(s.get_bool("inputgrab", false));
}
@@ -732,7 +727,6 @@
// Profile needs support for a Syntax definition to solve this in a
// sensible way
s.get_bool("fullscreen");
- s.get_bool("opengl");
s.get_int("xres");
s.get_int("yres");
s.get_int("border_snap_distance");
@@ -851,7 +845,7 @@
"alive!"
<< std::endl;
- init_graphics(0, 0, false, false);
+ init_graphics(0, 0, false);
SDL_QuitSubSystem(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
#ifndef _WIN32
=== modified file 'src/wlapplication.h'
--- src/wlapplication.h 2014-11-22 10:18:20 +0000
+++ src/wlapplication.h 2014-11-23 10:15:33 +0000
@@ -164,7 +164,7 @@
void set_mouse_lock(const bool locked) {m_mouse_locked = locked;}
//@}
- void init_graphics(int32_t w, int32_t h, bool fullscreen, bool opengl);
+ void init_graphics(int32_t w, int32_t h, bool fullscreen);
/**
* Refresh the graphics from the latest options.
=== modified file 'src/wlapplication_messages.cc'
--- src/wlapplication_messages.cc 2014-11-03 19:51:45 +0000
+++ src/wlapplication_messages.cc 2014-11-23 10:15:33 +0000
@@ -99,8 +99,7 @@
<< _(" --yres=[...] Height of the window in pixel.") << endl
/** TRANSLATORS: You may translate true/false, also as on/off or yes/no, but */
/** TRANSLATORS: it HAS TO BE CONSISTENT with the translation in the widelands textdomain */
- << _(" --opengl=[true|false]\n"
- " Enables OpenGL rendering") << endl << endl
+ << endl
<< _("Options for the internal window manager:") << endl
<< _(" --border_snap_distance=[0 ...]\n"
" Move a window to the edge of the screen\n"
=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc 2014-11-13 08:25:45 +0000
+++ src/wui/mapview.cc 2014-11-23 10:15:33 +0000
@@ -23,7 +23,6 @@
#include "graphic/gl/game_renderer.h"
#include "graphic/graphic.h"
#include "graphic/rendertarget.h"
-#include "graphic/sdl/game_renderer.h"
#include "logic/map.h"
#include "logic/player.h"
#include "wlapplication.h"
@@ -92,12 +91,7 @@
egbase.map().overlay_manager().load_graphics();
if (!m_renderer) {
- if (g_opengl) {
- m_renderer.reset(new GlGameRenderer());
- } else
- {
- m_renderer.reset(new SdlGameRenderer());
- }
+ m_renderer.reset(new GlGameRenderer());
}
if (upcast(InteractivePlayer const, interactive_player, &intbase())) {
m_renderer->rendermap(dst, egbase, interactive_player->player(), m_viewpoint);
References