added progress indicator for long conversions
[voxconv.git] / zglvox_new.d
blob307b8038c6b0c5496c9d38e2d84acf81c5a85bd4
1 module zglvox_new is aliced;
3 import arsd.simpledisplay;
4 //import arsd.color;
5 //import arsd.image;
7 import iv.bclamp;
8 import iv.glbinds.utils;
9 import iv.cmdcongl;
10 import iv.strex;
11 import iv.vfs;
12 import iv.vfs.io;
13 import iv.vmath;
15 static import iv.timer;
17 import vox_texatlas;
18 import vox_2dbmp;
19 import vox_3dbmp;
20 import vox_data;
21 import vox_load;
22 import vox_mesh;
23 import vox_meshgl;
25 //version = kvx_dump;
26 //version = vox_check_invariants;
27 version = voxdata_debug;
30 // ////////////////////////////////////////////////////////////////////////// //
31 __gshared int scrWidth = 800, scrHeight = 800;
32 __gshared bool paused = false;
35 // ////////////////////////////////////////////////////////////////////////// //
36 shared static this () {
37 conRegVar!scrWidth(64, 4096, "v_width", "screen width");
38 conRegVar!scrHeight(64, 4096, "v_height", "screen height");
42 public void renderSealVars () {
43 conSealVar("v_width");
44 conSealVar("v_height");
48 // ////////////////////////////////////////////////////////////////////////// //
49 __gshared VoxelData voxdata;
50 __gshared VoxelMesh vox;
51 __gshared GLVoxelMesh glvox;
52 __gshared bool glcreated = false;
53 __gshared int angle = 360/2;
54 __gshared bool vertical = false;
55 __gshared vec3 eye = vec3(0.0f, 14.0f, 64.0f);
58 void drawScene () {
59 import iv.glbinds;
61 if (vox is null) return; // just in case
63 if (!glcreated) {
64 glvox.create(vox);
65 glcreated = true;
68 glDisable(GL_TEXTURE_2D);
69 glEnable(GL_DEPTH_TEST);
70 glDisable(GL_LIGHTING);
71 glDisable(GL_DITHER);
72 glEnable(GL_COLOR_MATERIAL);
74 glEnable(GL_BLEND);
75 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
77 glDepthFunc(GL_LEQUAL);
78 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
80 glEnable(GL_CULL_FACE);
81 //glCullFace(GL_FRONT);
82 glCullFace(GL_BACK);
83 //glFrontFace(GL_CCW);
84 glFrontFace(GL_CW);
86 //glDisable(GL_CULL_FACE); // this way we can draw any model
87 glShadeModel(GL_FLAT);
89 //glDisable(GL_CULL_FACE); // this way we can draw any model
91 glDisable(GL_BLEND);
93 glClearDepth(1.0f);
94 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
96 // setup projection
97 glMatrixMode(GL_PROJECTION);
98 glLoadIdentity();
99 oglPerspective(
100 90.0, // field of view in degree
101 1.0, // aspect ratio
102 1.0, // Z near
103 10000.0, // Z far
105 version(none) {
106 oglLookAt(
107 0.0, -vox.cy-64, 30.0, // eye is at (0,0,5)
108 0.0, 0.0, 0.0, // center is at (0,0,0)
109 0.0, 0.0, 1.0, // up is in positive Z direction
111 } else {
112 oglLookAt(
113 eye.x, eye.y-vox.cy-64, eye.z, // eye is at (0,0,5)
114 0.0, 0.0, 0.0, // center is at (0,0,0)
115 0.0, 0.0, 1.0, // up is in positive Z direction
119 // setup model matrix
120 glMatrixMode(GL_MODELVIEW);
121 glLoadIdentity();
122 //glRotatef(1.0f*angle, 0.8f, 0.9f, 0.4f);
123 //glRotatef(1.0f*angle, 1.0f, 0.0f, 0.0f);
124 //glRotatef(1.0f*angle, 0.0f, 1.0f, 0.0f);
125 if (vertical) {
126 glRotatef(1.0f*angle, 1.0f, 0.0f, 0.0f);
127 } else {
128 glRotatef(1.0f*angle, 0.0f, 0.0f, 1.0f);
131 glvox.draw();
135 // ////////////////////////////////////////////////////////////////////////// //
136 void main (string[] args) {
137 //setOpenGLContextVersion(3, 2); // up to GLSL 150
138 //openGLContextCompatible = false;
140 if (args.length < 1) {
141 writeln("filename?");
142 return;
145 version(none) {
146 loadVoxel(ref voxdata, args[2]);
147 return;
150 conRegVar!paused("pause", "stop rotating");
151 conRegVar!angle(0, 359, "angle", "current angle");
152 conRegVar!vertical("vertical", "rotate vertically");
154 conProcessArgs(args);
155 while (conProcessQueue()) {}
157 renderSealVars();
159 int argidx = 1;
161 auto sdwin = new SimpleWindow(conGetVar!int("v_width"), conGetVar!int("v_height"),
162 "KVX Renderer",
163 OpenGlOptions.yes, Resizability.fixedSize);
166 void loadFrom (string fname) {
167 delete vox;
168 writeln("loading: ", fname, (vox_allow_normals ? " (with normals)" : " (no normals)"));
169 loadVoxel(ref voxdata, fname);
170 vox = new VoxelMesh(ref voxdata);
171 voxdata.clear();
172 glvox.create(vox);
173 glcreated = true;
174 import std.string : format;
175 sdwin.title = "(%s quads, %s verts) -- %s".format(vox.quads.length, glvox.uniqueVerts, fname);
176 vox.clear();
177 { import core.memory : GC; GC.collect(); GC.minimize(); }
178 { import core.memory : GC; GC.collect(); GC.minimize(); }
182 sdwin.redrawOpenGlScene = delegate () {
183 drawScene();
184 glconDraw();
187 sdwin.visibleForTheFirstTime = delegate () {
188 loadFrom(args[argidx]);
189 //vox = new Voxel(VFile("untitled.vxl"));
190 sdwin.setAsCurrentOpenGlContext(); // make this window active
191 glconResize(sdwin.width, sdwin.height);
192 sdwin.redrawOpenGlScene();
193 //drawScene();
196 sdwin.eventLoop(1000/35,
197 delegate () {
198 if (sdwin.closed) return;
199 conProcessQueue();
200 if (isQuitRequested) { sdwin.close(); return; }
201 if (!paused) angle = (angle+1)%360;
202 //angle = 50;
203 //angle = 360/2;
204 sdwin.redrawOpenGlSceneNow();
206 delegate (KeyEvent event) {
207 if (sdwin.closed) return;
208 if (glconKeyEvent(event)) return;
209 if (!event.pressed) return;
210 if (event.pressed && event.key == Key.Escape) { concmd("quit"); return; }
212 switch (event.key) {
213 case Key.Escape: sdwin.close(); break;
214 default:
217 if (event.pressed) {
218 float delta = 10.0f;
219 if (event.modifierState&ModifierState.shift) {
220 delta = (event.modifierState&ModifierState.ctrl ? 5.0f : 1.0f);
221 } else if (event.modifierState&ModifierState.ctrl) {
222 delta = 20.0f;
224 if (event.modifierState&ModifierState.alt) {
225 if (event.key == Key.Up) eye.y -= delta;
226 if (event.key == Key.Down) eye.y += delta;
227 } else {
228 if (event.key == Key.Left) eye.x -= delta;
229 if (event.key == Key.Right) eye.x += delta;
230 if (event.key == Key.Up) eye.z -= delta;
231 if (event.key == Key.Down) eye.z += delta;
235 delegate (MouseEvent event) {
237 delegate (dchar ch) {
238 if (sdwin.closed) return;
239 if (glconCharEvent(ch)) return;
240 if (ch == 'q') { concmd("quit"); return; }
241 if (ch == ' ') { concmd("pause toggle"); return; }
242 if (ch == 'v') { concmd("vertical toggle"); return; }
243 if (ch == '0') { eye = vec3(0.0f, 0.0f, 0.0f); return; }
244 if (ch == 'u') { vox_wireframe = !vox_wireframe; return; }
245 if (ch == 't') {
246 vox_fix_tjunctions = !vox_fix_tjunctions;
247 loadFrom(args[argidx]);
248 return;
250 if (ch == 'l') {
251 vox_allow_normals = !vox_allow_normals;
252 loadFrom(args[argidx]);
253 return;
255 if (ch == 'h') {
256 vox_optimize_hollow = !vox_optimize_hollow;
257 loadFrom(args[argidx]);
258 return;
260 if (ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5') {
261 vox_optimisation = (ch-'1');
262 loadFrom(args[argidx]);
263 return;
265 if (ch == 'O') {
266 vox_optimiser_use_3dbmp = !vox_optimiser_use_3dbmp;
267 conwriteln("OPTIMISER: use3dbmp is ", (vox_optimiser_use_3dbmp ? "on" : "off"));
268 loadFrom(args[argidx]);
269 return;
271 if (ch == 'C') {
272 vox_atlas_cache_colors = !vox_atlas_cache_colors;
273 conwriteln("OPTIMISER: cache_colors is ", (vox_atlas_cache_colors ? "on" : "off"));
274 loadFrom(args[argidx]);
275 return;
277 if (ch == 'F') {
278 vox_optimiser_use_cvox = !vox_optimiser_use_cvox;
279 conwriteln("OPTIMISER: use faster voxel data is ", (vox_optimiser_use_cvox ? "on" : "off"));
280 loadFrom(args[argidx]);
281 return;
283 if (ch == 'p' || ch == 'P') {
284 if (argidx > 1) {
285 --argidx;
286 loadFrom(args[argidx]);
288 return;
290 if (ch == 'n' || ch == 'N') {
291 if (argidx+1 < args.length) {
292 ++argidx;
293 loadFrom(args[argidx]);
295 return;
299 flushGui();