【OpenGL】畫立方體

編寫一個程序,該程序運行時能夠用鼠標的一個按鍵調整立方體的方向,用另外一個按鍵平移立方體,用第三個按鍵縮放立方體。windows

這是題目,個人程序不必定徹底按照這個來。初學OpenGL,對那一堆座標系表示十分混亂,慢慢看吧,有點頭緒了。函數

(一)oop

  1 #include <gl/glut.h>
  2 #include <math.h>
  3 #define GL_PI 3.1415f
  4 
  5 GLfloat xRot = -35.0f;
  6 GLfloat yRot = 15.0f;
  7 GLfloat xMov = 0.0f;
  8 GLfloat winW = 0.0f;
  9 GLfloat winH = 0.0f;
 10 GLfloat zoom = 1.0f;
 11 
 12 void RenderScene(void)
 13 {
 14     glClear(GL_COLOR_BUFFER_BIT);
 15 
 16     glPushMatrix();
 17     glLoadIdentity();
 18     glRotatef(xRot, 1.0f, 0.0f, 0.0f);
 19     glRotatef(yRot, 0.0f, 1.0f, 0.0f);
 20 
 21     // 底面
 22     glBegin(GL_LINE_LOOP);
 23     glVertex3f(0.0f+xMov, 0.0f, 0.0f);
 24     glVertex3f(1.0f+xMov, 0.0f, 0.0f);
 25     glVertex3f(1.0f+xMov, 0.0f, 1.0f);
 26     glVertex3f(0.0f+xMov, 0.0f, 1.0f);
 27     glEnd();
 28 
 29     // 頂面
 30     glBegin(GL_LINE_LOOP);
 31     glVertex3f(0.0f+xMov, 1.0f, 1.0f);
 32     glVertex3f(0.0f+xMov, 1.0f, 0.0f);
 33     glVertex3f(1.0f+xMov, 1.0f, 0.0f);
 34     glVertex3f(1.0f+xMov, 1.0f, 1.0f);
 35     glEnd();
 36 
 37     // 背面
 38     glBegin(GL_LINE_LOOP);
 39     glVertex3f(0.0f+xMov, 0.0f, 0.0f);
 40     glVertex3f(1.0f+xMov, 0.0f, 0.0f);
 41     glVertex3f(1.0f+xMov, 1.0f, 0.0f);
 42     glVertex3f(0.0f+xMov, 1.0f, 0.0f);
 43     glEnd();
 44 
 45     // 前面
 46     glBegin(GL_LINE_LOOP);
 47     glVertex3f(1.0f+xMov, 0.0f, 1.0f);
 48     glVertex3f(0.0f+xMov, 0.0f, 1.0f);
 49     glVertex3f(0.0f+xMov, 1.0f, 1.0f);
 50     glVertex3f(1.0f+xMov, 1.0f, 1.0f);
 51     glEnd();
 52 
 53     // 右面
 54     glBegin(GL_LINE_LOOP);
 55     glVertex3f(1.0f+xMov, 0.0f, 0.0f);
 56     glVertex3f(1.0f+xMov, 0.0f, 1.0f);
 57     glVertex3f(1.0f+xMov, 1.0f, 1.0f);
 58     glVertex3f(1.0f+xMov, 1.0f, 0.0f);
 59     glEnd();
 60 
 61     // 左面
 62     glBegin(GL_LINE_LOOP);
 63     glVertex3f(0.0f+xMov, 0.0f, 0.0f);
 64     glVertex3f(0.0f+xMov, 0.0f, 1.0f);
 65     glVertex3f(0.0f+xMov, 1.0f, 1.0f);
 66     glVertex3f(0.0f+xMov, 1.0f, 0.0f);
 67     glEnd();
 68 
 69     glPopMatrix();
 70     glFlush();
 71 }
 72 void OnReshape(int w, int h)
 73 {
 74     GLfloat aspectRatio = (GLfloat)w/(GLfloat)h;
 75     winW = w;
 76     winH = h;
 77 
 78     glViewport(0,0,w,h);
 79     glMatrixMode(GL_PROJECTION);
 80     glLoadIdentity();
 81     if (w <= h)
 82     {
 83         glOrtho(-3.0f*zoom, 3.0f*zoom, -3.0f*zoom/aspectRatio, 3.0f*zoom/aspectRatio, -10.0f*zoom, 10.0f*zoom);
 84     }
 85     else{
 86         glOrtho(-3.0f*zoom*aspectRatio, 3.0f*zoom*aspectRatio, -3.0f*zoom, 3.0f*zoom, -10.0f*zoom, 10.0f*zoom);
 87     }
 88     glMatrixMode(GL_MODELVIEW);
 89     glLoadIdentity();
 90 }
 91 void OnMouse(int button, int state, int x, int y)
 92 {
 93     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
 94     {
 95         xRot += 1;
 96         yRot += 1;
 97         glutPostRedisplay();
 98     }
 99     else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
100     {
101         xMov -= 0.1;
102         glutPostRedisplay();
103     }
104     else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
105     {
106         zoom += 0.1;
107         OnReshape(winW,winH);
108         glutPostRedisplay();
109     }
110 }
111 void OnKeyUpDown(int key, int x, int y)
112 {
113     if (key == GLUT_KEY_UP){
114         zoom -= 0.1;
115     }
116     else if (key == GLUT_KEY_DOWN){
117         zoom += 0.1;
118     }
119     OnReshape(winW,winH);
120     glutPostRedisplay();
121 }
122 
123 void SetupRC()
124 {
125     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
126     glColor3f(0.0f, 1.0f, 0.0f);
127 }
128 
129 void main(int argc, char **argv)
130 {
131     glutInit(&argc,argv);
132     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
133     glutCreateWindow("Cube");
134     glutDisplayFunc(RenderScene);
135     glutReshapeFunc(OnReshape);
136     glutMouseFunc(OnMouse);
137     glutSpecialFunc(OnKeyUpDown);
138 
139     SetupRC();
140 
141     glutMainLoop();
142 }

