Chinaunix首页 | 论坛 | 博客
  • 博客访问: 819684
  • 博文数量: 117
  • 博客积分: 2583
  • 博客等级: 少校
  • 技术积分: 1953
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-06 22:58
个人简介

Coder

文章分类
文章存档

2013年(1)

2012年(10)

2011年(12)

2010年(77)

2009年(13)

2008年(4)

分类: C/C++

2012-05-16 07:28:31


OpenGL是图形硬件的一种软件接口。OpenGL的设计目标就是作为一种流线型的、独立于硬件的接口,可以在许多不同的硬件平台上实现。为了实现这个目标,OpenGL并未包含用于执行窗口任务或者获取输入之类的函数。反之,必须通过具体的窗口系统来控制OpenGL应用程序所使用的特定硬件。OpenGL也并没有提供用于描述三维物体模型的高级函数。在OpenGL中,程序员必须根据一些为数不多的基本几何图元(如点、直线和多边形)来创建所需要的模型。

OpenGL工具库(GLU)提供了许多建模功能,例如二次曲面以及NURBS曲线和曲面。GLU是所有OpenGL实现的一个标准组成部分。

OpenGL对场景中的图像进行渲染时所执行的主要操作为:
1、根据几何图元创建形状,从而建立物体的数学描述。(OpenGL把点、直线、多边形和位图作为基本的图元。)
2、在三维空间中排列物体,并选择观察符合场景的有利视角。
3、计算所有物体的颜色。颜色可以是由应用程序明确指定的,也可以是根据特定的光照条件所确定的,或者是通过纹理贴到物体的表面而获得的,或者是上述这三种操作的混合产物。
4、把物体的数学描述以及与物体相关的颜色信息转换为屏幕上的像素。这个过程称为光栅化(rasterization)。

GLUT, OpenGL实用工具库
OpenGL包含了许多渲染函数,但它们的设计目的是独立于任何窗口系统或操作系统。因此,它并没有包含打开窗口或者从键盘或鼠标读取事件的函数。GLUT可用来简化打开窗口、检测输入等任务。GLUT还包含了一些函数,用于创建一些更为复杂的三维物体,例如球体、圆环面和茶壶等。

窗口管理
GLUT通过5个函数执行初始化窗口所需要的任务:
- glutInit(int *argc, char **argv)对GLUT进行初始化,并处里所有的命令行参数(对于X系统,这将是类似 -display和-geometry的选项)。glutInit()应该在调用其他任何GLUT函数之前被调用。
- glutInitDisplayMode(unsigned int mode)指定了是使用RGBA模式还是颜色索引模式。另外还可以指定是使用单缓冲还是使用双缓冲窗口。如果使用颜色索引模式,就需要把一些颜色加载到颜色映射表中,这个任务可以用glutSetColor()来完成。最后,还可以使用这个函数来表示希望窗口拥有相关联的深度、模板、多重采样和/或累积缓冲区。
- glutInitWindowPosition(int x, int y)指定了窗口左上角的屏幕位置。
- glutInitWindowSize(int width, int height)指定了窗口的大小(以像素为单位)。
int glutCreateWindow(char *string)创建一个支持OpenGL渲染环境的窗口。这个函数返回一个唯一的标识符,标识了这个窗口。在调用glutMainLoop()函数之前,这个窗口并没有被显示。

显示回调函数
glutDisplayFunc(void (*func)(void))函数,每当GLUT确定一个窗口的内容需要重新显示时,通过glutDisplayFunc() 所注册的那个回调函数就会被执行。应次应该把重绘场景所需要的所有代码都放在这个显示回调函数里。

如果程序修改了窗口的内容,有时候可能需要调用glutPostRedisplay(),这个函数将会指示glutMainLoop()调用已注册的显示回调函数。

运行程序
最后,必须调用glutMainLoop()来启动程序。所有已经创建的窗口将会在这时显示,对这些窗口的渲染也开始生效。事件处理循环开始启动,已注册的显示回调函数被触发。一旦进入循环,它就永远不会退出。

OpenGL的Hello World

