Merge lp:~nordfriese/widelands/workareas into lp:widelands

Proposed by Benedikt Straub
Status: Merged
Merged at revision: 9077
Proposed branch: lp:~nordfriese/widelands/workareas
Merge into: lp:widelands
Diff against target: 741 lines (+371/-46)
19 files modified
data/shaders/workarea.fp (+7/-0)
data/shaders/workarea.vp (+15/-0)
src/editor/editorinteractive.cc (+1/-1)
src/graphic/CMakeLists.txt (+2/-0)
src/graphic/game_renderer.cc (+8/-0)
src/graphic/game_renderer.h (+1/-0)
src/graphic/gl/workarea_program.cc (+134/-0)
src/graphic/gl/workarea_program.h (+78/-0)
src/graphic/render_queue.cc (+10/-0)
src/graphic/render_queue.h (+4/-0)
src/logic/widelands_geometry.h (+4/-0)
src/wui/buildingwindow.cc (+1/-1)
src/wui/interactive_base.cc (+87/-18)
src/wui/interactive_base.h (+5/-4)
src/wui/interactive_player.cc (+8/-10)
src/wui/interactive_player.h (+2/-0)
src/wui/interactive_spectator.cc (+1/-9)
src/wui/mapview.cc (+2/-2)
src/wui/mapview.h (+1/-1)
To merge this branch: bzr merge lp:~nordfriese/widelands/workareas
Reviewer Review Type Date Requested Status
GunChleoc Approve
Review via email: mp+364266@code.launchpad.net

Commit message

Show the work areas of buildings as overlays on triangles

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

A few nits in the comments

Revision history for this message
Toni Förster (stonerl) wrote :

I like it so far, the node markers are a little too thin, IMHO. Why not use the old workarea12.png or workarea1.png? They are small enough.

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Implemented your comment and updated the documentation.

I think the old markers are much too big and bright, I never really liked them. The purpose of these markers now is only to hint at the locations of nodes; IMHO a small, light cross is enough for that. If you want something bigger, you can always enable the buildhelp…

Revision history for this message
GunChleoc (gunchleoc) wrote :

constexpr kWorkareaTransparency = 127; <- this needs a datatype, e.g. int.

Revision history for this message
Toni Förster (stonerl) wrote :

Fair enough. But are they supposed to be a to look like a ++

Just a question; this is in no way related to your changes. I noticed that some military buildings, like the Fortress, have a different colour on the outer layer, what is this supposed to indicate?

Revision history for this message
Toni Förster (stonerl) wrote :

Can't build r9014.

src/graphic/gl/workarea_program.cc:63:11: error: C++ requires a type specifier for all declarations
constexpr kWorkareaTransparency = 127;

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Fixed the typo, should compile now.

The marker is a small star (*) with six beams that point in the six cardinal directions.

The outer circle(s) is/are the enhancement area(s). They indicate the additional area that will be part of the workarea after an upgrade. We already have different overlay images for those in trunk, it´s just more noticeable with the colours now.

Revision history for this message
Toni Förster (stonerl) wrote :

I made two different versions of the marker. You can find them here:

https://fosuta.org/pics/1_grid_marker.png
https://fosuta.org/pics/2_grid_marker.png

Would you give them a try?

Revision history for this message
Benedikt Straub (nordfriese) wrote :

I think version 2 looks like a square with a circle in it, that looks strange. Version 1 is good, a bit too large though IMHO. I uploaded a new image similar to it now, how about this?

Revision history for this message
Toni Förster (stonerl) wrote :

Looks good.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4585. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/504893428.
Appveyor build 4372. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_nordfriese_widelands_workareas-4372.

Revision history for this message
GunChleoc (gunchleoc) wrote :

I have done some testing as well and have selected multiple buildings on a slow machine - no problem :)

For the grid, how about having another shader that draws lines on the edges? That would also take care of most of the work for adding a grid to the editor:

https://bugs.launchpad.net/widelands/+bug/1529261

Revision history for this message
kaputtnik (franku) wrote :

Looks very good :)

I wonder why the little stars are missing on the border? For an enhanceable building the stars are at the edge of the bluish area. E.g. compare the workarea when trying to build an empire Outpost the stars are at the edge of the bluish and red area, then try to build an empire Barrier (the one which the Outpost can be enhanced to) on the same spot the stars are one node inside the bluish area.
For farms the stars are also one node inside the bluish area, so not showing all the nodes where fields can be planted.

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Well spotted, pushed a fix for it…

> For the grid, how about having another shader that draws lines on the edges? That would also take care of most of the work for adding a grid to the editor

I´m going to try to take care of that feature soon :)
But I´m against showing a real grid in-game. It´s fine to hint at it by using on-node markers like the buildhelp and these star markers, but IMHO an actual grid is only a tool to make it easier to design the map, and not desirable for the gameplay.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4599. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/505929624.
Appveyor build 4387. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_nordfriese_widelands_workareas-4387.

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

Is this for R20?

Revision history for this message
Benedikt Straub (nordfriese) wrote :

Would be nice, but I thought we were in feature freeze ;)

Revision history for this message
GunChleoc (gunchleoc) wrote :

Yes, feature freeze. We're mopping up the remaining bugs right now, so we can't risk merging anything else.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4645. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/511061362.
Appveyor build 4432. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_nordfriese_widelands_workareas-4432.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4672. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/516235502.
Appveyor build 4458. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_nordfriese_widelands_workareas-4458.

Revision history for this message
GunChleoc (gunchleoc) wrote :

@Nordfriese: You forgot to set the branch owner to widelands-dev, so I can't merge trunk to it. Can you take care of getting this branch in?

