一、 工作原理
(1)、OpenGL流水线
![](/images/cppblog_com/cass/opengl.jpg)
命名约定:![](/images/cppblog_com/cass/opengl2.jpg)
(2)、显示形状
函数功能:设置初始显示模式。
函数原型:void glutInitDisplayMode(unsigned int mode);
mode : mode可取以下值或其组合:
值 对应宏定义 意义
GLUT_RGB 0x0000 指定 RGB 颜色模式的窗口
GLUT_RGBA 0x0000 指定 RGBA 颜色模式的窗口
GLUT_INDEX 0x0001 指定颜色索引模式的窗口
GLUT_SINGLE 0x0000 指定单缓存窗口
GLUT_DOUBLE 0x0002 指定双缓存窗口
GLUT_ACCUM 0x0004 窗口使用累加缓存
GLUT_ALPHA 0x0008 窗口的颜色分量包含 alpha 值
GLUT_DEPTH 0x0010 窗口使用深度缓存
GLUT_STENCIL 0x0020 窗口使用模板缓存
GLUT_MULTISAMPLE0x0080 指定支持多样本功能的窗口
GLUT_STEREO 0x0100 指定立体窗口
GLUT_LUMINANCE 0x0200 窗口使用亮度颜色模型
2、再整形回调函数(逻辑笛卡儿坐标映射为物理屏幕的象素坐标)
glutReshapeFunc(ChangeSize); //
①、利用函数glViewport 定义视区:
void glViewport(GLint x,GLint y,GLsizei width,Glsizei height);
②、利用函数glOrtho 定义修剪区
void glOrtho(Gldouble left,Gldouble right,Gldouble bottom,Gldouble top,Gldouble near,Gldouble far);
调用函数glOrtho 之前,调用下面函数使坐标系“复位”。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //重置当前指定的矩阵为单位矩阵,使坐标系“复位”
3、 显示回调函数
glutDisplayFunc(RenderScene);
显示回调函数RenderScene 是调用OpenGL 渲染函数的地方。
① 、实际清除
glClear(GL_COLOR_BUFFER_BIT); //用当前清除色清除颜色缓冲区,即设定窗口的背景色
② 指定当前绘图颜色 //调用glColor3f 设置
③ 图形绘制
④ 刷新队列 //glFlush()用于让所有尚未执行的OpenGL 命令都被执行
由上面的程序可以看出,一个OpenGL 程序的基本结构主要包括以下几个部分:
(1)定义窗口:包括指定窗口的大小、位置、显示模式以及设置各种回调函数;
(2)初始化设置:清除各种缓冲区,并设置各种OpenGL 状态,例如设置背景色,打开光照,设置纹理等等。
(3)绘制场景:利用OpenGL 函数绘制场景中的各种物体。
(4)变换:指定场景中需要显示的范围并指定由修剪区到视区的变换。
(5)结束运行:清除命令缓冲区,执行OpenGL 命令。
(3)显示动画
glutTimerFunc(unsigned int msecs,(*func) (int value),int value);
该函数与其他的回调函数不一样的地方在于该函数只会被激发一次。为了实现连
续的动画,必须在定时器函数中再次重新设置定时器回调函数。
注意1:显示回调函数时的擦新方式。
glFlush()与glutSwapBuffers()的区别
简单地说glFlush就是强制刷新吧,要知道OPENGL是使用一条渲染管线线性处理命令的,一般情况下,我们提交给OPENGL的指令并不是马上送到驱动程序里执行的,而是放到一个缓冲区里面,等这个缓冲区满了再一次过发到驱动程序里执行;很多时候只有几条指令是填充不满那个缓冲区的,这就是说这些指令根本没有被发送到驱动里,所以我们要调用glFlush来强制把这些指令送到驱动里进行处理。
glutSwapBuffers其实就是交换缓冲区啦,估计是你的程序使用的是双缓冲技术吧;用了这种技术的话,你所有的绘制都是绘制到一个后台的缓冲区里面的,如果不交换缓冲区,就看不到绘制的东西了,就这么回事~
二、 绘图
1、 绘点
glBegin(GL_POINTS); //的定点到放在函数glBegin 和glEnd 之间,由函数glBegin 的参数指定绘制图元的类型,
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(10.0f,10.0f,10.0f);
glEnd();
glBegin的参数详解:
GL_POINTS 单一点
GL_LINES 两顶点创建一直线
GL_LINE_STRIP 创建线条,上一点是下一点的延伸
GL_LINE_LOOP 画线条,最后一点与第一点相连。
GL_TRIANGLES 每三个顶点指定一个新三角形,并用当前颜色填充
GL_TRIANGLE_STRIP 创建相邻的三角形
![](/images/cppblog_com/cass/opengl3.jpg)
注意:可以使用void glPointSize(GLfloat size);来设计像素点大小
通常使用下面的代码来获取点大小的范围和它们之间最小的中间值:
GLfloat sizes[2]; //保存绘制点的尺寸范围
GLfloat step; //保存绘制点尺寸的步长
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);
2、 绘制直线
glBegin(GL_LINES); // GL_LINES每两个顶点定义一条直线
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(10.0f,10.0f,10.0f);
glEnd();
注意:
① 、void glLineWidth(GLfloat width) //设置线宽
② 、glEnable(GL_LINE_STIPPLE); //修改模式
③ 、glLineStipple(GLint factor,GLushort pattern);//将factor 设为2 会使模式中的每一位代表一行中2 个象素的开或关。pattern 为0X00FF,可以画出点划线
3、 多边形的绘制
注意事项:
① 、绕法
如果要反转OpenGL 的默认行为,可以调用函数:
glFrontFace(GL_CW);
② 、明暗处理
void glShadeModel(GLenum mode);
GL_FLAT //平面明暗处理
GL_SMOOTH //光滑明暗处理
③ 、多边形的模式
glPolygonMode(Glenum face,Glenum mode);
face
GL_FRONT,GL_BACK 或GL_FRONT_AND_BACK 指定多边形的哪一面受模式改变的影响
参数mode 用于指定新的绘图模式。
GL_FILL 是默认值,生成填充的多边形;
GL_LINE 生成多边形的轮廓;
GL_POINT 只画出顶点。
GL_LINE 和GL_POINT 绘制的点和线受glEdgeFlag 所设置边缘标记的影响。
④ 、多边形的绘制规则
⑤
4、 多面体的绘制
1. 深度测试
为了启用深度测试,只要调用:
glEnable(GL_DEPTH_TEST);
如果要关闭深度测试,则只需调用glDisable(GL_DEPTH_TEST)即可。
另外为了使深度缓冲区正常完成深度测试功能,在每次渲染场景时,必须先清除深度缓
冲区:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2. 隐藏表面
5、
回调函数
void glutDisplayFunc(void (*func)(void) );
为当前窗口设置显示回调函数
void glutOverlayDisplayFunc(void (*func)(void) );
注册当前窗口的重叠层的显示回调函数
void glutReshapeFunc(void (*Func)(int width, int height) );
指定当窗口的大小改变时调用的函数
void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y) );
注册当前窗口的键盘回调函数
void glutMouseFunc(void (*func) (int button, int state, int x, int y));
注册当前窗口的鼠标回调函数
func为注册的鼠标回调函数,这个函数完成鼠标事件的处理
button为鼠标的按键,为以下定义的常量
GLUT_LEFT_BUTTON |
鼠标左键 |
GLUT_MIDDLE_BUTTON |
鼠标中键 |
GLUT_RIGHT_BUTTON |
鼠标右键 |
state为鼠标按键的动作,为以下定义的常量
GLUT_UP |
鼠标释放 |
GLUT_DOWN |
鼠标按下 |
x,y为鼠标按下式,光标相对于窗口左上角的位置
void glutMotionFunc(void (*func)(int x, int y));
void glutPassiveMotionFunc(void (*func)(int x, int y));
设置移动回调函数;设置当前鼠标移动函数
Func为注册的鼠标移动函数
x,y为鼠标按下式,光标相对于窗口左上角的位置
当鼠标在窗口中按下并移动时调用glutMotionFunc注册的回调函数
当鼠标在窗口中移动时调用glutPassiveMotionFunc注册的回调函数
void glutVisibilityFunc(void (*func) (int state) );
设置当前窗口的可视回调函数
Func为指定的可视回调函数
state表示窗口的可视性,为以下常量:
GLUT_NOT_VISIBLE |
窗口完全不可见 |
GLUT_VISIBLE |
窗口可见或部分可见 |
这个函数设置当前窗口的可视回调函数,当窗口的可视性改变时,该窗口的可视回调函数被调用.只要窗口中的任何一个像素是可见的,或者他的任意一个子窗口中任意一个像素是可见的,GLUT则认为窗口是可见的.
void glutEntryFunc(void (*func) (int state));
设置鼠标的进出窗口的回调函数
Func为注册的鼠标进出回调函数
state为鼠标的进出状态,为以下常量之一:
GLUT_LEFT |
鼠标离开窗口 |
GLUT_RIGHT |
鼠标进入窗口 |
当窗口取得焦点或失去焦点时调用这个函数,当鼠标进入窗口区域并点击时,state为GLUT_RIGHT,当鼠标离开窗口区域点击其他窗口时,state为GLUT_LEFT.
void glutSpecialFunc(void (*func) (int key, int x, int y))
设置当前窗口的特定键的回调函数
Func为注册的特定键的回调函数
key为按下的特定键,为以下定义的常量:
key常量 |
描述 |
GLUT_KEY_F1 |
F1功能键 |
GLUT_KEY_F2 |
F2功能键 |
GLUT_KEY_F3 |
F3功能键 |
GLUT_KEY_F4 |
F4功能键 |
GLUT_KEY_F5 |
F5功能键 |
GLUT_KEY_F6 |
F6功能键 |
GLUT_KEY_F7 |
F7功能键 |
GLUT_KEY_F8 |
F8功能键 |
GLUT_KEY_F9 |
F9功能键 |
GLUT_KEY_F10 |
F10功能键 |
GLUT_KEY_F11 |
F11功能键 |
GLUT_KEY_F12 |
F12功能键 |
GLUT_KEY_LEFT |
左方向键 |
GLUT_KEY_UP |
上方向键 |
GLUT_KEY_RIGHT |
右方向键 |
GLUT_KEY_DOWN |
下方向键 |
GLUT_KEY_PAGE_UP |
PageUp键 |
GLUT_KEY_PAGE_DOWN |
PageDown键 |
GLUT_KEY_HOME |
Home键 |
GLUT_KEY_END |
End键 |
GLUT_KEY_INSERT |
Insert键 |
x,y为当按下键时鼠标的坐标,相对于窗口左上角,以像素为单位
注意:ESC,回车和delete键由ASCII码产生.
void glutMenuStatusFunc(void (*func) (int status, int x, int y));
设置菜单状态回调函数
func是注册的菜单状态回调函数
status是当前是否使用菜单,为以下定义的常量
GLUT_MENU_IN_USE |
菜单正在使用 |
GLUT_MENU_NOT_IN_USE |
菜单未被使用 |
x,y是鼠标按下式,光标相对于窗口左上角的位置
这个函数时glut程序判定是否正在使用菜单,当弹出菜单时,调用注册的菜单状态回调函数,同时status设置为常量 GLUT_MENU_IN_USE, 当菜单使用完毕时,也调用菜单状态回调函数,此时status变量变为GLUT_MENU_NOT_IN_USE.从已弹出的菜单中再弹出的菜单不产生菜单状态回调过程.每个glut程序只有一个菜单状态回调函数.
glutSpaceballRotateFunc
glutSpaceballButtonFunc
glutButtonBoxFunc
glutDialsFunc
glutTabletMotionFunc
glutTabletButtonFunc
void glutMenuStatusFunc(void (*func) (int status, int x, int y));
设置菜单状态回调函数
func为注册的菜单状态回调函数
status表示当前是否使用菜单,为以下定义的常量
GLUT_MENU_IN_USE |
菜单正在使用 |
GLUT_MENU_NOT_IN_USE |
菜单未被使用 |
x,y表示鼠标按下式,光标相对于窗口左上角的位置
这个函数时glut程序判定是否正在使用菜单,当弹出菜单时,调用注册的菜单状态回调函数,同时status设置为常量 GLUT_MENU_IN_USE, 当菜单使用完毕时,也调用菜单状态回调函数,此时status变量变为GLUT_MENU_NOT_IN_USE.从已弹出的菜单中再弹出的菜单不产生菜单状态回调过程.每个glut程序只有一个菜单状态回调函数.
void glutIdleFunc(void (*func) (void));
设置空闲回调函数
func表示当系统空闲时调用的函数,它的形式为void func(void)
void glutTimerFunc(unsigned int msecs, void (*Func)(int value), int value);
注册一个回调函数,当指定时间值到达后,由GLUT调用注册的函数一次
msecs是等待的时间
Func是注册的函数
value是指定的一个数值,用来传递到回调函数Func中
这个函数注册了一个回调函数,当指定的毫秒数到达后,这个函数就调用注册的函数,value参数用来向这个注册的函数中传递参数.
posted on 2011-09-13 16:00
Yu_ 阅读(481)
评论(0) 编辑 收藏 引用 所属分类:
Windows程序设计