widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #03203
[Merge] lp:~widelands-dev/widelands/cleanup_game_renderer into lp:widelands
SirVer has proposed merging lp:~widelands-dev/widelands/cleanup_game_renderer into lp:widelands with lp:~widelands-dev/widelands/use_sdl_image_in_one_place as a prerequisite.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/cleanup_game_renderer/+merge/243124
This is bart of some chained branches. The base branches need to be merged before this.
Suggested commit message:
- Consolidated GameRenderer and its only base class into one.
- Pulled map renderer and minimap renderer into their own library. It becomes clear that we have basic graphics library and a widelands aware one.
- Removed unused files.
---
We should think about changing the directory layout of src. We have at least a wl/ui (wui) base/ui (ui_basic), wl/scripting (most of it), base/scripting (LuaTable at least) , wl/graphic (game renderer, minimap renderer) and base/graphic (surfaces, texture_atlas and so on).
I do not like the name base/ for the "basic" libraries. The separation is "could be useful for other projects" and "is widelands aware". Suggestions for cool names?
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/cleanup_game_renderer into lp:widelands.
=== modified file 'src/editor/CMakeLists.txt'
--- src/editor/CMakeLists.txt 2014-10-13 15:04:50 +0000
+++ src/editor/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -104,4 +104,6 @@
ui_fsmenu
widelands_ball_of_mud
wui
+ wui_mapview_pixelfunctions
+ wui_overlay_manager
)
=== modified file 'src/game_io/CMakeLists.txt'
--- src/game_io/CMakeLists.txt 2014-11-24 06:31:16 +0000
+++ src/game_io/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -27,6 +27,7 @@
base_time_string
economy
graphic
+ graphic_minimap_renderer
io_fileread
io_filesystem
logic
@@ -36,4 +37,6 @@
profile
scripting
wui
+ wui_mapview_pixelfunctions
+ wui_overlay_manager
)
=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt 2014-11-28 08:45:54 +0000
+++ src/graphic/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -1,5 +1,8 @@
add_subdirectory(text)
+# TODO(sirver): Separate this directory into a base directory and one
+# that is Widelands aware (can include logic stuff).
+
wl_library(graphic_color
SRCS
color.h
@@ -77,14 +80,52 @@
graphic_surface
)
+wl_library(graphic_game_renderer
+ SRCS
+ game_renderer.cc
+ game_renderer.h
+ gl/dither_program.cc
+ gl/dither_program.h
+ gl/fields_to_draw.h
+ gl/road_program.cc
+ gl/road_program.h
+ gl/terrain_program.cc
+ gl/terrain_program.h
+ DEPENDS
+ base_exceptions
+ base_geometry
+ base_log
+ base_macros
+ graphic
+ graphic_image_io
+ graphic_surface
+ io_filesystem
+ logic
+ wui_mapview_pixelfunctions
+ wui_overlay_manager
+)
+
+wl_library(graphic_minimap_renderer
+ SRCS
+ minimap_renderer.cc
+ minimap_renderer.h
+ DEPENDS
+ base_geometry
+ base_macros
+ economy
+ graphic
+ graphic_image
+ graphic_surface
+ logic
+ wui_mapview_pixelfunctions
+)
+
wl_library(graphic
SRCS
align.cc
align.h
animation.cc
animation.h
- colormap.cc
- colormap.h
default_resolution.h
diranimations.h
font.cc
@@ -93,34 +134,21 @@
font_handler.h
font_handler1.cc
font_handler1.h
- game_renderer.cc
- game_renderer.h
gl/blit_program.cc
gl/blit_program.h
- gl/dither_program.cc
- gl/dither_program.h
gl/draw_line_program.cc
gl/draw_line_program.h
gl/draw_rect_program.cc
gl/draw_rect_program.h
- gl/fields_to_draw.h
gl/fill_rect_program.cc
gl/fill_rect_program.h
- gl/game_renderer.cc
- gl/game_renderer.h
- gl/road_program.cc
- gl/road_program.h
gl/system_headers.h
- gl/terrain_program.cc
- gl/terrain_program.h
graphic.cc
graphic.h
image_transformations.cc
image_transformations.h
in_memory_image.cc
in_memory_image.h
- minimap_renderer.cc
- minimap_renderer.h
rendertarget.cc
rendertarget.h
richtext.cc
@@ -141,7 +169,6 @@
base_log
base_macros
build_info
- economy
graphic_color
graphic_image
graphic_image_io
@@ -156,6 +183,6 @@
profile
scripting
sound
- wui
+ wui_overlay_manager
wui_text_layout
)
=== removed file 'src/graphic/colormap.cc'
--- src/graphic/colormap.cc 2014-07-17 13:26:23 +0000
+++ src/graphic/colormap.cc 1970-01-01 00:00:00 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2002-2004, 2006, 2009 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/colormap.h"
-
-#include <algorithm>
-#include <cassert>
-#include <cstdlib>
-#include <cstring>
-
-/**
- * Create a new Colormap, taking the palette as a parameter.
- * It automatically creates the colormap for shading.
- */
-Colormap::Colormap (const SDL_Color & pal, const SDL_PixelFormat & format) {
- memcpy(palette, &pal, sizeof(palette));
-
- assert(format.BytesPerPixel == 4);
- colormap = malloc(format.BytesPerPixel * 65536);
-
- for (int i = 0; i < 256; ++i)
- for (int j = 0; j < 256; ++j) {
- int32_t shade = (j < 128) ? j : (j - 256);
- shade = 256 + 2 * shade;
-
- const uint32_t r = std::min<uint32_t>((palette[i].r * shade) >> 8, 255);
- const uint32_t g = std::min<uint32_t>((palette[i].g * shade) >> 8, 255);
- const uint32_t b = std::min<uint32_t>((palette[i].b * shade) >> 8, 255);
-
- const uint32_t value =
- SDL_MapRGB(&const_cast<SDL_PixelFormat &>(format), r, g, b);
- static_cast<uint32_t *>(colormap)[(j << 8) | i] = value;
- }
-}
-
-/**
- * Clean up.
- */
-Colormap::~Colormap ()
-{
- free(colormap);
-}
=== removed file 'src/graphic/colormap.h'
--- src/graphic/colormap.h 2014-07-12 12:25:21 +0000
+++ src/graphic/colormap.h 1970-01-01 00:00:00 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2002-2004, 2006, 2008 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_COLORMAP_H
-#define WL_GRAPHIC_COLORMAP_H
-
-#include <SDL_video.h>
-
-#include "graphic/color.h"
-
-/**
- * Colormap contains a palette and lookup table for use with ground textures.
-*/
-class Colormap {
-public:
- Colormap (const SDL_Color &, const SDL_PixelFormat & fmt);
- ~Colormap ();
-
- // Returns the palette of this colormap (256 entries of RGB Colors);
- SDL_Color * get_palette() {return palette;}
-
- // Returns the internally calculated colormap used in the renderer.
- void * get_colormap () const {return colormap;}
-
-private:
- SDL_Color palette[256];
-
- /// maps 8 bit color and brightness value to the shaded color.
- /// \note Brightness is currently 8 bits. Restricting brightness to 64 or
- /// less shades would greatly reduce the size of this table, and thus
- /// improve memory cache impact inside the renderer.
- void * colormap;
-};
-
-#endif // end of include guard: WL_GRAPHIC_COLORMAP_H
=== modified file 'src/graphic/game_renderer.cc'
--- src/graphic/game_renderer.cc 2014-09-27 18:53:55 +0000
+++ src/graphic/game_renderer.cc 2014-11-28 08:45:54 +0000
@@ -19,82 +19,227 @@
#include "graphic/game_renderer.h"
-#include "base/macros.h"
+#include <memory>
+
+#include "graphic/gl/dither_program.h"
+#include "graphic/gl/fields_to_draw.h"
+#include "graphic/gl/road_program.h"
+#include "graphic/gl/terrain_program.h"
#include "graphic/graphic.h"
#include "graphic/rendertarget.h"
+#include "graphic/surface.h"
#include "logic/editor_game_base.h"
#include "logic/player.h"
+#include "logic/world/world.h"
+#include "wui/mapviewpixelconstants.h"
#include "wui/mapviewpixelfunctions.h"
#include "wui/overlay_manager.h"
+// Explanation of how drawing works:
+// Schematic of triangle neighborhood:
+//
+// *
+// / \
+// / u \
+// (f)/ \
+// *------*------* (r)
+// \ l / \ r / \
+// \ / \ / \
+// \/ d \/ rr \
+// *------*------* (br)
+// \ dd /
+// \ /
+// \/
+// *
+//
+// Each field (f) owns two triangles: (r)ight & (d)own. When we look at the
+// field, we have to make sure to schedule drawing the triangles. This is done
+// by of these triangles is done by TerrainProgram.
+//
+// To draw dithered edges, we have to look at the neighboring triangles for the
+// two triangles too: If a neighboring triangle has another texture and our
+// dither layer is smaller, we have to draw a dithering triangle too - this lets the neighboring
+// texture
+// bleed into our triangle.
+//
+// The dither triangle is the triangle that should be partially (either r or
+// d). Example: if r and d have different textures and r.dither_layer >
+// d.dither_layer, then we will repaint d with the dither texture as mask.
+
+std::unique_ptr<TerrainProgram> GameRenderer::terrain_program_;
+std::unique_ptr<DitherProgram> GameRenderer::dither_program_;
+std::unique_ptr<RoadProgram> GameRenderer::road_program_;
+
+namespace {
+
using namespace Widelands;
-GameRenderer::GameRenderer()
-{
-}
-
-GameRenderer::~GameRenderer()
-{
-}
-
-void GameRenderer::rendermap
- (RenderTarget & dst,
- const Widelands::EditorGameBase & egbase,
- const Widelands::Player & player,
- const Point & viewofs)
-{
- m_dst = &dst;
- m_dst_offset = -viewofs;
- m_egbase = &egbase;
- m_player = &player;
-
- draw_wrapper();
-}
-
-void GameRenderer::rendermap
- (RenderTarget & dst,
- const Widelands::EditorGameBase & egbase,
- const Point & viewofs)
-{
- m_dst = &dst;
- m_dst_offset = -viewofs;
- m_egbase = &egbase;
- m_player = nullptr;
-
- draw_wrapper();
-}
-
-void GameRenderer::draw_wrapper()
-{
- Point tl_map = m_dst->get_offset() - m_dst_offset;
+// Returns the brightness value in [0, 1.] for 'fcoords' at 'gametime' for
+// 'player' (which can be nullptr).
+float field_brightness(const FCoords& fcoords,
+ const uint32_t gametime,
+ const Map& map,
+ const Player* const player) {
+ uint32_t brightness = 144 + fcoords.field->get_brightness();
+ brightness = std::min<uint32_t>(255, (brightness * 255) / 160);
+
+ if (player && !player->see_all()) {
+ const Player::Field& pf = player->fields()[Map::get_index(fcoords, map.get_width())];
+ if (pf.vision == 0) {
+ return 0.;
+ } else if (pf.vision == 1) {
+ static const uint32_t kDecayTimeInMs = 20000;
+ const Duration time_ago = gametime - pf.time_node_last_unseen;
+ if (time_ago < kDecayTimeInMs) {
+ brightness = (brightness * (2 * kDecayTimeInMs - time_ago)) / (2 * kDecayTimeInMs);
+ } else {
+ brightness = brightness / 2;
+ }
+ }
+ }
+ return brightness / 255.;
+}
+
+// Returns the road that should be rendered here. The format is like in field,
+// but this is not the physically present road, but the one that should be
+// drawn (i.e. taking into account if there is fog of war involved or road
+// building overlays enabled).
+uint8_t field_roads(const FCoords& coords, const Map& map, const Player* const player) {
+ uint8_t roads;
+ if (player && !player->see_all()) {
+ const Player::Field& pf = player->fields()[Map::get_index(coords, map.get_width())];
+ roads = pf.roads | map.overlay_manager().get_road_overlay(coords);
+ } else {
+ roads = coords.field->get_roads();
+ }
+ roads |= map.overlay_manager().get_road_overlay(coords);
+ return roads;
+}
+
+} // namespace
+
+GameRenderer::GameRenderer() {
+}
+
+GameRenderer::~GameRenderer() {
+}
+
+void GameRenderer::rendermap(RenderTarget& dst,
+ const Widelands::EditorGameBase& egbase,
+ const Point& view_offset,
+
+ const Widelands::Player& player) {
+ draw(dst, egbase, view_offset, &player);
+}
+
+void GameRenderer::rendermap(RenderTarget& dst,
+ const Widelands::EditorGameBase& egbase,
+ const Point& view_offset) {
+ draw(dst, egbase, view_offset, nullptr);
+}
+
+void GameRenderer::draw(RenderTarget& dst,
+ const EditorGameBase& egbase,
+ const Point& view_offset,
+ const Player* player) {
+ if (terrain_program_ == nullptr) {
+ terrain_program_.reset(new TerrainProgram());
+ dither_program_.reset(new DitherProgram());
+ road_program_.reset(new RoadProgram());
+ }
+
+ Point tl_map = dst.get_offset() + view_offset;
assert(tl_map.x >= 0); // divisions involving negative numbers are bad
assert(tl_map.y >= 0);
- m_minfx = tl_map.x / TRIANGLE_WIDTH - 1;
- m_minfy = tl_map.y / TRIANGLE_HEIGHT - 1;
- m_maxfx = (tl_map.x + m_dst->get_rect().w + (TRIANGLE_WIDTH / 2)) / TRIANGLE_WIDTH;
- m_maxfy = (tl_map.y + m_dst->get_rect().h) / TRIANGLE_HEIGHT;
+ int minfx = tl_map.x / TRIANGLE_WIDTH - 1;
+ int minfy = tl_map.y / TRIANGLE_HEIGHT - 1;
+ int maxfx = (tl_map.x + dst.get_rect().w + (TRIANGLE_WIDTH / 2)) / TRIANGLE_WIDTH;
+ int maxfy = (tl_map.y + dst.get_rect().h) / TRIANGLE_HEIGHT;
// fudge for triangle boundary effects and for height differences
- m_minfx -= 1;
- m_minfy -= 1;
- m_maxfx += 1;
- m_maxfy += 10;
-
- draw();
+ minfx -= 1;
+ minfy -= 1;
+ maxfx += 1;
+ maxfy += 10;
+
+
+ Surface* surface = dst.get_surface();
+ if (!surface)
+ return;
+
+ const Rect& bounding_rect = dst.get_rect();
+ const Point surface_offset = bounding_rect.top_left() + dst.get_offset() - view_offset;
+
+ glScissor(bounding_rect.x,
+ surface->height() - bounding_rect.y - bounding_rect.h,
+ bounding_rect.w,
+ bounding_rect.h);
+ glEnable(GL_SCISSOR_TEST);
+
+ Map& map = egbase.map();
+ const uint32_t gametime = egbase.get_gametime();
+
+ FieldsToDraw fields_to_draw(minfx, maxfx, minfy, maxfy);
+ for (int32_t fy = minfy; fy <= maxfy; ++fy) {
+ for (int32_t fx = minfx; fx <= maxfx; ++fx) {
+ FieldsToDraw::Field& f =
+ *fields_to_draw.mutable_field(fields_to_draw.calculate_index(fx, fy));
+
+ f.fx = fx;
+ f.fy = fy;
+
+ Coords coords(fx, fy);
+ int x, y;
+ MapviewPixelFunctions::get_basepix(coords, x, y);
+
+ map.normalize_coords(coords);
+ const FCoords& fcoords = map.get_fcoords(coords);
+
+ f.texture_x = float(x) / kTextureSideLength;
+ f.texture_y = float(y) / kTextureSideLength;
+
+ f.gl_x = f.pixel_x = x + surface_offset.x;
+ f.gl_y = f.pixel_y = y + surface_offset.y - fcoords.field->get_height() * HEIGHT_FACTOR;
+ surface->pixel_to_gl(&f.gl_x, &f.gl_y);
+
+ f.ter_d = fcoords.field->terrain_d();
+ f.ter_r = fcoords.field->terrain_r();
+
+ f.brightness = field_brightness(fcoords, gametime, map, player);
+
+ f.roads = field_roads(fcoords, map, player);
+ }
+ }
+
+ const World& world = egbase.world();
+ terrain_program_->draw(gametime, world.terrains(), fields_to_draw);
+ dither_program_->draw(gametime, world.terrains(), fields_to_draw);
+ road_program_->draw(*surface, fields_to_draw);
+
+ draw_objects(dst, egbase, view_offset, player, minfx, maxfx, minfy, maxfy);
+
+ glDisable(GL_SCISSOR_TEST);
}
-void GameRenderer::draw_objects()
-{
+void GameRenderer::draw_objects(RenderTarget& dst,
+ const EditorGameBase& egbase,
+ const Point& view_offset,
+ const Player* player,
+ int minfx,
+ int maxfx,
+ int minfy,
+ int maxfy) {
+ // TODO(sirver): this should use FieldsToDraw. Would simplify this function a lot.
static const uint32_t F = 0;
static const uint32_t R = 1;
static const uint32_t BL = 2;
static const uint32_t BR = 3;
- const Map & map = m_egbase->map();
+ const Map & map = egbase.map();
- for (int32_t fy = m_minfy; fy <= m_maxfy; ++fy) {
- for (int32_t fx = m_minfx; fx <= m_maxfx; ++fx) {
+ for (int32_t fy = minfy; fy <= maxfy; ++fy) {
+ for (int32_t fx = minfx; fx <= maxfx; ++fx) {
Coords ncoords(fx, fy);
map.normalize_coords(ncoords);
FCoords coords[4];
@@ -109,7 +254,7 @@
MapviewPixelFunctions::get_basepix(Coords(fx + (fy & 1), fy + 1), pos[BR].x, pos[BR].y);
for (uint32_t d = 0; d < 4; ++d) {
pos[d].y -= coords[d].field->get_height() * HEIGHT_FACTOR;
- pos[d] += m_dst_offset;
+ pos[d] -= view_offset;
}
PlayerNumber owner_number[4];
@@ -120,9 +265,9 @@
for (uint32_t d = 0; d < 4; ++d)
isborder[d] = coords[d].field->is_border();
- if (m_player && !m_player->see_all()) {
+ if (player && !player->see_all()) {
for (uint32_t d = 0; d < 4; ++d) {
- const Player::Field & pf = m_player->fields()[map.get_index(coords[d], map.get_width())];
+ const Player::Field & pf = player->fields()[map.get_index(coords[d], map.get_width())];
vision[d] = pf.vision;
if (pf.vision == 1) {
owner_number[d] = pf.owner;
@@ -132,32 +277,32 @@
}
if (isborder[F]) {
- const Player & owner = m_egbase->player(owner_number[F]);
+ const Player & owner = egbase.player(owner_number[F]);
uint32_t const anim_idx = owner.tribe().frontier_animation();
if (vision[F])
- m_dst->drawanim(pos[F], anim_idx, 0, &owner);
+ dst.drawanim(pos[F], anim_idx, 0, &owner);
for (uint32_t d = 1; d < 4; ++d) {
if
((vision[F] || vision[d]) &&
isborder[d] &&
(owner_number[d] == owner_number[F] || !owner_number[d]))
{
- m_dst->drawanim(middle(pos[F], pos[d]), anim_idx, 0, &owner);
+ dst.drawanim(middle(pos[F], pos[d]), anim_idx, 0, &owner);
}
}
}
if (1 < vision[F]) { // Render stuff that belongs to the node.
if (BaseImmovable * const imm = coords[F].field->get_immovable())
- imm->draw(*m_egbase, *m_dst, coords[F], pos[F]);
+ imm->draw(egbase, dst, coords[F], pos[F]);
for
(Bob * bob = coords[F].field->get_first_bob();
bob;
bob = bob->get_next_bob())
- bob->draw(*m_egbase, *m_dst, pos[F]);
+ bob->draw(egbase, dst, pos[F]);
} else if (vision[F] == 1) {
- const Player::Field & f_pl = m_player->fields()[map.get_index(coords[F], map.get_width())];
- const Player * owner = owner_number[F] ? m_egbase->get_player(owner_number[F]) : nullptr;
+ const Player::Field & f_pl = player->fields()[map.get_index(coords[F], map.get_width())];
+ const Player * owner = owner_number[F] ? egbase.get_player(owner_number[F]) : nullptr;
if
(const MapObjectDescr * const map_object_descr =
f_pl.map_object_descr[TCoords<>::None])
@@ -193,7 +338,7 @@
if (cur_frame) // not the first frame
// draw the prev frame from top to where next image will be drawing
- m_dst->drawanimrect
+ dst.drawanimrect
(pos[F], anim_idx, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
else if (csinf.was) {
// Is the first frame, but there was another building here before,
@@ -204,11 +349,11 @@
} catch (MapObjectDescr::AnimationNonexistent &) {
a = csinf.was->get_animation("idle");
}
- m_dst->drawanimrect
+ dst.drawanimrect
(pos[F], a, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
}
assert(lines <= h);
- m_dst->drawanimrect(pos[F], anim_idx, tanim, owner, Rect(Point(0, h - lines), w, lines));
+ dst.drawanimrect(pos[F], anim_idx, tanim, owner, Rect(Point(0, h - lines), w, lines));
} else if (upcast(const BuildingDescr, building, map_object_descr)) {
// this is a building therefore we either draw unoccupied or idle animation
uint32_t pic;
@@ -217,11 +362,11 @@
} catch (MapObjectDescr::AnimationNonexistent &) {
pic = building->get_animation("idle");
}
- m_dst->drawanim(pos[F], pic, 0, owner);
+ dst.drawanim(pos[F], pic, 0, owner);
} else if (const uint32_t pic = map_object_descr->main_animation()) {
- m_dst->drawanim(pos[F], pic, 0, owner);
+ dst.drawanim(pos[F], pic, 0, owner);
} else if (map_object_descr->type() == MapObjectType::FLAG) {
- m_dst->drawanim(pos[F], owner->tribe().flag_animation(), 0, owner);
+ dst.drawanim(pos[F], owner->tribe().flag_animation(), 0, owner);
}
}
}
@@ -239,7 +384,7 @@
(const OverlayManager::OverlayInfo * it = overlay_info;
it < end;
++it)
- m_dst->blit(pos[F] - it->hotspot, it->pic);
+ dst.blit(pos[F] - it->hotspot, it->pic);
}
{
@@ -259,7 +404,7 @@
(OverlayManager::OverlayInfo const * it = overlay_info;
it < end;
++it)
- m_dst->blit(tripos - it->hotspot, it->pic);
+ dst.blit(tripos - it->hotspot, it->pic);
}
{
@@ -279,7 +424,7 @@
(OverlayManager::OverlayInfo const * it = overlay_info;
it < end;
++it)
- m_dst->blit(tripos - it->hotspot, it->pic);
+ dst.blit(tripos - it->hotspot, it->pic);
}
}
}
=== modified file 'src/graphic/game_renderer.h'
--- src/graphic/game_renderer.h 2014-09-27 18:53:55 +0000
+++ src/graphic/game_renderer.h 2014-11-28 08:45:54 +0000
@@ -20,17 +20,22 @@
#ifndef WL_GRAPHIC_GAME_RENDERER_H
#define WL_GRAPHIC_GAME_RENDERER_H
-#include <boost/utility.hpp>
+#include <memory>
#include "base/macros.h"
#include "base/point.h"
+#include "graphic/gl/utils.h"
namespace Widelands {
class Player;
class EditorGameBase;
}
+class DitherProgram;
class RenderTarget;
+class RoadProgram;
+class TerrainProgram;
+
/**
* This abstract base class renders the main game view into an
@@ -45,56 +50,41 @@
class GameRenderer {
public:
GameRenderer();
- virtual ~GameRenderer();
-
- /**
- * Renders the map from a player's point of view into the
- * given drawing window.
- *
- * @param viewofs is the offset of the upper left corner of
- * the window into the map, in pixels.
- */
- void rendermap
- (RenderTarget & dst,
- const Widelands::EditorGameBase & egbase,
- const Widelands::Player & player,
- const Point & viewofs);
-
- /**
- * Renders the map from an omniscient perspective.
- * This is used for spectators, players that see all, and in the editor.
- */
- void rendermap
- (RenderTarget & dst,
- const Widelands::EditorGameBase & egbase,
- const Point & viewofs);
-
-protected:
- virtual void draw() = 0;
-
- void draw_objects();
-
- /**
- * The following variables, which are setup by @ref rendermap,
- * are only valid during rendering,
- * and should be treated as read-only by derived classes.
- */
- /*@{*/
- RenderTarget * m_dst;
- Widelands::EditorGameBase const * m_egbase;
- Widelands::Player const * m_player;
-
- /// Translation from map pixel coordinates to @ref m_dst pixel coordinates
- Point m_dst_offset;
-
- int32_t m_minfx;
- int32_t m_minfy;
- int32_t m_maxfx;
- int32_t m_maxfy;
- /*@}*/
+ ~GameRenderer();
+
+ // Renders the map from a player's point of view into the given
+ // drawing window. 'view_offset' is the offset of the upper left
+ // corner of the window into the map, in pixels.
+ void rendermap(RenderTarget& dst,
+ const Widelands::EditorGameBase& egbase,
+ const Point& view_offset,
+ const Widelands::Player& player);
+
+ // Renders the map from an omniscient perspective. This is used
+ // for spectators, players that see all, and in the editor.
+ void rendermap(RenderTarget& dst, const Widelands::EditorGameBase& egbase, const Point& view_offset);
private:
- void draw_wrapper();
+ static std::unique_ptr<TerrainProgram> terrain_program_;
+ static std::unique_ptr<DitherProgram> dither_program_;
+ static std::unique_ptr<RoadProgram> road_program_;
+
+ // Draw the map for the given parameters (see rendermap). 'player'
+ // can be nullptr in which case the whole map is drawn.
+ void draw(RenderTarget& dst,
+ const Widelands::EditorGameBase& egbase,
+ const Point& view_offset,
+ const Widelands::Player* player);
+
+ // Draws the objects (animations & overlays).
+ void draw_objects(RenderTarget& dst,
+ const Widelands::EditorGameBase& egbase,
+ const Point& view_offset,
+ const Widelands::Player* player,
+ int minfx,
+ int maxfx,
+ int minfy,
+ int maxfy);
DISALLOW_COPY_AND_ASSIGN(GameRenderer);
};
=== removed file 'src/graphic/gl/game_renderer.cc'
--- src/graphic/gl/game_renderer.cc 2014-11-28 08:45:54 +0000
+++ src/graphic/gl/game_renderer.cc 1970-01-01 00:00:00 +0000
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2011-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/gl/game_renderer.h"
-
-#include <memory>
-
-#include "graphic/gl/dither_program.h"
-#include "graphic/gl/fields_to_draw.h"
-#include "graphic/gl/road_program.h"
-#include "graphic/gl/terrain_program.h"
-#include "graphic/graphic.h"
-#include "graphic/rendertarget.h"
-#include "graphic/surface.h"
-#include "logic/editor_game_base.h"
-#include "logic/player.h"
-#include "logic/world/world.h"
-#include "wui/mapviewpixelconstants.h"
-#include "wui/mapviewpixelfunctions.h"
-#include "wui/overlay_manager.h"
-
-namespace {
-
-using namespace Widelands;
-
-// Returns the brightness value in [0, 1.] for 'fcoords' at 'gametime' for
-// 'player' (which can be nullptr).
-float field_brightness(const FCoords& fcoords,
- const uint32_t gametime,
- const Map& map,
- const Player* const player) {
- uint32_t brightness = 144 + fcoords.field->get_brightness();
- brightness = std::min<uint32_t>(255, (brightness * 255) / 160);
-
- if (player && !player->see_all()) {
- const Player::Field& pf = player->fields()[Map::get_index(fcoords, map.get_width())];
- if (pf.vision == 0) {
- return 0.;
- } else if (pf.vision == 1) {
- static const uint32_t kDecayTimeInMs = 20000;
- const Duration time_ago = gametime - pf.time_node_last_unseen;
- if (time_ago < kDecayTimeInMs) {
- brightness = (brightness * (2 * kDecayTimeInMs - time_ago)) / (2 * kDecayTimeInMs);
- } else {
- brightness = brightness / 2;
- }
- }
- }
- return brightness / 255.;
-}
-
-// Returns the road that should be rendered here. The format is like in field,
-// but this is not the physically present road, but the one that should be
-// drawn (i.e. taking into account if there is fog of war involved or road
-// building overlays enabled).
-uint8_t field_roads(const FCoords& coords, const Map& map, const Player* const player) {
- uint8_t roads;
- if (player && !player->see_all()) {
- const Player::Field& pf = player->fields()[Map::get_index(coords, map.get_width())];
- roads = pf.roads | map.overlay_manager().get_road_overlay(coords);
- } else {
- roads = coords.field->get_roads();
- }
- roads |= map.overlay_manager().get_road_overlay(coords);
- return roads;
-}
-
-} // namespace
-
-// Explanation of how drawing works:
-// Schematic of triangle neighborhood:
-//
-// *
-// / \
-// / u \
-// (f)/ \
-// *------*------* (r)
-// \ l / \ r / \
-// \ / \ / \
-// \/ d \/ rr \
-// *------*------* (br)
-// \ dd /
-// \ /
-// \/
-// *
-//
-// Each field (f) owns two triangles: (r)ight & (d)own. When we look at the
-// field, we have to make sure to schedule drawing the triangles. This is done
-// by of these triangles is done by TerrainProgram.
-//
-// To draw dithered edges, we have to look at the neighboring triangles for the
-// two triangles too: If a neighboring triangle has another texture and our
-// dither layer is smaller, we have to draw a dithering triangle too - this lets the neighboring
-// texture
-// bleed into our triangle.
-//
-// The dither triangle is the triangle that should be partially (either r or
-// d). Example: if r and d have different textures and r.dither_layer >
-// d.dither_layer, then we will repaint d with the dither texture as mask.
-
-
-std::unique_ptr<TerrainProgram> GlGameRenderer::terrain_program_;
-std::unique_ptr<DitherProgram> GlGameRenderer::dither_program_;
-std::unique_ptr<RoadProgram> GlGameRenderer::road_program_;
-
-GlGameRenderer::GlGameRenderer() {
-}
-
-GlGameRenderer::~GlGameRenderer() {
-}
-
-void GlGameRenderer::draw() {
- if (terrain_program_ == nullptr) {
- terrain_program_.reset(new TerrainProgram());
- dither_program_.reset(new DitherProgram());
- road_program_.reset(new RoadProgram());
- }
-
- Surface* surface = m_dst->get_surface();
- if (!surface)
- return;
-
- const Rect& bounding_rect = m_dst->get_rect();
- const Point surface_offset = m_dst_offset + bounding_rect.top_left() + m_dst->get_offset();
-
- glScissor(bounding_rect.x,
- surface->height() - bounding_rect.y - bounding_rect.h,
- bounding_rect.w,
- bounding_rect.h);
- glEnable(GL_SCISSOR_TEST);
-
- Map& map = m_egbase->map();
- const uint32_t gametime = m_egbase->get_gametime();
-
- FieldsToDraw fields_to_draw(m_minfx, m_maxfx, m_minfy, m_maxfy);
- for (int32_t fy = m_minfy; fy <= m_maxfy; ++fy) {
- for (int32_t fx = m_minfx; fx <= m_maxfx; ++fx) {
- FieldsToDraw::Field& f =
- *fields_to_draw.mutable_field(fields_to_draw.calculate_index(fx, fy));
-
- f.fx = fx;
- f.fy = fy;
-
- Coords coords(fx, fy);
- int x, y;
- MapviewPixelFunctions::get_basepix(coords, x, y);
-
- map.normalize_coords(coords);
- const FCoords& fcoords = map.get_fcoords(coords);
-
- f.texture_x = float(x) / kTextureSideLength;
- f.texture_y = float(y) / kTextureSideLength;
-
- f.gl_x = f.pixel_x = x + surface_offset.x;
- f.gl_y = f.pixel_y = y + surface_offset.y - fcoords.field->get_height() * HEIGHT_FACTOR;
- surface->pixel_to_gl(&f.gl_x, &f.gl_y);
-
- f.ter_d = fcoords.field->terrain_d();
- f.ter_r = fcoords.field->terrain_r();
-
- f.brightness = field_brightness(fcoords, gametime, map, m_player);
-
- f.roads = field_roads(fcoords, map, m_player);
- }
- }
-
- const World& world = m_egbase->world();
- terrain_program_->draw(gametime, world.terrains(), fields_to_draw);
- dither_program_->draw(gametime, world.terrains(), fields_to_draw);
- road_program_->draw(*surface, fields_to_draw);
-
- draw_objects();
-
- glDisable(GL_SCISSOR_TEST);
-}
=== removed file 'src/graphic/gl/game_renderer.h'
--- src/graphic/gl/game_renderer.h 2014-11-01 20:40:39 +0000
+++ src/graphic/gl/game_renderer.h 1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011-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_GL_GAME_RENDERER_H
-#define WL_GRAPHIC_GL_GAME_RENDERER_H
-
-#include <memory>
-
-#include "graphic/game_renderer.h"
-#include "graphic/gl/utils.h"
-
-class TerrainProgram;
-class DitherProgram;
-class RoadProgram;
-
-/**
- * OpenGL implementation of @ref GameRenderer.
- */
-class GlGameRenderer : public GameRenderer {
-public:
- GlGameRenderer();
- virtual ~GlGameRenderer();
-
-private:
- static std::unique_ptr<TerrainProgram> terrain_program_;
- static std::unique_ptr<DitherProgram> dither_program_;
- static std::unique_ptr<RoadProgram> road_program_;
-
- void draw() override;
-};
-
-#endif // end of include guard: WL_GRAPHIC_GL_GAME_RENDERER_H
=== modified file 'src/graphic/rendertarget.cc'
--- src/graphic/rendertarget.cc 2014-11-26 09:36:46 +0000
+++ src/graphic/rendertarget.cc 2014-11-28 08:45:54 +0000
@@ -27,7 +27,7 @@
#include "graphic/surface.h"
#include "logic/player.h"
#include "logic/tribe.h"
-#include "wui/mapviewpixelconstants.h"
+// #include "wui/mapviewpixelconstants.h"
#include "wui/overlay_manager.h"
using Widelands::BaseImmovable;
=== modified file 'src/logic/CMakeLists.txt'
--- src/logic/CMakeLists.txt 2014-11-28 08:45:54 +0000
+++ src/logic/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -6,6 +6,7 @@
base_log
graphic
graphic_image_io
+ graphic_minimap_renderer
graphic_surface
io_fileread
io_filesystem
@@ -251,5 +252,7 @@
ui_basic
widelands_ball_of_mud
wui
+ wui_mapview_pixelfunctions
+ wui_overlay_manager
wui_text_layout
)
=== modified file 'src/map_io/CMakeLists.txt'
--- src/map_io/CMakeLists.txt 2014-11-28 08:45:54 +0000
+++ src/map_io/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -94,6 +94,7 @@
economy
graphic
graphic_image_io
+ graphic_minimap_renderer
graphic_surface
helper
io_fileread
=== modified file 'src/scripting/CMakeLists.txt'
--- src/scripting/CMakeLists.txt 2014-07-25 20:16:31 +0000
+++ src/scripting/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -58,4 +58,5 @@
third_party_eris
ui_basic
wui
+ wui_mapview_pixelfunctions
)
=== modified file 'src/sound/CMakeLists.txt'
--- src/sound/CMakeLists.txt 2014-10-13 15:04:50 +0000
+++ src/sound/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -22,4 +22,5 @@
profile
random
wui
+ wui_mapview_pixelfunctions
)
=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt 2014-10-13 15:04:50 +0000
+++ src/wui/CMakeLists.txt 2014-11-28 08:45:54 +0000
@@ -29,6 +29,29 @@
wui
)
+wl_library(wui_overlay_manager
+ SRCS
+ overlay_manager.cc
+ overlay_manager.h
+ DEPENDS
+ base_geometry
+ graphic
+ logic
+ logic_widelands_geometry
+)
+
+wl_library(wui_mapview_pixelfunctions
+ SRCS
+ mapviewpixelconstants.h
+ mapviewpixelfunctions.cc
+ mapviewpixelfunctions.h
+ vector.h
+ DEPENDS
+ base_geometry
+ logic
+ logic_widelands_geometry
+)
+
wl_library(wui
SRCS
actionconfirm.cc
@@ -83,16 +106,11 @@
logmessage.h
mapview.cc
mapview.h
- mapviewpixelconstants.h
- mapviewpixelfunctions.cc
- mapviewpixelfunctions.h
militarysitewindow.cc
minimap.cc
minimap.h
multiplayersetupgroup.cc
multiplayersetupgroup.h
- overlay_manager.cc
- overlay_manager.h
playerdescrgroup.cc
playerdescrgroup.h
plot_area.cc
@@ -117,7 +135,6 @@
transport_ui.cc
unique_window_handler.cc
unique_window_handler.h
- vector.h
ware_statistics_menu.cc
ware_statistics_menu.h
warehousewindow.cc
@@ -141,7 +158,9 @@
game_io
graphic
graphic_color
+ graphic_game_renderer
graphic_image
+ graphic_minimap_renderer
graphic_surface
io_fileread
io_filesystem
@@ -158,5 +177,7 @@
ui_fsmenu
widelands_ball_of_mud
wui_chat_ui
+ wui_mapview_pixelfunctions
+ wui_overlay_manager
wui_text_layout
)
=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc 2014-11-22 18:36:33 +0000
+++ src/wui/mapview.cc 2014-11-28 08:45:54 +0000
@@ -20,7 +20,7 @@
#include "wui/mapview.h"
#include "base/macros.h"
-#include "graphic/gl/game_renderer.h"
+#include "graphic/game_renderer.h"
#include "graphic/graphic.h"
#include "graphic/rendertarget.h"
#include "logic/map.h"
@@ -31,16 +31,14 @@
#include "wui/mapviewpixelfunctions.h"
#include "wui/overlay_manager.h"
-MapView::MapView
- (UI::Panel * parent,
- int32_t x, int32_t y, uint32_t w, uint32_t h,
- InteractiveBase & player)
-:
-UI::Panel (parent, x, y, w, h),
-m_intbase (player),
-m_viewpoint (Point(0, 0)),
-m_dragging (false)
-{}
+MapView::MapView(
+ UI::Panel* parent, int32_t x, int32_t y, uint32_t w, uint32_t h, InteractiveBase& player)
+ : UI::Panel(parent, x, y, w, h),
+ m_renderer(new GameRenderer()),
+ m_intbase(player),
+ m_viewpoint(Point(0, 0)),
+ m_dragging(false) {
+}
MapView::~MapView()
{
@@ -90,11 +88,8 @@
egbase.map().overlay_manager().load_graphics();
- if (!m_renderer) {
- m_renderer.reset(new GlGameRenderer());
- }
if (upcast(InteractivePlayer const, interactive_player, &intbase())) {
- m_renderer->rendermap(dst, egbase, interactive_player->player(), m_viewpoint);
+ m_renderer->rendermap(dst, egbase, m_viewpoint, interactive_player->player());
} else {
m_renderer->rendermap(dst, egbase, m_viewpoint);
}
Follow ups