1 /*
2  * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
3  * License: http://www.opensource.org/licenses/BSD-2-Clause
4  */
5 
6 module metaballs;
7 
8 import std.typecons;
9 import std.math;
10 import gfm.core;
11 import gfm.sdl2;
12 import gfm.math;
13 
14 
15 import derelict.bgfx.bgfx;
16 
17 import vs_metaballs;
18 import fs_metaballs;
19 
20 
21 
22 
23 struct PosNormalColorVertex
24 {
25 	vec3f m_pos;
26 	vec3f m_normal;
27 	uint32_t m_abgr;
28 
29 	static void init()
30 	{
31         bgfx_vertex_decl_begin(&ms_decl);
32         bgfx_vertex_decl_add(&ms_decl, BGFX_ATTRIB_POSITION, 3, BGFX_ATTRIB_TYPE_FLOAT);
33         bgfx_vertex_decl_add(&ms_decl, BGFX_ATTRIB_NORMAL, 3, BGFX_ATTRIB_TYPE_FLOAT);
34         bgfx_vertex_decl_add(&ms_decl, BGFX_ATTRIB_COLOR0, 3, BGFX_ATTRIB_TYPE_UINT8, true);
35         bgfx_vertex_decl_end(&ms_decl);
36 	};
37 
38 	static bgfx_vertex_decl_t ms_decl;
39 };
40 
41 
42 struct Grid
43 {
44 	float m_val = 0;
45 	vec3f m_normal = vec3f(0, 0, 0);
46 };
47 
48 // Triangulation tables taken from:
49 // http://paulbourke.net/geometry/polygonise/
50 
51 static immutable uint16_t[256] s_edges =
52 [
53 	0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
54 	0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
55 	0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
56 	0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
57 	0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c,
58 	0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
59 	0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac,
60 	0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
61 	0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
62 	0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
63 	0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc,
64 	0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
65 	0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c,
66 	0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
67 	0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc,
68 	0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
69 	0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
70 	0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
71 	0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
72 	0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
73 	0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
74 	0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
75 	0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
76 	0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
77 	0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
78 	0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
79 	0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
80 	0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
81 	0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
82 	0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
83 	0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
84 	0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000,
85 ];
86 
87 static immutable int8_t[16][256] s_indices =
88 [
89 	[  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
90 	[   0,  8,  3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
91 	[   0,  1,  9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
92 	[   1,  8,  3,  9,  8,  1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
93 	[   1,  2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
94 	[   0,  8,  3,  1,  2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
95 	[   9,  2, 10,  0,  2,  9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
96 	[   2,  8,  3,  2, 10,  8, 10,  9,  8, -1, -1, -1, -1, -1, -1, -1 ],
97 	[   3, 11,  2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
98 	[   0, 11,  2,  8, 11,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
99 	[   1,  9,  0,  2,  3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
100 	[   1, 11,  2,  1,  9, 11,  9,  8, 11, -1, -1, -1, -1, -1, -1, -1 ],
101 	[   3, 10,  1, 11, 10,  3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
102 	[   0, 10,  1,  0,  8, 10,  8, 11, 10, -1, -1, -1, -1, -1, -1, -1 ],
103 	[   3,  9,  0,  3, 11,  9, 11, 10,  9, -1, -1, -1, -1, -1, -1, -1 ],
104 	[   9,  8, 10, 10,  8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
105 	[   4,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
106 	[   4,  3,  0,  7,  3,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
107 	[   0,  1,  9,  8,  4,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
108 	[   4,  1,  9,  4,  7,  1,  7,  3,  1, -1, -1, -1, -1, -1, -1, -1 ],
109 	[   1,  2, 10,  8,  4,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
110 	[   3,  4,  7,  3,  0,  4,  1,  2, 10, -1, -1, -1, -1, -1, -1, -1 ],
111 	[   9,  2, 10,  9,  0,  2,  8,  4,  7, -1, -1, -1, -1, -1, -1, -1 ],
112 	[   2, 10,  9,  2,  9,  7,  2,  7,  3,  7,  9,  4, -1, -1, -1, -1 ],
113 	[   8,  4,  7,  3, 11,  2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
114 	[  11,  4,  7, 11,  2,  4,  2,  0,  4, -1, -1, -1, -1, -1, -1, -1 ],
115 	[   9,  0,  1,  8,  4,  7,  2,  3, 11, -1, -1, -1, -1, -1, -1, -1 ],
116 	[   4,  7, 11,  9,  4, 11,  9, 11,  2,  9,  2,  1, -1, -1, -1, -1 ],
117 	[   3, 10,  1,  3, 11, 10,  7,  8,  4, -1, -1, -1, -1, -1, -1, -1 ],
118 	[   1, 11, 10,  1,  4, 11,  1,  0,  4,  7, 11,  4, -1, -1, -1, -1 ],
119 	[   4,  7,  8,  9,  0, 11,  9, 11, 10, 11,  0,  3, -1, -1, -1, -1 ],
120 	[   4,  7, 11,  4, 11,  9,  9, 11, 10, -1, -1, -1, -1, -1, -1, -1 ],
121 	[   9,  5,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
122 	[   9,  5,  4,  0,  8,  3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
123 	[   0,  5,  4,  1,  5,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
124 	[   8,  5,  4,  8,  3,  5,  3,  1,  5, -1, -1, -1, -1, -1, -1, -1 ],
125 	[   1,  2, 10,  9,  5,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
126 	[   3,  0,  8,  1,  2, 10,  4,  9,  5, -1, -1, -1, -1, -1, -1, -1 ],
127 	[   5,  2, 10,  5,  4,  2,  4,  0,  2, -1, -1, -1, -1, -1, -1, -1 ],
128 	[   2, 10,  5,  3,  2,  5,  3,  5,  4,  3,  4,  8, -1, -1, -1, -1 ],
129 	[   9,  5,  4,  2,  3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
130 	[   0, 11,  2,  0,  8, 11,  4,  9,  5, -1, -1, -1, -1, -1, -1, -1 ],
131 	[   0,  5,  4,  0,  1,  5,  2,  3, 11, -1, -1, -1, -1, -1, -1, -1 ],
132 	[   2,  1,  5,  2,  5,  8,  2,  8, 11,  4,  8,  5, -1, -1, -1, -1 ],
133 	[  10,  3, 11, 10,  1,  3,  9,  5,  4, -1, -1, -1, -1, -1, -1, -1 ],
134 	[   4,  9,  5,  0,  8,  1,  8, 10,  1,  8, 11, 10, -1, -1, -1, -1 ],
135 	[   5,  4,  0,  5,  0, 11,  5, 11, 10, 11,  0,  3, -1, -1, -1, -1 ],
136 	[   5,  4,  8,  5,  8, 10, 10,  8, 11, -1, -1, -1, -1, -1, -1, -1 ],
137 	[   9,  7,  8,  5,  7,  9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
138 	[   9,  3,  0,  9,  5,  3,  5,  7,  3, -1, -1, -1, -1, -1, -1, -1 ],
139 	[   0,  7,  8,  0,  1,  7,  1,  5,  7, -1, -1, -1, -1, -1, -1, -1 ],
140 	[   1,  5,  3,  3,  5,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
141 	[   9,  7,  8,  9,  5,  7, 10,  1,  2, -1, -1, -1, -1, -1, -1, -1 ],
142 	[  10,  1,  2,  9,  5,  0,  5,  3,  0,  5,  7,  3, -1, -1, -1, -1 ],
143 	[   8,  0,  2,  8,  2,  5,  8,  5,  7, 10,  5,  2, -1, -1, -1, -1 ],
144 	[   2, 10,  5,  2,  5,  3,  3,  5,  7, -1, -1, -1, -1, -1, -1, -1 ],
145 	[   7,  9,  5,  7,  8,  9,  3, 11,  2, -1, -1, -1, -1, -1, -1, -1 ],
146 	[   9,  5,  7,  9,  7,  2,  9,  2,  0,  2,  7, 11, -1, -1, -1, -1 ],
147 	[   2,  3, 11,  0,  1,  8,  1,  7,  8,  1,  5,  7, -1, -1, -1, -1 ],
148 	[  11,  2,  1, 11,  1,  7,  7,  1,  5, -1, -1, -1, -1, -1, -1, -1 ],
149 	[   9,  5,  8,  8,  5,  7, 10,  1,  3, 10,  3, 11, -1, -1, -1, -1 ],
150 	[   5,  7,  0,  5,  0,  9,  7, 11,  0,  1,  0, 10, 11, 10,  0, -1 ],
151 	[  11, 10,  0, 11,  0,  3, 10,  5,  0,  8,  0,  7,  5,  7,  0, -1 ],
152 	[  11, 10,  5,  7, 11,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
153 	[  10,  6,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
154 	[   0,  8,  3,  5, 10,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
155 	[   9,  0,  1,  5, 10,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
156 	[   1,  8,  3,  1,  9,  8,  5, 10,  6, -1, -1, -1, -1, -1, -1, -1 ],
157 	[   1,  6,  5,  2,  6,  1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
158 	[   1,  6,  5,  1,  2,  6,  3,  0,  8, -1, -1, -1, -1, -1, -1, -1 ],
159 	[   9,  6,  5,  9,  0,  6,  0,  2,  6, -1, -1, -1, -1, -1, -1, -1 ],
160 	[   5,  9,  8,  5,  8,  2,  5,  2,  6,  3,  2,  8, -1, -1, -1, -1 ],
161 	[   2,  3, 11, 10,  6,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
162 	[  11,  0,  8, 11,  2,  0, 10,  6,  5, -1, -1, -1, -1, -1, -1, -1 ],
163 	[   0,  1,  9,  2,  3, 11,  5, 10,  6, -1, -1, -1, -1, -1, -1, -1 ],
164 	[   5, 10,  6,  1,  9,  2,  9, 11,  2,  9,  8, 11, -1, -1, -1, -1 ],
165 	[   6,  3, 11,  6,  5,  3,  5,  1,  3, -1, -1, -1, -1, -1, -1, -1 ],
166 	[   0,  8, 11,  0, 11,  5,  0,  5,  1,  5, 11,  6, -1, -1, -1, -1 ],
167 	[   3, 11,  6,  0,  3,  6,  0,  6,  5,  0,  5,  9, -1, -1, -1, -1 ],
168 	[   6,  5,  9,  6,  9, 11, 11,  9,  8, -1, -1, -1, -1, -1, -1, -1 ],
169 	[   5, 10,  6,  4,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
170 	[   4,  3,  0,  4,  7,  3,  6,  5, 10, -1, -1, -1, -1, -1, -1, -1 ],
171 	[   1,  9,  0,  5, 10,  6,  8,  4,  7, -1, -1, -1, -1, -1, -1, -1 ],
172 	[  10,  6,  5,  1,  9,  7,  1,  7,  3,  7,  9,  4, -1, -1, -1, -1 ],
173 	[   6,  1,  2,  6,  5,  1,  4,  7,  8, -1, -1, -1, -1, -1, -1, -1 ],
174 	[   1,  2,  5,  5,  2,  6,  3,  0,  4,  3,  4,  7, -1, -1, -1, -1 ],
175 	[   8,  4,  7,  9,  0,  5,  0,  6,  5,  0,  2,  6, -1, -1, -1, -1 ],
176 	[   7,  3,  9,  7,  9,  4,  3,  2,  9,  5,  9,  6,  2,  6,  9, -1 ],
177 	[   3, 11,  2,  7,  8,  4, 10,  6,  5, -1, -1, -1, -1, -1, -1, -1 ],
178 	[   5, 10,  6,  4,  7,  2,  4,  2,  0,  2,  7, 11, -1, -1, -1, -1 ],
179 	[   0,  1,  9,  4,  7,  8,  2,  3, 11,  5, 10,  6, -1, -1, -1, -1 ],
180 	[   9,  2,  1,  9, 11,  2,  9,  4, 11,  7, 11,  4,  5, 10,  6, -1 ],
181 	[   8,  4,  7,  3, 11,  5,  3,  5,  1,  5, 11,  6, -1, -1, -1, -1 ],
182 	[   5,  1, 11,  5, 11,  6,  1,  0, 11,  7, 11,  4,  0,  4, 11, -1 ],
183 	[   0,  5,  9,  0,  6,  5,  0,  3,  6, 11,  6,  3,  8,  4,  7, -1 ],
184 	[   6,  5,  9,  6,  9, 11,  4,  7,  9,  7, 11,  9, -1, -1, -1, -1 ],
185 	[  10,  4,  9,  6,  4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
186 	[   4, 10,  6,  4,  9, 10,  0,  8,  3, -1, -1, -1, -1, -1, -1, -1 ],
187 	[  10,  0,  1, 10,  6,  0,  6,  4,  0, -1, -1, -1, -1, -1, -1, -1 ],
188 	[   8,  3,  1,  8,  1,  6,  8,  6,  4,  6,  1, 10, -1, -1, -1, -1 ],
189 	[   1,  4,  9,  1,  2,  4,  2,  6,  4, -1, -1, -1, -1, -1, -1, -1 ],
190 	[   3,  0,  8,  1,  2,  9,  2,  4,  9,  2,  6,  4, -1, -1, -1, -1 ],
191 	[   0,  2,  4,  4,  2,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
192 	[   8,  3,  2,  8,  2,  4,  4,  2,  6, -1, -1, -1, -1, -1, -1, -1 ],
193 	[  10,  4,  9, 10,  6,  4, 11,  2,  3, -1, -1, -1, -1, -1, -1, -1 ],
194 	[   0,  8,  2,  2,  8, 11,  4,  9, 10,  4, 10,  6, -1, -1, -1, -1 ],
195 	[   3, 11,  2,  0,  1,  6,  0,  6,  4,  6,  1, 10, -1, -1, -1, -1 ],
196 	[   6,  4,  1,  6,  1, 10,  4,  8,  1,  2,  1, 11,  8, 11,  1, -1 ],
197 	[   9,  6,  4,  9,  3,  6,  9,  1,  3, 11,  6,  3, -1, -1, -1, -1 ],
198 	[   8, 11,  1,  8,  1,  0, 11,  6,  1,  9,  1,  4,  6,  4,  1, -1 ],
199 	[   3, 11,  6,  3,  6,  0,  0,  6,  4, -1, -1, -1, -1, -1, -1, -1 ],
200 	[   6,  4,  8, 11,  6,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
201 	[   7, 10,  6,  7,  8, 10,  8,  9, 10, -1, -1, -1, -1, -1, -1, -1 ],
202 	[   0,  7,  3,  0, 10,  7,  0,  9, 10,  6,  7, 10, -1, -1, -1, -1 ],
203 	[  10,  6,  7,  1, 10,  7,  1,  7,  8,  1,  8,  0, -1, -1, -1, -1 ],
204 	[  10,  6,  7, 10,  7,  1,  1,  7,  3, -1, -1, -1, -1, -1, -1, -1 ],
205 	[   1,  2,  6,  1,  6,  8,  1,  8,  9,  8,  6,  7, -1, -1, -1, -1 ],
206 	[   2,  6,  9,  2,  9,  1,  6,  7,  9,  0,  9,  3,  7,  3,  9, -1 ],
207 	[   7,  8,  0,  7,  0,  6,  6,  0,  2, -1, -1, -1, -1, -1, -1, -1 ],
208 	[   7,  3,  2,  6,  7,  2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
209 	[   2,  3, 11, 10,  6,  8, 10,  8,  9,  8,  6,  7, -1, -1, -1, -1 ],
210 	[   2,  0,  7,  2,  7, 11,  0,  9,  7,  6,  7, 10,  9, 10,  7, -1 ],
211 	[   1,  8,  0,  1,  7,  8,  1, 10,  7,  6,  7, 10,  2,  3, 11, -1 ],
212 	[  11,  2,  1, 11,  1,  7, 10,  6,  1,  6,  7,  1, -1, -1, -1, -1 ],
213 	[   8,  9,  6,  8,  6,  7,  9,  1,  6, 11,  6,  3,  1,  3,  6, -1 ],
214 	[   0,  9,  1, 11,  6,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
215 	[   7,  8,  0,  7,  0,  6,  3, 11,  0, 11,  6,  0, -1, -1, -1, -1 ],
216 	[   7, 11,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
217 	[   7,  6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
218 	[   3,  0,  8, 11,  7,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
219 	[   0,  1,  9, 11,  7,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
220 	[   8,  1,  9,  8,  3,  1, 11,  7,  6, -1, -1, -1, -1, -1, -1, -1 ],
221 	[  10,  1,  2,  6, 11,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
222 	[   1,  2, 10,  3,  0,  8,  6, 11,  7, -1, -1, -1, -1, -1, -1, -1 ],
223 	[   2,  9,  0,  2, 10,  9,  6, 11,  7, -1, -1, -1, -1, -1, -1, -1 ],
224 	[   6, 11,  7,  2, 10,  3, 10,  8,  3, 10,  9,  8, -1, -1, -1, -1 ],
225 	[   7,  2,  3,  6,  2,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
226 	[   7,  0,  8,  7,  6,  0,  6,  2,  0, -1, -1, -1, -1, -1, -1, -1 ],
227 	[   2,  7,  6,  2,  3,  7,  0,  1,  9, -1, -1, -1, -1, -1, -1, -1 ],
228 	[   1,  6,  2,  1,  8,  6,  1,  9,  8,  8,  7,  6, -1, -1, -1, -1 ],
229 	[  10,  7,  6, 10,  1,  7,  1,  3,  7, -1, -1, -1, -1, -1, -1, -1 ],
230 	[  10,  7,  6,  1,  7, 10,  1,  8,  7,  1,  0,  8, -1, -1, -1, -1 ],
231 	[   0,  3,  7,  0,  7, 10,  0, 10,  9,  6, 10,  7, -1, -1, -1, -1 ],
232 	[   7,  6, 10,  7, 10,  8,  8, 10,  9, -1, -1, -1, -1, -1, -1, -1 ],
233 	[   6,  8,  4, 11,  8,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
234 	[   3,  6, 11,  3,  0,  6,  0,  4,  6, -1, -1, -1, -1, -1, -1, -1 ],
235 	[   8,  6, 11,  8,  4,  6,  9,  0,  1, -1, -1, -1, -1, -1, -1, -1 ],
236 	[   9,  4,  6,  9,  6,  3,  9,  3,  1, 11,  3,  6, -1, -1, -1, -1 ],
237 	[   6,  8,  4,  6, 11,  8,  2, 10,  1, -1, -1, -1, -1, -1, -1, -1 ],
238 	[   1,  2, 10,  3,  0, 11,  0,  6, 11,  0,  4,  6, -1, -1, -1, -1 ],
239 	[   4, 11,  8,  4,  6, 11,  0,  2,  9,  2, 10,  9, -1, -1, -1, -1 ],
240 	[  10,  9,  3, 10,  3,  2,  9,  4,  3, 11,  3,  6,  4,  6,  3, -1 ],
241 	[   8,  2,  3,  8,  4,  2,  4,  6,  2, -1, -1, -1, -1, -1, -1, -1 ],
242 	[   0,  4,  2,  4,  6,  2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
243 	[   1,  9,  0,  2,  3,  4,  2,  4,  6,  4,  3,  8, -1, -1, -1, -1 ],
244 	[   1,  9,  4,  1,  4,  2,  2,  4,  6, -1, -1, -1, -1, -1, -1, -1 ],
245 	[   8,  1,  3,  8,  6,  1,  8,  4,  6,  6, 10,  1, -1, -1, -1, -1 ],
246 	[  10,  1,  0, 10,  0,  6,  6,  0,  4, -1, -1, -1, -1, -1, -1, -1 ],
247 	[   4,  6,  3,  4,  3,  8,  6, 10,  3,  0,  3,  9, 10,  9,  3, -1 ],
248 	[  10,  9,  4,  6, 10,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
249 	[   4,  9,  5,  7,  6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
250 	[   0,  8,  3,  4,  9,  5, 11,  7,  6, -1, -1, -1, -1, -1, -1, -1 ],
251 	[   5,  0,  1,  5,  4,  0,  7,  6, 11, -1, -1, -1, -1, -1, -1, -1 ],
252 	[  11,  7,  6,  8,  3,  4,  3,  5,  4,  3,  1,  5, -1, -1, -1, -1 ],
253 	[   9,  5,  4, 10,  1,  2,  7,  6, 11, -1, -1, -1, -1, -1, -1, -1 ],
254 	[   6, 11,  7,  1,  2, 10,  0,  8,  3,  4,  9,  5, -1, -1, -1, -1 ],
255 	[   7,  6, 11,  5,  4, 10,  4,  2, 10,  4,  0,  2, -1, -1, -1, -1 ],
256 	[   3,  4,  8,  3,  5,  4,  3,  2,  5, 10,  5,  2, 11,  7,  6, -1 ],
257 	[   7,  2,  3,  7,  6,  2,  5,  4,  9, -1, -1, -1, -1, -1, -1, -1 ],
258 	[   9,  5,  4,  0,  8,  6,  0,  6,  2,  6,  8,  7, -1, -1, -1, -1 ],
259 	[   3,  6,  2,  3,  7,  6,  1,  5,  0,  5,  4,  0, -1, -1, -1, -1 ],
260 	[   6,  2,  8,  6,  8,  7,  2,  1,  8,  4,  8,  5,  1,  5,  8, -1 ],
261 	[   9,  5,  4, 10,  1,  6,  1,  7,  6,  1,  3,  7, -1, -1, -1, -1 ],
262 	[   1,  6, 10,  1,  7,  6,  1,  0,  7,  8,  7,  0,  9,  5,  4, -1 ],
263 	[   4,  0, 10,  4, 10,  5,  0,  3, 10,  6, 10,  7,  3,  7, 10, -1 ],
264 	[   7,  6, 10,  7, 10,  8,  5,  4, 10,  4,  8, 10, -1, -1, -1, -1 ],
265 	[   6,  9,  5,  6, 11,  9, 11,  8,  9, -1, -1, -1, -1, -1, -1, -1 ],
266 	[   3,  6, 11,  0,  6,  3,  0,  5,  6,  0,  9,  5, -1, -1, -1, -1 ],
267 	[   0, 11,  8,  0,  5, 11,  0,  1,  5,  5,  6, 11, -1, -1, -1, -1 ],
268 	[   6, 11,  3,  6,  3,  5,  5,  3,  1, -1, -1, -1, -1, -1, -1, -1 ],
269 	[   1,  2, 10,  9,  5, 11,  9, 11,  8, 11,  5,  6, -1, -1, -1, -1 ],
270 	[   0, 11,  3,  0,  6, 11,  0,  9,  6,  5,  6,  9,  1,  2, 10, -1 ],
271 	[  11,  8,  5, 11,  5,  6,  8,  0,  5, 10,  5,  2,  0,  2,  5, -1 ],
272 	[   6, 11,  3,  6,  3,  5,  2, 10,  3, 10,  5,  3, -1, -1, -1, -1 ],
273 	[   5,  8,  9,  5,  2,  8,  5,  6,  2,  3,  8,  2, -1, -1, -1, -1 ],
274 	[   9,  5,  6,  9,  6,  0,  0,  6,  2, -1, -1, -1, -1, -1, -1, -1 ],
275 	[   1,  5,  8,  1,  8,  0,  5,  6,  8,  3,  8,  2,  6,  2,  8, -1 ],
276 	[   1,  5,  6,  2,  1,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
277 	[   1,  3,  6,  1,  6, 10,  3,  8,  6,  5,  6,  9,  8,  9,  6, -1 ],
278 	[  10,  1,  0, 10,  0,  6,  9,  5,  0,  5,  6,  0, -1, -1, -1, -1 ],
279 	[   0,  3,  8,  5,  6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
280 	[  10,  5,  6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
281 	[  11,  5, 10,  7,  5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
282 	[  11,  5, 10, 11,  7,  5,  8,  3,  0, -1, -1, -1, -1, -1, -1, -1 ],
283 	[   5, 11,  7,  5, 10, 11,  1,  9,  0, -1, -1, -1, -1, -1, -1, -1 ],
284 	[  10,  7,  5, 10, 11,  7,  9,  8,  1,  8,  3,  1, -1, -1, -1, -1 ],
285 	[  11,  1,  2, 11,  7,  1,  7,  5,  1, -1, -1, -1, -1, -1, -1, -1 ],
286 	[   0,  8,  3,  1,  2,  7,  1,  7,  5,  7,  2, 11, -1, -1, -1, -1 ],
287 	[   9,  7,  5,  9,  2,  7,  9,  0,  2,  2, 11,  7, -1, -1, -1, -1 ],
288 	[   7,  5,  2,  7,  2, 11,  5,  9,  2,  3,  2,  8,  9,  8,  2, -1 ],
289 	[   2,  5, 10,  2,  3,  5,  3,  7,  5, -1, -1, -1, -1, -1, -1, -1 ],
290 	[   8,  2,  0,  8,  5,  2,  8,  7,  5, 10,  2,  5, -1, -1, -1, -1 ],
291 	[   9,  0,  1,  5, 10,  3,  5,  3,  7,  3, 10,  2, -1, -1, -1, -1 ],
292 	[   9,  8,  2,  9,  2,  1,  8,  7,  2, 10,  2,  5,  7,  5,  2, -1 ],
293 	[   1,  3,  5,  3,  7,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
294 	[   0,  8,  7,  0,  7,  1,  1,  7,  5, -1, -1, -1, -1, -1, -1, -1 ],
295 	[   9,  0,  3,  9,  3,  5,  5,  3,  7, -1, -1, -1, -1, -1, -1, -1 ],
296 	[   9,  8,  7,  5,  9,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
297 	[   5,  8,  4,  5, 10,  8, 10, 11,  8, -1, -1, -1, -1, -1, -1, -1 ],
298 	[   5,  0,  4,  5, 11,  0,  5, 10, 11, 11,  3,  0, -1, -1, -1, -1 ],
299 	[   0,  1,  9,  8,  4, 10,  8, 10, 11, 10,  4,  5, -1, -1, -1, -1 ],
300 	[  10, 11,  4, 10,  4,  5, 11,  3,  4,  9,  4,  1,  3,  1,  4, -1 ],
301 	[   2,  5,  1,  2,  8,  5,  2, 11,  8,  4,  5,  8, -1, -1, -1, -1 ],
302 	[   0,  4, 11,  0, 11,  3,  4,  5, 11,  2, 11,  1,  5,  1, 11, -1 ],
303 	[   0,  2,  5,  0,  5,  9,  2, 11,  5,  4,  5,  8, 11,  8,  5, -1 ],
304 	[   9,  4,  5,  2, 11,  3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
305 	[   2,  5, 10,  3,  5,  2,  3,  4,  5,  3,  8,  4, -1, -1, -1, -1 ],
306 	[   5, 10,  2,  5,  2,  4,  4,  2,  0, -1, -1, -1, -1, -1, -1, -1 ],
307 	[   3, 10,  2,  3,  5, 10,  3,  8,  5,  4,  5,  8,  0,  1,  9, -1 ],
308 	[   5, 10,  2,  5,  2,  4,  1,  9,  2,  9,  4,  2, -1, -1, -1, -1 ],
309 	[   8,  4,  5,  8,  5,  3,  3,  5,  1, -1, -1, -1, -1, -1, -1, -1 ],
310 	[   0,  4,  5,  1,  0,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
311 	[   8,  4,  5,  8,  5,  3,  9,  0,  5,  0,  3,  5, -1, -1, -1, -1 ],
312 	[   9,  4,  5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
313 	[   4, 11,  7,  4,  9, 11,  9, 10, 11, -1, -1, -1, -1, -1, -1, -1 ],
314 	[   0,  8,  3,  4,  9,  7,  9, 11,  7,  9, 10, 11, -1, -1, -1, -1 ],
315 	[   1, 10, 11,  1, 11,  4,  1,  4,  0,  7,  4, 11, -1, -1, -1, -1 ],
316 	[   3,  1,  4,  3,  4,  8,  1, 10,  4,  7,  4, 11, 10, 11,  4, -1 ],
317 	[   4, 11,  7,  9, 11,  4,  9,  2, 11,  9,  1,  2, -1, -1, -1, -1 ],
318 	[   9,  7,  4,  9, 11,  7,  9,  1, 11,  2, 11,  1,  0,  8,  3, -1 ],
319 	[  11,  7,  4, 11,  4,  2,  2,  4,  0, -1, -1, -1, -1, -1, -1, -1 ],
320 	[  11,  7,  4, 11,  4,  2,  8,  3,  4,  3,  2,  4, -1, -1, -1, -1 ],
321 	[   2,  9, 10,  2,  7,  9,  2,  3,  7,  7,  4,  9, -1, -1, -1, -1 ],
322 	[   9, 10,  7,  9,  7,  4, 10,  2,  7,  8,  7,  0,  2,  0,  7, -1 ],
323 	[   3,  7, 10,  3, 10,  2,  7,  4, 10,  1, 10,  0,  4,  0, 10, -1 ],
324 	[   1, 10,  2,  8,  7,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
325 	[   4,  9,  1,  4,  1,  7,  7,  1,  3, -1, -1, -1, -1, -1, -1, -1 ],
326 	[   4,  9,  1,  4,  1,  7,  0,  8,  1,  8,  7,  1, -1, -1, -1, -1 ],
327 	[   4,  0,  3,  7,  4,  3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
328 	[   4,  8,  7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
329 	[   9, 10,  8, 10, 11,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
330 	[   3,  0,  9,  3,  9, 11, 11,  9, 10, -1, -1, -1, -1, -1, -1, -1 ],
331 	[   0,  1, 10,  0, 10,  8,  8, 10, 11, -1, -1, -1, -1, -1, -1, -1 ],
332 	[   3,  1, 10, 11,  3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
333 	[   1,  2, 11,  1, 11,  9,  9, 11,  8, -1, -1, -1, -1, -1, -1, -1 ],
334 	[   3,  0,  9,  3,  9, 11,  1,  2,  9,  2, 11,  9, -1, -1, -1, -1 ],
335 	[   0,  2, 11,  8,  0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
336 	[   3,  2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
337 	[   2,  3,  8,  2,  8, 10, 10,  8,  9, -1, -1, -1, -1, -1, -1, -1 ],
338 	[   9, 10,  2,  0,  9,  2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
339 	[   2,  3,  8,  2,  8, 10,  0,  1,  8,  1, 10,  8, -1, -1, -1, -1 ],
340 	[   1, 10,  2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
341 	[   1,  3,  8,  9,  1,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
342 	[   0,  9,  1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
343 	[   0,  3,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
344 	[  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
345 ];
346 
347 static immutable float[3][8] s_cube =
348 [
349 	[ 0.0f, 1.0f, 1.0f ], // 0
350 	[ 1.0f, 1.0f, 1.0f ], // 1
351 	[ 1.0f, 1.0f, 0.0f ], // 2
352 	[ 0.0f, 1.0f, 0.0f ], // 3
353 	[ 0.0f, 0.0f, 1.0f ], // 4
354 	[ 1.0f, 0.0f, 1.0f ], // 5
355 	[ 1.0f, 0.0f, 0.0f ], // 6
356 	[ 0.0f, 0.0f, 0.0f ], // 7
357 ];
358 
359 float vertLerp(float* _result, float _iso, uint32_t _idx0, float _v0, uint32_t _idx1, float _v1)
360 {
361 	const float* edge0 = s_cube[_idx0].ptr;
362 	const float* edge1 = s_cube[_idx1].ptr;
363 
364 	if (std.math.abs(_iso-_v1) < 0.00001f)
365 	{
366 		_result[0] = edge1[0];
367 		_result[1] = edge1[1];
368 		_result[2] = edge1[2];
369 		return 1.0f;
370 	}
371 
372 	if (std.math.abs(_iso-_v0) < 0.00001f
373 	||  std.math.abs(_v0-_v1) < 0.00001f)
374 	{
375 		_result[0] = edge0[0];
376 		_result[1] = edge0[1];
377 		_result[2] = edge0[2];
378 		return 0.0f;
379 	}
380 
381 	float lerp = (_iso - _v0) / (_v1 - _v0);
382 	_result[0] = edge0[0] + lerp * (edge1[0] - edge0[0]);
383 	_result[1] = edge0[1] + lerp * (edge1[1] - edge0[1]);
384 	_result[2] = edge0[2] + lerp * (edge1[2] - edge0[2]);
385 
386 	return lerp;
387 }
388 
389 uint32_t triangulate(uint8_t* _result, uint32_t _stride, const(float)* _rgb, const(float)* _xyz, const (Grid*)* _val, float _iso)
390 {
391 	uint8_t cubeindex = 0;
392 	cubeindex |= (_val[0].m_val < _iso) ? 0x01 : 0;
393 	cubeindex |= (_val[1].m_val < _iso) ? 0x02 : 0;
394 	cubeindex |= (_val[2].m_val < _iso) ? 0x04 : 0;
395 	cubeindex |= (_val[3].m_val < _iso) ? 0x08 : 0;
396 	cubeindex |= (_val[4].m_val < _iso) ? 0x10 : 0;
397 	cubeindex |= (_val[5].m_val < _iso) ? 0x20 : 0;
398 	cubeindex |= (_val[6].m_val < _iso) ? 0x40 : 0;
399 	cubeindex |= (_val[7].m_val < _iso) ? 0x80 : 0;
400 
401 	if (0 == s_edges[cubeindex])
402 	{
403 		return 0;
404 	}
405 
406 	float verts[12][6];
407 	uint16_t flags = s_edges[cubeindex];
408 
409 	for (uint32_t ii = 0; ii < 12; ++ii)
410 	{
411 		if (flags & (1<<ii) )
412 		{
413 			uint32_t idx0 = ii&7;
414 			uint32_t idx1 = "\x01\x02\x03\x00\x05\x06\x07\x04\x04\x05\x06\x07"[ii];
415 			float* vertex = verts[ii].ptr;
416 			float lerp = vertLerp(vertex, _iso, idx0, _val[idx0].m_val, idx1, _val[idx1].m_val);
417 
418 			const float* na = _val[idx0].m_normal.ptr;
419 			const float* nb = _val[idx1].m_normal.ptr;
420 			vertex[3] = na[0] + lerp * (nb[0] - na[0]);
421 			vertex[4] = na[1] + lerp * (nb[1] - na[1]);
422 			vertex[5] = na[2] + lerp * (nb[2] - na[2]);
423 		}
424 	}
425 
426 	float dr = _rgb[3] - _rgb[0];
427 	float dg = _rgb[4] - _rgb[1];
428 	float db = _rgb[5] - _rgb[2];
429 
430 	uint32_t num = 0;
431 	const int8_t* indices = s_indices[cubeindex].ptr;
432 	for (uint32_t ii = 0; indices[ii] != -1; ++ii)
433 	{
434 		const float* vertex = verts[indices[ii] ].ptr;
435 
436 		float* xyz = cast(float*)_result;
437 		xyz[0] = _xyz[0] + vertex[0];
438 		xyz[1] = _xyz[1] + vertex[1];
439 		xyz[2] = _xyz[2] + vertex[2];
440 
441 		xyz[3] = vertex[3];
442 		xyz[4] = vertex[4];
443 		xyz[5] = vertex[5];
444 
445 		uint32_t rr = cast(uint8_t)( (_rgb[0] + vertex[0]*dr)*255.0f);
446 		uint32_t gg = cast(uint8_t)( (_rgb[1] + vertex[1]*dg)*255.0f);
447 		uint32_t bb = cast(uint8_t)( (_rgb[2] + vertex[2]*db)*255.0f);
448 
449 		uint32_t* abgr = cast(uint32_t*)(&_result[24]);
450 		*abgr = 0xff000000
451 			  | (bb<<16)
452 			  | (gg<<8)
453 			  | rr
454 			  ;
455 
456 		_result += _stride;
457 		++num;
458 	}
459 
460 	return num;
461 }
462 
463 int main(string[] args)
464 {
465 	uint32_t debug_ = BGFX_DEBUG_TEXT;
466 	uint32_t reset = BGFX_RESET_VSYNC;
467 
468     // create a logger
469     auto log = new ConsoleLogger();
470 
471     // load dynamic libraries
472     auto sdl2 = scoped!SDL2(log);
473 
474     int width = 1280;
475     int height = 720;
476 
477     // create an OpenGL-enabled SDL window
478     auto window = scoped!SDL2Window(sdl2, 
479                                     SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
480                                     width, height, 0);
481 
482     DerelictBgfx.load();
483 
484     version(Windows)
485     {
486         bgfx_win_set_hwnd(window.getWindowInfo().info.win.window);
487     }
488     else version(linux)
489     {
490         bgfx_x11_set_display_window(cast(Display*)window.getWindowInfo().info.x11.display,window.getWindowInfo().info.x11.window);
491     }
492     else
493     {
494         static assert(false, "TODO implement passing window handle to bgfx for this system");
495     }
496 
497 
498 	bgfx_init();
499 	bgfx_reset(width, height, reset);
500 
501 	// Enable debug text.
502 	bgfx_set_debug(debug_);
503 
504 	// Set view 0 clear state.
505 	bgfx_set_view_clear(0
506 		, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
507 		, 0x303030ff
508 		, 1.0f
509 		, 0
510 		);
511 
512 	// Create vertex stream declaration.
513 	PosNormalColorVertex.init();
514 
515 	const (bgfx_memory_t)* vs_metaballs;
516 	const (bgfx_memory_t)* fs_metaballs;
517 
518 	switch (bgfx_get_renderer_type() )
519 	{
520 	case BGFX_RENDERER_TYPE_DIRECT3D9:
521 		vs_metaballs = bgfx_make_ref(vs_metaballs_dx9.ptr, vs_metaballs_dx9.sizeof );
522 		fs_metaballs = bgfx_make_ref(fs_metaballs_dx9.ptr, fs_metaballs_dx9.sizeof );
523 		break;
524 
525 	case BGFX_RENDERER_TYPE_DIRECT3D11:
526 		vs_metaballs = bgfx_make_ref(vs_metaballs_dx11.ptr, vs_metaballs_dx11.sizeof );
527 		fs_metaballs = bgfx_make_ref(fs_metaballs_dx11.ptr, fs_metaballs_dx11.sizeof );
528 		break;
529 
530 	default:
531 		vs_metaballs = bgfx_make_ref(vs_metaballs_glsl.ptr, vs_metaballs_glsl.sizeof );
532 		fs_metaballs = bgfx_make_ref(fs_metaballs_glsl.ptr, fs_metaballs_glsl.sizeof );
533 		break;
534 	}
535 
536 	bgfx_shader_handle_t vsh = bgfx_create_shader(vs_metaballs);
537 	bgfx_shader_handle_t fsh = bgfx_create_shader(fs_metaballs);
538 
539 	// Create program from shaders.
540 	bgfx_program_handle_t program = bgfx_create_program(vsh, fsh, true /* destroy shaders when program is destroyed */);
541 
542     enum DIMS = 32;
543 
544 	Grid[] grid = new Grid[DIMS*DIMS*DIMS];
545 	const uint32_t ypitch = DIMS;
546 	const uint32_t zpitch = DIMS*DIMS;
547 	const float invdim = 1.0f/cast(float)(DIMS-1);
548 
549 	int64_t timeOffset = SDL_GetTicks();
550     int64_t last = timeOffset;
551 
552     while (!sdl2.keyboard().isPressed(SDLK_ESCAPE))
553     {
554         sdl2.processEvents();
555 
556 		// Set view 0 default viewport.
557 		bgfx_set_view_rect(cast(ushort)0, cast(ushort)0, cast(ushort)0, cast(ushort)width, cast(ushort)height);
558 
559 		// This dummy draw call is here to make sure that view 0 is cleared
560 		// if no other draw calls are submitted to view 0.
561 		bgfx_submit(0);
562 
563 		int64_t now = SDL_GetTicks();
564 		const int64_t frameTime = now - last;
565 		last = now;
566 		float time = cast(float)( (now - timeOffset)/ 1000.0 );
567 
568 		// Use debug font to print information about this example.
569 		bgfx_dbg_text_clear();
570 		bgfx_dbg_text_printf(0, 1, 0x4f, "bgfx/examples/02-metaball");
571 		bgfx_dbg_text_printf(0, 2, 0x6f, "Description: Rendering with transient buffers and embedding shaders.");
572 
573 		vec3f at = vec3f( 0.0f, 0.0f, 0.0f );
574 		vec3f eye = vec3f( 0.0f, 0.0f, -50.0f );
575         vec3f up = vec3f( 0.0f, 1.0f, 0.0f );
576 		
577         mat4f view = mat4f.lookAt(eye, at, up);
578         mat4f proj = mat4f.perspective(radians(60.0f), cast(float)(width)/height, 0.1f, 100.0f);
579 
580 		// Set view and projection matrix for view 0.
581 		bgfx_set_view_transform(0, view.transposed().ptr, proj.transposed().ptr);
582 
583 		// Stats.
584 		uint32_t numVertices = 0;
585 		int64_t profUpdate = 0;
586 		int64_t profNormal = 0;
587 		int64_t profTriangulate = 0;
588 
589 		// Allocate 32K vertices in transient vertex buffer.
590 		uint32_t maxVertices = (32<<10);
591 		bgfx_transient_vertex_buffer_t tvb;
592         bgfx_alloc_transient_vertex_buffer(&tvb, maxVertices, &PosNormalColorVertex.ms_decl);
593 
594 		const uint32_t numSpheres = 16;
595 		float sphere[numSpheres][4];
596 		for (uint32_t ii = 0; ii < numSpheres; ++ii)
597 		{
598 			sphere[ii][0] = sin(time*(ii*0.21f)+ii*0.37f) * (DIMS * 0.5f - 8.0f);
599 			sphere[ii][1] = sin(time*(ii*0.37f)+ii*0.67f) * (DIMS * 0.5f - 8.0f);
600 			sphere[ii][2] = cos(time*(ii*0.11f)+ii*0.13f) * (DIMS * 0.5f - 8.0f);
601 			sphere[ii][3] = 1.0f/(2.0f + (sin(time*(ii*0.13f) )*0.5f+0.5f)*2.0f);
602 		}
603 
604 		profUpdate = SDL_GetTicks();
605 		
606 		for (uint32_t zz = 0; zz < DIMS; ++zz)
607 		{
608 			for (uint32_t yy = 0; yy < DIMS; ++yy)
609 			{
610 				uint32_t offset = (zz*DIMS+yy)*DIMS;
611 
612 				for (uint32_t xx = 0; xx < DIMS; ++xx)
613 				{
614 					uint32_t xoffset = offset + xx;
615 
616 					float dist = 0.0f;
617 					float prod = 1.0f;
618 					for (uint32_t ii = 0; ii < numSpheres; ++ii)
619 					{
620 						const float* pos = sphere[ii].ptr;
621 						float dx = pos[0] - (-DIMS*0.5f + cast(float)(xx) );
622 						float dy = pos[1] - (-DIMS*0.5f + cast(float)(yy) );
623 						float dz = pos[2] - (-DIMS*0.5f + cast(float)(zz) );
624 						float invr = pos[3];
625 						float dot = dx*dx + dy*dy + dz*dz;
626 						dot *= invr*invr;
627 
628 						dist *= dot;
629 						dist += prod;
630 						prod *= dot;
631 					}
632 
633 					grid[xoffset].m_val = dist / prod - 1.0f;
634 				}
635 			}
636 		}
637 
638 		profUpdate = SDL_GetTicks() - profUpdate;
639 
640 		profNormal = SDL_GetTicks();
641 
642 		for (uint32_t zz = 1; zz < DIMS-1; ++zz)
643 		{
644 			for (uint32_t yy = 1; yy < DIMS-1; ++yy)
645 			{
646 				uint32_t offset = (zz*DIMS+yy)*DIMS;
647 
648 				for (uint32_t xx = 1; xx < DIMS-1; ++xx)
649 				{
650 					uint32_t xoffset = offset + xx;
651 
652 					vec3f normal = vec3f
653                     (
654 						grid[xoffset-1     ].m_val - grid[xoffset+1     ].m_val,
655 						grid[xoffset-ypitch].m_val - grid[xoffset+ypitch].m_val,
656 						grid[xoffset-zpitch].m_val - grid[xoffset+zpitch].m_val,
657 					);
658 
659 					grid[xoffset].m_normal = normal.normalized();
660 				}
661 			}
662 		}
663 
664 		profNormal = SDL_GetTicks() - profNormal;
665 
666 		profTriangulate = SDL_GetTicks();
667 
668 		PosNormalColorVertex* vertex = cast(PosNormalColorVertex*)tvb.data;
669 
670 		for (uint32_t zz = 0; zz < DIMS-1 && numVertices+12 < maxVertices; ++zz)
671 		{
672 			float rgb[6];
673 			rgb[2] = zz*invdim;
674 			rgb[5] = (zz+1)*invdim;
675 
676 			for (uint32_t yy = 0; yy < DIMS-1 && numVertices+12 < maxVertices; ++yy)
677 			{
678 				uint32_t offset = (zz*DIMS+yy)*DIMS;
679 
680 				rgb[1] = yy*invdim;
681 				rgb[4] = (yy+1)*invdim;
682 
683 				for (uint32_t xx = 0; xx < DIMS-1 && numVertices+12 < maxVertices; ++xx)
684 				{
685 					uint32_t xoffset = offset + xx;
686 
687 					rgb[0] = xx*invdim;
688 					rgb[3] = (xx+1)*invdim;
689 
690 					vec3f pos =
691 					vec3f(
692 						-DIMS*0.5f + cast(float)(xx),
693 						-DIMS*0.5f + cast(float)(yy),
694 						-DIMS*0.5f + cast(float)(zz)
695 					);
696 
697 					const Grid* val[8] = [
698 						&grid[xoffset+zpitch+ypitch  ],
699 						&grid[xoffset+zpitch+ypitch+1],
700 						&grid[xoffset+ypitch+1       ],
701 						&grid[xoffset+ypitch         ],
702 						&grid[xoffset+zpitch         ],
703 						&grid[xoffset+zpitch+1       ],
704 						&grid[xoffset+1              ],
705 						&grid[xoffset                ],
706 					];
707 
708 					uint32_t num = triangulate( cast(uint8_t*)vertex, PosNormalColorVertex.ms_decl.stride, rgb.ptr, pos.ptr, val.ptr, 0.5f);
709 					vertex += num;
710 					numVertices += num;
711 				}
712 			}
713 		}
714 
715 		profTriangulate = SDL_GetTicks() - profTriangulate;
716 
717         mat4f mtx = mat4f.rotateX(time*0.67f) * mat4f.rotateY(time);
718 		
719 		// Set model matrix for rendering.
720 		bgfx_set_transform(mtx.transposed().ptr);
721 
722 		// Set vertex and fragment shaders.
723 		bgfx_set_program(program);
724 
725 		// Set vertex and index buffer.
726 		bgfx_set_transient_vertex_buffer(&tvb, 0, numVertices);
727 
728 		// Submit primitive for rendering to view 0.
729 		bgfx_submit(0);
730 
731 		// Display stats.
732 		bgfx_dbg_text_printf(1, 4, 0x0f, "Num vertices: %5d (%6.4f%%)", numVertices, cast(float)(numVertices)/maxVertices * 100);
733 		bgfx_dbg_text_printf(1, 5, 0x0f, "      Update: % 7.3f[ms]", cast(double)(profUpdate));
734 		bgfx_dbg_text_printf(1, 6, 0x0f, "Calc normals: % 7.3f[ms]", cast(double)(profNormal));
735 		bgfx_dbg_text_printf(1, 7, 0x0f, " Triangulate: % 7.3f[ms]", cast(double)(profTriangulate));
736 		bgfx_dbg_text_printf(1, 8, 0x0f, "       Frame: % 7.3f[ms]", cast(double)(frameTime));
737 
738 		// Advance to next frame. Rendering thread will be kicked to 
739 		// process submitted rendering primitives.
740 		bgfx_frame();
741 	}
742 
743 	// Cleanup.
744 	bgfx_destroy_program(program);
745 
746 	// Shutdown bgfx.
747 	bgfx_shutdown();
748 
749 	return 0;
750 }