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 module voxelman.graphics.batch;
7 
8 import voxelman.container.buffer;
9 import voxelman.model.vertex;
10 import voxelman.geometry.cube : CubeSide;
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 	void putCube(T1, T2)(Vector!(T1, 3) pos, Vector!(T2, 3) size, Color4ub color, bool fill)
28 	{
29 		if (fill)
30 			putFilledBlock(triBuffer, pos, size, color);
31 		else
32 			putLineBlock(lineBuffer, pos, size, color);
33 	}
34 
35 	void putCubeFace(T1, T2)(Vector!(T1, 3) cubePos, Vector!(T2, 3) size, CubeSide side, Color4ub color, bool fill)
36 	{
37 		if (fill)
38 			putFilledSide(triBuffer, cubePos, size, side, color);
39 		else
40 			putLineSide(lineBuffer, cubePos, size, side, color);
41 	}
42 
43 	void putLine(T1, T2)(Vector!(T1, 3) start, Vector!(T2, 3) end, Color4ub color)
44 	{
45 		lineBuffer.put(
46 			ColoredVertex(start, color),
47 			ColoredVertex(end, color));
48 	}
49 
50 	void putPoint(T)(Vector!(T, 3) pos, Color4ub color)
51 	{
52 		pointBuffer.put(ColoredVertex(pos, color));
53 	}
54 
55 	void put3dGrid(T1, T2)(Vector!(T1, 3) pos, ivec3 count, Vector!(T2, 3) offset, Color4ub color)
56 	{
57 		// x
58 		foreach(i; 0..count.y)
59 		foreach(j; 0..count.z)
60 		{
61 			float y = pos.y + i * offset.y;
62 			float z = pos.z + j * offset.z;
63 			vec3 start = vec3(pos.x, y, z);
64 			vec3 end = vec3(pos.x + (count.x-1) * offset.x, y, z);
65 			putLine(start, end, color);
66 		}
67 
68 		// y
69 		foreach(i; 0..count.x)
70 		foreach(j; 0..count.z)
71 		{
72 			float x = pos.x + i * offset.x;
73 			float z = pos.z + j * offset.z;
74 			vec3 start = vec3(x, pos.y, z);
75 			vec3 end = vec3(x, pos.y + (count.y-1) * offset.y, z);
76 			putLine(start, end, color);
77 		}
78 
79 		// z
80 		foreach(i; 0..count.x)
81 		foreach(j; 0..count.y)
82 		{
83 			float x = pos.x + i * offset.x;
84 			float y = pos.y + j * offset.y;
85 			vec3 start = vec3(x, y, pos.z);
86 			vec3 end = vec3(x, y, pos.z + (count.z-1) * offset.z);
87 			putLine(start, end, color);
88 		}
89 	}
90 
91 	void reset()
92 	{
93 		triBuffer.clear();
94 		lineBuffer.clear();
95 		pointBuffer.clear();
96 	}
97 }
98 
99 void putMesh(V, VertRange)(ref Buffer!V output, VertRange vertices, vec3 offset)
100 {
101 	foreach(vert; vertices)
102 	{
103 		auto v = V(
104 			vert.position + offset,
105 			vert.color
106 		);
107 		output.put(v);
108 	}
109 }