Rev 8824 | Rev 8875 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8824 | IgorA | 1 | #include |
2 | #include |
||
3 | #include |
||
4 | #include |
||
5 | #include |
||
6 | #include |
||
7 | #include |
||
8 | |||
9 | using namespace Kolibri; |
||
10 | |||
11 | const char header[] = "Blocks"; |
||
12 | char library_path[2048]; |
||
13 | |||
14 | OpenDialog_data ofd; |
||
15 | unsigned char procinfo[1024]; |
||
16 | char plugin_path[4096], openfile_path[4096], filename_area[256]; |
||
17 | od_filter filter1 = { 7, "JS\0\0" }; |
||
18 | |||
19 | namespace Kolibri{ |
||
20 | char CurrentDirectoryPath[2048]; |
||
21 | } |
||
22 | |||
23 | struct BlockList{ |
||
24 | unsigned char* name; |
||
25 | long int id_l, p_cou; |
||
26 | float* vert_d; |
||
27 | float* norm_d; |
||
28 | }; |
||
29 | |||
30 | BlockList* b_list = 0; |
||
31 | long int b_count; |
||
32 | |||
33 | unsigned char* b_data = 0; |
||
34 | unsigned char* f_data = 0; |
||
35 | |||
36 | struct ColorList{ |
||
37 | unsigned char* name; |
||
38 | long int color; |
||
39 | }; |
||
40 | |||
41 | const long C_COUNT_MAX = 32; |
||
42 | ColorList c_list[C_COUNT_MAX]; |
||
43 | long c_count = 0; |
||
44 | |||
45 | struct ModelList{ |
||
46 | char* name; |
||
47 | long int color, t_cr; |
||
48 | float x,y,z, r_x,r_y,r_z; |
||
49 | long int level, id_l; |
||
50 | }; |
||
51 | |||
52 | ModelList* model_list = 0; |
||
53 | long int m_count; |
||
54 | |||
55 | TinyGLContext ctx1; |
||
56 | float angle_x = 135.0, angle_y = 0.0, angle_z = 0.0, delt_size = 3.0, |
||
57 | scale_o = 0.1, trans_z = 0.0; |
||
58 | double rat_h = 1.0; |
||
59 | bool mouse_drag = false; |
||
60 | short mouse_x, mouse_y; |
||
61 | float angle_dwm, //~ wnd_w/180 - прибавление углов поворота сцены при вращении мышей |
||
62 | angle_dhm; //~ wnd_h/180 |
||
63 | |||
64 | float light_position[] = {-30.0, 80.0, -50.0, 1.0}; //Расположение источника [0][1][2] |
||
65 | //[3] = (0.0 - бесконечно удаленный источник, 1.0 - источник света на определенном расстоянии) |
||
66 | float light_dir[] = {0.0,0.0,0.0}; //направление лампы |
||
67 | |||
68 | float mat_specular[] = {0.3, 0.3, 0.3, 1.0}; //Цвет блика |
||
69 | float mat_shininess = 3.0; //Размер блика (обратная пропорция) |
||
70 | float white_light[] = {1.0, 1.0, 1.0, 1.0}; //Цвет и интенсивность освещения, генерируемого источником |
||
71 | float lmodel_ambient[] = {0.3, 0.3, 0.3, 1.0}; //Параметры фонового освещения |
||
72 | |||
73 | void SetLight() |
||
74 | { |
||
75 | glLightfv(GL_LIGHT0, GL_POSITION, light_position); |
||
76 | glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir); |
||
77 | |||
78 | glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light); |
||
79 | glLightfv(GL_LIGHT0, GL_SPECULAR, white_light); |
||
80 | |||
81 | glEnable(GL_COLOR_MATERIAL); |
||
82 | glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); |
||
83 | glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); |
||
84 | glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); |
||
85 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); |
||
86 | |||
87 | glEnable(GL_LIGHTING); |
||
88 | glEnable(GL_LIGHT0); |
||
89 | } |
||
90 | |||
91 | long list_get_id(char* name) |
||
92 | { |
||
93 | long i; |
||
94 | long n = strchr(name, '\'')-name; |
||
95 | if(n) name[n] = 0; |
||
96 | for(i=0;i |
||
97 | if(!strcmp(name,b_list[i].name)) return b_list[i].id_l; |
||
98 | } |
||
99 | return b_list[0].id_l; //not found |
||
100 | } |
||
101 | |||
102 | long color_get_id(char* name) |
||
103 | { |
||
104 | long i; |
||
105 | char* buf; |
||
106 | for(i=0;i |
||
107 | buf = strchr(c_list[i].name, '='); |
||
108 | if(buf){ |
||
109 | buf[0]=0; |
||
110 | while(buf>c_list[i].name && buf[-1]==' '){ |
||
111 | buf--; buf[0]=0; |
||
112 | }; |
||
113 | } |
||
114 | while(name[0]==' '){ |
||
115 | name++; |
||
116 | }; |
||
117 | if(!strcmp(name,c_list[i].name)) return i; |
||
118 | } |
||
119 | return -1; //not found |
||
120 | } |
||
121 | |||
122 | void draw_3d() |
||
123 | { |
||
124 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //очистим буфер цвета и глубины |
||
125 | glPushMatrix(); |
||
126 | |||
127 | if(b_list){ |
||
128 | SetLight(); |
||
129 | glTranslatef(0.0,0.0,0.5); |
||
130 | glScalef(scale_o*rat_h,-scale_o,scale_o/4.0); // z/2.0 |
||
131 | glTranslatef(0.0, trans_z, 0.0); |
||
132 | glRotatef(angle_x,1.0,0.0,0.0); |
||
133 | glRotatef(angle_y,0.0,1.0,0.0); |
||
134 | glRotatef(angle_z,0.0,0.0,1.0); |
||
135 | |||
136 | long i; |
||
137 | if(model_list){ |
||
138 | unsigned long pu_cou=0, pu_lvl=0; |
||
139 | for(i=0;i |
||
140 | while(model_list[i].level<=pu_lvl && pu_cou){ |
||
141 | pu_cou--; |
||
142 | pu_lvl--; |
||
143 | glPopMatrix(); |
||
144 | }; |
||
145 | pu_lvl=model_list[i].level; |
||
146 | pu_cou++; |
||
147 | glPushMatrix(); |
||
148 | glTranslatef(model_list[i].x, model_list[i].y, model_list[i].z); |
||
149 | glRotatef(model_list[i].r_x, 1.0,0.0,0.0); |
||
150 | glRotatef(model_list[i].r_y, 0.0,1.0,0.0); |
||
151 | glRotatef(model_list[i].r_z, 0.0,0.0,1.0); |
||
152 | glColor3ub((model_list[i].color>>16)&255, |
||
153 | (model_list[i].color>> 8)&255, |
||
154 | model_list[i].color&255); |
||
155 | glCallList(model_list[i].id_l); |
||
156 | } |
||
157 | while(pu_cou){ |
||
158 | pu_cou--; |
||
159 | glPopMatrix(); |
||
160 | }; |
||
161 | } |
||
162 | else{ |
||
163 | glColor3f(1.0, 1.0, 0.0); |
||
164 | glCallList(b_list[0].id_l); |
||
165 | } |
||
166 | } |
||
167 | |||
168 | glPopMatrix(); |
||
169 | } |
||
170 | |||
171 | void compile_list(BlockList *list){ |
||
172 | long int i; |
||
173 | list->id_l = glGenLists(1); |
||
174 | if(list->id_l<1) return; //not found |
||
175 | glNewList(list->id_l, GL_COMPILE); |
||
176 | glBegin(GL_TRIANGLES); |
||
177 | for(i=0;i |
||
178 | glNormal3fv((float*)(list->norm_d+i*3)); |
||
179 | glVertex3fv((float*)(list->vert_d+i*3)); |
||
180 | } |
||
181 | glEnd(); |
||
182 | glEndList(); |
||
183 | } |
||
184 | |||
185 | bool init_block(){ |
||
186 | FileInfoBlock* file; |
||
187 | unsigned long int k; |
||
188 | |||
189 | file = FileOpen("block.bin"); |
||
190 | if (!file){ |
||
191 | //SetWindowCaption("Error open file 'block.bin'"); |
||
192 | return false; |
||
193 | } |
||
194 | k = FileGetLength(file); |
||
195 | if (k > 0){ |
||
196 | if(b_data) delete b_data; |
||
197 | b_data = new unsigned char[k]; |
||
198 | |||
199 | if (b_data){ |
||
200 | if(FileRead(file, b_data, k) != k){ |
||
201 | delete b_data; b_data = 0; |
||
202 | } |
||
203 | else if((long&)b_data[0]==0x4b43504b){ //"KPCK" |
||
204 | k = (long&)b_data[4]; |
||
205 | f_data = new unsigned char[k]; |
||
206 | unpack(b_data, f_data); |
||
207 | delete b_data; |
||
208 | b_data = f_data; |
||
209 | f_data = 0; |
||
210 | } |
||
211 | } |
||
212 | } |
||
213 | FileClose(file); |
||
214 | |||
215 | if (b_data){ |
||
216 | unsigned long i=0, n=0; |
||
217 | b_count=0; |
||
218 | while((long&)b_data[i] && i |
||
219 | while(b_data[i]){ i++; }; |
||
220 | i = (i|3)+1; |
||
221 | i += 4+((long&)b_data[i])*24; |
||
222 | b_count++; |
||
223 | }; |
||
224 | b_list = new BlockList[b_count]; |
||
225 | i=0; |
||
226 | while((long&)b_data[i] && i |
||
227 | b_list[n].name = (unsigned char*)(b_data+i); |
||
228 | while(b_data[i]){ i++; }; |
||
229 | i = (i|3)+1; |
||
230 | b_list[n].p_cou = (long&)b_data[i]; |
||
231 | i += 4; |
||
232 | b_list[n].vert_d = (float*)(b_data+i); |
||
233 | i += b_list[n].p_cou*12; |
||
234 | b_list[n].norm_d = (float*)(b_data+i); |
||
235 | i += b_list[n].p_cou*12; |
||
236 | compile_list(&b_list[n]); |
||
237 | n++; |
||
238 | }; |
||
239 | } |
||
240 | return (bool)b_data; |
||
241 | } |
||
242 | |||
243 | bool init_model() |
||
244 | { |
||
245 | long i, n; |
||
246 | char *ft = strstr(f_data, "const"); |
||
247 | char *fe; //end ']' |
||
248 | char *fp; //perv ',' |
||
249 | |||
250 | c_count=0; |
||
251 | while(ft && c_count |
||
252 | fp = ft+5; |
||
253 | while(fp[0]==' ') fp++; |
||
254 | c_list[c_count].name = fp; |
||
255 | ft = strchr(ft, '=')+1; |
||
256 | fe = strchr(ft, ';'); |
||
257 | fe[0] = 0; |
||
258 | c_list[c_count].color = StrToInt(ft); |
||
259 | fe[0] = ';'; |
||
260 | c_count++; |
||
261 | ft = strstr(ft, "const"); |
||
262 | } |
||
263 | |||
264 | float mz_min=0.0, mz_max=0.0; |
||
265 | ft = strstr(f_data, "model_list"); |
||
266 | if(ft==0) return false; |
||
267 | |||
268 | m_count=0; |
||
269 | fe=strchr(ft, ';'); |
||
270 | if(fe==0) return false; |
||
271 | do{ |
||
272 | ft=strchr(ft, '['); |
||
273 | ft=strchr(ft, ']'); |
||
274 | if(ft && ft |
||
275 | }while(ft && ft |
||
276 | |||
277 | if(model_list) delete model_list; |
||
278 | model_list = new ModelList[m_count]; |
||
279 | |||
280 | ft = strstr(f_data, "model_list"); |
||
281 | ft=strchr(ft, '[')+1; |
||
282 | for(i=0;i |
||
283 | ft=strchr(ft, '[')+1; |
||
284 | fe=strchr(ft, ']')+1; |
||
285 | ft=strchr(ft, '\'')+1; |
||
286 | model_list[i].name = ft; |
||
287 | ft=strchr(ft, ',')+1; //color |
||
288 | |||
289 | fp=ft; |
||
290 | ft=strchr(ft, ',')+1; |
||
291 | ft[-1]=0; |
||
292 | n=color_get_id(fp); |
||
293 | if(n>-1){ |
||
294 | model_list[i].color=c_list[n].color; |
||
295 | } |
||
296 | else{ |
||
297 | model_list[i].color=StrToInt(fp); |
||
298 | } |
||
299 | |||
300 | fp=ft; |
||
301 | ft=strchr(ft, ',')+1; |
||
302 | ft[-1]=0; |
||
303 | model_list[i].t_cr=StrToInt(fp); |
||
304 | |||
305 | fp=ft; |
||
306 | ft=strchr(ft, ',')+1; |
||
307 | ft[-1]=0; |
||
308 | model_list[i].x=StrToDouble(fp); |
||
309 | |||
310 | fp=ft; |
||
311 | ft=strchr(ft, ',')+1; |
||
312 | ft[-1]=0; |
||
313 | model_list[i].y=StrToDouble(fp); |
||
314 | |||
315 | fp=ft; |
||
316 | ft=strchr(ft, ',')+1; |
||
317 | ft[-1]=0; |
||
318 | model_list[i].z=StrToDouble(fp); |
||
319 | |||
320 | fp=ft; |
||
321 | ft=strchr(ft, ',')+1; |
||
322 | ft[-1]=0; |
||
323 | model_list[i].r_x=StrToDouble(fp); |
||
324 | |||
325 | fp=ft; |
||
326 | ft=strchr(ft, ',')+1; |
||
327 | ft[-1]=0; |
||
328 | model_list[i].r_y=StrToDouble(fp); |
||
329 | |||
330 | fp=ft; |
||
331 | ft=strchr(ft, ',')+1; |
||
332 | if(!ft || fe |
||
333 | ft=fe; |
||
334 | model_list[i].level=0; |
||
335 | if(mz_min>model_list[i].z) mz_min=model_list[i].z; |
||
336 | if(mz_max |
||
337 | } |
||
338 | ft[-1]=0; |
||
339 | model_list[i].r_z=StrToDouble(fp); |
||
340 | if(ft!=fe){ |
||
341 | fp=ft; |
||
342 | ft=fe; |
||
343 | ft[-1]=0; |
||
344 | model_list[i].level=StrToInt(fp); |
||
345 | } |
||
346 | model_list[i].id_l = list_get_id(model_list[i].name); |
||
347 | } |
||
348 | trans_z = (mz_max-mz_min)/2.0; |
||
349 | scale_o = .5/trans_z; |
||
350 | angle_x = 135.0; |
||
351 | angle_z = -45.0; |
||
352 | |||
353 | return true; |
||
354 | } |
||
355 | |||
356 | void KolibriOnPaint(void); |
||
357 | |||
358 | void __stdcall DrawWindow() |
||
359 | { |
||
360 | asm{ |
||
361 | push ebx |
||
362 | mcall SF_REDRAW,SSF_BEGIN_DRAW |
||
363 | } |
||
364 | KolibriOnPaint(); |
||
365 | asm{ |
||
366 | mcall SF_REDRAW,SSF_END_DRAW |
||
367 | pop ebx |
||
368 | } |
||
369 | } |
||
370 | |||
8849 | IgorA | 371 | bool OpenModel(char* f_path) |
372 | { |
||
373 | FileInfoBlock* file; |
||
374 | unsigned long int k; |
||
375 | |||
376 | file = FileOpen(f_path); |
||
377 | if (!file){ |
||
378 | SetWindowCaption("Error open file ..."); |
||
379 | return false; |
||
380 | } |
||
381 | k = FileGetLength(file); |
||
382 | if (k > 0){ |
||
383 | if(f_data) delete f_data; |
||
384 | f_data = new unsigned char[k]; |
||
385 | if (f_data){ |
||
386 | if (FileRead(file, f_data, k) != k){ |
||
387 | delete f_data; f_data = 0; |
||
388 | } |
||
389 | else{ |
||
390 | init_model(); |
||
391 | draw_3d(); |
||
392 | SetWindowCaption(ofd.openfile_path); |
||
393 | Redraw(1); |
||
394 | } |
||
395 | } |
||
396 | } |
||
397 | FileClose(file); |
||
398 | return (bool)f_data; |
||
399 | } |
||
400 | |||
8824 | IgorA | 401 | bool KolibriOnStart(TStartData &kos_start, TThreadData /*th*/) |
402 | { |
||
403 | kos_start.Left = 10; |
||
404 | kos_start.Top = 40; |
||
405 | kos_start.Width = 640; |
||
406 | kos_start.Height = 480; |
||
407 | kos_start.WinData.WindowColor = 0xFFFFFF; |
||
408 | kos_start.WinData.WindowType = 0x33; // 0x34 - fixed, 0x33 - not fixed |
||
409 | kos_start.WinData.Title = header; |
||
410 | |||
411 | if(LoadLibrary("proc_lib.obj", library_path, "/sys/lib/proc_lib.obj", &import_proc_lib)) |
||
412 | { |
||
413 | ofd.procinfo = procinfo; |
||
414 | ofd.com_area_name = "FFFFFFFF_open_dialog"; |
||
415 | ofd.com_area = 0; |
||
416 | ofd.opendir_path = plugin_path; |
||
417 | ofd.dir_default_path = "/rd/1"; |
||
418 | ofd.start_path = "/rd/1/File managers/opendial"; |
||
419 | ofd.draw_window = DrawWindow; |
||
420 | ofd.status = 0; |
||
421 | ofd.openfile_path = openfile_path; |
||
422 | ofd.filename_area = filename_area; |
||
423 | ofd.filter_area = &filter1; |
||
424 | ofd.x_size = 420; |
||
425 | ofd.x_start = 10; |
||
426 | ofd.y_size = 320; |
||
427 | ofd.y_start = 10; |
||
428 | OpenDialog_Init(&ofd); |
||
429 | } else return false; |
||
430 | if(LoadLibrary("tinygl.obj", library_path, "/sys/lib/tinygl.obj", &import_tinygl)) |
||
431 | { |
||
432 | kosglMakeCurrent(0,0,kos_start.Width,kos_start.Height,&ctx1); |
||
433 | rat_h = kos_start.Height; |
||
434 | rat_h /= kos_start.Width; |
||
435 | angle_dwm = kos_start.Width/180.0; |
||
436 | angle_dhm = kos_start.Height/180.0; |
||
437 | glEnable(GL_DEPTH_TEST); |
||
438 | glClearColor(0.2,0.2,0.2,0.0); |
||
439 | glEnable(GL_NORMALIZE); |
||
440 | //draw_3d(); |
||
8849 | IgorA | 441 | if(init_block()){ |
442 | if(CommandLine[0]) OpenModel(CommandLine); |
||
443 | return true; |
||
444 | } |
||
445 | } |
||
446 | return false; |
||
8824 | IgorA | 447 | } |
448 | |||
449 | void KolibriOnPaint(void) |
||
450 | { |
||
451 | kosglSwapBuffers(); |
||
452 | |||
453 | // If button have ID 1, this is close button |
||
454 | DrawButton(2,0xf0f0f0, 10,10,50,20); |
||
455 | DrawText(20,16,0,"Open"); |
||
456 | } |
||
457 | |||
458 | void KolibriOnButton(long id, TThreadData /*th*/) |
||
459 | { |
||
460 | switch(id){ |
||
461 | case 2: |
||
462 | ofd.type = 0; // 0 - open |
||
463 | OpenDialog_Start(&ofd); |
||
8849 | IgorA | 464 | if(ofd.status==1) OpenModel(ofd.openfile_path); |
8824 | IgorA | 465 | //break; |
466 | }; |
||
467 | } |
||
468 | |||
469 | void KolibriOnKeyPress(TThreadData /*th*/) |
||
470 | { |
||
471 | long key = GetKey(); |
||
472 | switch(key){ |
||
473 | case 178: //Up |
||
474 | angle_x+=delt_size; |
||
475 | draw_3d(); |
||
476 | kosglSwapBuffers(); |
||
477 | break; |
||
478 | case 177: //Down |
||
479 | angle_x-=delt_size; |
||
480 | draw_3d(); |
||
481 | kosglSwapBuffers(); |
||
482 | break; |
||
483 | case 176: //Left |
||
484 | angle_z+=delt_size; |
||
485 | draw_3d(); |
||
486 | kosglSwapBuffers(); |
||
487 | break; |
||
488 | case 179: //Right |
||
489 | angle_z-=delt_size; |
||
490 | draw_3d(); |
||
491 | kosglSwapBuffers(); |
||
492 | //break; |
||
493 | }; |
||
494 | } |
||
495 | |||
496 | void KolibriOnMouse(TThreadData /*th*/) |
||
497 | { |
||
498 | int m = GetMouseButton(); |
||
499 | short m_x_old, m_y_old; |
||
500 | |||
501 | if(m&1 && mouse_drag){ |
||
502 | //mouse l. but. move |
||
503 | m_x_old = mouse_x; |
||
504 | m_y_old = mouse_y; |
||
505 | GetMousePosPicture(mouse_x, mouse_y); |
||
506 | |||
507 | //если курсор движется по оси y (вверх или вниз) то поворот делаем вокруг оси x |
||
508 | angle_x -= (m_y_old - mouse_y) / angle_dwm; |
||
509 | |||
510 | //если курсор движется по оси x (влево или вправо) то поворот делаем вокруг оси z |
||
511 | angle_z -= (m_x_old - mouse_x) / angle_dhm; |
||
512 | |||
513 | draw_3d(); |
||
514 | kosglSwapBuffers(); |
||
515 | } |
||
516 | if(m&0x10000){ |
||
517 | //mouse l. but. up |
||
518 | mouse_drag=false; |
||
519 | } |
||
520 | if(m&0x100){ |
||
521 | //mouse l. but. press |
||
522 | GetMousePosPicture(mouse_x, mouse_y); |
||
523 | if(mouse_x>0 && mouse_y>0) mouse_drag=true; |
||
524 | } |
||
525 | |||
526 | GetMouseScrollData(m_x_old, m_y_old); |
||
527 | if(m_y_old<0 && scale_o<0.5){ |
||
528 | scale_o *= 1.414213562; |
||
529 | draw_3d(); |
||
530 | kosglSwapBuffers(); |
||
531 | } |
||
532 | else if(m_y_old>0 && scale_o>0.005){ |
||
533 | scale_o /= 1.414213562; |
||
534 | draw_3d(); |
||
535 | kosglSwapBuffers(); |
||
536 | } |
||
537 | } |
||
538 | |||
539 | void KolibriOnSize(int window_rect[], TThreadData /*th*/) |
||
540 | { |
||
541 | unsigned short int width, height; |
||
542 | GetClientSize(width, height); |
||
543 | if(!width || !height) return; |
||
544 | if(width<100) width=100; |
||
545 | if(height<80) height=80; |
||
546 | rat_h = (float)height / (float)width; |
||
547 | angle_dwm = (float)width/180.0; |
||
548 | angle_dhm = (float)height/180.0; |
||
549 | glViewport(0, 0, width, height); |
||
550 | draw_3d(); |
||
551 | } |
||
552 | |||
553 | bool KolibriOnClose(TThreadData /*th*/) |
||
554 | { |
||
555 | if(b_data){ |
||
556 | delete b_data; |
||
557 | delete b_list; |
||
558 | } |
||
559 | if(f_data) delete f_data; |
||
560 | if(model_list) delete model_list; |
||
561 | return true; |
||
562 | }80)>100)>0.5){ |