矩阵管理函数:glLoadIdentity()是把当前活动矩阵设置为单位矩阵。
栈处理函数:glPushMatrix()是将当前活动的变换矩阵复制一份,压入栈顶;glPopMatrix()是破坏当前活动的变换矩阵,将栈顶的矩阵弹出,设置为当前矩阵。栈中最底下默认有一个单位矩阵,因此glPopMatrix()只有在栈中矩阵数量>=2时才能使用。
9.8和9.9节书中提到,使用栈处理函数比矩阵管理函数更高效,尤其是在栈函数使用硬件实现时(这句话没有理解)。拿7.4节的例子(介绍矩阵操作在7.9节中)进行说明glPushMatrix/glPopMatrix比glLoadIdentity更高效。因此写了一段代码测试这两种用法的效率,结论是两种方式效率相当,循环调用9999999次时,glLoadIdentity用时60s,而glPushMatrix用时61s。不知道是调用方式不对还是没有使用硬件实现导致的。
glPushMatrix/glPopMatrix在需要对观察或几何变换做多次修改时更适用,可以随时调出前一次的矩阵,而不用设置为单位矩阵后重新计算变换矩阵。
1 #include <GLUT/GLUT.h> 2 #include <iostream> 3 #include <ctime> 4 5 void init (void) 6 { 7 glClearColor(1.0, 1.0, 1.0, 0.0); 8 glMatrixMode(GL_PROJECTION); 9 glLoadIdentity(); 10 gluOrtho2D(-225.0, 225.0, -225.0, 225.0); 11 } 12 13 void displayFcn (void) 14 { 15 glClear(GL_COLOR_BUFFER_BIT); 16 glMatrixMode(GL_MODELVIEW); 17 18 time_t nowtime = time(NULL); 19 for(int i = 0; i < 9999999; i++) 20 { 21 glColor3f(0.0, 1.0, 0.0); 22 glRotatef(90.0, 0.0, 0.0, 1.0); 23 glRecti(50, 100, 200, 150); 24 glLoadIdentity(); 25 } 26 time_t nowtime1 = time(NULL); 27 std::cout << "original: " << nowtime1 - nowtime << std::endl; // 60sec 28 29 30 time_t nowtime2 = time(NULL); 31 for(int i = 0; i < 9999999; i++) 32 { 33 glPushMatrix(); 34 glColor3f(0.0, 1.0, 0.0); 35 glRotatef(90.0, 0.0, 0.0, 1.0); 36 glRecti(50, 100, 200, 150); 37 glPopMatrix(); 38 } 39 time_t nowtime3 = time(NULL); 40 std::cout << "optimized: " << nowtime3 - nowtime2 << std::endl; //61sec 41 42 glFlush(); 43 } 44 45 int main(int argc, char * argv[]) 46 { 47 glutInit(&argc, argv); 48 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 49 glutInitWindowPosition(50, 50); 50 glutInitWindowSize(600.0, 600.0); 51 glutCreateWindow("Geometric Transformation Compare with Stack"); 52 53 init(); 54 glutDisplayFunc(displayFcn); 55 56 glutMainLoop(); 57 58 return 0; 59 }
补充:OpenGL的硬件实现和软件实现:
参考:http://www.huati365.com/post/1002167
“
OpenGL的实现可以是软件实现,也可以是硬件实现。软件实现是对OpengGL函数调用时作出的响应并创建二维或三维图像的函数库,那么硬件实现则是通过设置能够绘制图形或图像的图形卡驱动程序。一般来说,硬件实现要比软件实现快得多。我们都应该熟悉,在Windows上,是由图形设备接口将图形或图像显示在屏幕上或是其他显示设备上的。OpenGL的实现就软件实现来说,在Windows上会根据程序命令的要求,生成相应的图形或图像,然后会将这个图形或图像移交给图形设备接口,由图形设备接口将图形或是图像显示在我们的屏幕上或是其他显示设备。
OpenGL的硬件实现与软件实现稍微有些不同,硬件实现是将OpenGL的调用传递给硬件驱动程序,而硬件驱动程序不会将生成的图形或图像传递给图形设备接口,而是直接与显示设备通信,直接将图形或图像结果传递给显示器或其他显示设备。
”