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 module voxelman.graphics.batch; 7 8 import voxelman.container.buffer; 9 import voxelman.model.vertex; 10 import voxelman.geometry; 11 import voxelman.math; 12 import voxelman.graphics; 13 14 alias ColoredVertex = VertexPosColor!(float, 3, ubyte, 4); 15 16 struct Batch 17 { 18 Buffer!ColoredVertex triBuffer; 19 Buffer!ColoredVertex lineBuffer; 20 Buffer!ColoredVertex pointBuffer; 21 22 void putSolidMesh(VertRange)(VertRange vertices, vec3 offset) 23 { 24 putMesh(triBuffer, vertices, offset); 25 } 26 27 /// Creates a batch with a centered cube with 3 radiuses (not dimensions). 28 static Batch cube(T)(Vector!(T, 3) halfSize, Color4ub color, bool fill) 29 { 30 Batch b; 31 b.putCube(-halfSize, halfSize * 2, color, fill); 32 return b; 33 } 34 35 /// Creates a batch with a centered cube with 3 radiuses (not dimensions) and offset. 36 static Batch cube(T)(Vector!(T, 3) halfSize, Color4ub color, bool fill, Vector!(T, 3) offset) 37 { 38 Batch b; 39 b.putCube(-halfSize + offset, halfSize * 2, color, fill); 40 return b; 41 } 42 43 /// Creates a batch with a centered cube with 3 radiuses (not dimensions) where all dimensions are 1/32th (1 pixel in a 32x32 texture). 44 static Batch cube32(T)(Vector!(T, 3) halfSize, Color4ub color, bool fill) 45 { 46 Batch b; 47 b.putCube(-halfSize / 32.0, halfSize / 16.0, color, fill); 48 return b; 49 } 50 51 /// Creates a batch with a centered cube with 3 radiuses (not dimensions) and offset where all dimensions are 1/32th (1 pixel in a 32x32 texture). 52 static Batch cube32(T)(Vector!(T, 3) halfSize, Color4ub color, bool fill, Vector!(T, 3) offset) 53 { 54 Batch b; 55 b.putCube((-halfSize + offset) / 32.0, halfSize / 16.0, color, fill); 56 return b; 57 } 58 59 void putCube(T1, T2)(Vector!(T1, 3) pos, Vector!(T2, 3) size, Color4ub color, bool fill) 60 { 61 if (fill) 62 putFilledBlock(triBuffer, vec3(pos), vec3(size), color); 63 else 64 putLineBlock(lineBuffer, vec3(pos), vec3(size), color); 65 } 66 67 void putCubeFace(T1, T2)(Vector!(T1, 3) cubePos, Vector!(T2, 3) size, CubeSide side, Color4ub color, bool fill) 68 { 69 if (fill) 70 putFilledSide(triBuffer, cubePos, size, side, color); 71 else 72 putLineSide(lineBuffer, cubePos, size, side, color); 73 } 74 75 void putLine(T1, T2)(Vector!(T1, 3) start, Vector!(T2, 3) end, Color4ub color) 76 { 77 lineBuffer.put( 78 ColoredVertex(start, color), 79 ColoredVertex(end, color)); 80 } 81 82 void putLine(T1, T2)(Vector!(T1, 3) start, Vector!(T2, 3) end, Color4ub color1, Color4ub color2) 83 { 84 lineBuffer.put( 85 ColoredVertex(start, color1), 86 ColoredVertex(end, color2)); 87 } 88 89 void putLineVolumetric(T1, T2)(Vector!(T1, 3) start, Vector!(T2, 3) end, Color4ub color) 90 { 91 lineBuffer.put( 92 ColoredVertex(start, color), 93 ColoredVertex(end, color)); 94 } 95 96 void putPoint(T)(Vector!(T, 3) pos, Color4ub color) 97 { 98 pointBuffer.put(ColoredVertex(pos, color)); 99 } 100 101 void put3dGrid(T1, T2)(Vector!(T1, 3) pos, ivec3 count, Vector!(T2, 3) offset, Color4ub color) 102 { 103 // x 104 foreach(i; 0..count.y) 105 foreach(j; 0..count.z) 106 { 107 float y = pos.y + i * offset.y; 108 float z = pos.z + j * offset.z; 109 vec3 start = vec3(pos.x, y, z); 110 vec3 end = vec3(pos.x + (count.x-1) * offset.x, y, z); 111 putLine(start, end, color); 112 } 113 114 // y 115 foreach(i; 0..count.x) 116 foreach(j; 0..count.z) 117 { 118 float x = pos.x + i * offset.x; 119 float z = pos.z + j * offset.z; 120 vec3 start = vec3(x, pos.y, z); 121 vec3 end = vec3(x, pos.y + (count.y-1) * offset.y, z); 122 putLine(start, end, color); 123 } 124 125 // z 126 foreach(i; 0..count.x) 127 foreach(j; 0..count.y) 128 { 129 float x = pos.x + i * offset.x; 130 float y = pos.y + j * offset.y; 131 vec3 start = vec3(x, y, pos.z); 132 vec3 end = vec3(x, y, pos.z + (count.z-1) * offset.z); 133 putLine(start, end, color); 134 } 135 } 136 137 void reset() 138 { 139 triBuffer.clear(); 140 lineBuffer.clear(); 141 pointBuffer.clear(); 142 } 143 } 144 145 void putMesh(V, VertRange)(ref Buffer!V output, VertRange vertices, vec3 offset) 146 { 147 foreach(vert; vertices) 148 { 149 vert.addOffset(offset); 150 output.put(vert); 151 } 152 }