widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #16664
[Merge] lp:~widelands-dev/widelands/editor-grid into lp:widelands
Benedikt Straub has proposed merging lp:~widelands-dev/widelands/editor-grid into lp:widelands.
Commit message:
Add a grid overlay to the editor that can be toggled with a button or the hotkey 'G'
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #1529261 in widelands: "Create an overlay which shows a grid"
https://bugs.launchpad.net/widelands/+bug/1529261
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/editor-grid/+merge/366505
Next try :)
I also experimented with draw_line_strip – there was no visible difference but it was a bit slower. So a new, small shader is better IMHO.
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/editor-grid into lp:widelands.
=== added file 'data/images/wui/menus/menu_toggle_grid.png'
Binary files data/images/wui/menus/menu_toggle_grid.png 1970-01-01 00:00:00 +0000 and data/images/wui/menus/menu_toggle_grid.png 2019-04-25 09:23:16 +0000 differ
=== added file 'data/shaders/grid.fp'
--- data/shaders/grid.fp 1970-01-01 00:00:00 +0000
+++ data/shaders/grid.fp 2019-04-25 09:23:16 +0000
@@ -0,0 +1,5 @@
+#version 120
+
+void main() {
+ gl_FragColor = vec4(.0, .0, .0, .8);
+}
=== added file 'data/shaders/grid.vp'
--- data/shaders/grid.vp 1970-01-01 00:00:00 +0000
+++ data/shaders/grid.vp 2019-04-25 09:23:16 +0000
@@ -0,0 +1,10 @@
+#version 120
+
+// Attributes.
+attribute vec2 attr_position;
+
+uniform float u_z_value;
+
+void main() {
+ gl_Position = vec4(attr_position, u_z_value, 1.);
+}
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc 2019-04-24 15:56:31 +0000
+++ src/editor/editorinteractive.cc 2019-04-25 09:23:16 +0000
@@ -98,6 +98,10 @@
toggle_buildhelp_ = add_toolbar_button(
"wui/menus/menu_toggle_buildhelp", "buildhelp", _("Show building spaces (on/off)"));
toggle_buildhelp_->sigclicked.connect(boost::bind(&EditorInteractive::toggle_buildhelp, this));
+ toggle_grid_ =
+ add_toolbar_button("wui/menus/menu_toggle_grid", "grid", _("Show grid (on/off)"));
+ toggle_grid_->set_perm_pressed(true);
+ toggle_grid_->sigclicked.connect([this]() { toggle_grid(); });
toggle_immovables_ = add_toolbar_button(
"wui/menus/menu_toggle_immovables", "immovables", _("Show immovables (on/off)"));
toggle_immovables_->set_perm_pressed(true);
@@ -262,7 +266,7 @@
void EditorInteractive::draw(RenderTarget& dst) {
const auto& ebase = egbase();
- auto* fields_to_draw = map_view()->draw_terrain(ebase, Workareas(), &dst);
+ auto* fields_to_draw = map_view()->draw_terrain(ebase, Workareas(), draw_grid_, &dst);
const float scale = 1.f / map_view()->view().zoom;
const uint32_t gametime = ebase.get_gametime();
@@ -430,6 +434,11 @@
toggle_bobs_->set_perm_pressed(draw_bobs_);
}
+void EditorInteractive::toggle_grid() {
+ draw_grid_ = !draw_grid_;
+ toggle_grid_->set_perm_pressed(draw_grid_);
+}
+
bool EditorInteractive::handle_key(bool const down, SDL_Keysym const code) {
if (down) {
switch (code.sym) {
@@ -504,6 +513,10 @@
toggle_buildhelp();
return true;
+ case SDLK_g:
+ toggle_grid();
+ return true;
+
case SDLK_c:
set_display_flag(
InteractiveBase::dfShowCensus, !get_display_flag(InteractiveBase::dfShowCensus));
=== modified file 'src/editor/editorinteractive.h'
--- src/editor/editorinteractive.h 2019-04-24 07:09:29 +0000
+++ src/editor/editorinteractive.h 2019-04-25 09:23:16 +0000
@@ -149,6 +149,7 @@
void toggle_resources();
void toggle_immovables();
void toggle_bobs();
+ void toggle_grid();
// state variables
bool need_save_;
@@ -170,6 +171,7 @@
UI::UniqueWindow::Registry helpmenu_;
UI::Button* toggle_buildhelp_;
+ UI::Button* toggle_grid_;
UI::Button* toggle_resources_;
UI::Button* toggle_immovables_;
UI::Button* toggle_bobs_;
@@ -182,6 +184,7 @@
bool draw_resources_ = true;
bool draw_immovables_ = true;
bool draw_bobs_ = true;
+ bool draw_grid_ = true;
};
#endif // end of include guard: WL_EDITOR_EDITORINTERACTIVE_H
=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt 2019-04-24 15:56:31 +0000
+++ src/graphic/CMakeLists.txt 2019-04-25 09:23:16 +0000
@@ -225,6 +225,8 @@
wl_library(graphic_terrain_programs
SRCS
+ gl/grid_program.cc
+ gl/grid_program.h
gl/road_program.cc
gl/road_program.h
gl/terrain_program.cc
=== modified file 'src/graphic/game_renderer.cc'
--- src/graphic/game_renderer.cc 2019-04-24 15:56:31 +0000
+++ src/graphic/game_renderer.cc 2019-04-25 09:23:16 +0000
@@ -61,6 +61,7 @@
const FieldsToDraw& fields_to_draw,
const float scale,
Workareas workarea,
+ bool grid,
RenderTarget* dst) {
const Recti& bounding_rect = dst->get_rect();
const Surface& surface = dst->get_surface();
@@ -94,6 +95,13 @@
RenderQueue::instance().enqueue(i);
}
+ if (grid) {
+ // Enqueue the drawing of the grid layer.
+ i.program_id = RenderQueue::Program::kTerrainGrid;
+ i.blend_mode = BlendMode::UseAlpha;
+ RenderQueue::instance().enqueue(i);
+ }
+
// Enqueue the drawing of the road layer.
i.program_id = RenderQueue::Program::kTerrainRoad;
RenderQueue::instance().enqueue(i);
=== modified file 'src/graphic/game_renderer.h'
--- src/graphic/game_renderer.h 2019-03-11 14:45:04 +0000
+++ src/graphic/game_renderer.h 2019-04-25 09:23:16 +0000
@@ -34,6 +34,7 @@
const FieldsToDraw& fields_to_draw,
const float scale,
Workareas workarea,
+ bool grid,
RenderTarget* dst);
// Draw the border stones for 'field' if it is a border and 'visibility' is
=== added file 'src/graphic/gl/grid_program.cc'
--- src/graphic/gl/grid_program.cc 1970-01-01 00:00:00 +0000
+++ src/graphic/gl/grid_program.cc 2019-04-25 09:23:16 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2006-2019 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/grid_program.h"
+
+#include "graphic/gl/coordinate_conversion.h"
+#include "graphic/gl/fields_to_draw.h"
+#include "graphic/gl/utils.h"
+#include "graphic/texture.h"
+
+GridProgram::GridProgram() {
+ gl_program_.build("grid");
+
+ attr_position_ = glGetAttribLocation(gl_program_.object(), "attr_position");
+
+ u_z_value_ = glGetUniformLocation(gl_program_.object(), "u_z_value");
+}
+
+void GridProgram::gl_draw(int gl_texture, float z_value) {
+ glUseProgram(gl_program_.object());
+
+ auto& gl_state = Gl::State::instance();
+
+ gl_array_buffer_.bind();
+ gl_array_buffer_.update(vertices_);
+
+ Gl::vertex_attrib_pointer(
+ attr_position_, 2, sizeof(PerVertexData), offsetof(PerVertexData, gl_x));
+
+ gl_state.bind(GL_TEXTURE0, gl_texture);
+
+ glUniform1f(u_z_value_, z_value);
+
+ glDrawArrays(GL_LINES, 0, vertices_.size());
+}
+
+void GridProgram::add_vertex(const FieldsToDraw::Field& field) {
+ vertices_.emplace_back();
+ PerVertexData& back = vertices_.back();
+ back.gl_x = field.gl_position.x;
+ back.gl_y = field.gl_position.y;
+}
+
+void GridProgram::draw(uint32_t texture_id,
+ const FieldsToDraw& fields_to_draw,
+ float z_value) {
+ vertices_.clear();
+ vertices_.reserve(fields_to_draw.size() * 2);
+
+ for (size_t current_index = 0; current_index < fields_to_draw.size(); ++current_index) {
+ const FieldsToDraw::Field& field = fields_to_draw.at(current_index);
+
+ // Southwestern edge
+ if (field.bln_index != FieldsToDraw::kInvalidIndex) {
+ add_vertex(fields_to_draw.at(current_index));
+ add_vertex(fields_to_draw.at(field.bln_index));
+ }
+
+ // Southeastern edge
+ if (field.brn_index != FieldsToDraw::kInvalidIndex) {
+ add_vertex(fields_to_draw.at(current_index));
+ add_vertex(fields_to_draw.at(field.brn_index));
+ }
+
+ // Eastern edge
+ if (field.rn_index != FieldsToDraw::kInvalidIndex) {
+ add_vertex(fields_to_draw.at(current_index));
+ add_vertex(fields_to_draw.at(field.rn_index));
+ }
+ }
+
+ gl_draw(texture_id, z_value);
+}
=== added file 'src/graphic/gl/grid_program.h'
--- src/graphic/gl/grid_program.h 1970-01-01 00:00:00 +0000
+++ src/graphic/gl/grid_program.h 2019-04-25 09:23:16 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006-2019 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef WL_GRAPHIC_GL_GRID_PROGRAM_H
+#define WL_GRAPHIC_GL_GRID_PROGRAM_H
+
+#include <vector>
+
+#include "base/vector.h"
+#include "graphic/gl/fields_to_draw.h"
+#include "graphic/gl/utils.h"
+#include "logic/description_maintainer.h"
+#include "logic/map_objects/world/terrain_description.h"
+
+class GridProgram {
+public:
+ // Compiles the program. Throws on errors.
+ GridProgram();
+
+ // Draws the grid layer
+ void draw(uint32_t texture_id,
+ const FieldsToDraw& fields_to_draw,
+ float z_value);
+
+private:
+ struct PerVertexData {
+ float gl_x;
+ float gl_y;
+ };
+ static_assert(sizeof(PerVertexData) == 8, "Wrong padding.");
+
+ void gl_draw(int gl_texture, float z_value);
+
+ // Adds a vertex to the end of vertices with data from 'field'.
+ void add_vertex(const FieldsToDraw::Field& field);
+
+ // The program used for drawing the grid layer
+ Gl::Program gl_program_;
+
+ // The buffer that will contain 'vertices_' for rendering.
+ Gl::Buffer<PerVertexData> gl_array_buffer_;
+
+ // Attributes.
+ GLint attr_position_;
+
+ // Uniforms.
+ GLint u_z_value_;
+
+ // Objects below are kept around to avoid memory allocations on each frame.
+ // They could theoretically also be recreated.
+ std::vector<PerVertexData> vertices_;
+
+ DISALLOW_COPY_AND_ASSIGN(GridProgram);
+};
+
+#endif // end of include guard: WL_GRAPHIC_GL_GRID_PROGRAM_H
=== modified file 'src/graphic/render_queue.cc'
--- src/graphic/render_queue.cc 2019-04-25 00:03:42 +0000
+++ src/graphic/render_queue.cc 2019-04-25 09:23:16 +0000
@@ -28,6 +28,7 @@
#include "graphic/gl/dither_program.h"
#include "graphic/gl/draw_line_program.h"
#include "graphic/gl/fill_rect_program.h"
+#include "graphic/gl/grid_program.h"
#include "graphic/gl/road_program.h"
#include "graphic/gl/terrain_program.h"
#include "graphic/gl/workarea_program.h"
@@ -144,6 +145,7 @@
terrain_program_(new TerrainProgram()),
dither_program_(new DitherProgram()),
workarea_program_(new WorkareaProgram()),
+ grid_program_(new GridProgram()),
road_program_(new RoadProgram()) {
}
@@ -167,6 +169,7 @@
case Program::kTerrainBase:
case Program::kTerrainDither:
case Program::kTerrainWorkarea:
+ case Program::kTerrainGrid:
case Program::kTerrainRoad:
/* all fallthroughs intended */
break;
@@ -262,6 +265,13 @@
++i;
} break;
+ case Program::kTerrainGrid: {
+ ScopedScissor scoped_scissor(item.terrain_arguments.destination_rect);
+ grid_program_->draw(item.terrain_arguments.terrains->get(0).get_texture(0).blit_data().texture_id,
+ *item.terrain_arguments.fields_to_draw, item.z_value);
+ ++i;
+ } break;
+
case Program::kTerrainRoad: {
ScopedScissor scoped_scissor(item.terrain_arguments.destination_rect);
road_program_->draw(item.terrain_arguments.renderbuffer_width,
=== modified file 'src/graphic/render_queue.h'
--- src/graphic/render_queue.h 2019-03-11 14:45:04 +0000
+++ src/graphic/render_queue.h 2019-04-25 09:23:16 +0000
@@ -36,6 +36,7 @@
#include "logic/map_objects/world/terrain_description.h"
class DitherProgram;
+class GridProgram;
class RoadProgram;
class TerrainProgram;
class WorkareaProgram;
@@ -84,6 +85,7 @@
kTerrainBase,
kTerrainDither,
kTerrainWorkarea,
+ kTerrainGrid,
kTerrainRoad,
kBlit,
kRect,
@@ -182,6 +184,7 @@
std::unique_ptr<TerrainProgram> terrain_program_;
std::unique_ptr<DitherProgram> dither_program_;
std::unique_ptr<WorkareaProgram> workarea_program_;
+ std::unique_ptr<GridProgram> grid_program_;
std::unique_ptr<RoadProgram> road_program_;
std::vector<Item> blended_items_;
=== modified file 'src/wui/interactive_player.cc'
--- src/wui/interactive_player.cc 2019-04-25 00:03:42 +0000
+++ src/wui/interactive_player.cc 2019-04-25 09:23:16 +0000
@@ -288,7 +288,7 @@
const uint32_t gametime = gbase.get_gametime();
Workareas workareas = get_workarea_overlays(map);
- auto* fields_to_draw = given_map_view->draw_terrain(gbase, workareas, dst);
+ auto* fields_to_draw = given_map_view->draw_terrain(gbase, workareas, false, dst);
const auto& road_building = road_building_overlays();
const float scale = 1.f / given_map_view->view().zoom;
=== modified file 'src/wui/interactive_spectator.cc'
--- src/wui/interactive_spectator.cc 2019-04-24 15:56:31 +0000
+++ src/wui/interactive_spectator.cc 2019-04-25 09:23:16 +0000
@@ -116,7 +116,7 @@
const Widelands::Game& the_game = game();
const Widelands::Map& map = the_game.map();
- auto* fields_to_draw = given_map_view->draw_terrain(the_game, get_workarea_overlays(map), dst);
+ auto* fields_to_draw = given_map_view->draw_terrain(the_game, get_workarea_overlays(map), false, dst);
const float scale = 1.f / given_map_view->view().zoom;
const uint32_t gametime = the_game.get_gametime();
=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc 2019-04-25 00:03:42 +0000
+++ src/wui/mapview.cc 2019-04-25 09:23:16 +0000
@@ -341,6 +341,7 @@
FieldsToDraw* MapView::draw_terrain(const Widelands::EditorGameBase& egbase,
Workareas workarea,
+ bool grid,
RenderTarget* dst) {
uint32_t now = SDL_GetTicks();
while (!view_plans_.empty()) {
@@ -385,7 +386,7 @@
fields_to_draw_.reset(egbase, view_.viewpoint, view_.zoom, dst);
const float scale = 1.f / view_.zoom;
- ::draw_terrain(egbase, fields_to_draw_, scale, workarea, dst);
+ ::draw_terrain(egbase, fields_to_draw_, scale, workarea, grid, dst);
return &fields_to_draw_;
}
=== modified file 'src/wui/mapview.h'
--- src/wui/mapview.h 2019-04-25 00:03:42 +0000
+++ src/wui/mapview.h 2019-04-25 09:23:16 +0000
@@ -172,8 +172,10 @@
// 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, Workareas workarea, RenderTarget* dst);
+ FieldsToDraw* draw_terrain(const Widelands::EditorGameBase& egbase,
+ Workareas workarea,
+ bool grid,
+ RenderTarget* dst);
// Not overriden from UI::Panel, instead we expect to be passed the data through.
bool handle_mousepress(uint8_t btn, int32_t x, int32_t y);
Follow ups