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/int.h"
25#include "common/Color.h"
26
27// C
28#include <stddef.h>
29#include <vector>
30#include <string>
31
32namespace love
33{
34namespace graphics
35{
36
37class Resource;
38
39// Vertex attribute indices used in shaders by LOVE. The values map to GPU
40// generic vertex attribute indices.
41enum BuiltinVertexAttribute
42{
43 ATTRIB_POS = 0,
44 ATTRIB_TEXCOORD,
45 ATTRIB_COLOR,
46 ATTRIB_CONSTANTCOLOR,
47 ATTRIB_MAX_ENUM
48};
49
50enum BuiltinVertexAttributeFlag
51{
52 ATTRIBFLAG_POS = 1 << ATTRIB_POS,
53 ATTRIBFLAG_TEXCOORD = 1 << ATTRIB_TEXCOORD,
54 ATTRIBFLAG_COLOR = 1 << ATTRIB_COLOR,
55 ATTRIBFLAG_CONSTANTCOLOR = 1 << ATTRIB_CONSTANTCOLOR
56};
57
58enum BufferType
59{
60 BUFFER_VERTEX = 0,
61 BUFFER_INDEX,
62 BUFFER_MAX_ENUM
63};
64
65enum IndexDataType
66{
67 INDEX_UINT16,
68 INDEX_UINT32,
69 INDEX_MAX_ENUM
70};
71
72// http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png
73enum PrimitiveType
74{
75 PRIMITIVE_TRIANGLES,
76 PRIMITIVE_TRIANGLE_STRIP,
77 PRIMITIVE_TRIANGLE_FAN,
78 PRIMITIVE_POINTS,
79 PRIMITIVE_MAX_ENUM
80};
81
82enum AttributeStep
83{
84 STEP_PER_VERTEX,
85 STEP_PER_INSTANCE,
86 STEP_MAX_ENUM
87};
88
89enum CullMode
90{
91 CULL_NONE,
92 CULL_BACK,
93 CULL_FRONT,
94 CULL_MAX_ENUM
95};
96
97namespace vertex
98{
99
100// The expected usage pattern of vertex data.
101enum Usage
102{
103 USAGE_STREAM,
104 USAGE_DYNAMIC,
105 USAGE_STATIC,
106 USAGE_MAX_ENUM
107};
108
109enum DataType
110{
111 DATA_UNORM8,
112 DATA_UNORM16,
113 DATA_FLOAT,
114 DATA_MAX_ENUM
115};
116
117enum Winding
118{
119 WINDING_CW,
120 WINDING_CCW,
121 WINDING_MAX_ENUM
122};
123
124enum class TriangleIndexMode
125{
126 NONE,
127 STRIP,
128 FAN,
129 QUADS,
130};
131
132enum class CommonFormat
133{
134 NONE,
135 XYf,
136 XYZf,
137 RGBAub,
138 STf_RGBAub,
139 STPf_RGBAub,
140 XYf_STf,
141 XYf_STPf,
142 XYf_STf_RGBAub,
143 XYf_STus_RGBAub,
144 XYf_STPf_RGBAub,
145};
146
147struct STf_RGBAub
148{
149 float s, t;
150 Color32 color;
151};
152
153struct STPf_RGBAub
154{
155 float s, t, p;
156 Color32 color;
157};
158
159struct XYf_STf
160{
161 float x, y;
162 float s, t;
163};
164
165struct XYf_STPf
166{
167 float x, y;
168 float s, t, p;
169};
170
171struct XYf_STf_RGBAub
172{
173 float x, y;
174 float s, t;
175 Color32 color;
176};
177
178struct XYf_STus_RGBAub
179{
180 float x, y;
181 uint16 s, t;
182 Color32 color;
183};
184
185struct XYf_STPf_RGBAub
186{
187 float x, y;
188 float s, t, p;
189 Color32 color;
190};
191
192struct BufferBindings
193{
194 static const uint32 MAX = 32;
195
196 uint32 useBits = 0;
197
198 struct
199 {
200 Resource *buffer;
201 size_t offset;
202 } info[MAX];
203
204 void set(uint32 index, Resource *r, size_t offset)
205 {
206 useBits |= (1u << index);
207 info[index] = {r, offset};
208 }
209
210 void disable(uint32 index) { useBits &= (1u << index); }
211 void clear() { useBits = 0; }
212};
213
214struct AttributeInfo
215{
216 uint8 bufferIndex;
217 DataType type : 4;
218 uint8 components : 4;
219 uint16 offsetFromVertex;
220};
221
222struct BufferLayout
223{
224 uint16 stride;
225};
226
227struct Attributes
228{
229 static const uint32 MAX = 32;
230
231 uint32 enableBits = 0; // indexed by attribute
232 uint32 instanceBits = 0; // indexed by buffer
233
234 AttributeInfo attribs[MAX];
235 BufferLayout bufferLayouts[BufferBindings::MAX];
236
237 Attributes() {}
238 Attributes(CommonFormat format, uint8 bufferindex)
239 {
240 setCommonFormat(format, bufferindex);
241 }
242
243 void set(uint32 index, DataType type, uint8 components, uint16 offsetfromvertex, uint8 bufferindex)
244 {
245 enableBits |= (1u << index);
246
247 attribs[index].bufferIndex = bufferindex;
248 attribs[index].type = type;
249 attribs[index].components = components;
250 attribs[index].offsetFromVertex = offsetfromvertex;
251 }
252
253 void setBufferLayout(uint32 bufferindex, uint16 stride, AttributeStep step = STEP_PER_VERTEX)
254 {
255 uint32 bufferbit = (1u << bufferindex);
256
257 if (step == STEP_PER_INSTANCE)
258 instanceBits |= bufferbit;
259 else
260 instanceBits &= ~bufferbit;
261
262 bufferLayouts[bufferindex].stride = stride;
263 }
264
265 void disable(uint32 index)
266 {
267 enableBits &= ~(1u << index);
268 }
269
270 void clear()
271 {
272 enableBits = 0;
273 }
274
275 bool isEnabled(uint32 index) const
276 {
277 return (enableBits & (1u << index)) != 0;
278 }
279
280 AttributeStep getBufferStep(uint32 index) const
281 {
282 return (instanceBits & (1u << index)) != 0 ? STEP_PER_INSTANCE : STEP_PER_VERTEX;
283 }
284
285 void setCommonFormat(CommonFormat format, uint8 bufferindex);
286};
287
288size_t getFormatStride(CommonFormat format);
289
290uint32 getFormatFlags(CommonFormat format);
291
292int getFormatPositionComponents(CommonFormat format);
293
294inline CommonFormat getSinglePositionFormat(bool is2D)
295{
296 return is2D ? CommonFormat::XYf : CommonFormat::XYZf;
297}
298
299size_t getIndexDataSize(IndexDataType type);
300size_t getDataTypeSize(DataType datatype);
301
302IndexDataType getIndexDataTypeFromMax(size_t maxvalue);
303
304int getIndexCount(TriangleIndexMode mode, int vertexCount);
305
306void fillIndices(TriangleIndexMode mode, uint16 vertexStart, uint16 vertexCount, uint16 *indices);
307void fillIndices(TriangleIndexMode mode, uint32 vertexStart, uint32 vertexCount, uint32 *indices);
308
309bool getConstant(const char *in, BuiltinVertexAttribute &out);
310bool getConstant(BuiltinVertexAttribute in, const char *&out);
311
312bool getConstant(const char *in, IndexDataType &out);
313bool getConstant(IndexDataType in, const char *&out);
314std::vector<std::string> getConstants(IndexDataType);
315
316bool getConstant(const char *in, Usage &out);
317bool getConstant(Usage in, const char *&out);
318std::vector<std::string> getConstants(Usage);
319
320bool getConstant(const char *in, PrimitiveType &out);
321bool getConstant(PrimitiveType in, const char *&out);
322std::vector<std::string> getConstants(PrimitiveType);
323
324bool getConstant(const char *in, AttributeStep &out);
325bool getConstant(AttributeStep in, const char *&out);
326std::vector<std::string> getConstants(AttributeStep);
327
328bool getConstant(const char *in, DataType &out);
329bool getConstant(DataType in, const char *&out);
330std::vector<std::string> getConstants(DataType);
331
332bool getConstant(const char *in, CullMode &out);
333bool getConstant(CullMode in, const char *&out);
334std::vector<std::string> getConstants(CullMode);
335
336bool getConstant(const char *in, Winding &out);
337bool getConstant(Winding in, const char *&out);
338std::vector<std::string> getConstants(Winding);
339
340} // vertex
341
342typedef vertex::XYf_STf_RGBAub Vertex;
343
344} // graphics
345} // love
346