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 ];