1 /*
2  * Copyright (C) 2006-2020 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 <memory>
24 
25 #include "base/vector.h"
26 #include "graphic/gl/fields_to_draw.h"
27 #include "graphic/gl/utils.h"
28 #include "logic/map_objects/tribes/workarea_info.h"
29 
30 class WorkareaProgram {
31 public:
32 	// Compiles the program. Throws on errors.
33 	WorkareaProgram();
34 
35 	// Draws the workarea overlay.
36 	void draw(uint32_t texture_id, Workareas, const FieldsToDraw&, float z, Vector2f rendertarget);
37 
38 private:
39 	struct PerVertexData {
40 		float gl_x;
41 		float gl_y;
42 		float overlay_r;
43 		float overlay_g;
44 		float overlay_b;
45 		float overlay_a;
46 	};
47 	static_assert(sizeof(PerVertexData) == 24, "Wrong padding.");
48 
49 	void gl_draw(int gl_texture, float z_value);
50 
51 	// Adds a vertex to the end of vertices with data from 'field' in order to apply the specified
52 	// 'overlay' and, if desired, at the specified offset.
53 	void add_vertex(const FieldsToDraw::Field& field,
54 	                RGBAColor overlay,
55 	                std::vector<PerVertexData>*,
56 	                Vector2f offset = Vector2f::zero(),
57 	                Vector2f viewport = Vector2f::zero());
58 
59 	// The program used for drawing the workarea overlay.
60 	Gl::Program gl_program_;
61 
62 	// The buffer that will contain 'vertices_' for rendering.
63 	Gl::Buffer<PerVertexData> gl_array_buffer_;
64 
65 	// Attributes.
66 	GLint attr_position_;
67 	GLint attr_overlay_;
68 
69 	// Uniforms.
70 	GLint u_z_value_;
71 
72 	// Objects below are kept around to avoid memory allocations on each frame.
73 	// They could theoretically also be recreated.
74 	std::vector<PerVertexData> vertices_;
75 	std::vector<PerVertexData> outer_vertices_;
76 
77 	// Calculating the workareas is a bit slow, so we only recalculate when we have to
78 	struct WorkareasCache {
WorkareasCacheWorkareasCache79 		WorkareasCache(const Workareas& wa, const Widelands::FCoords f, const Vector2f v)
80 		   : workareas(wa), fcoords(f), surface_pixel(v) {
81 		}
82 
83 		const Workareas workareas;
84 		// Viewpoint data
85 		const Widelands::FCoords fcoords;
86 		const Vector2f surface_pixel;
87 	};
88 	std::unique_ptr<WorkareasCache> cache_;
89 
90 	DISALLOW_COPY_AND_ASSIGN(WorkareaProgram);
91 };
92 
93 #endif  // end of include guard: WL_GRAPHIC_GL_WORKAREA_PROGRAM_H
94