1/**
2 * Copyright (c) 2006-2023 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#pragma once
22
23// LOVE
24#include "common/config.h"
25#include "common/int.h"
26#include "common/math.h"
27#include "common/StringMap.h"
28#include "Drawable.h"
29#include "Texture.h"
30#include "vertex.h"
31#include "Buffer.h"
32
33// C++
34#include <vector>
35#include <unordered_map>
36
37namespace love
38{
39namespace graphics
40{
41
42class Graphics;
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 **/
49class Mesh : public Drawable
50{
51public:
52
53 static love::Type type;
54
55 struct AttribFormat
56 {
57 std::string name;
58 vertex::DataType type;
59 int components; // max 4
60 };
61
62 Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage);
63 Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage);
64
65 virtual ~Mesh();
66
67 /**
68 * Sets the values of all attributes at a specific vertex index in the Mesh.
69 * The size of the data must be less than or equal to the total size of all
70 * vertex attributes.
71 **/
72 void setVertex(size_t vertindex, const void *data, size_t datasize);
73 size_t getVertex(size_t vertindex, void *data, size_t datasize);
74 void *getVertexScratchBuffer();
75
76 /**
77 * Sets the values for a single attribute at a specific vertex index in the
78 * Mesh. The size of the data must be less than or equal to the size of the
79 * attribute.
80 **/
81 void setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize);
82 size_t getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize);
83
84 /**
85 * Gets the total number of vertices that can be used when drawing the Mesh.
86 **/
87 size_t getVertexCount() const;
88
89 /**
90 * Gets the size in bytes of the start of one vertex to the start of the
91 * next, in the buffer.
92 **/
93 size_t getVertexStride() const;
94
95 /**
96 * Gets the format of each vertex attribute stored in the Mesh.
97 **/
98 const std::vector<AttribFormat> &getVertexFormat() const;
99 vertex::DataType getAttributeInfo(int attribindex, int &components) const;
100 int getAttributeIndex(const std::string &name) const;
101
102 /**
103 * Sets whether a specific vertex attribute is used when drawing the Mesh.
104 **/
105 void setAttributeEnabled(const std::string &name, bool enable);
106 bool isAttributeEnabled(const std::string &name) const;
107
108 /**
109 * Attaches a vertex attribute from another Mesh to this one. The attribute
110 * will be used when drawing this Mesh.
111 **/
112 void attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX);
113 bool detachAttribute(const std::string &name);
114
115 void *mapVertexData();
116 void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1);
117
118 /**
119 * Flushes all modified data to the GPU.
120 **/
121 void flush();
122
123 /**
124 * Sets the vertex map to use when drawing the Mesh. The vertex map
125 * determines the order in which vertices are used by the draw mode.
126 * A 0-element vector is equivalent to the default vertex map:
127 * {0, 1, 2, 3, 4, ...}
128 **/
129 void setVertexMap(const std::vector<uint32> &map);
130 void setVertexMap(IndexDataType datatype, const void *data, size_t datasize);
131 void setVertexMap();
132
133 /**
134 * Fills the uint32 vector passed into the method with the previously set
135 * vertex map (index buffer) values.
136 **/
137 bool getVertexMap(std::vector<uint32> &map) const;
138
139 /**
140 * Gets the total number of elements in the vertex map array.
141 **/
142 size_t getVertexMapCount() const;
143
144 /**
145 * Sets the texture used when drawing the Mesh.
146 **/
147 void setTexture(Texture *texture);
148
149 /**
150 * Disables any texture from being used when drawing the Mesh.
151 **/
152 void setTexture();
153
154 /**
155 * Gets the texture used when drawing the Mesh. May return null if no
156 * texture is set.
157 **/
158 Texture *getTexture() const;
159
160 /**
161 * Sets the draw mode used when drawing the Mesh.
162 **/
163 void setDrawMode(PrimitiveType mode);
164 PrimitiveType getDrawMode() const;
165
166 void setDrawRange(int start, int count);
167 void setDrawRange();
168 bool getDrawRange(int &start, int &count) const;
169
170 // Implements Drawable.
171 void draw(Graphics *gfx, const Matrix4 &m) override;
172
173 void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount);
174
175 static std::vector<AttribFormat> getDefaultVertexFormat();
176
177private:
178
179 friend class SpriteBatch;
180
181 struct AttachedAttribute
182 {
183 Mesh *mesh;
184 int index;
185 AttributeStep step;
186 bool enabled;
187 };
188
189 void setupAttachedAttributes();
190 void calculateAttributeSizes();
191 size_t getAttributeOffset(size_t attribindex) const;
192
193 std::vector<AttribFormat> vertexFormat;
194 std::vector<size_t> attributeSizes;
195
196 std::unordered_map<std::string, AttachedAttribute> attachedAttributes;
197
198 // Vertex buffer, for the vertex data.
199 Buffer *vertexBuffer;
200 size_t vertexCount;
201 size_t vertexStride;
202
203 // Block of memory whose size is at least as large as a single vertex. Helps
204 // avoid memory allocations when using Mesh::setVertex etc.
205 char *vertexScratchBuffer;
206
207 // Index buffer, for the vertex map.
208 Buffer *indexBuffer;
209 bool useIndexBuffer;
210 size_t indexCount;
211 IndexDataType indexDataType;
212
213 PrimitiveType primitiveType;
214
215 int rangeStart;
216 int rangeCount;
217
218 StrongRef<Texture> texture;
219
220}; // Mesh
221
222} // graphics
223} // love
224