widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #11030
[Merge] lp:~widelands-dev/widelands/fields_to_draw into lp:widelands
SirVer has proposed merging lp:~widelands-dev/widelands/fields_to_draw into lp:widelands.
Commit message:
Split 'GameRenderer' into individual functions and move drawing logic into individual classes.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/fields_to_draw/+merge/329723
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/fields_to_draw into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc 2017-08-28 07:39:59 +0000
+++ src/editor/editorinteractive.cc 2017-08-28 12:55:36 +0000
@@ -312,11 +312,38 @@
}
void EditorInteractive::draw(RenderTarget& dst) {
- const GameRenderer::Overlays overlays{get_text_to_draw(), {}};
- map_view()->draw_map_view(
- egbase(), overlays,
- draw_immovables_ ? GameRenderer::DrawImmovables::kYes : GameRenderer::DrawImmovables::kNo,
- draw_bobs_ ? GameRenderer::DrawBobs::kYes : GameRenderer::DrawBobs::kNo, nullptr, &dst);
+ const auto& ebase = egbase();
+ auto* fields_to_draw = map_view()->draw_terrain(ebase, &dst);
+
+ const float scale = 1.f / map_view()->view().zoom;
+ const uint32_t gametime = ebase.get_gametime();
+
+ for (size_t idx = 0; idx < fields_to_draw->size(); ++idx) {
+ const FieldsToDraw::Field& field = fields_to_draw->at(idx);
+ if (draw_immovables_) {
+ Widelands::BaseImmovable* const imm = field.fcoords.field->get_immovable();
+ if (imm != nullptr && imm->get_positions(ebase).front() == field.fcoords) {
+ imm->draw(gametime, TextToDraw::kNone, field.rendertarget_pixel, scale, &dst);
+ }
+ }
+
+ if (draw_bobs_) {
+ for (Widelands::Bob* bob = field.fcoords.field->get_first_bob(); bob;
+ bob = bob->get_next_bob()) {
+ bob->draw(ebase, TextToDraw::kNone, field.rendertarget_pixel, scale, &dst);
+ }
+ }
+
+ // TODO(sirver): Do not use the field_overlay_manager, instead draw the
+ // overlays we are interested in here directly.
+ field_overlay_manager().foreach_overlay(
+ field.fcoords, [&dst, &field, scale](const Image* pic, const Vector2i& hotspot) {
+ dst.blitrect_scale(Rectf(field.rendertarget_pixel - hotspot.cast<float>() * scale,
+ pic->width() * scale, pic->height() * scale),
+ pic, Recti(0, 0, pic->width(), pic->height()), 1.f,
+ BlendMode::UseAlpha);
+ });
+ }
}
/// Needed to get freehand painting tools (hold down mouse and move to edit).
=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt 2017-08-11 20:01:03 +0000
+++ src/graphic/CMakeLists.txt 2017-08-28 12:55:36 +0000
@@ -164,8 +164,9 @@
base_geometry
base_macros
graphic_color
+ graphic_draw_programs
+ graphic_fields_to_draw
graphic_terrain_programs
- graphic_draw_programs
logic
)
@@ -177,10 +178,10 @@
base_geometry
base_macros
graphic
+ graphic_fields_to_draw
graphic_gl_utils
graphic_render_queue
graphic_surface
- graphic_terrain_programs
logic
wui
wui_field_overlay_manager
@@ -201,9 +202,22 @@
wui_mapview_pixelfunctions
)
+wl_library(graphic_fields_to_draw
+ SRCS
+ gl/fields_to_draw.cc
+ gl/fields_to_draw.h
+ DEPENDS
+ base_geometry
+ graphic
+ graphic_gl_utils
+ logic
+ logic_constants
+ logic_widelands_geometry
+ wui_mapview_pixelfunctions
+)
+
wl_library(graphic_terrain_programs
SRCS
- gl/fields_to_draw.h
gl/road_program.cc
gl/road_program.h
gl/terrain_program.cc
@@ -216,13 +230,12 @@
base_log
base_macros
graphic
+ graphic_fields_to_draw
graphic_gl_utils
graphic_image_io
graphic_surface
io_filesystem
logic
- logic_constants
- logic_widelands_geometry
)
=== modified file 'src/graphic/game_renderer.cc'
--- src/graphic/game_renderer.cc 2017-08-28 11:52:39 +0000
+++ src/graphic/game_renderer.cc 2017-08-28 12:55:36 +0000
@@ -66,324 +66,38 @@
* d.dither_layer, then we will repaint d with the dither texture as mask.
*/
-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.;
-}
-
-void draw_immovables_for_visible_field(const EditorGameBase& egbase,
- const FieldsToDraw::Field& field,
- const float zoom,
- const TextToDraw text_to_draw,
- const Player* player,
- RenderTarget* dst) {
- BaseImmovable* const imm = field.fcoords.field->get_immovable();
- if (imm != nullptr && imm->get_positions(egbase).front() == field.fcoords) {
- TextToDraw draw_text_for_this_immovable = text_to_draw;
- const Player* owner = imm->get_owner();
- if (player != nullptr && owner != nullptr && !player->see_all() &&
- player->is_hostile(*owner)) {
- draw_text_for_this_immovable =
- static_cast<TextToDraw>(draw_text_for_this_immovable & ~TextToDraw::kStatistics);
- }
- imm->draw(
- egbase.get_gametime(), draw_text_for_this_immovable, field.rendertarget_pixel, zoom, dst);
- }
-}
-
-void draw_bobs_for_visible_field(const EditorGameBase& egbase,
- const FieldsToDraw::Field& field,
- const float zoom,
- const TextToDraw text_to_draw,
- const Player* player,
- RenderTarget* dst) {
- for (Bob* bob = field.fcoords.field->get_first_bob(); bob; bob = bob->get_next_bob()) {
- TextToDraw draw_text_for_this_bob = text_to_draw;
- const Player* owner = bob->get_owner();
- if (player != nullptr && owner != nullptr && !player->see_all() &&
- player->is_hostile(*owner)) {
- draw_text_for_this_bob =
- static_cast<TextToDraw>(draw_text_for_this_bob & ~TextToDraw::kStatistics);
- }
- bob->draw(egbase, draw_text_for_this_bob, field.rendertarget_pixel, zoom, dst);
- }
-}
-
-void draw_immovables_for_formerly_visible_field(const FieldsToDraw::Field& field,
- const Player::Field& player_field,
- const float zoom,
- RenderTarget* dst) {
- if (const MapObjectDescr* const map_object_descr =
- player_field.map_object_descr[TCoords<>::None]) {
- if (player_field.constructionsite.becomes) {
- assert(field.owner != nullptr);
- const ConstructionsiteInformation& csinf = player_field.constructionsite;
- // draw the partly finished constructionsite
- uint32_t anim_idx;
- try {
- anim_idx = csinf.becomes->get_animation("build");
- } catch (MapObjectDescr::AnimationNonexistent&) {
- try {
- anim_idx = csinf.becomes->get_animation("unoccupied");
- } catch (MapObjectDescr::AnimationNonexistent) {
- anim_idx = csinf.becomes->get_animation("idle");
- }
- }
- const Animation& anim = g_gr->animations().get_animation(anim_idx);
- const size_t nr_frames = anim.nr_frames();
- uint32_t cur_frame =
- csinf.totaltime ? csinf.completedtime * nr_frames / csinf.totaltime : 0;
- uint32_t tanim = cur_frame * FRAME_LENGTH;
-
- uint32_t percent = 100 * csinf.completedtime * nr_frames;
- if (csinf.totaltime) {
- percent /= csinf.totaltime;
- }
- percent -= 100 * cur_frame;
-
- if (cur_frame) { // not the first frame
- // Draw the prev frame
- dst->blit_animation(field.rendertarget_pixel, zoom, anim_idx, tanim - FRAME_LENGTH,
- field.owner->get_playercolor());
- } else if (csinf.was) {
- // Is the first frame, but there was another building here before,
- // get its last build picture and draw it instead.
- uint32_t a;
- try {
- a = csinf.was->get_animation("unoccupied");
- } catch (MapObjectDescr::AnimationNonexistent&) {
- a = csinf.was->get_animation("idle");
- }
- dst->blit_animation(field.rendertarget_pixel, zoom, a, tanim - FRAME_LENGTH,
- field.owner->get_playercolor());
- }
- dst->blit_animation(field.rendertarget_pixel, zoom, anim_idx, tanim,
- field.owner->get_playercolor(), percent);
- } else if (upcast(const BuildingDescr, building, map_object_descr)) {
- assert(field.owner != nullptr);
- // this is a building therefore we either draw unoccupied or idle animation
- uint32_t pic;
- try {
- pic = building->get_animation("unoccupied");
- } catch (MapObjectDescr::AnimationNonexistent&) {
- pic = building->get_animation("idle");
- }
- dst->blit_animation(
- field.rendertarget_pixel, zoom, pic, 0, field.owner->get_playercolor());
- } else if (map_object_descr->type() == MapObjectType::FLAG) {
- assert(field.owner != nullptr);
- dst->blit_animation(field.rendertarget_pixel, zoom, field.owner->tribe().flag_animation(),
- 0, field.owner->get_playercolor());
- } else if (const uint32_t pic = map_object_descr->main_animation()) {
- if (field.owner != nullptr) {
- dst->blit_animation(
- field.rendertarget_pixel, zoom, pic, 0, field.owner->get_playercolor());
- } else {
- dst->blit_animation(field.rendertarget_pixel, zoom, pic, 0);
- }
- }
- }
-}
-
-// Draws the objects (animations & overlays).
-void draw_objects(const EditorGameBase& egbase,
- const float zoom,
+void draw_border_markers(const FieldsToDraw::Field& field,
+ const float scale,
+ const FieldsToDraw& fields_to_draw,
+ RenderTarget* dst) {
+ if (!field.all_neighbors_valid() || !field.is_border) {
+ return;
+ }
+ assert(field.owner != nullptr);
+
+ uint32_t const anim_idx = field.owner->tribe().frontier_animation();
+ if (field.vision) {
+ dst->blit_animation(
+ field.rendertarget_pixel, scale, anim_idx, 0, field.owner->get_playercolor());
+ }
+ for (const auto& nf : {fields_to_draw.at(field.rn_index), fields_to_draw.at(field.bln_index),
+ fields_to_draw.at(field.brn_index)}) {
+ if ((field.vision || nf.vision) && nf.is_border &&
+ (field.owner == nf.owner || nf.owner == nullptr)) {
+ dst->blit_animation(middle(field.rendertarget_pixel, nf.rendertarget_pixel), scale,
+ anim_idx, 0, field.owner->get_playercolor());
+ }
+ }
+}
+
+void draw_terrain(const Widelands::EditorGameBase& egbase,
const FieldsToDraw& fields_to_draw,
- const Player* player,
- const TextToDraw text_to_draw,
- const GameRenderer::DrawImmovables& draw_immovables,
- const GameRenderer::DrawBobs& draw_bobs,
+ const float scale,
RenderTarget* dst) {
- for (size_t current_index = 0; current_index < fields_to_draw.size(); ++current_index) {
- const FieldsToDraw::Field& field = fields_to_draw.at(current_index);
- if (!field.all_neighbors_valid()) {
- continue;
- }
-
- const FieldsToDraw::Field& rn = fields_to_draw.at(field.rn_index);
- const FieldsToDraw::Field& bln = fields_to_draw.at(field.bln_index);
- const FieldsToDraw::Field& brn = fields_to_draw.at(field.brn_index);
-
- if (field.is_border && draw_immovables == GameRenderer::DrawImmovables::kYes) {
- assert(field.owner != nullptr);
- uint32_t const anim_idx = field.owner->tribe().frontier_animation();
- if (field.vision) {
- dst->blit_animation(
- field.rendertarget_pixel, zoom, anim_idx, 0, field.owner->get_playercolor());
- }
- for (const auto& nf : {rn, bln, brn}) {
- if ((field.vision || nf.vision) && nf.is_border &&
- (field.owner == nf.owner || nf.owner == nullptr)) {
- dst->blit_animation(middle(field.rendertarget_pixel, nf.rendertarget_pixel), zoom,
- anim_idx, 0, field.owner->get_playercolor());
- }
- }
- }
-
- if (1 < field.vision) { // Render stuff that belongs to the node.
- if (draw_immovables == GameRenderer::DrawImmovables::kYes) {
- draw_immovables_for_visible_field(egbase, field, zoom, text_to_draw, player, dst);
- }
- if (draw_bobs == GameRenderer::DrawBobs::kYes) {
- draw_bobs_for_visible_field(egbase, field, zoom, text_to_draw, player, dst);
- }
- } else if (field.vision == 1 && draw_immovables == GameRenderer::DrawImmovables::kYes) {
- // We never show census or statistics for objects in the fog.
- assert(player != nullptr);
- const Map& map = egbase.map();
- const Player::Field& player_field =
- player->fields()[map.get_index(field.fcoords, map.get_width())];
- draw_immovables_for_formerly_visible_field(field, player_field, zoom, dst);
- }
-
- egbase.get_ibase()->field_overlay_manager().foreach_overlay(
- field.fcoords, [dst, &field, zoom](const Image* pic, const Vector2i& hotspot) {
- dst->blitrect_scale(Rectf(field.rendertarget_pixel - hotspot.cast<float>() * zoom,
- pic->width() * zoom, pic->height() * zoom),
- pic, Recti(0, 0, pic->width(), pic->height()), 1.f,
- BlendMode::UseAlpha);
- });
- }
-}
-
-} // namespace
-
-GameRenderer::GameRenderer() {
-}
-
-GameRenderer::~GameRenderer() {
-}
-
-void GameRenderer::render(const EditorGameBase& egbase,
- const Vector2f& viewpoint,
- const float zoom,
- const Player* player,
- const Overlays& overlays,
- const DrawImmovables& draw_immovables,
- const DrawBobs& draw_bobs,
- RenderTarget* dst) {
- assert(viewpoint.x >= 0); // divisions involving negative numbers are bad
- assert(viewpoint.y >= 0);
- assert(dst->get_offset().x <= 0);
- assert(dst->get_offset().y <= 0);
-
- int minfx = std::floor(viewpoint.x / kTriangleWidth);
- int minfy = std::floor(viewpoint.y / kTriangleHeight);
-
- // If a view window is partially moved outside of the display, its 'rect' is
- // adjusted to be fully contained on the screen - i.e. x = 0 and width is
- // made smaller. Its offset is made negative to account for this change.
- // To figure out which fields we need to draw, we have to add the absolute
- // value of 'offset' to the actual dimension of the 'rect' to get to desired
- // dimension of the 'rect'
- const Vector2f br_map = MapviewPixelFunctions::panel_to_map(
- viewpoint, zoom, Vector2f(dst->get_rect().w + std::abs(dst->get_offset().x),
- dst->get_rect().h + std::abs(dst->get_offset().y)));
- int maxfx = std::ceil(br_map.x / kTriangleWidth);
- int maxfy = std::ceil(br_map.y / kTriangleHeight);
-
- // Adjust for triangle boundary effects and for height differences.
- minfx -= 2;
- maxfx += 2;
- minfy -= 2;
- maxfy += 10;
-
- Surface* surface = dst->get_surface();
- if (!surface)
- return;
-
const Recti& bounding_rect = dst->get_rect();
- const int surface_width = surface->width();
- const int surface_height = surface->height();
-
- const Map& map = egbase.map();
- const uint32_t gametime = egbase.get_gametime();
-
- const float scale = 1.f / zoom;
- fields_to_draw_.reset(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.geometric_coords = Coords(fx, fy);
-
- f.ln_index = fields_to_draw_.calculate_index(fx - 1, fy);
- f.rn_index = fields_to_draw_.calculate_index(fx + 1, fy);
- f.trn_index = fields_to_draw_.calculate_index(fx + (fy & 1), fy - 1);
- f.bln_index = fields_to_draw_.calculate_index(fx + (fy & 1) - 1, fy + 1);
- f.brn_index = fields_to_draw_.calculate_index(fx + (fy & 1), fy + 1);
-
- // Texture coordinates for pseudo random tiling of terrain and road
- // graphics. Since screen space X increases top-to-bottom and OpenGL
- // increases bottom-to-top we flip the y coordinate to not have
- // terrains and road graphics vertically mirrorerd.
- Vector2f map_pixel =
- MapviewPixelFunctions::to_map_pixel_ignoring_height(f.geometric_coords);
- f.texture_coords.x = map_pixel.x / kTextureSideLength;
- f.texture_coords.y = -map_pixel.y / kTextureSideLength;
-
- Coords normalized = f.geometric_coords;
- map.normalize_coords(normalized);
- f.fcoords = map.get_fcoords(normalized);
-
- map_pixel.y -= f.fcoords.field->get_height() * kHeightFactor;
-
- f.rendertarget_pixel = MapviewPixelFunctions::map_to_panel(viewpoint, zoom, map_pixel);
- f.gl_position = f.surface_pixel = f.rendertarget_pixel +
- dst->get_rect().origin().cast<float>() +
- dst->get_offset().cast<float>();
- pixel_to_gl_renderbuffer(
- surface_width, surface_height, &f.gl_position.x, &f.gl_position.y);
-
- f.brightness = field_brightness(f.fcoords, gametime, map, player);
-
- PlayerNumber owned_by = f.fcoords.field->get_owned_by();
- f.owner = owned_by != 0 ? &egbase.player(owned_by) : nullptr;
- f.is_border = f.fcoords.field->is_border();
- f.vision = 2;
- f.roads = f.fcoords.field->get_roads();
- if (player && !player->see_all()) {
- const Player::Field& pf = player->fields()[map.get_index(f.fcoords, map.get_width())];
- f.roads = pf.roads;
- f.vision = pf.vision;
- if (pf.vision == 1) {
- f.owner = pf.owner != 0 ? &egbase.player(owned_by) : nullptr;
- f.is_border = pf.border;
- }
- }
-
- const auto it = overlays.road_building_preview.find(f.fcoords);
- if (it != overlays.road_building_preview.end()) {
- f.roads |= it->second;
- }
- }
- }
+ const Surface& surface = dst->get_surface();
+ const int surface_width = surface.width();
+ const int surface_height = surface.height();
// Enqueue the drawing of the terrain.
RenderQueue::Item i;
@@ -392,11 +106,11 @@
i.terrain_arguments.destination_rect =
Rectf(bounding_rect.x, surface_height - bounding_rect.y - bounding_rect.h, bounding_rect.w,
bounding_rect.h);
- i.terrain_arguments.gametime = gametime;
+ i.terrain_arguments.gametime = egbase.get_gametime();
i.terrain_arguments.renderbuffer_width = surface_width;
i.terrain_arguments.renderbuffer_height = surface_height;
i.terrain_arguments.terrains = &egbase.world().terrains();
- i.terrain_arguments.fields_to_draw = &fields_to_draw_;
+ i.terrain_arguments.fields_to_draw = &fields_to_draw;
i.terrain_arguments.scale = scale;
RenderQueue::instance().enqueue(i);
@@ -408,7 +122,4 @@
// Enqueue the drawing of the road layer.
i.program_id = RenderQueue::Program::kTerrainRoad;
RenderQueue::instance().enqueue(i);
-
- draw_objects(egbase, scale, fields_to_draw_, player, overlays.text_to_draw, draw_immovables,
- draw_bobs, dst);
}
=== modified file 'src/graphic/game_renderer.h'
--- src/graphic/game_renderer.h 2017-08-28 11:52:39 +0000
+++ src/graphic/game_renderer.h 2017-08-28 12:55:36 +0000
@@ -26,47 +26,21 @@
#include "base/macros.h"
#include "base/vector.h"
#include "graphic/gl/fields_to_draw.h"
+#include "logic/editor_game_base.h"
#include "logic/map_objects/draw_text.h"
-
-namespace Widelands {
-class Player;
-class EditorGameBase;
-}
-
-class RenderTarget;
-
-// Renders the MapView on screen.
-class GameRenderer {
-public:
- struct Overlays {
- TextToDraw text_to_draw;
- std::map<Widelands::Coords, uint8_t> road_building_preview;
- };
-
- enum class DrawImmovables { kNo, kYes };
- enum class DrawBobs { kNo, kYes };
-
- GameRenderer();
- ~GameRenderer();
-
- // Renders the map from a 'player's point of view (or omniscient if nullptr)
- // into the given drawing window. The 'viewpoint' is the top left screens
- // pixel map pixel and 'scale' is the magnification of the view.
- void render(const Widelands::EditorGameBase& egbase,
- const Vector2f& viewpoint,
- float zoom,
- const Widelands::Player* player,
- const Overlays& overlays,
- const DrawImmovables& draw_immovables,
- const DrawBobs& draw_bobs,
- RenderTarget* dst);
-
-private:
- // This is owned and handled by us, but handed to the RenderQueue, so we
- // basically promise that this stays valid for one frame.
- FieldsToDraw fields_to_draw_;
-
- DISALLOW_COPY_AND_ASSIGN(GameRenderer);
-};
+#include "logic/player.h"
+
+// Draw the terrain only.
+void draw_terrain(const Widelands::EditorGameBase& egbase,
+ const FieldsToDraw& fields_to_draw,
+ const float scale,
+ RenderTarget* dst);
+
+// Draw the border stones for 'field' if it is a border and 'visibility' is
+// correct.
+void draw_border_markers(const FieldsToDraw::Field& field,
+ const float scale,
+ const FieldsToDraw& fields_to_draw,
+ RenderTarget* dst);
#endif // end of include guard: WL_GRAPHIC_GAME_RENDERER_H
=== added file 'src/graphic/gl/fields_to_draw.cc'
--- src/graphic/gl/fields_to_draw.cc 1970-01-01 00:00:00 +0000
+++ src/graphic/gl/fields_to_draw.cc 2017-08-28 12:55:36 +0000
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2006-2017 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/fields_to_draw.h"
+
+#include "graphic/gl/coordinate_conversion.h"
+#include "logic/map_objects/world/terrain_description.h"
+#include "wui/mapviewpixelconstants.h"
+#include "wui/mapviewpixelfunctions.h"
+
+namespace {
+
+// Returns the brightness value in [0, 1.] for 'fcoords'.
+float field_brightness(const Widelands::FCoords& fcoords) {
+ uint32_t brightness = 144 + fcoords.field->get_brightness();
+ brightness = std::min<uint32_t>(255, (brightness * 255) / 160);
+ return brightness / 255.;
+}
+
+} // namespace
+
+void FieldsToDraw::reset(const Widelands::EditorGameBase& egbase,
+ const Vector2f& viewpoint,
+ const float zoom,
+ RenderTarget* dst) {
+ assert(viewpoint.x >= 0); // divisions involving negative numbers are bad
+ assert(viewpoint.y >= 0);
+ assert(dst->get_offset().x <= 0);
+ assert(dst->get_offset().y <= 0);
+
+ int minfx = std::floor(viewpoint.x / kTriangleWidth);
+ int minfy = std::floor(viewpoint.y / kTriangleHeight);
+
+ // If a view window is partially moved outside of the display, its 'rect' is
+ // adjusted to be fully contained on the screen - i.e. x = 0 and width is
+ // made smaller. Its offset is made negative to account for this change.
+ // To figure out which fields we need to draw, we have to add the absolute
+ // value of 'offset' to the actual dimension of the 'rect' to get to desired
+ // dimension of the 'rect'
+ const Vector2f br_map = MapviewPixelFunctions::panel_to_map(
+ viewpoint, zoom, Vector2f(dst->get_rect().w + std::abs(dst->get_offset().x),
+ dst->get_rect().h + std::abs(dst->get_offset().y)));
+ int maxfx = std::ceil(br_map.x / kTriangleWidth);
+ int maxfy = std::ceil(br_map.y / kTriangleHeight);
+
+ // Adjust for triangle boundary effects and for height differences.
+ minfx -= 2;
+ maxfx += 2;
+ minfy -= 2;
+ maxfy += 10;
+
+ const auto& surface = dst->get_surface();
+ const int surface_width = surface.width();
+ const int surface_height = surface.height();
+
+ const Widelands::Map& map = egbase.map();
+
+ min_fx_ = minfx;
+ max_fx_ = maxfx;
+ min_fy_ = minfy;
+ max_fy_ = maxfy;
+ w_ = max_fx_ - min_fx_ + 1;
+ h_ = max_fy_ - min_fy_ + 1;
+ const size_t dimension = w_ * h_;
+ if (fields_.size() != dimension) {
+ fields_.resize(dimension);
+ }
+
+ for (int32_t fy = minfy; fy <= maxfy; ++fy) {
+ for (int32_t fx = minfx; fx <= maxfx; ++fx) {
+ FieldsToDraw::Field& f = fields_[calculate_index(fx, fy)];
+
+ f.geometric_coords = Widelands::Coords(fx, fy);
+
+ f.ln_index = calculate_index(fx - 1, fy);
+ f.rn_index = calculate_index(fx + 1, fy);
+ f.trn_index = calculate_index(fx + (fy & 1), fy - 1);
+ f.bln_index = calculate_index(fx + (fy & 1) - 1, fy + 1);
+ f.brn_index = calculate_index(fx + (fy & 1), fy + 1);
+
+ // Texture coordinates for pseudo random tiling of terrain and road
+ // graphics. Since screen space X increases top-to-bottom and OpenGL
+ // increases bottom-to-top we flip the y coordinate to not have
+ // terrains and road graphics vertically mirrorerd.
+ Vector2f map_pixel =
+ MapviewPixelFunctions::to_map_pixel_ignoring_height(f.geometric_coords);
+ f.texture_coords.x = map_pixel.x / Widelands::kTextureSideLength;
+ f.texture_coords.y = -map_pixel.y / Widelands::kTextureSideLength;
+
+ Widelands::Coords normalized = f.geometric_coords;
+ map.normalize_coords(normalized);
+ f.fcoords = map.get_fcoords(normalized);
+
+ map_pixel.y -= f.fcoords.field->get_height() * kHeightFactor;
+
+ f.rendertarget_pixel = MapviewPixelFunctions::map_to_panel(viewpoint, zoom, map_pixel);
+ f.gl_position = f.surface_pixel = f.rendertarget_pixel +
+ dst->get_rect().origin().cast<float>() +
+ dst->get_offset().cast<float>();
+ pixel_to_gl_renderbuffer(
+ surface_width, surface_height, &f.gl_position.x, &f.gl_position.y);
+
+ f.brightness = field_brightness(f.fcoords);
+
+ Widelands::PlayerNumber owned_by = f.fcoords.field->get_owned_by();
+ f.owner = owned_by != 0 ? &egbase.player(owned_by) : nullptr;
+ f.is_border = f.fcoords.field->is_border();
+ f.vision = 2;
+ f.roads = f.fcoords.field->get_roads();
+ }
+ }
+}
=== modified file 'src/graphic/gl/fields_to_draw.h'
--- src/graphic/gl/fields_to_draw.h 2017-08-09 17:53:24 +0000
+++ src/graphic/gl/fields_to_draw.h 2017-08-28 12:55:36 +0000
@@ -28,13 +28,12 @@
#include <stdint.h>
#include "base/vector.h"
-#include "logic/map_objects/tribes/road_textures.h"
-#include "logic/player.h"
+#include "graphic/rendertarget.h"
+#include "logic/editor_game_base.h"
#include "logic/widelands.h"
#include "logic/widelands_geometry.h"
-// Helper struct that contains the data needed for drawing all fields. All
-// methods are inlined for performance reasons.
+// Helper struct that contains the data needed for drawing all fields.
class FieldsToDraw {
public:
static constexpr int kInvalidIndex = std::numeric_limits<int>::min();
@@ -77,39 +76,11 @@
}
};
- FieldsToDraw() {
- // Initialize everything to make cppcheck happy.
- reset(0, 0, 0, 0);
- }
-
- // Resize this fields to draw for reuse.
- void reset(int minfx, int maxfx, int minfy, int maxfy) {
- min_fx_ = minfx;
- max_fx_ = maxfx;
- min_fy_ = minfy;
- max_fy_ = maxfy;
- w_ = max_fx_ - min_fx_ + 1;
- h_ = max_fy_ - min_fy_ + 1;
- const size_t dimension = w_ * h_;
- if (fields_.size() != dimension) {
- fields_.resize(dimension);
- }
- }
-
- // Calculates the index of the given field with ('fx', 'fy') being geometric
- // coordinates in the map. Returns kInvalidIndex if this field is not in the
- // fields_to_draw.
- inline int calculate_index(int fx, int fy) const {
- uint16_t xidx = fx - min_fx_;
- if (xidx >= w_) {
- return kInvalidIndex;
- }
- uint16_t yidx = fy - min_fy_;
- if (yidx >= h_) {
- return kInvalidIndex;
- }
- return yidx * w_ + xidx;
- }
+ // Reinitialize for the given view parameters.
+ void reset(const Widelands::EditorGameBase& egbase,
+ const Vector2f& viewpoint,
+ const float zoom,
+ RenderTarget* dst);
// The number of fields to draw.
inline size_t size() const {
@@ -127,15 +98,30 @@
}
private:
+ // Calculates the index of the given field with ('fx', 'fy') being geometric
+ // coordinates in the map. Returns kInvalidIndex if this field is not in the
+ // fields_to_draw.
+ inline int calculate_index(int fx, int fy) const {
+ uint16_t xidx = fx - min_fx_;
+ if (xidx >= w_) {
+ return kInvalidIndex;
+ }
+ uint16_t yidx = fy - min_fy_;
+ if (yidx >= h_) {
+ return kInvalidIndex;
+ }
+ return yidx * w_ + xidx;
+ }
+
// Minimum and maximum field coordinates (geometric) to render. Can be negative.
- int min_fx_;
- int max_fx_;
- int min_fy_;
- int max_fy_;
+ int min_fx_ = 0;
+ int max_fx_ = 0;
+ int min_fy_ = 0;
+ int max_fy_ = 0;
// Width and height in number of fields.
- int w_;
- int h_;
+ int w_ = 0;
+ int h_ = 0;
std::vector<Field> fields_;
};
=== modified file 'src/graphic/gl/road_program.cc'
--- src/graphic/gl/road_program.cc 2017-05-19 06:40:44 +0000
+++ src/graphic/gl/road_program.cc 2017-08-28 12:55:36 +0000
@@ -29,6 +29,7 @@
#include "graphic/graphic.h"
#include "graphic/image_io.h"
#include "graphic/texture.h"
+#include "logic/player.h"
#include "logic/roadtype.h"
// We target OpenGL 2.1 for the desktop here.
=== modified file 'src/graphic/render_queue.h'
--- src/graphic/render_queue.h 2017-08-09 17:53:24 +0000
+++ src/graphic/render_queue.h 2017-08-28 12:55:36 +0000
@@ -118,7 +118,7 @@
int renderbuffer_width = 0;
int renderbuffer_height = 0;
const DescriptionMaintainer<Widelands::TerrainDescription>* terrains = nullptr;
- FieldsToDraw* fields_to_draw = nullptr;
+ const FieldsToDraw* fields_to_draw = nullptr;
float scale = 1.f;
Rectf destination_rect = Rectf(0.f, 0.f, 0.f, 0.f);
};
=== modified file 'src/graphic/rendertarget.cc'
--- src/graphic/rendertarget.cc 2017-05-21 19:07:27 +0000
+++ src/graphic/rendertarget.cc 2017-08-28 12:55:36 +0000
@@ -28,8 +28,7 @@
/**
* Build a render target for the given surface.
*/
-RenderTarget::RenderTarget(Surface* surf) {
- surface_ = surf;
+RenderTarget::RenderTarget(Surface* surf) : surface_(surf) {
reset();
}
=== modified file 'src/graphic/rendertarget.h'
--- src/graphic/rendertarget.h 2017-06-24 08:47:46 +0000
+++ src/graphic/rendertarget.h 2017-08-28 12:55:36 +0000
@@ -120,8 +120,8 @@
void reset();
- Surface* get_surface() const {
- return surface_;
+ const Surface& get_surface() const {
+ return *surface_;
}
const Recti& get_rect() const {
return rect_;
@@ -143,7 +143,7 @@
const int percent_from_bottom = 100);
/// The target surface
- Surface* surface_;
+ Surface* const surface_;
/// The current clip rectangle
Recti rect_;
/// Drawing offset
=== modified file 'src/logic/widelands_geometry.h'
--- src/logic/widelands_geometry.h 2017-08-12 06:51:08 +0000
+++ src/logic/widelands_geometry.h 2017-08-28 12:55:36 +0000
@@ -122,6 +122,7 @@
Field* field;
};
+// TODO(sirver): This should not derive from CoordsType. Replace with NodeAndTriangle.
template <typename CoordsType = Coords> struct TCoords : public CoordsType {
enum TriangleIndex { D, R, None };
=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt 2017-08-20 16:12:28 +0000
+++ src/wui/CMakeLists.txt 2017-08-28 12:55:36 +0000
@@ -106,6 +106,7 @@
base_macros
base_math
graphic
+ graphic_fields_to_draw
graphic_game_renderer
logic
logic_widelands_geometry
=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc 2017-08-28 11:52:39 +0000
+++ src/wui/interactive_player.cc 2017-08-28 12:55:36 +0000
@@ -58,6 +58,146 @@
using Widelands::Building;
using Widelands::Map;
+namespace {
+
+// Returns the brightness value in [0, 1.] for 'fcoords' at 'gametime' for
+// 'pf'. See 'field_brightness' in fields_to_draw.cc for scale of values.
+float adjusted_field_brightness(const Widelands::FCoords& fcoords,
+ const uint32_t gametime,
+ const Widelands::Player::Field& pf) {
+ if (pf.vision == 0) {
+ return 0.;
+ };
+
+ uint32_t brightness = 144 + fcoords.field->get_brightness();
+ brightness = std::min<uint32_t>(255, (brightness * 255) / 160);
+
+ if (pf.vision == 1) {
+ static const uint32_t kDecayTimeInMs = 20000;
+ const Widelands::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.;
+}
+
+void draw_immovables_for_visible_field(const Widelands::EditorGameBase& egbase,
+ const FieldsToDraw::Field& field,
+ const float scale,
+ const TextToDraw text_to_draw,
+ const Widelands::Player& player,
+ RenderTarget* dst) {
+ Widelands::BaseImmovable* const imm = field.fcoords.field->get_immovable();
+ if (imm != nullptr && imm->get_positions(egbase).front() == field.fcoords) {
+ TextToDraw draw_text_for_this_immovable = text_to_draw;
+ const Widelands::Player* owner = imm->get_owner();
+ if (owner != nullptr && !player.see_all() && player.is_hostile(*owner)) {
+ draw_text_for_this_immovable =
+ static_cast<TextToDraw>(draw_text_for_this_immovable & ~TextToDraw::kStatistics);
+ }
+ imm->draw(
+ egbase.get_gametime(), draw_text_for_this_immovable, field.rendertarget_pixel, scale, dst);
+ }
+}
+
+void draw_bobs_for_visible_field(const Widelands::EditorGameBase& egbase,
+ const FieldsToDraw::Field& field,
+ const float scale,
+ const TextToDraw text_to_draw,
+ const Widelands::Player& player,
+ RenderTarget* dst) {
+ for (Widelands::Bob* bob = field.fcoords.field->get_first_bob(); bob; bob = bob->get_next_bob()) {
+ TextToDraw draw_text_for_this_bob = text_to_draw;
+ const Widelands::Player* owner = bob->get_owner();
+ if (owner != nullptr && !player.see_all() && player.is_hostile(*owner)) {
+ draw_text_for_this_bob =
+ static_cast<TextToDraw>(draw_text_for_this_bob & ~TextToDraw::kStatistics);
+ }
+ bob->draw(egbase, draw_text_for_this_bob, field.rendertarget_pixel, scale, dst);
+ }
+}
+
+void draw_immovables_for_formerly_visible_field(const FieldsToDraw::Field& field,
+ const Widelands::Player::Field& player_field,
+ const float scale,
+ RenderTarget* dst) {
+ if (const Widelands::MapObjectDescr* const map_object_descr =
+ player_field.map_object_descr[Widelands::TCoords<>::None]) {
+ if (player_field.constructionsite.becomes) {
+ assert(field.owner != nullptr);
+ const Widelands::ConstructionsiteInformation& csinf = player_field.constructionsite;
+ // draw the partly finished constructionsite
+ uint32_t anim_idx;
+ try {
+ anim_idx = csinf.becomes->get_animation("build");
+ } catch (Widelands::MapObjectDescr::AnimationNonexistent&) {
+ try {
+ anim_idx = csinf.becomes->get_animation("unoccupied");
+ } catch (Widelands::MapObjectDescr::AnimationNonexistent) {
+ anim_idx = csinf.becomes->get_animation("idle");
+ }
+ }
+ const Animation& anim = g_gr->animations().get_animation(anim_idx);
+ const size_t nr_frames = anim.nr_frames();
+ uint32_t cur_frame =
+ csinf.totaltime ? csinf.completedtime * nr_frames / csinf.totaltime : 0;
+ uint32_t tanim = cur_frame * FRAME_LENGTH;
+
+ uint32_t percent = 100 * csinf.completedtime * nr_frames;
+ if (csinf.totaltime) {
+ percent /= csinf.totaltime;
+ }
+ percent -= 100 * cur_frame;
+
+ if (cur_frame) { // not the first frame
+ // Draw the prev frame
+ dst->blit_animation(field.rendertarget_pixel, scale, anim_idx, tanim - FRAME_LENGTH,
+ field.owner->get_playercolor());
+ } else if (csinf.was) {
+ // Is the first frame, but there was another building here before,
+ // get its last build picture and draw it instead.
+ uint32_t a;
+ try {
+ a = csinf.was->get_animation("unoccupied");
+ } catch (Widelands::MapObjectDescr::AnimationNonexistent&) {
+ a = csinf.was->get_animation("idle");
+ }
+ dst->blit_animation(field.rendertarget_pixel, scale, a, tanim - FRAME_LENGTH,
+ field.owner->get_playercolor());
+ }
+ dst->blit_animation(field.rendertarget_pixel, scale, anim_idx, tanim,
+ field.owner->get_playercolor(), percent);
+ } else if (upcast(const Widelands::BuildingDescr, building, map_object_descr)) {
+ assert(field.owner != nullptr);
+ // this is a building therefore we either draw unoccupied or idle animation
+ uint32_t pic;
+ try {
+ pic = building->get_animation("unoccupied");
+ } catch (Widelands::MapObjectDescr::AnimationNonexistent&) {
+ pic = building->get_animation("idle");
+ }
+ dst->blit_animation(
+ field.rendertarget_pixel, scale, pic, 0, field.owner->get_playercolor());
+ } else if (map_object_descr->type() == Widelands::MapObjectType::FLAG) {
+ assert(field.owner != nullptr);
+ dst->blit_animation(field.rendertarget_pixel, scale, field.owner->tribe().flag_animation(),
+ 0, field.owner->get_playercolor());
+ } else if (const uint32_t pic = map_object_descr->main_animation()) {
+ if (field.owner != nullptr) {
+ dst->blit_animation(
+ field.rendertarget_pixel, scale, pic, 0, field.owner->get_playercolor());
+ } else {
+ dst->blit_animation(field.rendertarget_pixel, scale, pic, 0);
+ }
+ }
+ }
+}
+
+} // namespace
+
InteractivePlayer::InteractivePlayer(Widelands::Game& g,
Section& global_s,
Widelands::PlayerNumber const plyn,
@@ -181,9 +321,63 @@
}
void InteractivePlayer::draw_map_view(MapView* given_map_view, RenderTarget* dst) {
- const GameRenderer::Overlays overlays{get_text_to_draw(), road_building_preview()};
- given_map_view->draw_map_view(egbase(), overlays, GameRenderer::DrawImmovables::kYes,
- GameRenderer::DrawBobs::kYes, &player(), dst);
+ const Widelands::Player& plr = player();
+ const auto& gbase = egbase();
+ const Widelands::Map& map = gbase.map();
+ const uint32_t gametime = gbase.get_gametime();
+
+ auto* fields_to_draw = given_map_view->draw_terrain(gbase, dst);
+ const auto& roads_preview = road_building_preview();
+
+ for (size_t idx = 0; idx < fields_to_draw->size(); ++idx) {
+ auto* f = fields_to_draw->mutable_field(idx);
+
+ const Widelands::Player::Field& player_field =
+ plr.fields()[map.get_index(f->fcoords, map.get_width())];
+
+ // Adjust this field for visibility for this player.
+ if (!plr.see_all()) {
+ f->brightness = adjusted_field_brightness(f->fcoords, gametime, player_field);
+ f->roads = player_field.roads;
+ f->vision = player_field.vision;
+ if (player_field.vision == 0) {
+ // If the player cannot see the field, no need to do any more work.
+ continue;
+ } else if (player_field.vision == 1) {
+ f->owner = player_field.owner != 0 ? &gbase.player(player_field.owner) : nullptr;
+ f->is_border = player_field.border;
+ }
+ }
+
+ // Add road building overlays if applicable.
+ const auto it = roads_preview.find(f->fcoords);
+ if (it != roads_preview.end()) {
+ f->roads |= it->second;
+ }
+
+ const float scale = 1.f / given_map_view->view().zoom;
+ draw_border_markers(*f, scale, *fields_to_draw, dst);
+
+ // Render stuff that belongs to the node.
+ if (f->vision > 1) {
+ const auto text_to_draw = get_text_to_draw();
+ draw_immovables_for_visible_field(gbase, *f, scale, text_to_draw, plr, dst);
+ draw_bobs_for_visible_field(gbase, *f, scale, text_to_draw, plr, dst);
+ } else if (f->vision == 1) {
+ // We never show census or statistics for objects in the fog.
+ draw_immovables_for_formerly_visible_field(*f, player_field, scale, dst);
+ }
+
+ // TODO(sirver): Do not use the field_overlay_manager, instead draw the
+ // overlays we are interested in here directly.
+ field_overlay_manager().foreach_overlay(
+ f->fcoords, [dst, f, scale](const Image* pic, const Vector2i& hotspot) {
+ dst->blitrect_scale(Rectf(f->rendertarget_pixel - hotspot.cast<float>() * scale,
+ pic->width() * scale, pic->height() * scale),
+ pic, Recti(0, 0, pic->width(), pic->height()), 1.f,
+ BlendMode::UseAlpha);
+ });
+ }
}
void InteractivePlayer::popup_message(Widelands::MessageId const id,
=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc 2017-08-28 07:39:59 +0000
+++ src/wui/interactive_spectator.cc 2017-08-28 12:55:36 +0000
@@ -109,9 +109,40 @@
}
void InteractiveSpectator::draw_map_view(MapView* given_map_view, RenderTarget* dst) {
- const GameRenderer::Overlays overlays{get_text_to_draw(), road_building_preview()};
- given_map_view->draw_map_view(egbase(), overlays, GameRenderer::DrawImmovables::kYes,
- GameRenderer::DrawBobs::kYes, nullptr, dst);
+ // A spectator cannot build roads.
+ assert(road_building_preview().empty());
+
+ const auto& gbase = egbase();
+ auto* fields_to_draw = given_map_view->draw_terrain(gbase, dst);
+ const float scale = 1.f / given_map_view->view().zoom;
+ const uint32_t gametime = gbase.get_gametime();
+
+ const auto text_to_draw = get_text_to_draw();
+ for (size_t idx = 0; idx < fields_to_draw->size(); ++idx) {
+ const FieldsToDraw::Field& field = fields_to_draw->at(idx);
+
+ draw_border_markers(field, scale, *fields_to_draw, dst);
+
+ Widelands::BaseImmovable* const imm = field.fcoords.field->get_immovable();
+ if (imm != nullptr && imm->get_positions(gbase).front() == field.fcoords) {
+ imm->draw(gametime, text_to_draw, field.rendertarget_pixel, scale, dst);
+ }
+
+ for (Widelands::Bob* bob = field.fcoords.field->get_first_bob(); bob;
+ bob = bob->get_next_bob()) {
+ bob->draw(gbase, text_to_draw, field.rendertarget_pixel, scale, dst);
+ }
+
+ // TODO(sirver): Do not use the field_overlay_manager, instead draw the
+ // overlays we are interested in here directly.
+ field_overlay_manager().foreach_overlay(
+ field.fcoords, [dst, &field, scale](const Image* pic, const Vector2i& hotspot) {
+ dst->blitrect_scale(Rectf(field.rendertarget_pixel - hotspot.cast<float>() * scale,
+ pic->width() * scale, pic->height() * scale),
+ pic, Recti(0, 0, pic->width(), pic->height()), 1.f,
+ BlendMode::UseAlpha);
+ });
+ }
}
/**
=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc 2017-08-19 20:55:57 +0000
+++ src/wui/mapview.cc 2017-08-28 12:55:36 +0000
@@ -25,8 +25,6 @@
#include "base/math.h"
#include "graphic/graphic.h"
#include "graphic/rendertarget.h"
-#include "logic/map_objects/draw_text.h"
-#include "logic/player.h"
#include "wlapplication.h"
#include "wui/mapviewpixelfunctions.h"
@@ -294,7 +292,6 @@
UI::Panel* parent, const Widelands::Map& map, int32_t x, int32_t y, uint32_t w, uint32_t h)
: UI::Panel(parent, x, y, w, h),
map_(map),
- renderer_(new GameRenderer()),
view_(),
last_mouse_pos_(Vector2i::zero()),
dragging_(false) {
@@ -339,12 +336,7 @@
NEVER_HERE();
}
-void MapView::draw_map_view(const Widelands::EditorGameBase& egbase,
- const GameRenderer::Overlays& overlays,
- const GameRenderer::DrawImmovables& draw_immovables,
- const GameRenderer::DrawBobs& draw_bobs,
- const Widelands::Player* player,
- RenderTarget* dst) {
+FieldsToDraw* MapView::draw_terrain(const Widelands::EditorGameBase& egbase, RenderTarget* dst) {
uint32_t now = SDL_GetTicks();
while (!view_plans_.empty()) {
auto& plan = view_plans_.front();
@@ -384,8 +376,10 @@
break;
}
- renderer_->render(
- egbase, view_.viewpoint, view_.zoom, player, overlays, draw_immovables, draw_bobs, dst);
+ fields_to_draw_.reset(egbase, view_.viewpoint, view_.zoom, dst);
+ const float scale = 1.f / view_.zoom;
+ ::draw_terrain(egbase, fields_to_draw_, scale, dst);
+ return &fields_to_draw_;
}
void MapView::set_view(const View& target_view, const Transition& transition) {
=== modified file 'src/wui/mapview.h'
--- src/wui/mapview.h 2017-08-19 20:55:57 +0000
+++ src/wui/mapview.h 2017-08-28 12:55:36 +0000
@@ -29,12 +29,11 @@
#include "base/rect.h"
#include "base/vector.h"
#include "graphic/game_renderer.h"
+#include "graphic/gl/fields_to_draw.h"
#include "logic/map.h"
#include "logic/widelands_geometry.h"
#include "ui_basic/panel.h"
-class GameRenderer;
-
/**
* Implements a view of a map. It is used to render a valid map on the screen.
*/
@@ -159,13 +158,12 @@
// True if a 'Transition::Smooth' animation is playing.
bool is_animating() const;
+ // Schedules drawing of the terrain of this MapView. The returned value can
+ // be used to override contents of 'fields_to_draw' for player knowledge and
+ // visibility, and to correctly draw map objects, overlays and text.
+ FieldsToDraw* draw_terrain(const Widelands::EditorGameBase& egbase, RenderTarget* dst);
+
// Not overriden from UI::Panel, instead we expect to be passed the data through.
- void draw_map_view(const Widelands::EditorGameBase& egbase,
- const GameRenderer::Overlays& overlays,
- const GameRenderer::DrawImmovables& draw_immovables,
- const GameRenderer::DrawBobs& draw_bobs,
- const Widelands::Player* player,
- RenderTarget* dst);
bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);
bool handle_mouserelease(uint8_t btn, int32_t x, int32_t y);
bool handle_mousemove(uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
@@ -190,7 +188,11 @@
Vector2f to_map(const Vector2i& panel_pixel) const;
const Widelands::Map& map_;
- std::unique_ptr<GameRenderer> renderer_;
+
+ // This is owned and handled by us, but handed to the RenderQueue, so we
+ // basically promise that this stays valid for one frame.
+ FieldsToDraw fields_to_draw_;
+
View view_;
Vector2i last_mouse_pos_;
bool dragging_;
References