1 /** 2 Copyright: Copyright (c) 2014-2016 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module voxelman.utils.renderutils; 8 9 import std.experimental.logger; 10 11 import derelict.opengl3.gl3; 12 import dlib.math.vector; 13 14 import voxelman.core.basicblocks : faces; 15 import voxelman.core.block : Side; 16 17 18 align(4) struct ColoredVertex 19 { 20 vec3 pos; 21 Vector!(ubyte, 3) color; 22 } 23 24 alias Color3ub = Vector!(ubyte, 3); 25 26 enum Colors : Color3ub 27 { 28 black = Color3ub(0, 0, 0), 29 white = Color3ub(255, 255, 255), 30 red = Color3ub(255, 0, 0), 31 green = Color3ub(0, 255, 0), 32 blue = Color3ub(0, 0, 255), 33 cyan = Color3ub(0, 255, 255), 34 magenta = Color3ub(255, 0, 255), 35 yellow = Color3ub(255, 255, 0), 36 } 37 38 39 Color3ub[] colorsArray = 40 [ 41 Colors.black, Colors.white, Colors.red, 42 Colors.green, Colors.blue, Colors.cyan, 43 Colors.magenta, Colors.yellow 44 ]; 45 46 struct Batch 47 { 48 ColoredVertex[] triBuffer; 49 ColoredVertex[] lineBuffer; 50 ColoredVertex[] pointBuffer; 51 52 void putCube(vec3 pos, vec3 size, Color3ub color, bool fill) 53 { 54 if (fill) 55 putFilledBlock(triBuffer, pos, size, color); 56 else 57 putLineBlock(lineBuffer, pos, size, color); 58 } 59 60 void putCubeFace(vec3 cubePos, vec3 size, Side side, Color3ub color, bool fill) 61 { 62 if (fill) 63 putFilledSide(triBuffer, cubePos, size, side, color); 64 else 65 putLineSide(lineBuffer, cubePos, size, side, color); 66 } 67 68 void putLine(vec3 start, vec3 end, Color3ub color) 69 { 70 if (lineBuffer.capacity - lineBuffer.length < 2) 71 lineBuffer.reserve(lineBuffer.capacity + 1024); 72 73 lineBuffer ~= ColoredVertex(start, color); 74 lineBuffer ~= ColoredVertex(end, color); 75 } 76 77 void putPoint(vec3 pos, Color3ub color) 78 { 79 if (pointBuffer.capacity - pointBuffer.length < 1) 80 pointBuffer.reserve(pointBuffer.capacity + 1024); 81 82 pointBuffer ~= ColoredVertex(pos, color); 83 } 84 85 void reset() 86 { 87 resetBuffer(triBuffer); 88 resetBuffer(lineBuffer); 89 resetBuffer(pointBuffer); 90 } 91 } 92 93 void resetBuffer(ref ColoredVertex[] buffer) 94 { 95 buffer.length = 0; 96 assumeSafeAppend(buffer); 97 } 98 99 void putFilledBlock(ref ColoredVertex[] output, vec3 pos, vec3 size, Color3ub color) 100 { 101 output.reserve(6 * 6); // 6 faces, 6 points per edge 102 103 for (size_t i = 0; i!=18*6; i+=3) 104 { 105 ColoredVertex v; 106 v.pos.x = faces[i]*size.x + pos.x; 107 v.pos.y = faces[i+1]*size.y + pos.y; 108 v.pos.z = faces[i+2]*size.z + pos.z; 109 v.color = color; 110 output ~= v; 111 } 112 } 113 114 void putLineBlock(ref ColoredVertex[] output, vec3 pos, vec3 size, Color3ub color) 115 { 116 output.reserve(12 * 2); // 12 edges, 2 points per edge 117 118 for (size_t i = 0; i!=12*2*3; i+=3) 119 { 120 ColoredVertex v; 121 v.pos.x = cubeLines[i]*size.x + pos.x; 122 v.pos.y = cubeLines[i+1]*size.y + pos.y; 123 v.pos.z = cubeLines[i+2]*size.z + pos.z; 124 v.color = color; 125 output ~= v; 126 } 127 } 128 129 void putFilledSide(ref ColoredVertex[] output, vec3 pos, vec3 size, Side side, Color3ub color) 130 { 131 output.reserve(6); 132 133 for (size_t i = side * 18; i!=side*18+18; i+=3) 134 { 135 ColoredVertex v; 136 v.pos.x = faces[i]*size.x + pos.x; 137 v.pos.y = faces[i+1]*size.y + pos.y; 138 v.pos.z = faces[i+2]*size.z + pos.z; 139 v.color = color; 140 output ~= v; 141 } 142 } 143 144 void putLineSide(ref ColoredVertex[] output, vec3 pos, vec3 size, Side side, Color3ub color) 145 { 146 output.reserve(6); 147 148 for (size_t i = side * 24; i!=side*24+24; i+=3) 149 { 150 ColoredVertex v; 151 v.pos.x = cubeLineSides[i]*size.x + pos.x; 152 v.pos.y = cubeLineSides[i+1]*size.y + pos.y; 153 v.pos.z = cubeLineSides[i+2]*size.z + pos.z; 154 v.color = color; 155 output ~= v; 156 } 157 } 158 159 immutable ubyte[] cubeLines = 160 [ 161 0, 0, 0, 1, 0, 0, 162 1, 0, 0, 1, 0, 1, 163 1, 0, 1, 0, 0, 1, 164 0, 0, 1, 0, 0, 0, 165 166 0, 1, 0, 1, 1, 0, 167 1, 1, 0, 1, 1, 1, 168 1, 1, 1, 0, 1, 1, 169 0, 1, 1, 0, 1, 0, 170 171 0, 0, 0, 0, 1, 0, 172 1, 0, 0, 1, 1, 0, 173 1, 0, 1, 1, 1, 1, 174 0, 0, 1, 0, 1, 1, 175 ]; 176 177 immutable ubyte[] cubeLineSides = 178 [ 179 0, 0, 0, // north 180 1, 0, 0, 181 0, 1, 0, 182 1, 1, 0, 183 0, 0, 0, 184 0, 1, 0, 185 1, 0, 0, 186 1, 1, 0, 187 188 0, 0, 1, // south 189 1, 0, 1, 190 0, 1, 1, 191 1, 1, 1, 192 0, 0, 1, 193 0, 1, 1, 194 1, 0, 1, 195 1, 1, 1, 196 197 1, 0, 0, // east 198 1, 0, 1, 199 1, 1, 0, 200 1, 1, 1, 201 1, 0, 0, 202 1, 1, 0, 203 1, 0, 1, 204 1, 1, 1, 205 206 0, 0, 0, // west 207 0, 0, 1, 208 0, 1, 0, 209 0, 1, 1, 210 0, 0, 0, 211 0, 1, 0, 212 0, 0, 1, 213 0, 1, 1, 214 215 1, 1, 1, // top 216 0, 1, 1, 217 1, 1, 0, 218 0, 1, 0, 219 1, 1, 1, 220 1, 1, 0, 221 0, 1, 1, 222 0, 1, 0, 223 224 1, 0, 1, // bottom 225 0, 0, 1, 226 1, 0, 0, 227 0, 0, 0, 228 1, 0, 1, 229 1, 0, 0, 230 0, 0, 1, 231 0, 0, 0, 232 ];