Subversion Repositories Kolibri OS

Rev

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;ip_cou;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
}