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
489     {
490         static assert(false, "TODO implement passing window handle to bgfx for this system");
491     }
492 
493 
494 	bgfx_init();
495 	bgfx_reset(width, height, reset);
496 
497 	// Enable debug text.
498 	bgfx_set_debug(debug_);
499 
500 	// Set view 0 clear state.
501 	bgfx_set_view_clear(0
502 		, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
503 		, 0x303030ff
504 		, 1.0f
505 		, 0
506 		);
507 
508 	// Create vertex stream declaration.
509 	PosNormalColorVertex.init();
510 
511 	const (bgfx_memory_t)* vs_metaballs;
512 	const (bgfx_memory_t)* fs_metaballs;
513 
514 	switch (bgfx_get_renderer_type() )
515 	{
516 	case BGFX_RENDERER_TYPE_DIRECT3D9:
517 		vs_metaballs = bgfx_make_ref(vs_metaballs_dx9.ptr, vs_metaballs_dx9.sizeof );
518 		fs_metaballs = bgfx_make_ref(fs_metaballs_dx9.ptr, fs_metaballs_dx9.sizeof );
519 		break;
520 
521 	case BGFX_RENDERER_TYPE_DIRECT3D11:
522 		vs_metaballs = bgfx_make_ref(vs_metaballs_dx11.ptr, vs_metaballs_dx11.sizeof );
523 		fs_metaballs = bgfx_make_ref(fs_metaballs_dx11.ptr, fs_metaballs_dx11.sizeof );
524 		break;
525 
526 	default:
527 		vs_metaballs = bgfx_make_ref(vs_metaballs_glsl.ptr, vs_metaballs_glsl.sizeof );
528 		fs_metaballs = bgfx_make_ref(fs_metaballs_glsl.ptr, fs_metaballs_glsl.sizeof );
529 		break;
530 	}
531 
532 	bgfx_shader_handle_t vsh = bgfx_create_shader(vs_metaballs);
533 	bgfx_shader_handle_t fsh = bgfx_create_shader(fs_metaballs);
534 
535 	// Create program from shaders.
536 	bgfx_program_handle_t program = bgfx_create_program(vsh, fsh, true /* destroy shaders when program is destroyed */);
537 
538     enum DIMS = 32;
539 
540 	Grid[] grid = new Grid[DIMS*DIMS*DIMS];
541 	const uint32_t ypitch = DIMS;
542 	const uint32_t zpitch = DIMS*DIMS;
543 	const float invdim = 1.0f/cast(float)(DIMS-1);
544 
545 	int64_t timeOffset = SDL_GetTicks();
546     int64_t last = timeOffset;
547 
548     while (!sdl2.keyboard().isPressed(SDLK_ESCAPE))
549     {
550         sdl2.processEvents();
551 
552 		// Set view 0 default viewport.
553 		bgfx_set_view_rect(cast(ushort)0, cast(ushort)0, cast(ushort)0, cast(ushort)width, cast(ushort)height);
554 
555 		// This dummy draw call is here to make sure that view 0 is cleared
556 		// if no other draw calls are submitted to view 0.
557 		bgfx_submit(0);
558 
559 		int64_t now = SDL_GetTicks();
560 		const int64_t frameTime = now - last;
561 		last = now;
562 		float time = cast(float)( (now - timeOffset)/ 1000.0 );
563 
564 		// Use debug font to print information about this example.
565 		bgfx_dbg_text_clear();
566 		bgfx_dbg_text_printf(0, 1, 0x4f, "bgfx/examples/02-metaball");
567 		bgfx_dbg_text_printf(0, 2, 0x6f, "Description: Rendering with transient buffers and embedding shaders.");
568 
569 		vec3f at = vec3f( 0.0f, 0.0f, 0.0f );
570 		vec3f eye = vec3f( 0.0f, 0.0f, -50.0f );
571         vec3f up = vec3f( 0.0f, 1.0f, 0.0f );
572 		
573         mat4f view = mat4f.lookAt(eye, at, up);
574         mat4f proj = mat4f.perspective(radians(60.0f), cast(float)(width)/height, 0.1f, 100.0f);
575 
576 		// Set view and projection matrix for view 0.
577 		bgfx_set_view_transform(0, view.transposed().ptr, proj.transposed().ptr);
578 
579 		// Stats.
580 		uint32_t numVertices = 0;
581 		int64_t profUpdate = 0;
582 		int64_t profNormal = 0;
583 		int64_t profTriangulate = 0;
584 
585 		// Allocate 32K vertices in transient vertex buffer.
586 		uint32_t maxVertices = (32<<10);
587 		bgfx_transient_vertex_buffer_t tvb;
588         bgfx_alloc_transient_vertex_buffer(&tvb, maxVertices, &PosNormalColorVertex.ms_decl);
589 
590 		const uint32_t numSpheres = 16;
591 		float sphere[numSpheres][4];
592 		for (uint32_t ii = 0; ii < numSpheres; ++ii)
593 		{
594 			sphere[ii][0] = sin(time*(ii*0.21f)+ii*0.37f) * (DIMS * 0.5f - 8.0f);
595 			sphere[ii][1] = sin(time*(ii*0.37f)+ii*0.67f) * (DIMS * 0.5f - 8.0f);
596 			sphere[ii][2] = cos(time*(ii*0.11f)+ii*0.13f) * (DIMS * 0.5f - 8.0f);
597 			sphere[ii][3] = 1.0f/(2.0f + (sin(time*(ii*0.13f) )*0.5f+0.5f)*2.0f);
598 		}
599 
600 		profUpdate = SDL_GetTicks();
601 		
602 		for (uint32_t zz = 0; zz < DIMS; ++zz)
603 		{
604 			for (uint32_t yy = 0; yy < DIMS; ++yy)
605 			{
606 				uint32_t offset = (zz*DIMS+yy)*DIMS;
607 
608 				for (uint32_t xx = 0; xx < DIMS; ++xx)
609 				{
610 					uint32_t xoffset = offset + xx;
611 
612 					float dist = 0.0f;
613 					float prod = 1.0f;
614 					for (uint32_t ii = 0; ii < numSpheres; ++ii)
615 					{
616 						const float* pos = sphere[ii].ptr;
617 						float dx = pos[0] - (-DIMS*0.5f + cast(float)(xx) );
618 						float dy = pos[1] - (-DIMS*0.5f + cast(float)(yy) );
619 						float dz = pos[2] - (-DIMS*0.5f + cast(float)(zz) );
620 						float invr = pos[3];
621 						float dot = dx*dx + dy*dy + dz*dz;
622 						dot *= invr*invr;
623 
624 						dist *= dot;
625 						dist += prod;
626 						prod *= dot;
627 					}
628 
629 					grid[xoffset].m_val = dist / prod - 1.0f;
630 				}
631 			}
632 		}
633 
634 		profUpdate = SDL_GetTicks() - profUpdate;
635 
636 		profNormal = SDL_GetTicks();
637 
638 		for (uint32_t zz = 1; zz < DIMS-1; ++zz)
639 		{
640 			for (uint32_t yy = 1; yy < DIMS-1; ++yy)
641 			{
642 				uint32_t offset = (zz*DIMS+yy)*DIMS;
643 
644 				for (uint32_t xx = 1; xx < DIMS-1; ++xx)
645 				{
646 					uint32_t xoffset = offset + xx;
647 
648 					vec3f normal = vec3f
649                     (
650 						grid[xoffset-1     ].m_val - grid[xoffset+1     ].m_val,
651 						grid[xoffset-ypitch].m_val - grid[xoffset+ypitch].m_val,
652 						grid[xoffset-zpitch].m_val - grid[xoffset+zpitch].m_val,
653 					);
654 
655 					grid[xoffset].m_normal = normal.normalized();
656 				}
657 			}
658 		}
659 
660 		profNormal = SDL_GetTicks() - profNormal;
661 
662 		profTriangulate = SDL_GetTicks();
663 
664 		PosNormalColorVertex* vertex = cast(PosNormalColorVertex*)tvb.data;
665 
666 		for (uint32_t zz = 0; zz < DIMS-1 && numVertices+12 < maxVertices; ++zz)
667 		{
668 			float rgb[6];
669 			rgb[2] = zz*invdim;
670 			rgb[5] = (zz+1)*invdim;
671 
672 			for (uint32_t yy = 0; yy < DIMS-1 && numVertices+12 < maxVertices; ++yy)
673 			{
674 				uint32_t offset = (zz*DIMS+yy)*DIMS;
675 
676 				rgb[1] = yy*invdim;
677 				rgb[4] = (yy+1)*invdim;
678 
679 				for (uint32_t xx = 0; xx < DIMS-1 && numVertices+12 < maxVertices; ++xx)
680 				{
681 					uint32_t xoffset = offset + xx;
682 
683 					rgb[0] = xx*invdim;
684 					rgb[3] = (xx+1)*invdim;
685 
686 					vec3f pos =
687 					vec3f(
688 						-DIMS*0.5f + cast(float)(xx),
689 						-DIMS*0.5f + cast(float)(yy),
690 						-DIMS*0.5f + cast(float)(zz)
691 					);
692 
693 					const Grid* val[8] = [
694 						&grid[xoffset+zpitch+ypitch  ],
695 						&grid[xoffset+zpitch+ypitch+1],
696 						&grid[xoffset+ypitch+1       ],
697 						&grid[xoffset+ypitch         ],
698 						&grid[xoffset+zpitch         ],
699 						&grid[xoffset+zpitch+1       ],
700 						&grid[xoffset+1              ],
701 						&grid[xoffset                ],
702 					];
703 
704 					uint32_t num = triangulate( cast(uint8_t*)vertex, PosNormalColorVertex.ms_decl.stride, rgb.ptr, pos.ptr, val.ptr, 0.5f);
705 					vertex += num;
706 					numVertices += num;
707 				}
708 			}
709 		}
710 
711 		profTriangulate = SDL_GetTicks() - profTriangulate;
712 
713         mat4f mtx = mat4f.rotateX(time*0.67f) * mat4f.rotateY(time);
714 		
715 		// Set model matrix for rendering.
716 		bgfx_set_transform(mtx.transposed().ptr);
717 
718 		// Set vertex and fragment shaders.
719 		bgfx_set_program(program);
720 
721 		// Set vertex and index buffer.
722 		bgfx_set_transient_vertex_buffer(&tvb, 0, numVertices);
723 
724 		// Submit primitive for rendering to view 0.
725 		bgfx_submit(0);
726 
727 		// Display stats.
728 		bgfx_dbg_text_printf(1, 4, 0x0f, "Num vertices: %5d (%6.4f%%)", numVertices, cast(float)(numVertices)/maxVertices * 100);
729 		bgfx_dbg_text_printf(1, 5, 0x0f, "      Update: % 7.3f[ms]", cast(double)(profUpdate));
730 		bgfx_dbg_text_printf(1, 6, 0x0f, "Calc normals: % 7.3f[ms]", cast(double)(profNormal));
731 		bgfx_dbg_text_printf(1, 7, 0x0f, " Triangulate: % 7.3f[ms]", cast(double)(profTriangulate));
732 		bgfx_dbg_text_printf(1, 8, 0x0f, "       Frame: % 7.3f[ms]", cast(double)(frameTime));
733 
734 		// Advance to next frame. Rendering thread will be kicked to 
735 		// process submitted rendering primitives.
736 		bgfx_frame();
737 	}
738 
739 	// Cleanup.
740 	bgfx_destroy_program(program);
741 
742 	// Shutdown bgfx.
743 	bgfx_shutdown();
744 
745 	return 0;
746 }