posts - 34,comments - 2,trackbacks - 0

一、      工作原理

1)、OpenGL流水线

 

命名约定:

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 xGLint yGLsizei widthGlsizei height)

②、利用函数glOrtho 定义修剪区

void glOrtho(Gldouble leftGldouble rightGldouble bottomGldouble topGldouble nearGldouble 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       创建相邻的三角形

 

 

注意:可以使用void glPointSize(GLfloat size);来设计像素点大小

通常使用下面的代码来获取点大小的范围和它们之间最小的中间值:

GLfloat sizes[2] //保存绘制点的尺寸范围

GLfloat step //保存绘制点尺寸的步长

glGetFloatv(GL_POINT_SIZE_RANGEsizes)

glGetFloatv(GL_POINT_SIZE_GRANULARITY&step)

 

2、   绘制直线

glBegin(GL_LINES)        // GL_LINES每两个顶点定义一条直线    

glVertex3f(0.0f0.0f0.0f)

glVertex3f(10.0f10.0f10.0f)

glEnd()

 

注意:

  void glLineWidth(GLfloat width)   //设置线宽

  glEnable(GL_LINE_STIPPLE)   //修改模式

  glLineStipple(GLint factorGLushort pattern)//factor 设为2 会使模式中的每一位代表一行中2 个象素的开或关。pattern 0X00FF,可以画出点划线

3、   多边形的绘制

注意事项:

绕法

如果要反转OpenGL 的默认行为,可以调用函数:

glFrontFace(GL_CW)

、明暗处理

void glShadeModel(GLenum mode);

GL_FLAT                                        //平面明暗处理

GL_SMOOTH                                 //光滑明暗处理

  多边形的模式

glPolygonMode(Glenum faceGlenum mode)

face

GL_FRONTGL_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

鼠标进入窗口

当窗口取得焦点或失去焦点时调用这个函数,当鼠标进入窗口区域并点击时,stateGLUT_RIGHT,当鼠标离开窗口区域点击其他窗口时,stateGLUT_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_ 阅读(488) 评论(0)  编辑 收藏 引用 所属分类: Windows程序设计

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理