close
這次主要是練習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:
全站熱搜
留言列表