1 /**
2 Copyright: Copyright (c) 2016-2017 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module voxelman.model.vertex;
8 
9 import std.meta;
10 import derelict.opengl3.gl3;
11 import voxelman.math;
12 
13 align(4) struct VertexPosColor(PosType, uint pos_size, ColType, uint col_size)
14 {
15 	static if (pos_size == 2)
16 	this(Pos, Col)(Pos x, Pos y, Col color)
17 	{
18 		this.position = Vector!(PosType, pos_size)(x, y);
19 		this.color = Vector!(ColType, col_size)(color);
20 	}
21 
22 	static if (pos_size == 3)
23 	this(Pos, Col)(Pos x, Pos y, Pos z, Col color)
24 	{
25 		this.position = Vector!(PosType, pos_size)(x, y, z);
26 		this.color = Vector!(ColType, col_size)(color);
27 	}
28 
29 	static if (pos_size == 3)
30 	this(Pos, Col)(Pos x, Pos y, Pos z, ColType[col_size] color)
31 	{
32 		this.positionArray = [x, y, z];
33 		this.colorArray = color;
34 	}
35 
36 	this(Vector!(PosType, pos_size) p, Vector!(ColType, col_size) color)
37 	{
38 		this.position = p;
39 		this.color = color;
40 	}
41 
42 	union {
43 		struct {
44 			align(4):
45 			Vector!(PosType, pos_size) position;
46 			Vector!(ColType, col_size) color;
47 		}
48 		struct {
49 			align(4):
50 			PosType[pos_size] positionArray;
51 			ColType[col_size] colorArray;
52 		}
53 	}
54 
55 	void toString()(scope void delegate(const(char)[]) sink) const
56 	{
57 		import std.format : formattedWrite;
58 		sink.formattedWrite("V!(%s,%s)(%s, %s)", stringof(PosType), stringof(ColType), position, color);
59 	}
60 
61 	static void setAttributes() {
62 		enum Size = typeof(this).sizeof;
63 
64 		// position
65 		glEnableVertexAttribArray(0);
66 		enum uint posGlType = glTypeOf!PosType;
67 		enum posOffset = position.offsetof;
68 		enum bool doPosNomalization = GL_FALSE;
69 		glVertexAttribPointer(0, pos_size, posGlType, doPosNomalization, Size, null);
70 
71 		// color
72 		glEnableVertexAttribArray(1);
73 		enum uint colGlType = glTypeOf!ColType;
74 		enum colOffset = color.offsetof;
75 		enum bool doColNomalization = normalizeColorType!ColType;
76 		glVertexAttribPointer(1, col_size, colGlType, doColNomalization, Size, cast(void*)colOffset);
77 	}
78 }
79 
80 template glTypeOf(T) {
81 	enum glTypeOf = glTypes[glTypeIndex!T];
82 }
83 
84 template normalizeColorType(T) {
85 	enum normalizeColorType = normalizeColorTable[glTypeIndex!T];
86 }
87 
88 alias glTypeIndex(T) = staticIndexOf!(T,
89 	byte,  // GL_BYTE
90 	ubyte, // GL_UNSIGNED_BYTE
91 	short, // GL_SHORT
92 	ushort,// GL_UNSIGNED_SHORT
93 	int,   // GL_INT
94 	uint,  // GL_UNSIGNED_INT
95 	half,  // GL_HALF_FLOAT
96 	float, // GL_FLOAT
97 	double,// GL_DOUBLE
98 	);
99 
100 static immutable uint[] glTypes = [
101 	GL_BYTE,
102 	GL_UNSIGNED_BYTE,
103 	GL_SHORT,
104 	GL_UNSIGNED_SHORT,
105 	GL_INT,
106 	GL_UNSIGNED_INT,
107 	GL_HALF_FLOAT,
108 	GL_FLOAT,
109 	GL_DOUBLE,
110 ];
111 
112 static immutable bool[] normalizeColorTable = [
113 	true,  // GL_BYTE
114 	true,  // GL_UNSIGNED_BYTE
115 	true,  // GL_SHORT
116 	true,  // GL_UNSIGNED_SHORT
117 	true,  // GL_INT
118 	true,  // GL_UNSIGNED_INT
119 	false, // GL_HALF_FLOAT
120 	false, // GL_FLOAT
121 	false, // GL_DOUBLE
122 ];