Subversion Repositories Kolibri OS

Rev

Rev 8824 | Rev 8875 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <kolibri.h>
  2. #include <kos_heap.h>
  3. #include <kos_file.h>
  4. #include <kos_unpack.h>
  5. #include <load_lib.h>
  6. #include <l_proc_lib.h>
  7. #include <l_tinygl.h>
  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<b_count;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<c_count;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<m_count;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<list->p_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<k){
  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<k){
  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<C_COUNT_MAX){
  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<fe) m_count++;
  275.         }while(ft && ft<fe);
  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<m_count;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<ft){
  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<model_list[i].z) mz_max=model_list[i].z;
  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.  
  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.  
  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();
  441.                 if(init_block()){
  442.                         if(CommandLine[0]) OpenModel(CommandLine);
  443.                         return true;
  444.                 }
  445.         }
  446.         return false;
  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);
  464.                 if(ofd.status==1) OpenModel(ofd.openfile_path);
  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. }