review: Approve
Revision history for this message
Benedikt Straub (nordfriese) wrote :

Merged trunk

@bunnybot merge

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4784. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/524065227.
Appveyor build 4565. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_nordfriese_widelands_workareas-4565.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Refusing to merge, since Travis is not green. Use @bunnybot merge force for merging anyways.

Travis build 4784. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/524065227.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Transient failure on Travis

@bunnybot merge force

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== renamed file 'data/images/wui/overlays/workarea123.png' => 'data/images/wui/buildings/toggle_workarea.png'
=== added file 'data/images/wui/overlays/grid_marker.png'
0Binary files data/images/wui/overlays/grid_marker.png 1970-01-01 00:00:00 +0000 and data/images/wui/overlays/grid_marker.png 2019-04-24 15:57:58 +0000 differ0Binary files data/images/wui/overlays/grid_marker.png 1970-01-01 00:00:00 +0000 and data/images/wui/overlays/grid_marker.png 2019-04-24 15:57:58 +0000 differ
=== removed file 'data/images/wui/overlays/workarea1.png'
1Binary files data/images/wui/overlays/workarea1.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea1.png 1970-01-01 00:00:00 +0000 differ1Binary files data/images/wui/overlays/workarea1.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea1.png 1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/wui/overlays/workarea12.png'
2Binary files data/images/wui/overlays/workarea12.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea12.png 1970-01-01 00:00:00 +0000 differ2Binary files data/images/wui/overlays/workarea12.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea12.png 1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/wui/overlays/workarea2.png'
3Binary files data/images/wui/overlays/workarea2.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea2.png 1970-01-01 00:00:00 +0000 differ3Binary files data/images/wui/overlays/workarea2.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea2.png 1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/wui/overlays/workarea23.png'
4Binary files data/images/wui/overlays/workarea23.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea23.png 1970-01-01 00:00:00 +0000 differ4Binary files data/images/wui/overlays/workarea23.png 2019-03-30 06:46:25 +0000 and data/images/wui/overlays/workarea23.png 1970-01-01 00:00:00 +0000 differ
=== removed file 'data/images/wui/overlays/workarea3.png'
5Binary files data/images/wui/overlays/workarea3.png 2014-12-03 20:13:06 +0000 and data/images/wui/overlays/workarea3.png 1970-01-01 00:00:00 +0000 differ5Binary files data/images/wui/overlays/workarea3.png 2014-12-03 20:13:06 +0000 and data/images/wui/overlays/workarea3.png 1970-01-01 00:00:00 +0000 differ
=== added file 'data/shaders/workarea.fp'
--- data/shaders/workarea.fp 1970-01-01 00:00:00 +0000
+++ data/shaders/workarea.fp 2019-04-24 15:57:58 +0000
@@ -0,0 +1,7 @@
1#version 120
2
3varying vec4 var_overlay;
4
5void main() {
6 gl_FragColor = var_overlay;
7}
08
=== added file 'data/shaders/workarea.vp'
--- data/shaders/workarea.vp 1970-01-01 00:00:00 +0000
+++ data/shaders/workarea.vp 2019-04-24 15:57:58 +0000
@@ -0,0 +1,15 @@
1#version 120
2
3// Attributes.
4attribute vec2 attr_position;
5attribute vec4 attr_overlay;
6
7uniform float u_z_value;
8
9// Output of vertex shader.
10varying vec4 var_overlay;
11
12void main() {
13 var_overlay = attr_overlay;
14 gl_Position = vec4(attr_position, u_z_value, 1.);
15}
016
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc 2019-04-24 07:09:29 +0000
+++ src/editor/editorinteractive.cc 2019-04-24 15:57:58 +0000
@@ -262,7 +262,7 @@
262262
263void EditorInteractive::draw(RenderTarget& dst) {263void EditorInteractive::draw(RenderTarget& dst) {
264 const auto& ebase = egbase();264 const auto& ebase = egbase();
265 auto* fields_to_draw = map_view()->draw_terrain(ebase, &dst);265 auto* fields_to_draw = map_view()->draw_terrain(ebase, Workareas(), &dst);
266266
267 const float scale = 1.f / map_view()->view().zoom;267 const float scale = 1.f / map_view()->view().zoom;
268 const uint32_t gametime = ebase.get_gametime();268 const uint32_t gametime = ebase.get_gametime();
269269
=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt 2019-04-08 13:32:28 +0000
+++ src/graphic/CMakeLists.txt 2019-04-24 15:57:58 +0000
@@ -231,6 +231,8 @@
231 gl/terrain_program.h231 gl/terrain_program.h
232 gl/dither_program.cc232 gl/dither_program.cc
233 gl/dither_program.h233 gl/dither_program.h
234 gl/workarea_program.cc
235 gl/workarea_program.h
234 DEPENDS236 DEPENDS
235 base_exceptions237 base_exceptions
236 base_geometry238 base_geometry
237239
=== modified file 'src/graphic/game_renderer.cc'
--- src/graphic/game_renderer.cc 2019-04-24 06:01:37 +0000
+++ src/graphic/game_renderer.cc 2019-04-24 15:57:58 +0000
@@ -60,6 +60,7 @@
60void draw_terrain(const Widelands::EditorGameBase& egbase,60void draw_terrain(const Widelands::EditorGameBase& egbase,
61 const FieldsToDraw& fields_to_draw,61 const FieldsToDraw& fields_to_draw,
62 const float scale,62 const float scale,
63 Workareas workarea,
63 RenderTarget* dst) {64 RenderTarget* dst) {
64 const Recti& bounding_rect = dst->get_rect();65 const Recti& bounding_rect = dst->get_rect();
65 const Surface& surface = dst->get_surface();66 const Surface& surface = dst->get_surface();
@@ -86,6 +87,13 @@
86 i.blend_mode = BlendMode::UseAlpha;87 i.blend_mode = BlendMode::UseAlpha;
87 RenderQueue::instance().enqueue(i);88 RenderQueue::instance().enqueue(i);
8889
90 if (!workarea.empty()) {
91 // Enqueue the drawing of the workarea overlay layer.
92 i.program_id = RenderQueue::Program::kTerrainWorkarea;
93 i.terrain_arguments.workareas = workarea;
94 RenderQueue::instance().enqueue(i);
95 }
96
89 // Enqueue the drawing of the road layer.97 // Enqueue the drawing of the road layer.
90 i.program_id = RenderQueue::Program::kTerrainRoad;98 i.program_id = RenderQueue::Program::kTerrainRoad;
91 RenderQueue::instance().enqueue(i);99 RenderQueue::instance().enqueue(i);
92100
=== modified file 'src/graphic/game_renderer.h'
--- src/graphic/game_renderer.h 2019-02-23 11:00:49 +0000
+++ src/graphic/game_renderer.h 2019-04-24 15:57:58 +0000
@@ -33,6 +33,7 @@
33void draw_terrain(const Widelands::EditorGameBase& egbase,33void draw_terrain(const Widelands::EditorGameBase& egbase,
34 const FieldsToDraw& fields_to_draw,34 const FieldsToDraw& fields_to_draw,
35 const float scale,35 const float scale,
36 Workareas workarea,
36 RenderTarget* dst);37 RenderTarget* dst);
3738
38// Draw the border stones for 'field' if it is a border and 'visibility' is39// Draw the border stones for 'field' if it is a border and 'visibility' is
3940
=== added file 'src/graphic/gl/workarea_program.cc'
--- src/graphic/gl/workarea_program.cc 1970-01-01 00:00:00 +0000
+++ src/graphic/gl/workarea_program.cc 2019-04-24 15:57:58 +0000
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2006-2019 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#include "graphic/gl/workarea_program.h"
21
22#include "graphic/gl/coordinate_conversion.h"
23#include "graphic/gl/fields_to_draw.h"
24#include "graphic/gl/utils.h"
25#include "graphic/texture.h"
26
27WorkareaProgram::WorkareaProgram() {
28 gl_program_.build("workarea");
29
30 attr_position_ = glGetAttribLocation(gl_program_.object(), "attr_position");
31 attr_overlay_ = glGetAttribLocation(gl_program_.object(), "attr_overlay");
32
33 u_z_value_ = glGetUniformLocation(gl_program_.object(), "u_z_value");
34}
35
36void WorkareaProgram::gl_draw(int gl_texture, float z_value) {
37 glUseProgram(gl_program_.object());
38
39 auto& gl_state = Gl::State::instance();
40 gl_state.enable_vertex_attrib_array(
41 {attr_position_, attr_overlay_});
42
43 gl_array_buffer_.bind();
44 gl_array_buffer_.update(vertices_);
45
46 Gl::vertex_attrib_pointer(
47 attr_position_, 2, sizeof(PerVertexData), offsetof(PerVertexData, gl_x));
48 Gl::vertex_attrib_pointer(
49 attr_overlay_, 4, sizeof(PerVertexData), offsetof(PerVertexData, overlay_r));
50
51 gl_state.bind(GL_TEXTURE0, gl_texture);
52
53 glUniform1f(u_z_value_, z_value);
54
55 glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
56}
57
58constexpr uint8_t kWorkareaTransparency = 127;
59static RGBAColor workarea_colors[] {
60 RGBAColor(63, 31, 127, kWorkareaTransparency), // All three circles
61 RGBAColor(127, 63, 0, kWorkareaTransparency), // Medium and outer circle
62 RGBAColor(0, 127, 0, kWorkareaTransparency), // Outer circle
63 RGBAColor(63, 0, 127, kWorkareaTransparency), // Inner and medium circle
64 RGBAColor(127, 0, 0, kWorkareaTransparency), // Medium circle
65 RGBAColor(0, 0, 127, kWorkareaTransparency), // Inner circle
66};
67static inline RGBAColor apply_color(RGBAColor c1, RGBAColor c2) {
68 uint8_t r = (c1.r * c1.a + c2.r * c2.a) / (c1.a + c2.a);
69 uint8_t g = (c1.g * c1.a + c2.g * c2.a) / (c1.a + c2.a);
70 uint8_t b = (c1.b * c1.a + c2.b * c2.a) / (c1.a + c2.a);
71 uint8_t a = (c1.a + c2.a) / 2;
72 return RGBAColor(r, g, b, a);
73}
74
75void WorkareaProgram::add_vertex(const FieldsToDraw::Field& field, RGBAColor overlay) {
76 vertices_.emplace_back();
77 PerVertexData& back = vertices_.back();
78
79 back.gl_x = field.gl_position.x;
80 back.gl_y = field.gl_position.y;
81 back.overlay_r = overlay.r / 255.f;
82 back.overlay_g = overlay.g / 255.f;
83 back.overlay_b = overlay.b / 255.f;
84 back.overlay_a = overlay.a / 255.f;
85}
86
87void WorkareaProgram::draw(uint32_t texture_id,
88 Workareas workarea,
89 const FieldsToDraw& fields_to_draw,
90 float z_value) {
91 vertices_.clear();
92 vertices_.reserve(fields_to_draw.size() * 3);
93
94 for (size_t current_index = 0; current_index < fields_to_draw.size(); ++current_index) {
95 const FieldsToDraw::Field& field = fields_to_draw.at(current_index);
96
97 // The bottom right neighbor fields_to_draw is needed for both triangles
98 // associated with this field. If it is not in fields_to_draw, there is no need to
99 // draw any triangles.
100 if (field.brn_index == FieldsToDraw::kInvalidIndex) {
101 continue;
102 }
103
104 // Down triangle.
105 if (field.bln_index != FieldsToDraw::kInvalidIndex) {
106 RGBAColor color(0, 0, 0, 0);
107 for (const std::map<Widelands::TCoords<>, uint8_t>& wa_map : workarea) {
108 const auto it = wa_map.find(Widelands::TCoords<>(field.fcoords, Widelands::TriangleIndex::D));
109 if (it != wa_map.end()) {
110 color = apply_color(color, workarea_colors[it->second]);
111 }
112 }
113 add_vertex(fields_to_draw.at(current_index), color);
114 add_vertex(fields_to_draw.at(field.bln_index), color);
115 add_vertex(fields_to_draw.at(field.brn_index), color);
116 }
117
118 // Right triangle.
119 if (field.rn_index != FieldsToDraw::kInvalidIndex) {
120 RGBAColor color(0, 0, 0, 0);
121 for (const std::map<Widelands::TCoords<>, uint8_t>& wa_map : workarea) {
122 const auto it = wa_map.find(Widelands::TCoords<>(field.fcoords, Widelands::TriangleIndex::R));
123 if (it != wa_map.end()) {
124 color = apply_color(color, workarea_colors[it->second]);
125 }
126 }
127 add_vertex(fields_to_draw.at(current_index), color);
128 add_vertex(fields_to_draw.at(field.brn_index), color);
129 add_vertex(fields_to_draw.at(field.rn_index), color);
130 }
131 }
132
133 gl_draw(texture_id, z_value);
134}
0135
=== added file 'src/graphic/gl/workarea_program.h'
--- src/graphic/gl/workarea_program.h 1970-01-01 00:00:00 +0000
+++ src/graphic/gl/workarea_program.h 2019-04-24 15:57:58 +0000
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2006-2019 by the Widelands Development Team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20#ifndef WL_GRAPHIC_GL_WORKAREA_PROGRAM_H
21#define WL_GRAPHIC_GL_WORKAREA_PROGRAM_H
22
23#include <vector>
24
25#include "base/vector.h"
26#include "graphic/gl/fields_to_draw.h"
27#include "graphic/gl/utils.h"
28#include "logic/description_maintainer.h"
29#include "logic/map_objects/world/terrain_description.h"
30
31class WorkareaProgram {
32public:
33 // Compiles the program. Throws on errors.
34 WorkareaProgram();
35
36 // Draws the workarea overlay.
37 void draw(uint32_t texture_id,
38 Workareas workarea,
39 const FieldsToDraw& fields_to_draw,
40 float z_value);
41
42private:
43 struct PerVertexData {
44 float gl_x;
45 float gl_y;
46 float overlay_r;
47 float overlay_g;
48 float overlay_b;
49 float overlay_a;
50 };
51 static_assert(sizeof(PerVertexData) == 24, "Wrong padding.");
52
53 void gl_draw(int gl_texture, float z_value);
54
55 // Adds a vertex to the end of vertices with data from 'field' in order to apply the specified 'overlay'.
56 void add_vertex(const FieldsToDraw::Field& field, RGBAColor overlay);
57
58 // The program used for drawing the workarea overlay.
59 Gl::Program gl_program_;
60
61 // The buffer that will contain 'vertices_' for rendering.
62 Gl::Buffer<PerVertexData> gl_array_buffer_;
63
64 // Attributes.
65 GLint attr_position_;
66 GLint attr_overlay_;
67
68 // Uniforms.
69 GLint u_z_value_;
70
71 // Objects below are kept around to avoid memory allocations on each frame.
72 // They could theoretically also be recreated.
73 std::vector<PerVertexData> vertices_;
74
75 DISALLOW_COPY_AND_ASSIGN(WorkareaProgram);
76};
77
78#endif // end of include guard: WL_GRAPHIC_GL_WORKAREA_PROGRAM_H
079
=== modified file 'src/graphic/render_queue.cc'
--- src/graphic/render_queue.cc 2019-02-23 11:00:49 +0000
+++ src/graphic/render_queue.cc 2019-04-24 15:57:58 +0000
@@ -30,6 +30,7 @@
30#include "graphic/gl/fill_rect_program.h"30#include "graphic/gl/fill_rect_program.h"
31#include "graphic/gl/road_program.h"31#include "graphic/gl/road_program.h"
32#include "graphic/gl/terrain_program.h"32#include "graphic/gl/terrain_program.h"
33#include "graphic/gl/workarea_program.h"
3334
34namespace {35namespace {
3536
@@ -142,6 +143,7 @@
142 : next_z_(1),143 : next_z_(1),
143 terrain_program_(new TerrainProgram()),144 terrain_program_(new TerrainProgram()),
144 dither_program_(new DitherProgram()),145 dither_program_(new DitherProgram()),
146 workarea_program_(new WorkareaProgram()),
145 road_program_(new RoadProgram()) {147 road_program_(new RoadProgram()) {
146}148}
147149
@@ -164,6 +166,7 @@
164 case Program::kRect:166 case Program::kRect:
165 case Program::kTerrainBase:167 case Program::kTerrainBase:
166 case Program::kTerrainDither:168 case Program::kTerrainDither:
169 case Program::kTerrainWorkarea:
167 case Program::kTerrainRoad:170 case Program::kTerrainRoad:
168 /* all fallthroughs intended */171 /* all fallthroughs intended */
169 break;172 break;
@@ -251,6 +254,13 @@
251 ++i;254 ++i;
252 } break;255 } break;
253256
257 case Program::kTerrainWorkarea: {
258 ScopedScissor scoped_scissor(item.terrain_arguments.destination_rect);
259 workarea_program_->draw(item.terrain_arguments.terrains->get(0).get_texture(0).blit_data().texture_id,
260 item.terrain_arguments.workareas, *item.terrain_arguments.fields_to_draw, item.z_value);
261 ++i;
262 } break;
263
254 case Program::kTerrainRoad: {264 case Program::kTerrainRoad: {
255 ScopedScissor scoped_scissor(item.terrain_arguments.destination_rect);265 ScopedScissor scoped_scissor(item.terrain_arguments.destination_rect);
256 road_program_->draw(item.terrain_arguments.renderbuffer_width,266 road_program_->draw(item.terrain_arguments.renderbuffer_width,
257267
=== modified file 'src/graphic/render_queue.h'
--- src/graphic/render_queue.h 2019-02-23 11:00:49 +0000
+++ src/graphic/render_queue.h 2019-04-24 15:57:58 +0000
@@ -38,6 +38,7 @@
38class DitherProgram;38class DitherProgram;
39class RoadProgram;39class RoadProgram;
40class TerrainProgram;40class TerrainProgram;
41class WorkareaProgram;
4142
42// The RenderQueue is a singleton implementing the concept of deferred43// The RenderQueue is a singleton implementing the concept of deferred
43// rendering: Every rendering call that pretends to draw onto the screen will44// rendering: Every rendering call that pretends to draw onto the screen will
@@ -82,6 +83,7 @@
82 enum Program {83 enum Program {
83 kTerrainBase,84 kTerrainBase,
84 kTerrainDither,85 kTerrainDither,
86 kTerrainWorkarea,
85 kTerrainRoad,87 kTerrainRoad,
86 kBlit,88 kBlit,
87 kRect,89 kRect,
@@ -119,6 +121,7 @@
119 int renderbuffer_height = 0;121 int renderbuffer_height = 0;
120 const DescriptionMaintainer<Widelands::TerrainDescription>* terrains = nullptr;122 const DescriptionMaintainer<Widelands::TerrainDescription>* terrains = nullptr;
121 const FieldsToDraw* fields_to_draw = nullptr;123 const FieldsToDraw* fields_to_draw = nullptr;
124 Workareas workareas;
122 float scale = 1.f;125 float scale = 1.f;
123 Rectf destination_rect = Rectf(0.f, 0.f, 0.f, 0.f);126 Rectf destination_rect = Rectf(0.f, 0.f, 0.f, 0.f);
124 };127 };
@@ -178,6 +181,7 @@
178181
179 std::unique_ptr<TerrainProgram> terrain_program_;182 std::unique_ptr<TerrainProgram> terrain_program_;
180 std::unique_ptr<DitherProgram> dither_program_;183 std::unique_ptr<DitherProgram> dither_program_;
184 std::unique_ptr<WorkareaProgram> workarea_program_;
181 std::unique_ptr<RoadProgram> road_program_;185 std::unique_ptr<RoadProgram> road_program_;
182186
183 std::vector<Item> blended_items_;187 std::vector<Item> blended_items_;
184188
=== modified file 'src/logic/widelands_geometry.h'
--- src/logic/widelands_geometry.h 2019-02-23 11:00:49 +0000
+++ src/logic/widelands_geometry.h 2019-04-24 15:57:58 +0000
@@ -21,6 +21,8 @@
21#define WL_LOGIC_WIDELANDS_GEOMETRY_H21#define WL_LOGIC_WIDELANDS_GEOMETRY_H
2222
23#include <cmath>23#include <cmath>
24#include <map>
25#include <set>
24#include <tuple>26#include <tuple>
2527
26#include <stdint.h>28#include <stdint.h>
@@ -155,4 +157,6 @@
155};157};
156} // namespace Widelands158} // namespace Widelands
157159
160using Workareas = std::set<std::map<Widelands::TCoords<>, uint8_t>>;
161
158#endif // end of include guard: WL_LOGIC_WIDELANDS_GEOMETRY_H162#endif // end of include guard: WL_LOGIC_WIDELANDS_GEOMETRY_H
159163
=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc 2019-03-22 18:52:17 +0000
+++ src/wui/buildingwindow.cc 2019-04-24 15:57:58 +0000
@@ -320,7 +320,7 @@
320 if (!wa_info->empty()) {320 if (!wa_info->empty()) {
321 toggle_workarea_ =321 toggle_workarea_ =
322 new UI::Button(capsbuttons, "workarea", 0, 0, 34, 34, UI::ButtonStyle::kWuiMenu,322 new UI::Button(capsbuttons, "workarea", 0, 0, 34, 34, UI::ButtonStyle::kWuiMenu,
323 g_gr->images().get("images/wui/overlays/workarea123.png"));323 g_gr->images().get("images/wui/buildings/toggle_workarea.png"));
324 toggle_workarea_->sigclicked.connect(324 toggle_workarea_->sigclicked.connect(
325 boost::bind(&BuildingWindow::toggle_workarea, boost::ref(*this)));325 boost::bind(&BuildingWindow::toggle_workarea, boost::ref(*this)));
326326
327327
=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc 2019-04-24 06:01:37 +0000
+++ src/wui/interactive_base.cc 2019-04-24 15:57:58 +0000
@@ -112,14 +112,7 @@
112 avg_usframetime_(0),112 avg_usframetime_(0),
113 buildroad_(nullptr),113 buildroad_(nullptr),
114 road_build_player_(0),114 road_build_player_(0),
115 unique_window_handler_(new UniqueWindowHandler()),115 unique_window_handler_(new UniqueWindowHandler()) {
116 // Start at idx 0 for 2 enhancements, idx 3 for 1, idx 5 if none
117 workarea_pics_{g_gr->images().get("images/wui/overlays/workarea123.png"),
118 g_gr->images().get("images/wui/overlays/workarea23.png"),
119 g_gr->images().get("images/wui/overlays/workarea3.png"),
120 g_gr->images().get("images/wui/overlays/workarea12.png"),
121 g_gr->images().get("images/wui/overlays/workarea2.png"),
122 g_gr->images().get("images/wui/overlays/workarea1.png")} {
123116
124 // Load the buildhelp icons.117 // Load the buildhelp icons.
125 {118 {
@@ -200,8 +193,20 @@
200 return nullptr;193 return nullptr;
201}194}
202195
203bool InteractiveBase::has_workarea_preview(const Widelands::Coords& coords) const {196bool InteractiveBase::has_workarea_preview(const Widelands::Coords& coords, const Widelands::Map* map) const {
204 return workarea_previews_.count(coords) == 1;197 if (!map) {
198 return workarea_previews_.count(coords) == 1;
199 }
200 for (const auto& pair : workarea_previews_) {
201 uint32_t radius = 0;
202 for (const auto& p : *pair.second) {
203 radius = std::max(radius, p.first);
204 }
205 if (map->calc_distance(coords, pair.first) <= radius) {
206 return true;
207 }
208 }
209 return false;
205}210}
206211
207UniqueWindowHandler& InteractiveBase::unique_windows() {212UniqueWindowHandler& InteractiveBase::unique_windows() {
@@ -303,12 +308,53 @@
303 workarea_previews_[coords] = &workarea_info;308 workarea_previews_[coords] = &workarea_info;
304}309}
305310
306std::map<Coords, const Image*>311/* Helper function to get the correct index for graphic/gl/workarea_program.cc::workarea_colors .
307InteractiveBase::get_workarea_overlays(const Widelands::Map& map) const {312 * a, b, c are the indices for the three nodes bordering this triangle.
308 std::map<Coords, const Image*> result;313 * This function returns the biggest workarea type that matches all three corners.
309 for (const auto& pair : workarea_previews_) {314 * The indices stand for:
310 const Coords& coords = pair.first;315 * 0 – all three circles
311 const WorkareaInfo* workarea_info = pair.second;316 * 1 – medium and outer circle
317 * 2 – outer circle
318 * 3 – inner and medium circle
319 * 4 – medium circle
320 * 5 – inner circle
321 * We currently assume that no building will have more than three workarea circles.
322 */
323static uint8_t workarea_max(uint8_t a, uint8_t b, uint8_t c) {
324 // Whether all nodes are part of the inner circle
325 bool inner = (a == 0 || a == 3 || a == 5) && (b == 0 || b == 3 || b == 5) && (c == 0 || c == 3 || c == 5);
326 // Whether all nodes are part of the medium circle
327 bool medium = (a == 0 || a == 1 || a == 3 || a == 4) && (b == 0 || b == 1 || b == 3 || b == 4) &&
328 (c == 0 || c == 1 || c == 3 || c == 4);
329 // Whether all nodes are part of the outer circle
330 bool outer = a <= 2 && b <= 2 && c <= 2;
331
332 if (medium) {
333 if (outer && inner) {
334 return 0;
335 } else if (inner) {
336 return 3;
337 } else if (outer) {
338 return 1;
339 } else {
340 return 4;
341 }
342 } else if (outer) {
343 assert(!inner);
344 return 2;
345 } else {
346 assert(inner);
347 return 5;
348 }
349}
350
351Workareas InteractiveBase::get_workarea_overlays(const Widelands::Map& map) const {
352 Workareas result_set;
353 for (const auto& wa_pair : workarea_previews_) {
354 std::map<Coords, uint8_t> intermediate_result;
355 const Coords& coords = wa_pair.first;
356 const WorkareaInfo* workarea_info = wa_pair.second;
357 intermediate_result[coords] = 0;
312 WorkareaInfo::size_type wa_index;358 WorkareaInfo::size_type wa_index;
313 switch (workarea_info->size()) {359 switch (workarea_info->size()) {
314 case 0:360 case 0:
@@ -335,13 +381,36 @@
335 hollow_area.radius = it->first;381 hollow_area.radius = it->first;
336 Widelands::MapHollowRegion<> mr(map, hollow_area);382 Widelands::MapHollowRegion<> mr(map, hollow_area);
337 do {383 do {
338 result[mr.location()] = workarea_pics_[wa_index];384 intermediate_result[mr.location()] = wa_index;
339 } while (mr.advance(map));385 } while (mr.advance(map));
340 wa_index++;386 wa_index++;
341 hollow_area.hole_radius = hollow_area.radius;387 hollow_area.hole_radius = hollow_area.radius;
342 }388 }
389
390 std::map<TCoords<>, uint8_t> result;
391 for (const auto& pair : intermediate_result) {
392 Coords c;
393 map.get_brn(pair.first, &c);
394 const auto brn = intermediate_result.find(c);
395 if (brn == intermediate_result.end()) {
396 continue;
397 }
398 map.get_bln(pair.first, &c);
399 const auto bln = intermediate_result.find(c);
400 map.get_rn(pair.first, &c);
401 const auto rn = intermediate_result.find(c);
402 if (bln != intermediate_result.end()) {
403 result[TCoords<>(pair.first, Widelands::TriangleIndex::D)] = workarea_max(
404 pair.second, brn->second, bln->second);
405 }
406 if (rn != intermediate_result.end()) {
407 result[TCoords<>(pair.first, Widelands::TriangleIndex::R)] = workarea_max(
408 pair.second, brn->second, rn->second);
409 }
410 }
411 result_set.emplace(result);
343 }412 }
344 return result;413 return result_set;
345}414}
346415
347void InteractiveBase::hide_workarea(const Widelands::Coords& coords) {416void InteractiveBase::hide_workarea(const Widelands::Coords& coords) {
348417
=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h 2019-04-19 07:27:15 +0000
+++ src/wui/interactive_base.h 2019-04-24 15:57:58 +0000
@@ -231,7 +231,7 @@
231 TextToDraw get_text_to_draw() const;231 TextToDraw get_text_to_draw() const;
232232
233 // Returns the current overlays for the work area previews.233 // Returns the current overlays for the work area previews.
234 std::map<Widelands::Coords, const Image*> get_workarea_overlays(const Widelands::Map& map) const;234 Workareas get_workarea_overlays(const Widelands::Map& map) const;
235235
236 // Returns the 'BuildhelpOverlay' for 'caps' or nullptr if there is no help236 // Returns the 'BuildhelpOverlay' for 'caps' or nullptr if there is no help
237 // to be displayed on this field.237 // to be displayed on this field.
@@ -241,8 +241,10 @@
241 return road_building_overlays_;241 return road_building_overlays_;
242 }242 }
243243
244 /// Returns true if there is a workarea preview being shown at the given coordinates244 /// Returns true if there is a workarea preview being shown at the given coordinates.
245 bool has_workarea_preview(const Widelands::Coords& coords) const;245 /// If 'map' is 0, checks only if the given coords are the center of a workarea;
246 /// otherwise checks if the coords are within any workarea.
247 bool has_workarea_preview(const Widelands::Coords& coords, const Widelands::Map* map = nullptr) const;
246248
247 /// Returns true if the current player is allowed to hear sounds from map objects on this field249 /// Returns true if the current player is allowed to hear sounds from map objects on this field
248 virtual bool player_hears_field(const Widelands::Coords& coords) const = 0;250 virtual bool player_hears_field(const Widelands::Coords& coords) const = 0;
@@ -304,7 +306,6 @@
304306
305 UI::UniqueWindow::Registry debugconsole_;307 UI::UniqueWindow::Registry debugconsole_;
306 std::unique_ptr<UniqueWindowHandler> unique_window_handler_;308 std::unique_ptr<UniqueWindowHandler> unique_window_handler_;
307 std::vector<const Image*> workarea_pics_;
308 BuildhelpOverlay buildhelp_overlays_[Widelands::Field::Buildhelp_None];309 BuildhelpOverlay buildhelp_overlays_[Widelands::Field::Buildhelp_None];
309};310};
310311
311312
=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc 2019-04-24 06:01:37 +0000
+++ src/wui/interactive_player.cc 2019-04-24 15:57:58 +0000
@@ -160,7 +160,8 @@
160 bool const multiplayer)160 bool const multiplayer)
161 : InteractiveGameBase(g, global_s, NONE, multiplayer),161 : InteractiveGameBase(g, global_s, NONE, multiplayer),
162 auto_roadbuild_mode_(global_s.get_bool("auto_roadbuild_mode", true)),162 auto_roadbuild_mode_(global_s.get_bool("auto_roadbuild_mode", true)),
163 flag_to_connect_(Widelands::Coords::null()) {163 flag_to_connect_(Widelands::Coords::null()),
164 grid_marker_pic_(g_gr->images().get("images/wui/overlays/grid_marker.png")) {
164 add_toolbar_button(165 add_toolbar_button(
165 "wui/menus/menu_options_menu", "options_menu", _("Main menu"), &options_, true);166 "wui/menus/menu_options_menu", "options_menu", _("Main menu"), &options_, true);
166 options_.open_window = [this] { new GameOptionsMenu(*this, options_, main_windows_); };167 options_.open_window = [this] { new GameOptionsMenu(*this, options_, main_windows_); };
@@ -286,9 +287,9 @@
286 const Widelands::Map& map = gbase.map();287 const Widelands::Map& map = gbase.map();
287 const uint32_t gametime = gbase.get_gametime();288 const uint32_t gametime = gbase.get_gametime();
288289
289 auto* fields_to_draw = given_map_view->draw_terrain(gbase, dst);290 Workareas workareas = get_workarea_overlays(map);
291 auto* fields_to_draw = given_map_view->draw_terrain(gbase, workareas, dst);
290 const auto& road_building = road_building_overlays();292 const auto& road_building = road_building_overlays();
291 const std::map<Widelands::Coords, const Image*> workarea_overlays = get_workarea_overlays(map);
292293
293 const float scale = 1.f / given_map_view->view().zoom;294 const float scale = 1.f / given_map_view->view().zoom;
294295
@@ -329,13 +330,10 @@
329 }330 }
330 }331 }
331332
332 // Draw work area previews.333 // Draw work area markers.
333 {334 if (has_workarea_preview(f->fcoords, &map)) {
334 const auto it = workarea_overlays.find(f->fcoords);335 blit_field_overlay(dst, *f, grid_marker_pic_,
335 if (it != workarea_overlays.end()) {336 Vector2i(grid_marker_pic_->width() / 2, grid_marker_pic_->height() / 2), scale);
336 blit_field_overlay(dst, *f, it->second,
337 Vector2i(it->second->width() / 2, it->second->height() / 2), scale);
338 }
339 }337 }
340338
341 if (f->vision > 0) {339 if (f->vision > 0) {
342340
=== modified file 'src/wui/interactive_player.h'
--- src/wui/interactive_player.h 2019-03-14 23:06:02 +0000
+++ src/wui/interactive_player.h 2019-04-24 15:57:58 +0000
@@ -91,6 +91,8 @@
91 UI::UniqueWindow::Registry objectives_;91 UI::UniqueWindow::Registry objectives_;
92 UI::UniqueWindow::Registry encyclopedia_;92 UI::UniqueWindow::Registry encyclopedia_;
93 UI::UniqueWindow::Registry message_menu_;93 UI::UniqueWindow::Registry message_menu_;
94
95 const Image* grid_marker_pic_;
94};96};
9597
96#endif // end of include guard: WL_WUI_INTERACTIVE_PLAYER_H98#endif // end of include guard: WL_WUI_INTERACTIVE_PLAYER_H
9799
=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc 2019-04-24 06:01:37 +0000
+++ src/wui/interactive_spectator.cc 2019-04-24 15:57:58 +0000
@@ -116,12 +116,11 @@
116116
117 const Widelands::Game& the_game = game();117 const Widelands::Game& the_game = game();
118 const Widelands::Map& map = the_game.map();118 const Widelands::Map& map = the_game.map();
119 auto* fields_to_draw = given_map_view->draw_terrain(the_game, dst);119 auto* fields_to_draw = given_map_view->draw_terrain(the_game, get_workarea_overlays(map), dst);
120 const float scale = 1.f / given_map_view->view().zoom;120 const float scale = 1.f / given_map_view->view().zoom;
121 const uint32_t gametime = the_game.get_gametime();121 const uint32_t gametime = the_game.get_gametime();
122122
123 const auto text_to_draw = get_text_to_draw();123 const auto text_to_draw = get_text_to_draw();
124 const std::map<Widelands::Coords, const Image*> workarea_overlays = get_workarea_overlays(map);
125 for (size_t idx = 0; idx < fields_to_draw->size(); ++idx) {124 for (size_t idx = 0; idx < fields_to_draw->size(); ++idx) {
126 const FieldsToDraw::Field& field = fields_to_draw->at(idx);125 const FieldsToDraw::Field& field = fields_to_draw->at(idx);
127126
@@ -137,13 +136,6 @@
137 bob->draw(the_game, text_to_draw, field.rendertarget_pixel, field.fcoords, scale, dst);136 bob->draw(the_game, text_to_draw, field.rendertarget_pixel, field.fcoords, scale, dst);
138 }137 }
139138
140 // Draw work area previews.
141 const auto it = workarea_overlays.find(field.fcoords);
142 if (it != workarea_overlays.end()) {
143 const Image* pic = it->second;
144 blit_field_overlay(dst, field, pic, Vector2i(pic->width() / 2, pic->height() / 2), scale);
145 }
146
147 // Draw build help.139 // Draw build help.
148 if (buildhelp()) {140 if (buildhelp()) {
149 auto caps = Widelands::NodeCaps::CAPS_NONE;141 auto caps = Widelands::NodeCaps::CAPS_NONE;
150142
=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc 2019-04-23 16:24:40 +0000
+++ src/wui/mapview.cc 2019-04-24 15:57:58 +0000
@@ -339,7 +339,7 @@
339 NEVER_HERE();339 NEVER_HERE();
340}340}
341341
342FieldsToDraw* MapView::draw_terrain(const Widelands::EditorGameBase& egbase, RenderTarget* dst) {342FieldsToDraw* MapView::draw_terrain(const Widelands::EditorGameBase& egbase, Workareas workarea, RenderTarget* dst) {
343 uint32_t now = SDL_GetTicks();343 uint32_t now = SDL_GetTicks();
344 while (!view_plans_.empty()) {344 while (!view_plans_.empty()) {
345 auto& plan = view_plans_.front();345 auto& plan = view_plans_.front();
@@ -383,7 +383,7 @@
383383
384 fields_to_draw_.reset(egbase, view_.viewpoint, view_.zoom, dst);384 fields_to_draw_.reset(egbase, view_.viewpoint, view_.zoom, dst);
385 const float scale = 1.f / view_.zoom;385 const float scale = 1.f / view_.zoom;
386 ::draw_terrain(egbase, fields_to_draw_, scale, dst);386 ::draw_terrain(egbase, fields_to_draw_, scale, workarea, dst);
387 return &fields_to_draw_;387 return &fields_to_draw_;
388}388}
389389
390390
=== modified file 'src/wui/mapview.h'
--- src/wui/mapview.h 2019-03-26 02:56:03 +0000
+++ src/wui/mapview.h 2019-04-24 15:57:58 +0000
@@ -172,7 +172,7 @@
172 // Schedules drawing of the terrain of this MapView. The returned value can172 // Schedules drawing of the terrain of this MapView. The returned value can
173 // be used to override contents of 'fields_to_draw' for player knowledge and173 // be used to override contents of 'fields_to_draw' for player knowledge and
174 // visibility, and to correctly draw map objects, overlays and text.174 // visibility, and to correctly draw map objects, overlays and text.
175 FieldsToDraw* draw_terrain(const Widelands::EditorGameBase& egbase, RenderTarget* dst);175 FieldsToDraw* draw_terrain(const Widelands::EditorGameBase& egbase, Workareas workarea, RenderTarget* dst);
176176
177 // Not overriden from UI::Panel, instead we expect to be passed the data through.177 // Not overriden from UI::Panel, instead we expect to be passed the data through.
178 bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);178 bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);

Subscribers

People subscribed via source and target branches

to status/vote changes: