glPushMatrix()和glPopMatrix()以及glLoadIdentity()的理解

本文介绍了OpenGL中使用glLoadIdentity()重置当前矩阵的原因,并通过实例解释了如何利用glPushMatrix()和glPopMatrix()确保矩阵变换不影响后续操作。同时展示了Translate()和Rotate()函数在3D空间中的应用。

glLoadIdentity()重置当前矩阵,为什么要PushMatrix(),然后PopMatrix(),因为是由于是对矩阵进行变换,这样操作不至

于影响后面的矩阵操作。

Translate()每一次操作都把当前所在的位置作为原点。Rotate()每一次操作都是相对于当前原点的(而不是屏幕的中央)。

#include <windows.h> #include <GL/gl.h> #include <gl/glu.h> #include <gl/glut.h> void init(void) { glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_SMOOTH); glClearDepth(1.0f); } void display(void) { glClear( GL_COLOR_BUFFER_BIT ); glShadeModel( GL_SMOOTH ); //现在原点绘制一个红色正方形 glColor3f( 1.0, 0.0, 0.0 ); glRectf( -0.05, -0.05, 0.05, 0.05 ); //glPushMatrix(); //变换--沿x轴移动 glTranslatef( 1.2, 0.0, 0.0 ); // glLoadIdentity(); // glPopMatrix(); //再绘制一个正方形 glColor3f( 0.0, 1.0, 0.0 ); //glRectf( -0.05, -0.05, 0.05, 0.05 );//这时,当我们还想在同样位置绘制时,却发现已经偏移 glFlush(); glFlush(); } void reshape(int w,int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0); else glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10.0,10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void mouse(int button,int state,int x,int y)//鼠标函数 { switch(button) { case GLUT_LEFT_BUTTON: //按下左键 if(state==GLUT_DOWN) { } break; case GLUT_MIDDLE_BUTTON: //按下左键 if(state==GLUT_DOWN) { } break; case GLUT_RIGHT_BUTTON: //按下左键 if(state==GLUT_DOWN) { } break; default: break; } } void keyboard(unsigned char key,int x,int y) { switch(key) { case 27: exit(0); break; default: break; } glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(50,50); glutCreateWindow("测试"); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

参考文章:http://blog.sina.com.cn/s/blog_602c65870100e703.html

