首页 > 代码库 > 【OpenGL】画立方体

【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 onm ouse(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 onm ouse(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( onm ouse );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 onm ouse(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( onm ouse );79     glutMainLoop();80     return 0;81 }

用的是透视投影。我的理解是gluPerspective()和gluLookAt()要配合使用,二者中的相机位置要一致。

【OpenGL】画立方体