点击(此处)折叠或打开

  1. #include <GL/glut.h>

  2. #define kWindowWidth 400
  3. #define kWindowHeight 300

  4. void initGL(void) {
  5.     /* Select clearing (background) color */
  6.     glClearColor(0.0, 0.0, 0.0, 0.0);

  7.     /* Initialize viewing values */
  8.     glMatrixMode(GL_PROJECTION);
  9.     glLoadIdentity();
  10.     glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
  11. }

  12. void DrawGLScene(void) {
  13.     /* clear all pixel */
  14.     glClear(GL_COLOR_BUFFER_BIT);

  15.     /* draw white polygon (rectangle) with corners at
  16.      * (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
  17.      */
  18.     glColor3f(0, 0.5, 1.0);
  19.     glBegin(GL_POLYGON);
  20.         glVertex3f(0.25, 0.25, 0.0);
  21.         glVertex3f(0.75, 0.25, 0.0);
  22.         glVertex3f(0.75, 0.75, 0.0);
  23.         glVertex3f(0.25, 0.75, 0.0);
  24.     glEnd();

  25.     /* don't wait
  26.      * start processing buffered OpenGL routines
  27.      */
  28.     glFlush();
  29. }

  30. void ResizeGLScene(int width, int height) {

  31. }

  32. /*
  33.  * Declare initial window size, position, and display mode
  34.  * (single buffer and RGBA). Open window with "hello"
  35.  * in its title bar. Call initialization routines.
  36.  * Register callback function to display graphics.
  37.  * Enter main loop and process events.
  38.  */
  39. int main(int argc, char **argv) {
  40.     glutInit(&argc, argv);
  41.     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  42.     glutInitWindowSize(kWindowWidth, kWindowHeight);
  43.     glutInitWindowPosition(100, 100);
  44.     glutCreateWindow(argv[0]);

  45.     initGL();

  46.     glutDisplayFunc(DrawGLScene);
  47.     glutReshapeFunc(ResizeGLScene);
  48.     glutMainLoop();

  49.     return 0;
  50. }

程序运行的前提当然为系统有OpenGL的一个实现,系统中存在GLUT library。Ubuntu上,编译时可使用如下的编译命令:

点击(此处)折叠或打开

  1. $ g++ -lglut -o OpenGLTest01 main.cpp

处理输入事件
可以使用下面这些函数注册一些回调函数,当指定的事件发生时,这些函数便会被调用:
- glutReshapeFunc(void (*func)(int w, int h))表示当窗口的大小发生改变时应该采取什么行动。
- glutKeyboardFunc(void (*func)(unsigned char key, int x, int y))和glutMouseFunc(void (*func)(int button, int state, int x, int y))允许把键盘上的一个键或鼠标上的一个按钮与一个函数相关联,当这个键或按钮被按下或释放时,这个函数就会被调用。
- glutMotionFunc(void (*func)(int x, int y))注册了一个函数,当按下一个鼠标按钮移动鼠标时,这个函数就会被调用。

空闲处理
可以在glutIdleFunc(void (*func)(void))回调函数中指定一个函数,如果不存在其他尚未完成的事件,就执行这个函数。这个回调函数接受一个函数指针作为它的唯一参数。如果向它传递NULL(0),就相当于禁用这个函数。


动画 = 重绘 + 交换

点击(此处)折叠或打开

  1. #include <GL/glut.h>
  2. #include <stdlib.h>

  3. #define kWindowWidth 400
  4. #define kWindowHeight 300

  5. static GLfloat spin = 0.0;

  6. void initGL(void) {
  7.     /* Select clearing (background) color */
  8.     glClearColor(0.0, 0.0, 0.0, 0.0);
  9.     glShadeModel(GL_FLAT);
  10. }

  11. void DrawGLScene(void) {
  12.     /* clear all pixel */
  13.     glClear(GL_COLOR_BUFFER_BIT);

  14.     glPushMatrix();
  15.     glRotatef(spin, 0.0, 0.0, 1.0);
  16.     glColor3f(0, 0.5, 1.0);
  17.     glRectf(-0.75, -0.75, 0.75, 0.75);
  18.     glPopMatrix();
  19.     glutSwapBuffers();
  20. }

  21. void spinDisplay(void) {
  22.     spin = spin + 2.0;
  23.     if(spin > 360.0)
  24.         spin = spin - 360;
  25.     glutPostRedisplay();
  26. }

  27. void ResizeGLScene(int width, int height) {
  28.     glViewport(0, 0, (GLsizei) width, (GLsizei) height);
  29.     glMatrixMode(GL_PROJECTION);

  30.     glLoadIdentity();
  31.     glOrtho(-2.0, 2.0, -2.0, 2.0, -1.0, 1.0);
  32.     glMatrixMode(GL_MODELVIEW);
  33.     glLoadIdentity();
  34. }

  35. void mouse(int button, int state, int x, int y) {
  36.     switch(button) {
  37.     case GLUT_LEFT_BUTTON:
  38.         if(state == GLUT_DOWN)
  39.             glutIdleFunc(spinDisplay);
  40.         break;
  41.     case GLUT_MIDDLE_BUTTON:
  42.         if(state == GLUT_DOWN)
  43.             glutIdleFunc(NULL);
  44.         break;
  45.     default:
  46.         break;
  47.     }
  48. }

  49. /*
  50.  * Request double buffer dispaly mode.
  51.  * Register mouse input callback functions.
  52.  */
  53. int main(int argc, char **argv) {
  54.     glutInit(&argc, argv);
  55.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  56.     glutInitWindowSize(kWindowWidth, kWindowHeight);
  57.     glutInitWindowPosition(100, 100);
  58.     glutCreateWindow(argv[0]);

  59.     initGL();

  60.     glutDisplayFunc(DrawGLScene);
  61.     glutReshapeFunc(ResizeGLScene);
  62.     glutMouseFunc(mouse);
  63.     glutMainLoop();

  64.     return 0;
  65. }




阅读(3269) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~