有了freeglut.libfreeglut.dll为什么小熊猫c++的编译器会报错:[错误] ld returned 1 exit status #include <GL/glut.h> #include <cmath> #include <cstdio> // 游戏状态 float basketballPos[3] = {0.0f, 1.0f, 0.0f}; float basketPos[3] = {0.0f, 3.0f, -5.0f}; int score = 0; bool isShooting = false; float velocity = 0.0f; float angle = 45.0f; float time = 0.0f; void init() { glEnable(GL_DEPTH_TEST); glClearColor(0.53f, 0.81f, 0.98f, 1.0f); // 天空蓝背景 } void drawBasketball() { glColor3f(1.0f, 0.5f, 0.0f); // 橙色 glPushMatrix(); glTranslatef(basketballPos[0], basketballPos[1], basketballPos[2]); glutSolidSphere(0.3f, 32, 32); glPopMatrix(); } void drawBasket() { // 篮板 glColor3f(0.8f, 0.8f, 0.8f); glPushMatrix(); glTranslatef(basketPos[0], basketPos[1], basketPos[2]); glScalef(2.0f, 1.5f, 0.1f); glutSolidCube(1.0f); glPopMatrix(); // 篮筐 glColor3f(1.0f, 0.0f, 0.0f); glPushMatrix(); glTranslatef(basketPos[0], basketPos[1]-0.3f, basketPos[2]); glutSolidTorus(0.05f, 0.3f, 16, 16); glPopMatrix(); } void displayScore() { glColor3f(1.0f, 1.0f, 1.0f); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, 400, 0, 300); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); char buffer[50]; snprintf(buffer, sizeof(buffer), "Score: %d", score); glRasterPos2i(10, 280); for (char* c = buffer; *c != '\0'; c++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c); } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } void updatePhysics() { if (isShooting) { time += 0.016f; // 约60FPS // 抛物线运动公式 basketballPos[0] = velocity * time * cos(angle * 3.14159f / 180.0f); basketballPos[1] = velocity * time * sin(angle * 3.14159f / 180.0f) - 0.5f * 9.8f * time * time; basketballPos[2] = -velocity * time * 0.5f; // 碰撞检测 if (fabs(basketballPos[0] - basketPos[0]) < 0.3f && fabs(basketballPos[1] - (basketPos[1]-0.3f)) < 0.2f && fabs(basketballPos[2] - basketPos[2]) < 0.3f) { score++
03-29
Windows有了freeglut.libfreeglut.dll(存在C:\windows\system32)为什么小熊猫c++的编译器会报错:[错误] ld returned 1 exit status#include <GL/glut.h> #include <cmath> #include <cstdio> // 游戏状态 float basketballPos[3] = {0.0f, 1.0f, 0.0f}; float basketPos[3] = {0.0f, 3.0f, -5.0f}; int score = 0; bool isShooting = false; float velocity = 0.0f; float angle = 45.0f; float time = 0.0f; void init() { glEnable(GL_DEPTH_TEST); glClearColor(0.53f, 0.81f, 0.98f, 1.0f); // 天空蓝背景 } void drawBasketball() { glColor3f(1.0f, 0.5f, 0.0f); // 橙色 glPushMatrix(); glTranslatef(basketballPos[0], basketballPos[1], basketballPos[2]); glutSolidSphere(0.3f, 32, 32); glPopMatrix(); } void drawBasket() { // 篮板 glColor3f(0.8f, 0.8f, 0.8f); glPushMatrix(); glTranslatef(basketPos[0], basketPos[1], basketPos[2]); glScalef(2.0f, 1.5f, 0.1f); glutSolidCube(1.0f); glPopMatrix(); // 篮筐 glColor3f(1.0f, 0.0f, 0.0f); glPushMatrix(); glTranslatef(basketPos[0], basketPos[1]-0.3f, basketPos[2]); glutSolidTorus(0.05f, 0.3f, 16, 16); glPopMatrix(); } void displayScore() { glColor3f(1.0f, 1.0f, 1.0f); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, 400, 0, 300); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); char buffer[50]; snprintf(buffer, sizeof(buffer), "Score: %d", score); glRasterPos2i(10, 280); for (char* c = buffer; *c != '\0'; c++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c); } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } void updatePhysics() { if (isShooting) { time += 0.016f; // 约60FPS // 抛物线运动公式 basketballPos[0] = velocity * time * cos(angle * 3.14159f / 180.0f); basketballPos[1] = velocity * time * sin(angle * 3.14159f / 180.0f) - 0.5f * 9.8f * time * time; basketballPos[2] = -velocity * time * 0.5f; // 碰撞检测 if (fabs(basketballPos[0] - basketPos[0]) < 0.3f && fabs(basketballPos[1] - (basketPos[1]-0.3f)) < 0.2f && fabs(basketballPos[2] - basketPos[2]) < 0.3f) { score++; isShooting = false; } // 重置位置 if (basketballPos[1] < 0.0f) { isShooting = false; basketballPos[0] = 0.0f; basketballPos[1] = 1.0f; basketballPos[2] = 0.0f; } } } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // 设置摄像机 gluLookAt(0.0f, 5.0f, 10.0f, // 摄像机位置 0.0f, 2.0f, 0.0f, // 观察点 0.0f, 1.0f, 0.0f); // 上方向 drawBasket(); drawBasketball(); displayScore(); glutSwapBuffers(); } void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (float)w/h, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); } void keyboard(unsigned char key, int x, int y) { switch(key) { case ' ': if (!isShooting) { isShooting = true; time = 0.0f; velocity = 10.0f; angle = 45.0f; } break; case 27: // ESC exit(0); } glutPostRedisplay(); } void timer(int value) { updatePhysics(); glutPostRedisplay(); glutTimerFunc(16, timer, 0); // 约60FPS } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 600); glutCreateWindow("3D Basketball Game"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutTimerFunc(0, timer, 0); glutMainLoop(); return 0; }
03-29
为什么下面的程序会报错:[错误] ld returned 1 exit status #include <GL/glut.h> #include <cmath> #include <cstdio> // 游戏状态 float basketballPos[3] = {0.0f, 1.0f, 0.0f}; float basketPos[3] = {0.0f, 3.0f, -5.0f}; int score = 0; bool isShooting = false; float velocity = 0.0f; float angle = 45.0f; float time = 0.0f; void init() { glEnable(GL_DEPTH_TEST); glClearColor(0.53f, 0.81f, 0.98f, 1.0f); // 天空蓝背景 } void drawBasketball() { glColor3f(1.0f, 0.5f, 0.0f); // 橙色 glPushMatrix(); glTranslatef(basketballPos[0], basketballPos[1], basketballPos[2]); glutSolidSphere(0.3f, 32, 32); glPopMatrix(); } void drawBasket() { // 篮板 glColor3f(0.8f, 0.8f, 0.8f); glPushMatrix(); glTranslatef(basketPos[0], basketPos[1], basketPos[2]); glScalef(2.0f, 1.5f, 0.1f); glutSolidCube(1.0f); glPopMatrix(); // 篮筐 glColor3f(1.0f, 0.0f, 0.0f); glPushMatrix(); glTranslatef(basketPos[0], basketPos[1]-0.3f, basketPos[2]); glutSolidTorus(0.05f, 0.3f, 16, 16); glPopMatrix(); } void displayScore() { glColor3f(1.0f, 1.0f, 1.0f); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0, 400, 0, 300); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); char buffer[50]; snprintf(buffer, sizeof(buffer), "Score: %d", score); glRasterPos2i(10, 280); for (char* c = buffer; *c != '\0'; c++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c); } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } void updatePhysics() { if (isShooting) { time += 0.016f; // 约60FPS // 抛物线运动公式 basketballPos[0] = velocity * time * cos(angle * 3.14159f / 180.0f); basketballPos[1] = velocity * time * sin(angle * 3.14159f / 180.0f) - 0.5f * 9.8f * time * time; basketballPos[2] = -velocity * time * 0.5f; // 碰撞检测 if (fabs(basketballPos[0] - basketPos[0]) < 0.3f && fabs(basketballPos[1] - (basketPos[1]-0.3f)) < 0.2f && fabs(basketballPos[2] - basketPos[2]) < 0.3f) { score++; isShooting = false; } // 重置位置 if (basketballPos[1] < 0.0f) { isShooting = false; basketballPos[0] = 0.0f; basketballPos[1] = 1.0f; basketballPos[2] = 0.0f; } } } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // 设置摄像机 gluLookAt(0.0f, 5.0f, 10.0f, // 摄像机位置 0.0f, 2.0f, 0.0f, // 观察点 0.0f, 1.0f, 0.0f); // 上方向 drawBasket(); drawBasketball(); displayScore(); glutSwapBuffers(); } void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (float)w/h, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); } void keyboard(unsigned char key, int x, int y) { switch(key) { case ' ': if (!isShooting) { isShooting = true; time = 0.0f; velocity = 10.0f; angle = 45.0f; } break; case 27: // ESC exit(0); } glutPostRedisplay(); } void timer(int value) { updatePhysics(); glutPostRedisplay(); glutTimerFunc(16, timer, 0); // 约60FPS } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 600); glutCreateWindow("3D Basketball Game"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutTimerFunc(0, timer, 0); glutMainLoop(); return 0; }
最新发布
03-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值