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 voxelman.container.buffer; 13 import voxelman.math; 14 import voxelman.model.vertex; 15 16 import voxelman.block.utils : Side, faces; 17 18 alias ColoredVertex = VertexPosColor!(float, ubyte); 19 20 alias Color3ub = Vector!(ubyte, 3); 21 22 enum Colors : Color3ub 23 { 24 black = Color3ub(0, 0, 0), 25 white = Color3ub(255, 255, 255), 26 red = Color3ub(255, 0, 0), 27 green = Color3ub(0, 255, 0), 28 blue = Color3ub(0, 0, 255), 29 cyan = Color3ub(0, 255, 255), 30 magenta = Color3ub(255, 0, 255), 31 yellow = Color3ub(255, 255, 0), 32 gray = Color3ub(128, 128, 128), 33 } 34 35 36 Color3ub[] colorsArray = 37 [ 38 Colors.black, Colors.white, Colors.red, 39 Colors.green, Colors.blue, Colors.cyan, 40 Colors.magenta, Colors.yellow 41 ]; 42 43 struct Batch 44 { 45 Buffer!ColoredVertex triBuffer; 46 Buffer!ColoredVertex lineBuffer; 47 Buffer!ColoredVertex pointBuffer; 48 49 void putCube(vec3 pos, vec3 size, Color3ub color, bool fill) 50 { 51 if (fill) 52 putFilledBlock(triBuffer, pos, size, color); 53 else 54 putLineBlock(lineBuffer, pos, size, color); 55 } 56 57 void putCubeFace(vec3 cubePos, vec3 size, Side side, Color3ub color, bool fill) 58 { 59 if (fill) 60 putFilledSide(triBuffer, cubePos, size, side, color); 61 else 62 putLineSide(lineBuffer, cubePos, size, side, color); 63 } 64 65 void putLine(vec3 start, vec3 end, Color3ub color) 66 { 67 lineBuffer.put( 68 ColoredVertex(start, color), 69 ColoredVertex(end, color)); 70 } 71 72 void putPoint(vec3 pos, Color3ub color) 73 { 74 pointBuffer.put(ColoredVertex(pos, color)); 75 } 76 77 void put3dGrid(vec3 pos, ivec3 count, vec3 offset, Color3ub color) 78 { 79 // x 80 foreach(i; 0..count.y) 81 foreach(j; 0..count.z) 82 { 83 float y = pos.y + i * offset.y; 84 float z = pos.z + j * offset.z; 85 vec3 start = vec3(pos.x, y, z); 86 vec3 end = vec3(pos.x + (count.x-1) * offset.x, y, z); 87 putLine(start, end, color); 88 } 89 90 // y 91 foreach(i; 0..count.x) 92 foreach(j; 0..count.z) 93 { 94 float x = pos.x + i * offset.x; 95 float z = pos.z + j * offset.z; 96 vec3 start = vec3(x, pos.y, z); 97 vec3 end = vec3(x, pos.y + (count.y-1) * offset.y, z); 98 putLine(start, end, color); 99 } 100 101 // z 102 foreach(i; 0..count.x) 103 foreach(j; 0..count.y) 104 { 105 float x = pos.x + i * offset.x; 106 float y = pos.y + j * offset.y; 107 vec3 start = vec3(x, y, pos.z); 108 vec3 end = vec3(x, y, pos.z + (count.z-1) * offset.z); 109 putLine(start, end, color); 110 } 111 } 112 113 void reset() 114 { 115 triBuffer.clear(); 116 lineBuffer.clear(); 117 pointBuffer.clear(); 118 } 119 } 120 121 void putFilledBlock(ref Buffer!ColoredVertex output, vec3 pos, vec3 size, Color3ub color) 122 { 123 output.reserve(6 * 6); // 6 faces, 6 points per edge 124 125 for (size_t i = 0; i!=18*6; i+=3) 126 { 127 auto v = ColoredVertex( 128 faces[i ]*size.x + pos.x, 129 faces[i+1]*size.y + pos.y, 130 faces[i+2]*size.z + pos.z, 131 color); 132 output.put(v); 133 } 134 } 135 136 void putLineBlock(ref Buffer!ColoredVertex output, vec3 pos, vec3 size, Color3ub color) 137 { 138 output.reserve(12 * 2); // 12 edges, 2 points per edge 139 140 for (size_t i = 0; i!=12*2*3; i+=3) 141 { 142 auto v = ColoredVertex( 143 cubeLines[i ]*size.x + pos.x, 144 cubeLines[i+1]*size.y + pos.y, 145 cubeLines[i+2]*size.z + pos.z, 146 color); 147 output.put(v); 148 } 149 } 150 151 void putFilledSide(ref Buffer!ColoredVertex output, vec3 pos, vec3 size, Side side, Color3ub color) 152 { 153 output.reserve(6); 154 155 for (size_t i = side * 18; i!=side*18+18; i+=3) 156 { 157 auto v = ColoredVertex( 158 faces[i ]*size.x + pos.x, 159 faces[i+1]*size.y + pos.y, 160 faces[i+2]*size.z + pos.z, 161 color); 162 output.put(v); 163 } 164 } 165 166 void putLineSide(ref Buffer!ColoredVertex output, vec3 pos, vec3 size, Side side, Color3ub color) 167 { 168 output.reserve(8); // 4 edges, 2 points per edge 169 170 for (size_t i = side * 24; i!=side*24+24; i+=3) 171 { 172 auto v = ColoredVertex( 173 cubeLineSides[i ]*size.x + pos.x, 174 cubeLineSides[i+1]*size.y + pos.y, 175 cubeLineSides[i+2]*size.z + pos.z, 176 color); 177 output.put(v); 178 } 179 } 180 181 immutable ubyte[] cubeLines = 182 [ 183 0, 0, 0, 1, 0, 0, 184 1, 0, 0, 1, 0, 1, 185 1, 0, 1, 0, 0, 1, 186 0, 0, 1, 0, 0, 0, 187 188 0, 1, 0, 1, 1, 0, 189 1, 1, 0, 1, 1, 1, 190 1, 1, 1, 0, 1, 1, 191 0, 1, 1, 0, 1, 0, 192 193 0, 0, 0, 0, 1, 0, 194 1, 0, 0, 1, 1, 0, 195 1, 0, 1, 1, 1, 1, 196 0, 0, 1, 0, 1, 1, 197 ]; 198 199 immutable ubyte[] cubeLineSides = 200 [ 201 0, 0, 0, // zneg 202 1, 0, 0, 203 0, 1, 0, 204 1, 1, 0, 205 0, 0, 0, 206 0, 1, 0, 207 1, 0, 0, 208 1, 1, 0, 209 210 0, 0, 1, // zpos 211 1, 0, 1, 212 0, 1, 1, 213 1, 1, 1, 214 0, 0, 1, 215 0, 1, 1, 216 1, 0, 1, 217 1, 1, 1, 218 219 1, 0, 0, // xpos 220 1, 0, 1, 221 1, 1, 0, 222 1, 1, 1, 223 1, 0, 0, 224 1, 1, 0, 225 1, 0, 1, 226 1, 1, 1, 227 228 0, 0, 0, // xneg 229 0, 0, 1, 230 0, 1, 0, 231 0, 1, 1, 232 0, 0, 0, 233 0, 1, 0, 234 0, 0, 1, 235 0, 1, 1, 236 237 1, 1, 1, // ypos 238 0, 1, 1, 239 1, 1, 0, 240 0, 1, 0, 241 1, 1, 1, 242 1, 1, 0, 243 0, 1, 1, 244 0, 1, 0, 245 246 1, 0, 1, // yneg 247 0, 0, 1, 248 1, 0, 0, 249 0, 0, 0, 250 1, 0, 1, 251 1, 0, 0, 252 0, 0, 1, 253 0, 0, 0, 254 ];