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);
_______________________________________________ Mailing list: https://launchpad.net/~widelands-dev Post to : widelands-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~widelands-dev More help : https://help.launchpad.net/ListHelp