1 /** 2 Copyright: Copyright (c) 2016-2018 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 voxelman.graphics.gl; 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.arrayof = [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.arrayof = [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.position.arrayof = [x, y, z]; 33 this.color.arrayof = color; 34 } 35 36 static if (col_size == 4 && is(ColType == ubyte)) 37 this(Vector!(PosType, pos_size) p, ColType[3] color) 38 { 39 this.position = p; 40 this.color.arrayof = [color[0], color[1], color[2], 255]; 41 } 42 43 static if (col_size == 4 && is(ColType == ubyte)) 44 this(Vector!(PosType, pos_size) p, Vector!(ColType, 3) color) 45 { 46 this.position = p; 47 this.color.arrayof = [color.r, color.g, color.b, 255]; 48 } 49 50 this(Vector!(PosType, pos_size) p, Vector!(ColType, col_size) color) 51 { 52 this.position = p; 53 this.color = color; 54 } 55 56 void addOffset(vec3 offset) 57 { 58 position += Vector!(PosType, pos_size)(offset); 59 } 60 61 align(4): 62 Vector!(PosType, pos_size) position; 63 Vector!(ColType, col_size) color; 64 65 void toString()(scope void delegate(const(char)[]) sink) const 66 { 67 import std.format : formattedWrite; 68 sink.formattedWrite("V!(%s,%s)(%s, %s)", stringof(PosType), stringof(ColType), position, color); 69 } 70 71 static void setAttributes() { 72 enum Size = typeof(this).sizeof; 73 setupAttribute!(0, pos_size, PosType, false, true, Size, position.offsetof); 74 setupAttribute!(1, col_size, ColType, true, true, Size, color.offsetof); 75 } 76 } 77 78 align(4) struct VertexPosUvColor(PosType, uint pos_size, UvType, uint uv_size, ColType, uint col_size) 79 { 80 align(4): 81 Vector!(PosType, pos_size) position; 82 Vector!(UvType, uv_size) uv; 83 Vector!(ColType, col_size) color; 84 85 void addOffset(vec3 offset) 86 { 87 position += Vector!(PosType, pos_size)(offset); 88 } 89 90 void toString()(scope void delegate(const(char)[]) sink) const 91 { 92 import std.format : formattedWrite; 93 sink.formattedWrite("V!(%s,%s,%s)(%s, %s, %s)", 94 stringof(PosType), stringof(UvType), stringof(ColType), 95 position, uv, color); 96 } 97 98 static void setAttributes() { 99 enum Size = typeof(this).sizeof; 100 setupAttribute!(0, pos_size, PosType, false, true, Size, position.offsetof); 101 setupAttribute!(1, uv_size, UvType, true, true, Size, uv.offsetof); 102 setupAttribute!(2, col_size, ColType, true, true, Size, color.offsetof); 103 } 104 } 105 106 void setupAttribute(int index, int numComponents, AttrT, bool normalize, bool isFloatAttrib, int totalVertSize, int offset)() 107 { 108 glEnableVertexAttribArray(index); 109 static if (isFloatAttrib) 110 { 111 enum bool doPosNomalization = normalize && normalizeAttributeType!AttrT; 112 checkgl!glVertexAttribPointer(index, numComponents, glTypeOf!AttrT, doPosNomalization, totalVertSize, cast(void*)offset); 113 } 114 else 115 { 116 static if (normalizeAttributeType!AttrT) // only if integer 117 checkgl!glVertexAttribIPointer(index, numComponents, glTypeOf!AttrT, totalVertSize, cast(void*)offset); 118 else 119 checkgl!glVertexAttribPointer(index, numComponents, glTypeOf!AttrT, false, totalVertSize, cast(void*)offset); 120 } 121 } 122 123 enum glTypeOf(T) = glTypes[glTypeIndex!T]; 124 enum normalizeAttributeType(T) = normalizeTypeTable[glTypeIndex!T]; 125 126 alias glTypeIndex(T) = staticIndexOf!(T, 127 byte, // GL_BYTE 128 ubyte, // GL_UNSIGNED_BYTE 129 short, // GL_SHORT 130 ushort,// GL_UNSIGNED_SHORT 131 int, // GL_INT 132 uint, // GL_UNSIGNED_INT 133 half, // GL_HALF_FLOAT 134 float, // GL_FLOAT 135 double,// GL_DOUBLE 136 ); 137 138 static immutable uint[] glTypes = [ 139 GL_BYTE, 140 GL_UNSIGNED_BYTE, 141 GL_SHORT, 142 GL_UNSIGNED_SHORT, 143 GL_INT, 144 GL_UNSIGNED_INT, 145 GL_HALF_FLOAT, 146 GL_FLOAT, 147 GL_DOUBLE, 148 ]; 149 150 static immutable bool[] normalizeTypeTable = [ 151 true, // GL_BYTE 152 true, // GL_UNSIGNED_BYTE 153 true, // GL_SHORT 154 true, // GL_UNSIGNED_SHORT 155 true, // GL_INT 156 true, // GL_UNSIGNED_INT 157 false, // GL_HALF_FLOAT 158 false, // GL_FLOAT 159 false, // GL_DOUBLE 160 ];