close

plymodel.jpg

 

 

這次主要是練習load ply model 再把它呈現出來,

基本上只是將模型資料讀出來儲存,然後根據資訊將每一個polygon描繪出來

由下面程式碼中的void LoadPly(char *file_name,int style); 完成

style可以選擇用哪種方式描繪..,point或是polygon.......

另外一開始主要是希望這函式以後要用直接一拿來就可以直接使用,

所以變成每次描繪模型時都要重新在讀取資料,這樣一來東西一多執行效率會變很差

要變快的話,可以將儲存的資料存成全域變數,

之後就不用再一直重新讀取資料了,只要讀取一次就好

然後程式裡面有些lighting部分,其實lighting還蠻不熟的,

所以只是在網路上找個範例然後讓這次程式更漂亮一點

 

   1: /*
   2: 操作說明:
   3: 鍵盤按下
   4: r=會變成紅色          
   5: g=會變成綠色
   6: b=會變成藍色
   7: p=ploygon組成
   8: l=line組成
   9: model本身會自動旋轉 
  10: */
  11:  
  12: #include <iostream>
  13: #include <fstream>
  14: #include <string.h>
  15: #include <GL/glut.h>
  16: #include <math.h>
  17:  
  18: using namespace std;
  19:  
  20: void LoadPly(char *file_name,int style);//讀取並畫出ply函式 
  21:  
  22: double r_ang=0.5;//旋轉角度變數 
  23: double R=255.0, G=0.0, B=0.0;//顏色儲存變數 
  24: int style=GL_POLYGON;//畫出model的方式 
  25:  
  26: /*lighting 變數*/
  27: const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
  28: const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
  29: const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  30: const GLfloat light_position[] = { 2.0f, 5.0f, 15.0f, 0.0f };
  31:     
  32: const GLfloat mat_ambient[]    = { 0.0f, 0.0f, 0.0f, 1.0f };
  33: const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
  34: const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
  35: const GLfloat high_shininess[] = { 1.0f };
  36:  
  37:  
  38: void LoadPly(char *file_name,int style)
  39: {
  40:  ifstream fin ( file_name, ios_base::in );//開檔 
  41:  
  42:  
  43:  if ( !fin.is_open ( ) )
  44:  { 
  45:   cout << "Cannot read the file." << endl;
  46:   cout << "Please check again." << endl;
  47:   exit(0);
  48:  }
  49:  
  50:  string str;
  51:  int vertex, face;
  52:  char ch;
  53:  
  54:     /*讀取header*/
  55:  while ( !fin.eof ( ) ){
  56:   fin.get ( ch );
  57:   if( ch != ' ' && ch != '\t' && ch != '\n' ){
  58:    str.push_back ( ch );   
  59:   }
  60:   else
  61:   {
  62:             //取得vertex個數 
  63:             if(str == "vertex")
  64:             {
  65:                 str.clear ( );
  66:                 getline ( fin, str, '\n' ); 
  67:                 vertex = atoi(str.c_str());       
  68:             }
  69:             //取得face個數 
  70:             else if(str == "face")
  71:             {
  72:                 str.clear ( );
  73:                 getline ( fin, str, '\n' );  
  74:                 face = atoi(str.c_str());             
  75:             }
  76:             else if(str == "end_header"){
  77:                  str.clear ( );     
  78:                  break;     
  79:             }
  80:             else
  81:                 str.clear ( );             
  82:         }
  83:  
  84:  } 
  85:     //動態產生array 
  86:     double *vertex_arrayX = new double[vertex];
  87:     double *vertex_arrayY = new double[vertex];
  88:     double *vertex_arrayZ = new double[vertex];
  89:     
  90:     int pos = 0;
  91:     int counter = 0;
  92:     double number;
  93:     double max_edge = 0;
  94:     static double temp_max = 0;
  95:      
  96:     /*讀取Vertex*/ 
  97:     while ( !fin.eof ( ) ){
  98:           
  99:   fin.get ( ch );
 100:   if( ch != ' ' && ch != '\t' && ch != '\n' ){
 101:    str.push_back ( ch );
 102:    }
 103:    else
 104:   { 
 105:             if(counter == vertex){
 106:               break;                    
 107:             }
 108:             /*儲存vertex資料*/
 109:             if(str == ""){
 110:               continue;            
 111:             }           
 112:             else if(pos%3 == 0){
 113:               number = atof(str.c_str());               
 114:               vertex_arrayX[counter] = number; 
 115:               str.clear ( );        
 116:             }
 117:             else if(pos%3 == 1){
 118:               number = atof(str.c_str());                   
 119:               vertex_arrayY[counter] = number;   
 120:               str.clear ( );      
 121:             }
 122:             else if(pos%3 == 2){
 123:               number = atof(str.c_str());                   
 124:               vertex_arrayZ[counter] = number;  
 125:               str.clear ( );  
 126:               counter++;     
 127:             }
 128:             pos++;    
 129:             
 130:             //紀錄最大的邊 
 131:             if(abs((int)number) > max_edge) 
 132:               max_edge = abs((int)number);          
 133:         }   
 134:    }
 135:     
 136:     int point[4];
 137:     int i = 0;
 138:     counter = 0;    
 139:     
 140:    /*畫Polygon*/  
 141:    while ( !fin.eof ( ) ){
 142:           
 143:   fin.get ( ch );
 144:   if( ch != ' ' && ch != '\t' && ch != '\n' ){
 145:    str.push_back ( ch );
 146:         }
 147:         else
 148:         {
 149:             if(counter == face){
 150:               break;                    
 151:             }
 152:             
 153:             if(ch == '\n'){
 154:               
 155:               // 計算法線向量 (打光)    
 156:               GLfloat vc1[3],vc2[3];
 157:               GLfloat a,b,c;
 158:               GLdouble r;                   
 159:               vc1[0]= vertex_arrayX[point[2]] - vertex_arrayX[point[1]]; 
 160:               vc1[1]= vertex_arrayY[point[2]] - vertex_arrayY[point[1]]; 
 161:               vc1[2]= vertex_arrayZ[point[2]] - vertex_arrayZ[point[1]];                
 162:               vc2[0]= vertex_arrayX[point[3]] - vertex_arrayX[point[1]]; 
 163:               vc2[1]= vertex_arrayY[point[3]] - vertex_arrayY[point[1]]; 
 164:               vc2[2]= vertex_arrayZ[point[3]] - vertex_arrayZ[point[1]];                
 165:               a = vc1[1] * vc2[2] - vc2[1] * vc1[2];
 166:               b = vc2[0] * vc1[2] - vc1[0] * vc2[2];
 167:               c = vc1[0] * vc2[1] - vc2[0] * vc1[1];
 168:               r = sqrt( a * a + b* b + c * c);                
 169:               float nor[3];        
 170:               nor[0] = a / r;
 171:               nor[1] = b / r;
 172:               nor[2] = c / r;
 173:               
 174:               glNormal3f(nor[0],nor[1],nor[2]); 
 175:               
 176:               //畫出所有face
 177:               glBegin(style); 
 178:                             
 179:               for(int i=1;i<=point[0];i++){      
 180:                  glVertex3f(vertex_arrayX[point[i]], vertex_arrayY[point[i]],vertex_arrayZ[point[i]]);      
 181:               }
 182:               
 183:            glEnd();
 184:               
 185:               counter++;                    
 186:             }
 187:             else if(str == ""){
 188:               continue;            
 189:             }
 190:             else {                 
 191:               point[i%4] = atoi(str.c_str());                 
 192:               i++;              
 193:               str.clear ( );       
 194:             }     
 195:         }
 196:    }
 197:    fin.close();    
 198:    
 199:    //調整視角
 200:    if(max_edge > temp_max){
 201:        glLoadIdentity ();            
 202:        glOrtho(-(max_edge*2), (max_edge*2), -(max_edge*2), (max_edge*2), -(max_edge*2), (max_edge*2)); 
 203:    }
 204:    temp_max = max_edge;     
 205: }
 206:  
 207: void display(){     
 208:     
 209:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);      
 210:   
 211:     glRotatef(r_ang, 0.0, 1.0, 1.0);   
 212:     glColor3f(R,G,B);       
 213:      LoadPly("ant.ply",style);    
 214:     glFlush(); 
 215:     glutSwapBuffers(); 
 216:      
 217: }
 218:  
 219: void init()
 220: {
 221:  glClearColor (0.0, 0.0, 0.0, 1.0);      
 222:  glLoadIdentity ();    
 223:  glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);   
 224: }
 225:  
 226: void keyboard(unsigned char key, int x, int y)
 227: {
 228:    //按esc離開
 229:    switch (key) {
 230:       case 27:
 231:          exit(0);
 232:          break;
 233:       case 'r':
 234:          R=255;G=0;B=0;   
 235:          break; 
 236:       case 'g':
 237:          R=0;G=255;B=0;   
 238:          break;
 239:       case 'b':
 240:          R=0;G=0;B=255;  
 241:          break;
 242:       case 'p':
 243:          style = GL_POLYGON;
 244:          break;
 245:       case 'l':
 246:          style = GL_LINES;          
 247:          break;
 248:                                 
 249:    }
 250:    glutPostRedisplay();   
 251: }
 252:  
 253: void idle(void){
 254:     glutPostRedisplay();
 255: }
 256:  
 257: int main(int argc, char** argv){
 258:  
 259:     glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
 260:     glutInitWindowSize (600, 600); 
 261:     glutInitWindowPosition (300, 50);  
 262:     glutCreateWindow("Load Ply Model");  
 263:     glutDisplayFunc(display);
 264:     glutIdleFunc(idle);
 265:     glutKeyboardFunc(keyboard);//偵測keyboard
 266:     init();     
 267:     
 268:     //使用lighting 相關函式
 269:     glEnable(GL_CULL_FACE);
 270:     glCullFace(GL_BACK);
 271:     glEnable(GL_DEPTH_TEST);
 272:     glDepthFunc(GL_LESS);
 273:     glEnable(GL_LIGHT0);
 274:     glEnable(GL_NORMALIZE);
 275:     glEnable(GL_COLOR_MATERIAL);
 276:     glEnable(GL_LIGHTING);
 277:     glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
 278:     glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
 279:     glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
 280:     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 281:     glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
 282:     glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
 283:     glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
 284:     glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);    
 285:        
 286:     glutMainLoop();
 287:  
 288:     return EXIT_SUCCESS;
 289: }
 290:  

拜託.gif

arrow
arrow
    全站熱搜

    tinylin 發表在 痞客邦 留言(0) 人氣()