【OpenGL】画立方体

编写一个程序,该程序运行时可以用鼠标的一个按键调整立方体的方向,用另一个按键平移立方体,用第三个按键缩放立方体。

这是题目,我的程序不一定完全按照这个来。初学OpenGL,对那一堆坐标系表示十分混乱,慢慢看吧,有点头绪了。

(一)

  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 }

这个程序略长,显得有点笨。手工实现了平移和放大缩小的功能,值得记录一下。

(二)

 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不是很清楚。

(三)

 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()要配合使用,二者中的相机位置要一致。

原文地址:https://www.cnblogs.com/raul-ac/p/4030909.html