码迷,mamicode.com
首页 > 其他好文 > 详细

OpenGL——3D Rendering Pipeline

时间:2015-06-03 21:18:58      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

  1 // Computer Graphics: HW3
  2 // 3D Transformation: 
  3 
  4 
  5 #include <iostream>
  6 #include <string>
  7 #include <cstdlib>
  8 #include <cmath>
  9 #include <cstdio>
 10 #include <vector>
 11 #include <gl/glut.h>
 12 #include <iomanip>
 13 #include <fstream>
 14 
 15 using namespace std;
 16 
 17 const int dimension = 4;
 18 const double PI = acos(-1);
 19 const double eps = 0.0000001;
 20 
 21 //定义向量 
 22 struct vec {
 23     float x;
 24     float y;
 25     float z;
 26     vec(float _x=0, float _y=0, float _z=0):x(_x), y(_y), z(_z){}
 27 };
 28 
 29 //向量的叉乘并化为单位向量 
 30 vec cross(vec a, vec b)
 31 {
 32     vec res;
 33     res.x = a.y * b.z - b.y * a.z;
 34     res.y = -(a.x * b.z - b.x * a.z);
 35     res.z = a.x * b.y - b.x * a.y;
 36     float l = sqrt(res.x*res.x+res.y*res.y+res.z*res.z);
 37     res.x = res.x / l;
 38     res.y = res.y / l;
 39     res.z = res.z / l;
 40     return res;
 41 }
 42 
 43 //定义多边形的点 
 44 struct poly_point {        
 45     float x;
 46     float y;
 47     float z;
 48     float w;
 49     poly_point(){ x=0; y=0; z=0; w=1;}
 50     poly_point(float _x, float _y, float _z, float _w=1){ x=_x; y=_y; z=_z; w=_w;}
 51 };
 52 
 53 //定义矩阵用作变换操作  
 54 struct mat {                    
 55     float m[4][4];
 56     mat()
 57     {
 58         memset(m,0,sizeof(m));
 59         m[0][0]=m[1][1]=m[2][2]=m[3][3]=1;        
 60     }
 61     void reset_mat()
 62     {
 63         memset(m,0,sizeof(m));
 64         m[0][0]=m[1][1]=m[2][2]=m[3][3]=1;
 65     }
 66 };
 67 
 68 //新建各种变换矩阵,初始化为单位矩阵 
 69 mat T,S,R,Rx,Ry,Rz,Sh,TM, M,GRM,EM,Mirrorx, PM, WTVM;
 70 
 71 //重载*号实现矩阵乘法
 72 mat operator * (mat a, mat b)        
 73 {
 74     mat c;
 75     memset(c.m,0,sizeof(c.m));    //注意要先初始化为0 
 76     for(int i=0; i<dimension; i++)
 77         for(int j=0; j<dimension; j++)
 78             for(int k=0; k<dimension; k++)
 79                 c.m[i][j] += (a.m[i][k]*b.m[k][j]);        
 80     return c;
 81 }
 82 
 83 //定义矩阵乘以向量 
 84 poly_point mat_mul_vec(mat t, poly_point pp)
 85 {
 86     poly_point res;
 87     res.x = t.m[0][0]*pp.x+t.m[0][1]*pp.y+t.m[0][2]*pp.z+t.m[0][3]*pp.w;
 88     res.y = t.m[1][0]*pp.x+t.m[1][1]*pp.y+t.m[1][2]*pp.z+t.m[1][3]*pp.w;
 89     res.z = t.m[2][0]*pp.x+t.m[2][1]*pp.y+t.m[2][2]*pp.z+t.m[2][3]*pp.w;
 90     res.w = t.m[3][0]*pp.x+t.m[3][1]*pp.y+t.m[3][2]*pp.z+t.m[3][3]*pp.w;
 91     return res;
 92 }
 93 //输出矩阵用作测试 
 94 void print_mat(mat M)
 95 {
 96     for(int i=0; i<dimension; i++)
 97     {
 98         for(int j=0; j<dimension; j++)
 99             printf("%.2lf ", M.m[i][j]);
100         printf("\n");
101     }
102     printf("\n");
103 }
104 
105 int num_tm=0;                                                //记录输入object的个数 
106 poly_point poly_vertex[10][2000], observe[10][2000];        //保存原来的输入的多边形的点,保存经历所有变换后的点用于输出 
107 int poly_face[4000][4];                                        //保存多边形的面用于画线 
108 string file_name;                                            //读取asc文件的文件名 
109 float VL,VR,VB,VT;                                            //viewport的坐标                 
110 float Near, Far, FOV;                                        //求PM投影矩阵用到的参数 
111 int height, width, n;                                        //n为多边形组成每个面的点的个数 
112 int num_vertex, num_face;                                    //记录输入的多边形的点的个数和面的个数 
113 void displayFunc(void);
114 void ReadInput(bool& IsExit);
115 
116 //hw3
117 void scale(float sx, float sy, float sz);                    //scale放缩变换    
118 void rotate(float rx, float ry, float rz, int i=0);            //rotate旋转变换 
119 void translate(float tx, float ty, float tz);                //translate平移变换 
120 void reset(); 
121 //获得EM和PM矩阵 
122 void observer(float PX, float PY, float PZ, float CX, float CY, float CZ, float Tilt, float Near, float Far, float FOV);
123 void view(float VL, float VR, float VB, float VT);            //获得WTVM矩阵 
124 void display();                                                //做observer和viewport变换并画点 
125 void read_asc_file();                                        //读取asc文件 
126 void transform(mat t);                                        //输入一个矩阵,对poly_vertex里的每个点做一次变换 
127 void projection(float AR, float Near, float Far, float FOV);//投影变换,即获得PM矩阵 
128 void per_div();                                                //perspective divide
129 void transform_observe(mat t);                                //对observe中的每个点进行矩阵变换 
130 void DrawWindow();                                            //画框框 
131 void print_mat(mat t);                                        //输出矩阵测试 
132 void print();                                                //输出点测试 
133 
134 //hw1中已经实现的函数 
135 void drawDot(int x, int y, float r, float g, float b);    
136 void drawLine1(int x0, int x1, int y0, int y1, bool xy_interchange);
137 void drawLine2(int x0, int x1, int y0, int y1, bool xy_interchange);
138 void drawLine3(int x0, int x1, int y0, int y1, bool xy_interchange);
139 void drawLine4(int x0, int x1, int y0, int y1, bool xy_interchange);
140 void DrawLines_4(int x1, int y1, int x2, int y2);
141 
142 void myKeyboard(unsigned char key, int x, int y) 
143 {
144     cout << "KEYYYY" << endl;
145     switch(key) {
146     // Draw dots with ‘d‘ or ‘D‘
147     case q:
148     case Q:
149         //glutMouseFunc(Mymouse);
150           exit(0);
151           break;
152     }
153 }
154 void ReadInput(bool& IsExit)
155 {
156     float sx,sy,sz, tx,ty,tz, rx,ry,rz;
157     float PX, PY, PZ, CX, CY, CZ, Tilt; 
158     string command,comment;
159     cin>>command;
160     if (command=="scale")
161     {
162         cout<<command<<endl;
163         cin>>sx>>sy>>sz;
164         scale(sx,sy,sz);    
165     }
166     else if (command=="rotate")
167     {
168         cout<<command<<endl;
169         cin>>rx>>ry>>rz;
170         rotate(rx,ry,rz,0);    
171     }
172     else if (command=="translate")
173     {
174         cout<<command<<endl;
175         cin>>tx>>ty>>tz;
176         translate(tx,ty,tz);    
177     }
178     else if (command=="reset")
179     {
180         cout<<command<<endl;
181         //reset();
182     }
183     else if (command=="observer")
184     {
185         cout<<command<<endl;
186         cin>>PX>>PY>>PZ>>CX>>CY>>CZ>>Tilt>>Near>>Far>>FOV;
187         observer(PX,PY,PZ,CX,CY,CZ,Tilt,Near,Far,FOV);
188     }
189     else if (command=="viewport")
190     {
191         cout<<command<<endl;
192         cin>>VL>>VR>>VB>>VT;
193         view(VL,VR,VB,VT);
194     }
195     else if (command=="end")
196     {
197         cout<<command<<endl;
198         IsExit=true;
199         //exit(0);
200     }
201     else if (command=="#")
202     {
203         getline(cin, comment);
204     }
205     else if (command=="display")
206     {
207         cout<<command<<endl;
208         display();
209     }
210     else if (command=="object")
211     {
212         cout<<command<<endl;
213         cin >> file_name;
214         read_asc_file();
215     }
216 }
217 
218 
219 // Display function
220 void displayFunc(void){
221   
222   freopen("test.in", "r", stdin);
223   bool IsExit;
224   IsExit=false;
225   // clear the entire window to the background color
226   glClear(GL_COLOR_BUFFER_BIT);
227   while (!IsExit)
228   {
229     glClearColor(0.0, 0.0, 0.0, 0.0); 
230 //    redraw();
231   // draw the contents!!! Iterate your object‘s data structure!
232   // flush the queue to actually paint the dots on the opengl window
233     glFlush();
234     ReadInput(IsExit);
235   }
236  // infile.close();
237   //exit(0);
238 }
239 
240 
241 // Main
242 void main(int ac, char** av) {
243   //initial();
244   
245   int winSizeX, winSizeY;
246   string name;
247   
248   if(ac == 3) {
249     winSizeX = atoi(av[1]);
250     winSizeY = atoi(av[2]);
251 //        cout<<"Done";
252   }
253   else { // default window size
254     winSizeX = 800;
255     winSizeY = 600;
256 
257   }
258   
259     
260 //  cout<<"Please input file name:"<<endl;
261 //  cin>>name;
262 //  infile.open(name.c_str());
263  // exit(0);
264  // infile.open("inp3.txt");
265 // infile.open(av[1]);
266   width  = winSizeX;
267   height = winSizeY;
268 
269   // initialize OpenGL utility toolkit (glut)
270   glutInit(&ac, av);
271 
272   // single disply and RGB color mapping
273   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
274   glutInitWindowSize(winSizeX, winSizeY);      // set window size
275   glutInitWindowPosition(0, 0);                // set window position on screen
276   glutCreateWindow("Lab2 Window");       // set window title
277   
278   // set up the mouse and keyboard callback functions
279    // register the keyboard action function
280   glutKeyboardFunc(myKeyboard);
281   // displayFunc is called whenever there is a need to redisplay the window,
282   // e.g., when the window is exposed from under another window or when the window is de-iconified
283   glutDisplayFunc(displayFunc); // register the redraw function
284   
285   // set background color
286   glClearColor(0.0, 0.0, 0.0, 0.0);     // set the background to black
287   glClear(GL_COLOR_BUFFER_BIT); // clear the buffer
288 
289   // misc setup
290   glMatrixMode(GL_PROJECTION);  // setup coordinate system
291   glLoadIdentity();
292   gluOrtho2D(0, winSizeX, 0, winSizeY);
293   glShadeModel(GL_FLAT);
294   glFlush();
295   glutMainLoop();
296 }
297 
298 
299 void scale(float sx, float sy, float sz)
300 {
301     S.m[0][0]=sx;    S.m[1][1]=sy;    S.m[2][2]=sz;
302     TM=S*TM;
303 }
304 void rotate(float rx, float ry, float rz, int i)
305 {
306     if(i == 0)
307     {
308         rx = rx * PI / 180.0;    ry = ry * PI / 180.0;    rz = rz * PI / 180.0;
309     }
310     Rx.m[1][1]=cos(rx);    Rx.m[2][2]=cos(rx);    Rx.m[1][2]=-sin(rx);    Rx.m[2][1]=sin(rx);
311     Ry.m[0][0]=cos(ry);    Ry.m[2][2]=cos(ry);    Ry.m[0][2]=sin(ry);        Ry.m[2][0]=-sin(ry);
312     Rz.m[0][0]=cos(rz);    Rz.m[1][1]=cos(rz);    Rz.m[0][1]=-sin(rz);    Rz.m[1][0]=sin(rz);
313     R = Rz*Ry*Rz;
314     TM=R*TM;
315 }
316 void translate(float tx, float ty, float tz)
317 {
318     T.m[0][3]=tx;    T.m[1][3]=ty;    T.m[2][3]=tz;
319     TM=T*TM;
320 }
321 void reset()
322 {
323     /*T.reset_mat(),S.reset_mat(),R.reset_mat(),Rx.reset_mat(),Ry.reset_mat(),Rz.reset_mat(),
324     Sh.reset_mat(),TM.reset_mat(), M.reset_mat(),GRM.reset_mat(),EM.reset_mat(),Mirrorx.reset_mat(), 
325     PM.reset_mat(), WTVM.reset_mat();*/
326     for(int j=0; j<num_tm; j++)
327     {
328         for(int i=1; i<=num_vertex; i++) 
329         {
330             observe[j][i].x = poly_vertex[j][i].x; 
331             observe[j][i].y = poly_vertex[j][i].y;
332             observe[j][i].z = poly_vertex[j][i].z;
333         }
334     }
335     
336 }
337 void observer(float PX, float PY, float PZ, float CX, float CY, float CZ, float Tilt, float Near, float Far, float FOV)
338 {
339     //GRM
340     translate(-PX,-PY,-PZ);
341     //print_mat(T);
342     float x = CX-PX;
343     float y = CY-PY;
344     float z = CZ-PZ;
345     //Tilt=Tilt*PI/180.0;
346     float l=sqrt(x*x+y*y+z*z);
347     vec v(x,y,z);
348     vec t(0,1,sin(Tilt*PI/180.0));
349     vec v3;
350     v3.x = v.x/l; v3.y = v.y/l; v3.z = v.z/l;
351     vec v1=cross(v,t);
352     vec v2=cross(v1,v3);
353     GRM.m[0][0]=v1.x;    GRM.m[0][1]=v1.y;    GRM.m[0][2]=v1.z;
354     GRM.m[1][0]=v2.x;    GRM.m[1][1]=v2.y;    GRM.m[1][2]=v2.z;
355     GRM.m[2][0]=v3.x;    GRM.m[2][1]=v3.y;    GRM.m[2][2]=v3.z;
356     //GRM.m[1][2]=-0.71;
357     //float ry = abs(asin(x/sqrt(x*x+y*y+z*z)));
358     /*float ry = abs(asin(x/sqrt(x*x+y*y+z*z)));
359     float rx = atan(y/sqrt(pow(x,2.0)+pow(z,2.0)));
360     float rz = Tilt*PI/180.0;
361 
362     rotate(rx,ry,rz,1);
363     print_mat(Ry);
364     print_mat(Rx);
365     print_mat(Rz);
366     Mirrorx.m[0][0]=-1;
367     GRM = Mirrorx*Rz*Rx*Ry;*/
368     //GRM.m[1][1]=0.71;
369     //GRM.m[1][2]=-0.71;
370     //GRM.m[2][1]=-0.71;
371     //GRM.m[2][2]=-0.71;
372     //Mirrorx.m[0][0]=-1;
373     printf("GRM\n");
374     print_mat(GRM);
375     EM = Mirrorx*GRM*T;
376     //print_mat(EM);
377     transform_observe(EM);
378     //print();
379 
380     //projection(1.33,Near,Far,FOV);
381 }
382 void view(float VL, float VR, float VB, float VT)
383 {
384     DrawWindow();
385     float WL=-1, WR=1, WB=-1, WT=1;
386     translate(-WL, -WB, 0);    
387     WTVM = T * WTVM;    
388     scale((VR-VL)/(WR-WL), (VT-VB)/(WT-WB), 1);
389     WTVM = S * WTVM;    
390     translate(VL, VB, 0);    
391     WTVM = T * WTVM;
392     printf("WTVM\n");
393     print_mat(WTVM);
394     //transform_observe(WTVM);
395     
396 }
397 void display()
398 {
399     projection((VR-VL)/(VT-VB),Near,Far,FOV);
400     transform_observe(WTVM);
401     cout << "num_tm: " << num_tm << endl;
402     //cout << num_vertex << " " << num_face << endl;
403     //print();
404     for(int k=0; k<num_tm; k++)
405     {
406         for(int i=0; i<num_face; i++) 
407         {
408             for(int j=0; j<n-1; j++)
409                 DrawLines_4(observe[k][poly_face[i][j]].x, observe[k][poly_face[i][j]].y, observe[k][poly_face[i][j+1]].x, observe[k][poly_face[i][j+1]].y);
410             DrawLines_4(observe[k][poly_face[i][n-1]].x, observe[k][poly_face[i][n-1]].y, observe[k][poly_face[i][0]].x, observe[k][poly_face[i][0]].y);
411         }
412     }
413     reset();
414     EM.reset_mat();
415     PM.reset_mat();
416     WTVM.reset_mat();
417 }
418 void read_asc_file()
419 {
420     num_tm++;
421     cout << file_name << endl;
422     ifstream fin(file_name);
423     fin >> num_vertex >> num_face;
424     cout << num_vertex << " " << num_face << endl;
425     // read vertex one by one
426     for(int i=1; i<=num_vertex; i++) 
427     {
428         fin >> poly_vertex[num_tm-1][i].x >> poly_vertex[num_tm-1][i].y >> poly_vertex[num_tm-1][i].z;
429     }
430     // read face one by one
431     for(int i=0; i<num_face; i++) 
432     {
433         fin >> n;
434         for(int j=0; j<n; j++)
435             fin >> poly_face[i][j];
436     }
437     
438     transform(TM);//
439     reset();
440     TM.reset_mat();
441     
442     //print();
443 }
444 
445 void transform(mat t)
446 {
447     for(int i=1; i<=num_vertex; i++) 
448         poly_vertex[num_tm-1][i] = mat_mul_vec(t, poly_vertex[num_tm-1][i]);
449 }
450 void transform_observe(mat t)
451 {
452     for(int j=0; j<num_tm; j++)
453     {
454         for(int i=1; i<=num_vertex; i++) 
455             observe[j][i] = mat_mul_vec(t, observe[j][i]);
456     }
457 }    
458 
459 void projection(float AR, float Near, float Far, float FOV)
460 {
461     //PM
462     FOV=FOV*PI/180.0;
463     float Y=Far*tan(FOV);
464     float H=Near*tan(FOV);
465     PM.m[1][1]=AR;
466     PM.m[2][2]=Y/(Y-H)*tan(FOV);
467     PM.m[2][3]=Y*H/(H-Y)*tan(FOV);
468     PM.m[3][2]=tan(FOV);
469     PM.m[3][3]=0;
470     /*PM.m[1][1]=AR;
471     PM.m[2][2]=0.58;
472     PM.m[3][2]=0.58;
473     PM.m[3][3]=0;*
474     PM.m[2][3]=-0.58;*/
475     print_mat(PM);
476     transform_observe(PM);
477 
478     per_div();    //
479 }
480 
481 void per_div()
482 {
483     for(int j=0; j<num_tm; j++)
484     {
485         for(int i=1; i<=num_vertex; i++) 
486         {
487             observe[j][i].x /= observe[j][i].w;
488             observe[j][i].y /= observe[j][i].w;
489             observe[j][i].z /= observe[j][i].w;
490             observe[j][i].w /= observe[j][i].w;
491         }
492     }
493     
494 }
495 
496 void DrawWindow()
497 {
498     DrawLines_4(VL, VB, VR, VB);
499     DrawLines_4(VR, VB, VR, VT);
500     DrawLines_4(VR, VT, VL, VT);
501     DrawLines_4(VL, VT, VL, VB);
502 }
503 
504 void print()
505 {
506     for(int j=0; j<num_tm; j++)
507     {
508         for(int i=1; i<=num_vertex; i++)
509             cout <<  poly_vertex[j][i].x << " " << poly_vertex[j][i].y << " " << poly_vertex[j][i].z << endl;
510     }
511 }
512 
513 
514 
515 
516 
517 
518 
519 
520 
521 
522 
523 
524 
525 
526 
527 
528 
529 
530 
531 
532 
533 
534 
535 
536 
537 
538 
539 
540 
541 
542 
543 
544 
545 
546 
547 
548 //////////////////////////////////////////////////////////////////////////////////////hw1///////////////////////////////////////////////////////////
549 void DrawLines_4(int x1, int y1, int x2, int y2) //判断画哪一种线
550 {
551     if(x1 >= x2)
552     {
553         if(y1 >= y2)
554         {
555             swap(x1, x2);
556             swap(y1, y2);
557             if((y2-y1) >= (x2-x1))            
558                 drawLine2(x1, y1, x2, y2, 1);    
559             else
560                 drawLine1(x1, y1, x2, y2, 1);
561         }
562         else
563         {
564             if((y2-y1) >= (x1-x2))
565                 drawLine3(x1, y1, x2, y2, 1);
566             else
567                 drawLine4(x2, y2, x1, y1, 1);
568         }                
569     }
570     else
571     {
572         if(y2 >= y1)
573         {
574             if((y2-y1) <= (x2-x1))
575                 drawLine1(x1, y1, x2, y2, 1);
576             else
577                 drawLine2(x1, y1, x2, y2, 1);
578         }
579         else
580         {
581             if((y1-y2) <= (x2-x1))
582                 drawLine4(x1, y1, x2, y2, 1);
583             else
584                 drawLine3(x2, y2, x1, y1, 1);
585         }
586     }
587     
588     glFlush();
589 }
590 
591 // draw a dot at location with integer coordinates (x,y), and with color (r,g,b)
592 void drawDot(int x, int y, float r, float g, float b) 
593 {
594     glBegin(GL_POINTS);
595   
596     // set the color of dot
597     glColor3f(r, g, b);
598   
599     // invert height because the opengl origin is at top-left instead of bottom-left
600     glVertex2i(x ,  height-y);
601   
602     glEnd();
603 }
604 
605 // Draw line for dx>0 and dy>0
606 void drawLine1(int x1, int y1, int x2, int y2, bool xy_interchange) //0-45度
607 {
608     //cout << "Drawing Line1!" << endl;
609     int x = x1;
610     int y = y1;    
611 
612     int a = y2 - y1;
613     int b = x1 - x2;
614     int d = 2 * a + b;
615     int IncE = 2 * a;
616     int IncNE = 2 * (a + b);
617 
618     while(x <= x2)
619     {
620         if(d <= 0)
621         {
622             x++;
623             d += IncE;
624         }
625         else
626         {
627             x++;
628             y++;
629             d += IncNE;
630         }
631         drawDot(x, height-y, 0.0, 0.0, 10.0);
632         
633     }
634 }
635 
636 // Draw line for dx>0 and dy<0
637 void drawLine2(int x1, int y1, int x2, int y2, bool xy_interchange) //45-90度
638 {
639     //cout << "Drawing Line2!" << endl;
640     //转换为0-45度的情况
641     swap(x2, y2);
642     swap(x1, y1);
643 
644     int x = x1;
645     int y = y1;
646     
647     int a = y2 - y1;
648     int b = x1 - x2;
649     int d = 2 * a + b;
650     int IncE = 2 * a;
651     int IncNE = 2 * (a + b);
652 
653     while(x <= x2)
654     {
655         if(d <= 0)
656         {
657             x++;
658             d += IncE;
659         }
660         else
661         {
662             x++;
663             y++;
664             d += IncNE;
665         }
666         drawDot(y, height-x, 0.0, 0.0, 10.0);
667         
668     }    
669 }
670 
671 // Draw line for dx<0 and dy>0
672 void drawLine3(int x1, int y1, int x2, int y2, bool xy_interchange) //90-135度
673 {
674     //cout << "Drawing Line3!" << endl;
675     swap(x2, y2);
676     swap(x1, y1);
677     y1 = -y1;
678     y2 = -y2;
679     int x = x1;
680     int y = y1;
681 
682     int a = y2 - y1;
683     int b = x1 - x2;
684     int d = 2 * a + b;
685     int IncE = 2 * a;
686     int IncNE = 2 * (a + b);
687 
688     while(x <= x2)
689     {
690         if(d <= 0)
691         {
692             x++;
693             d += IncE;
694         }
695         else
696         {
697             x++;
698             y++;
699             d += IncNE;
700         }
701         drawDot(-y, height-x, 0.0, 0.0, 10.0);
702         
703     }
704 }
705 
706 // Draw line for dx<0 and dy>0
707 void drawLine4(int x1, int y1, int x2, int y2, bool xy_interchange) //135-180度
708 {
709     //cout << "Drawing Line4!" << endl;
710     y1 = -y1;
711     y2 = -y2;
712     int x = x1;
713     int y = y1;
714     
715     int a = y2 - y1;
716     int b = x1 - x2;
717     int d = 2 * a + b;
718     int IncE = 2 * a;
719     int IncNE = 2 * (a + b);
720 
721     while(x <= x2)
722     {
723         if(d <= 0)
724         {
725             x++;
726             d += IncE;
727         }
728         else
729         {
730             x++;
731             y++;
732             d += IncNE;
733         }
734         drawDot(x, height+y, 0.0, 0.0, 10.0);
735         
736     }
737 }

 

OpenGL——3D Rendering Pipeline

标签:

原文地址:http://www.cnblogs.com/dominjune/p/4550162.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!