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