normals calculation fix
[voxconv.git] / zglvox_new.d
blob0bb988cf3d1f7ebd08a37a21317c20ad486e0bf0
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 = true;
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/3;
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 (!glcreated) return;
63 glDisable(GL_TEXTURE_2D);
64 glEnable(GL_DEPTH_TEST);
65 glDisable(GL_LIGHTING);
66 glDisable(GL_DITHER);
67 glEnable(GL_COLOR_MATERIAL);
69 glEnable(GL_BLEND);
70 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
72 glDepthFunc(GL_LEQUAL);
73 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
75 glEnable(GL_CULL_FACE);
76 //glCullFace(GL_FRONT);
77 glCullFace(GL_BACK);
78 //glFrontFace(GL_CCW);
79 glFrontFace(GL_CW);
81 //glDisable(GL_CULL_FACE); // this way we can draw any model
82 glShadeModel(GL_FLAT);
84 //glDisable(GL_CULL_FACE); // this way we can draw any model
86 glDisable(GL_BLEND);
88 glClearDepth(1.0f);
89 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
91 // setup projection
92 glMatrixMode(GL_PROJECTION);
93 glLoadIdentity();
94 oglPerspective(
95 90.0, // field of view in degree
96 1.0, // aspect ratio
97 1.0, // Z near
98 10000.0, // Z far
100 version(none) {
101 oglLookAt(
102 0.0, -vox.cy-64, 30.0, // eye is at (0,0,5)
103 0.0, 0.0, 0.0, // center is at (0,0,0)
104 0.0, 0.0, 1.0, // up is in positive Z direction
106 } else {
107 oglLookAt(
108 eye.x, eye.y-vox.cy-64, eye.z, // eye is at (0,0,5)
109 0.0, 0.0, 0.0, // center is at (0,0,0)
110 0.0, 0.0, 1.0, // up is in positive Z direction
114 // setup model matrix
115 glMatrixMode(GL_MODELVIEW);
116 glLoadIdentity();
117 //glRotatef(1.0f*angle, 0.8f, 0.9f, 0.4f);
118 //glRotatef(1.0f*angle, 1.0f, 0.0f, 0.0f);
119 //glRotatef(1.0f*angle, 0.0f, 1.0f, 0.0f);
120 if (vertical) {
121 glRotatef(1.0f*angle, 1.0f, 0.0f, 0.0f);
122 } else {
123 glRotatef(1.0f*angle, 0.0f, 0.0f, 1.0f);
126 glvox.draw();
130 // ////////////////////////////////////////////////////////////////////////// //
131 void main (string[] args) {
132 //setOpenGLContextVersion(3, 2); // up to GLSL 150
133 //openGLContextCompatible = false;
135 if (args.length < 1) {
136 writeln("filename?");
137 return;
140 version(none) {
141 loadVoxel(ref voxdata, args[2]);
142 return;
145 conRegVar!paused("pause", "stop rotating");
146 conRegVar!angle(0, 359, "angle", "current angle");
147 conRegVar!vertical("vertical", "rotate vertically");
149 conProcessArgs(args);
150 while (conProcessQueue()) {}
152 renderSealVars();
154 int argidx = 1;
156 auto sdwin = new SimpleWindow(conGetVar!int("v_width"), conGetVar!int("v_height"),
157 "KVX Renderer",
158 OpenGlOptions.yes, Resizability.fixedSize);
161 void loadFrom (string fname) {
162 writeln("loading: ", fname, (vox_allow_normals ? " (with normals)" : " (no normals)"));
163 loadVoxel(ref voxdata, fname);
164 vox.createFrom(ref voxdata);
165 voxdata.clear();
166 glvox.create(vox);
167 glcreated = true;
168 import std.string : format;
169 sdwin.title = "(%s quads, %s verts) -- %s".format(vox.quads.length, glvox.uniqueVerts, fname);
170 vox.clear();
171 { import core.memory : GC; GC.collect(); GC.minimize(); }
172 //{ import core.memory : GC; GC.collect(); GC.minimize(); }
176 sdwin.redrawOpenGlScene = delegate () {
177 drawScene();
178 glconDraw();
181 sdwin.visibleForTheFirstTime = delegate () {
182 loadFrom(args[argidx]);
183 //vox = new Voxel(VFile("untitled.vxl"));
184 sdwin.setAsCurrentOpenGlContext(); // make this window active
185 glconResize(sdwin.width, sdwin.height);
186 sdwin.redrawOpenGlScene();
187 //drawScene();
190 sdwin.eventLoop(1000/35,
191 delegate () {
192 if (sdwin.closed) return;
193 conProcessQueue();
194 if (isQuitRequested) { sdwin.close(); return; }
195 if (!paused) angle = (angle+1)%360;
196 //angle = 50;
197 //angle = 360/2;
198 sdwin.redrawOpenGlSceneNow();
200 delegate (KeyEvent event) {
201 if (sdwin.closed) return;
202 if (glconKeyEvent(event)) return;
203 if (!event.pressed) return;
204 if (event.pressed && event.key == Key.Escape) { concmd("quit"); return; }
206 switch (event.key) {
207 case Key.Escape: sdwin.close(); break;
208 default:
211 if (event.pressed) {
212 float delta = 10.0f;
213 if (event.modifierState&ModifierState.shift) {
214 delta = (event.modifierState&ModifierState.ctrl ? 5.0f : 1.0f);
215 } else if (event.modifierState&ModifierState.ctrl) {
216 delta = 20.0f;
218 if (event.modifierState&ModifierState.alt) {
219 if (event.key == Key.Up) eye.y -= delta;
220 if (event.key == Key.Down) eye.y += delta;
221 } else {
222 if (event.key == Key.Left) eye.x -= delta;
223 if (event.key == Key.Right) eye.x += delta;
224 if (event.key == Key.Up) eye.z -= delta;
225 if (event.key == Key.Down) eye.z += delta;
229 delegate (MouseEvent event) {
231 delegate (dchar ch) {
232 if (sdwin.closed) return;
233 if (glconCharEvent(ch)) return;
234 if (ch == 'q') { concmd("quit"); return; }
235 if (ch == ' ') { concmd("pause toggle"); return; }
236 if (ch == 'v') { concmd("vertical toggle"); return; }
237 if (ch == '0') { eye = vec3(0.0f, 0.0f, 0.0f); return; }
238 if (ch == 'u') { vox_wireframe = !vox_wireframe; return; }
239 if (ch == 't') {
240 vox_fix_tjunctions = !vox_fix_tjunctions;
241 loadFrom(args[argidx]);
242 return;
244 if (ch == 'l') {
245 vox_allow_normals = !vox_allow_normals;
246 loadFrom(args[argidx]);
247 return;
249 if (ch == 'h') {
250 vox_optimize_hollow = !vox_optimize_hollow;
251 loadFrom(args[argidx]);
252 return;
254 if (ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5') {
255 vox_optimisation = (ch-'1');
256 loadFrom(args[argidx]);
257 return;
259 if (ch == 'O') {
260 vox_optimiser_use_3dbmp = !vox_optimiser_use_3dbmp;
261 conwriteln("OPTIMISER: use3dbmp is ", (vox_optimiser_use_3dbmp ? "on" : "off"));
262 loadFrom(args[argidx]);
263 return;
265 if (ch == 'C') {
266 vox_atlas_cache_colors = !vox_atlas_cache_colors;
267 conwriteln("OPTIMISER: cache_colors is ", (vox_atlas_cache_colors ? "on" : "off"));
268 loadFrom(args[argidx]);
269 return;
271 if (ch == 'F') {
272 vox_optimiser_use_cvox = !vox_optimiser_use_cvox;
273 conwriteln("OPTIMISER: use faster voxel data is ", (vox_optimiser_use_cvox ? "on" : "off"));
274 loadFrom(args[argidx]);
275 return;
277 if (ch == 'p' || ch == 'P') {
278 if (argidx > 1) {
279 --argidx;
280 loadFrom(args[argidx]);
282 return;
284 if (ch == 'n' || ch == 'N') {
285 if (argidx+1 < args.length) {
286 ++argidx;
287 loadFrom(args[argidx]);
289 return;
293 flushGui();