這個程序略長,顯得有點笨。手工實現了平移和放大縮小的功能,值得記錄一下。spa

 

(二)code

 1 #include <windows.h>
 2 #include<gl/glut.h>
 3 #include <math.h> 
 4 #include<stdio.h>
 5 
 6 GLfloat angle=0.0f;
 7 GLfloat translate_x=0.0f;
 8 GLfloat zoom=1.0f;
 9 
10 void myDisplay()
11 {
12     glClear (GL_COLOR_BUFFER_BIT);
13     glColor3f (1.0f, 1.0f, 1.0f);
14     glPushMatrix();
15     {
16         glMatrixMode(GL_MODELVIEW);        //切換到模型視圖矩陣
17         glLoadIdentity();
18         glRotatef(angle,1.0f,0.0f,0.0f);
19         glRotatef(angle, 0.0f, 1.0f, 0.0f);
20         glTranslatef(translate_x,0.0f,0.0f);
21         glScalef (zoom, zoom, zoom);
22         glutWireCube(1.5); //畫立方體
23     }
24     glPopMatrix();
25     glFlush();
26 }
27 
28 void reshape(int w,int h) 
29 { 
30     glViewport (0, 0, (GLsizei) w, (GLsizei) h);  //調整視口位置和大小
31     glMatrixMode (GL_PROJECTION);//切換到投影矩陣
32     glLoadIdentity();//加載單位陣至投影矩陣
33     if (w <= h){
34         glOrtho(-3.0f, 3.0f, -3.0f/(w/h), 3.0f/(w/h), -3.0f, 3.0f);
35     }
36     else{
37         glOrtho(-3.0f*w/h, 3.0f*w/h, -3.0f, 3.0f, -3.0f, 3.0f);
38     }
39 
40     glMatrixMode (GL_MODELVIEW);
41     glLoadIdentity();
42 }
43 
44 void OnMouse(int button, int state, int x, int y)
45 {
46     //鼠標左鍵
47     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
48     {
49         angle += 10.0f;
50         glutPostRedisplay();
51     }
52     //鼠標右鍵
53     else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
54     {
55         translate_x+=0.1f;
56         glutPostRedisplay();
57     }
58     //鼠標滾輪
59     else if (state == GLUT_UP && button == GLUT_WHEEL_DOWN)
60     {
61         if(zoom>0)
62             zoom-=0.1f;
63         glutPostRedisplay();
64     }
65     else if(state == GLUT_UP && button == GLUT_WHEEL_UP)
66     {
67         zoom+=0.1f;
68         glutPostRedisplay();
69     }
70 }
71 
72 
73 int main(int argc, char** argv)
74 {
75     glutInit(&argc, argv);
76     glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
77     glutInitWindowPosition(100,100);
78     glutInitWindowSize(500,500); 
79     glutCreateWindow("cube");
80     
81     glutDisplayFunc(myDisplay); 
82     glutReshapeFunc(reshape);
83     glutMouseFunc( OnMouse );
84     glutMainLoop();
85     return 0;
86 }

