1 /**
2  * Copyright (c) 2006-2016 LOVE Development Team
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  **/
20 
21 #ifndef LOVE_GRAPHICS_OPENGL_MESH_H
22 #define LOVE_GRAPHICS_OPENGL_MESH_H
23 
24 // LOVE
25 #include "common/config.h"
26 #include "common/int.h"
27 #include "common/math.h"
28 #include "common/StringMap.h"
29 #include "graphics/Drawable.h"
30 #include "graphics/Texture.h"
31 #include "GLBuffer.h"
32 
33 // C++
34 #include <vector>
35 #include <unordered_map>
36 
37 namespace love
38 {
39 namespace graphics
40 {
41 namespace opengl
42 {
43 
44 /**
45  * Holds and draws arbitrary vertex geometry.
46  * Each vertex in the Mesh has a collection of vertex attributes specified on
47  * creation.
48  **/
49 class Mesh : public Drawable
50 {
51 public:
52 
53 	// The expected usage pattern of the Mesh's vertex data.
54 	enum Usage
55 	{
56 		USAGE_STREAM,
57 		USAGE_DYNAMIC,
58 		USAGE_STATIC,
59 		USAGE_MAX_ENUM
60 	};
61 
62 	// How the Mesh's vertices are used when drawing.
63 	// http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png
64 	enum DrawMode
65 	{
66 		DRAWMODE_FAN,
67 		DRAWMODE_STRIP,
68 		DRAWMODE_TRIANGLES,
69 		DRAWMODE_POINTS,
70 		DRAWMODE_MAX_ENUM
71 	};
72 
73 	// The type of data a vertex attribute can store.
74 	enum DataType
75 	{
76 		DATA_BYTE,
77 		DATA_FLOAT,
78 		DATA_MAX_ENUM
79 	};
80 
81 	struct AttribFormat
82 	{
83 		std::string name;
84 		DataType type;
85 		int components; // max 4
86 	};
87 
88 	Mesh(const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, DrawMode drawmode, Usage usage);
89 	Mesh(const std::vector<AttribFormat> &vertexformat, int vertexcount, DrawMode drawmode, Usage usage);
90 
91 	Mesh(const std::vector<Vertex> &vertices, DrawMode drawmode, Usage usage);
92 	Mesh(int vertexcount, DrawMode drawmode, Usage usage);
93 
94 	virtual ~Mesh();
95 
96 	/**
97 	 * Sets the values of all attributes at a specific vertex index in the Mesh.
98 	 * The size of the data must be less than or equal to the total size of all
99 	 * vertex attributes.
100 	 **/
101 	void setVertex(size_t vertindex, const void *data, size_t datasize);
102 	size_t getVertex(size_t vertindex, void *data, size_t datasize);
103 	void *getVertexScratchBuffer();
104 
105 	/**
106 	 * Sets the values for a single attribute at a specific vertex index in the
107 	 * Mesh. The size of the data must be less than or equal to the size of the
108 	 * attribute.
109 	 **/
110 	void setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize);
111 	size_t getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize);
112 
113 	/**
114 	 * Gets the total number of vertices that can be used when drawing the Mesh.
115 	 **/
116 	size_t getVertexCount() const;
117 
118 	/**
119 	 * Gets the size in bytes of the start of one vertex to the start of the
120 	 * next, in the buffer.
121 	 **/
122 	size_t getVertexStride() const;
123 
124 	/**
125 	 * Gets the format of each vertex attribute stored in the Mesh.
126 	 **/
127 	const std::vector<AttribFormat> &getVertexFormat() const;
128 	DataType getAttributeInfo(int attribindex, int &components) const;
129 	int getAttributeIndex(const std::string &name) const;
130 
131 	/**
132 	 * Sets whether a specific vertex attribute is used when drawing the Mesh.
133 	 **/
134 	void setAttributeEnabled(const std::string &name, bool enable);
135 	bool isAttributeEnabled(const std::string &name) const;
136 
137 	/**
138 	 * Attaches a vertex attribute from another Mesh to this one. The attribute
139 	 * will be used when drawing this Mesh.
140 	 **/
141 	void attachAttribute(const std::string &name, Mesh *mesh);
142 
143 	void *mapVertexData();
144 	void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1);
145 
146 	/**
147 	 * Flushes all modified data to the GPU.
148 	 **/
149 	void flush();
150 
151 	/**
152 	 * Sets the vertex map to use when drawing the Mesh. The vertex map
153 	 * determines the order in which vertices are used by the draw mode.
154 	 * A 0-element vector is equivalent to the default vertex map:
155 	 * {0, 1, 2, 3, 4, ...}
156 	 **/
157 	void setVertexMap(const std::vector<uint32> &map);
158 	void setVertexMap();
159 
160 	/**
161 	 * Fills the uint32 vector passed into the method with the previously set
162 	 * vertex map (index buffer) values.
163 	 **/
164 	bool getVertexMap(std::vector<uint32> &map) const;
165 
166 	/**
167 	 * Gets the total number of elements in the vertex map array.
168 	 **/
169 	size_t getVertexMapCount() const;
170 
171 	/**
172 	 * Sets the texture used when drawing the Mesh.
173 	 **/
174 	void setTexture(Texture *texture);
175 
176 	/**
177 	 * Disables any texture from being used when drawing the Mesh.
178 	 **/
179 	void setTexture();
180 
181 	/**
182 	 * Gets the texture used when drawing the Mesh. May return null if no
183 	 * texture is set.
184 	 **/
185 	Texture *getTexture() const;
186 
187 	/**
188 	 * Sets the draw mode used when drawing the Mesh.
189 	 **/
190 	void setDrawMode(DrawMode mode);
191 	DrawMode getDrawMode() const;
192 
193 	void setDrawRange(int min, int max);
194 	void setDrawRange();
195 	void getDrawRange(int &min, int &max) const;
196 
197 	int bindAttributeToShaderInput(int attributeindex, const std::string &inputname);
198 
199 	// Implements Drawable.
200 	void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) override;
201 
202 	static GLenum getGLBufferUsage(Usage usage);
203 
204 	static bool getConstant(const char *in, Usage &out);
205 	static bool getConstant(Usage in, const char *&out);
206 
207 	static bool getConstant(const char *in, DrawMode &out);
208 	static bool getConstant(DrawMode in, const char *&out);
209 
210 	static bool getConstant(const char *in, DataType &out);
211 	static bool getConstant(DataType in, const char *&out);
212 
213 private:
214 
215 	struct AttachedAttribute
216 	{
217 		Mesh *mesh;
218 		int index;
219 		bool enabled;
220 	};
221 
222 	void setupAttachedAttributes();
223 	void calculateAttributeSizes();
224 	size_t getAttributeOffset(size_t attribindex) const;
225 
226 	static size_t getAttribFormatSize(const AttribFormat &format);
227 
228 	static GLenum getGLDrawMode(DrawMode mode);
229 	static GLenum getGLDataType(DataType type);
230 	static GLenum getGLDataTypeFromMax(size_t maxvalue);
231 	static size_t getGLDataTypeSize(GLenum datatype);
232 
233 	std::vector<AttribFormat> vertexFormat;
234 	std::vector<size_t> attributeSizes;
235 
236 	std::unordered_map<std::string, AttachedAttribute> attachedAttributes;
237 
238 	// Vertex buffer, for the vertex data.
239 	GLBuffer *vbo;
240 	size_t vertexCount;
241 	size_t vertexStride;
242 
243 	// Block of memory whose size is at least as large as a single vertex. Helps
244 	// avoid memory allocations when using Mesh::setVertex etc.
245 	char *vertexScratchBuffer;
246 
247 	// Element (vertex index) buffer, for the vertex map.
248 	GLBuffer *ibo;
249 	bool useIndexBuffer;
250 	size_t elementCount;
251 	GLenum elementDataType;
252 
253 	DrawMode drawMode;
254 
255 	int rangeMin;
256 	int rangeMax;
257 
258 	StrongRef<Texture> texture;
259 
260 	static StringMap<Usage, USAGE_MAX_ENUM>::Entry usageEntries[];
261 	static StringMap<Usage, USAGE_MAX_ENUM> usages;
262 
263 	static StringMap<DrawMode, DRAWMODE_MAX_ENUM>::Entry drawModeEntries[];
264 	static StringMap<DrawMode, DRAWMODE_MAX_ENUM> drawModes;
265 
266 	static StringMap<DataType, DATA_MAX_ENUM>::Entry dataTypeEntries[];
267 	static StringMap<DataType, DATA_MAX_ENUM> dataTypes;
268 
269 }; // Mesh
270 
271 } // opengl
272 } // graphics
273 } // love
274 
275 #endif // LOVE_GRAPHICS_OPENGL_MESH_H
276