採用了OpenGL的一些庫函數實現,投影仍是採用平行投影,表示對透視投影函數gluPerspective以及視點變化函數gluLookAt不是很清楚。blog

(三)ci

 1 #include <windows.h>
 2 #include<gl/glut.h>
 3 #include <math.h> 
 4 #include<stdio.h>
 5 
 6 GLfloat angle=0.0f;
 7 GLfloat translate_x=0.0f;
 8 GLfloat zoom=1.0f;
 9 
10 void myDisplay()
11 {
12     glClear (GL_COLOR_BUFFER_BIT);
13     glColor3f (1.0f, 1.0f, 1.0f);
14     glPushMatrix();
15 
16     glMatrixMode(GL_MODELVIEW);        //切換到模型視圖矩陣
17     glLoadIdentity(); 
18     gluLookAt (0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); //設置相機參數
19     glRotatef(angle, 0.0f, 1.0f, 0.0f);
20     glTranslatef(translate_x,0.0f,0.0f);
21     glScalef (zoom, zoom, zoom);
22     glutWireCube(0.5); //畫立方體
23 
24     glPopMatrix();
25     glFlush();
26 }
27 
28 void reshape(int w,int h) 
29 { 
30     glViewport (0, 0, (GLsizei) w, (GLsizei) h);  //調整視口位置和大小
31     glMatrixMode (GL_PROJECTION);//切換到投影矩陣
32     glLoadIdentity();//加載單位陣至投影矩陣
33     gluPerspective(30,w/h,5,20);
34     glMatrixMode (GL_MODELVIEW);
35     glLoadIdentity();
36 }
37 
38 void OnMouse(int button, int state, int x, int y)
39 {
40     //鼠標左鍵
41     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
42     {
43         angle += 10.0f;
44         glutPostRedisplay();
45     }
46     //鼠標右鍵
47     else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
48     {
49         //xMov -= 0.1;
50         translate_x+=0.1f;
51         glutPostRedisplay();
52     }
53     //鼠標滾輪
54     else if (state == GLUT_UP && button == GLUT_WHEEL_DOWN)
55     {
56         if(zoom>0)
57             zoom-=0.1f;
58         glutPostRedisplay();
59     }
60     else if(state == GLUT_UP && button == GLUT_WHEEL_UP)
61     {
62         zoom+=0.1f;
63         glutPostRedisplay();
64     }
65 }
66 
67 
68 int main(int argc, char** argv)
69 {
70     glutInit(&argc, argv);
71     glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
72     glutInitWindowPosition(100,100);
73     glutInitWindowSize(500,500); 
74     glutCreateWindow("cube");
75     
76     glutDisplayFunc(myDisplay); 
77     glutReshapeFunc(reshape);
78     glutMouseFunc( OnMouse );
79     glutMainLoop();
80     return 0;
81 }

用的是透視投影。個人理解是gluPerspective()和gluLookAt()要配合使用,兩者中的相機位置要一致。it

相關文章
相關標籤/搜索