1、OpenGL语法与规定,OpenGL 函数都遵循一个命名约定,通过这个约定可以了解函数来源于哪个库,需要多少个参数以及参数的类型。以函数glColor3f()为例 gl 表示这个函数来自库gl.h, color 是该函数的根段,表示该函数用于颜色设定, 3f 表示这个函数采用了三个浮点数参数。 glVertex2f,glVertex3i表示什么含义? 当函数名以v结尾时表示函数接收一个数组指针 例:glVertex3iv接收一个指向三个元素的GLint数组指针,OpenGL 状态机,OpenGL 是一种直接模式的API,每条命令根据当前的渲染状态都会产生某种立即效果。 渲染状态是各种标记,他们
2、指出哪些特性是打开的,哪些是关闭的,以及应该如何应用他们。 在OpenGL 中,使用glEnable 函数和glDisable 函数来启用和禁用渲染特征。,OpenGL图元绘制,chap31,OpenGL图元绘制(点),glVertex 函数用于指定顶点 点大小的默认值是一个象素,可用函数修改个值:void glPointSize(GLfloat size);glBegin(GL_POINTS);glVertex3f(0.0f,0.0f,0.0f);glVertex3f(10.0f,10.0f,10.0f); glEnd();,OpenGL图元绘制(线段),由函数glBegin 的参数指定绘制
3、图元的类型, 图4-19,多边形的朝向,每个多边形都有两面:前面和后面 系统默认逆时针朝向为观察者的正面,可以指定顺时针为正面 glFrontFace(GL_CCW) 指定逆时针为正面(默认) glFrontFace(GL_CW) 指定顺时针为正面,glBegin(GL_POLYGON); glColor3f(1.0,0,0.0); /红glVertex2i(50,50);glColor3f(0,1.0,0.0); /绿glVertex2i(120,100);glColor3f(0,0,1); /蓝glVertex2i(80,140); glEnd();,红(50, 50),绿(120,100
4、),蓝(80, 140),正面 反面,多边形的填充方式,glPolygonMode( face , mode ) 控制每一面的填充方式,GL_POINT(点) GL_LINE(边界) GL_FILL(区域),多边形的朝向与填充方式,按 红点、绿点、蓝点顺序定义点 按如下方式定义 多边形的朝向与填充方式 glPolygonMode(GL_FRONT,GL_FILL); /正面,填充 glPolygonMode(GL_BACK,GL_LINE); /背面,线框,红(50, 50),绿(120,100),蓝(80, 140),/顺时针为正面 glFrontFace(GL_CW);,/逆时针为正面 g
5、lFrontFace(GL_CCW);,几何变换,OpenGL没有二维变换的机制,所有二维变换都作为三维变换的特例处理 OpenGL保持一个modelview的矩阵,它是用来进行建模变换与观察变换的合成变换矩阵 将建模与观察矩阵设为系统当前的矩阵 glMatrixMode(GL_MODELVIEW);glLoadIdentity();,几何变换: 平移 缩放 旋转,平移 glTranslate (Tx,Ty,Tz) 缩放 glScaled (Sx,Sy,Sz) 旋转 glRotate (angle,x,y,z) 以上三个函数首先建立一个相应的矩阵M,然后用M右乘当前的矩阵C,得到CM 参cha
6、p62,几何变换:复合变换,注意变换次序若先glTranslate后glRotate,则CMTMR,其效果是先旋转后平移 变换之前保存矩阵副本 glPushMatrix() 使用矩阵栈中的矩阵 glPopMatrix() 参chap63,几何变换:复合变换,GLfloat shield43=5,5,0,20,5,0,20,20,0,5,20,0; 原始图形: 红色方块 几何变换后图形: 绿色方块,glTranslated( 30,0,0); /沿x轴平移,glRotated(45,0,0,1); /绕z轴旋转,glRotated(45,0,0,1); /绕z轴旋转 glTranslated(
7、30,0,0); /沿x轴平移,glTranslated( 30,0,0); /沿x轴平移 glRotated(45,0,0,1); /绕z轴旋转,先平移再旋转,先旋转再平移,几何变换:任意变换,glLoadMatrix*将当前的矩阵设为任意的44矩阵。参数:指向16个GLfloat或GLdouble类型元素的数组的指针,按照列优先的顺序组成矩阵(前四个元素组成第一列,随后四个元素组成第二列) glMultMatrix* 用任意44矩阵去右乘当前的矩阵,GLfloat matrix16=1,0,0,0,0.5,1,0,0,0,0,1,0,0,0,0,1;glPushMatrix(); /保存原
8、始矩阵栈 glColor3f(0,1,0); /绿色 glLoadMatrixf(matrix); glMultMatrixf(matrix); draw_shield(); glPopMatrix();,OpenGL的颜色,RGBA 模式: 用RGB定义颜色 void glColor (red, green, blue, alpha); x =3 时,参数为R、G、B ;x =4时还包括Alpha 值(0.0 -1.0) 颜色表模式:从颜色表中选取当前颜色 void glIndexsifd(TYPE c); void glIndexsifdv(TYPE *c); 参数值c 用于设置当前颜色索
9、引值,即调色板号,若值大于颜色位面数时则取模。 参cindex,GLUT 物体1:球体,实心球体 glutSolidSphere(radius, slices, stacks); 线框球体 glutWireSphere(radius, slices, stacks); GLdouble radius 球体的半径。 GLint slices 球体围绕z 轴(相对于经度线)分割的数目。 GLint stacks 球体沿着z 轴(相对于纬度线)分割的数目。 说明: 球体绘制中心在模型坐标原点、半径为radius 球体围绕z 轴分割为slices 个数目沿着z 轴分割stacks 个的数目。,glut
10、SolidSphere(1,20,20),glutSolidSphere(1,10,10),GLUT 物体2:立方体,实心立方体glutSolidCube(GKdouble size); 线框立方体glutWireCube(GKdouble size); 参数:size 立方体的边长。 说明:这两个函数用于绘制以模型坐标原点为中心、边长为size 的实心立方体和线框立方体。,glutSolidCube(2) glutWireCube(2),GLUT 物体3:圆锥体,实心圆锥体glutSolidCone(radius, height, slices, stacks); 线框圆锥体glutWire
11、Cone(radius, height, slices, stacks); 参数 GLdouble radius 圆锥体基底的半径。 GLdouble height 圆锥体的高度。 GLint slices 圆锥体围绕z 轴的分割数。 GLint stacks 圆锥体数沿着z 轴的分割数。 绘制沿着z 轴方向定位的圆锥体。圆锥体的基底定位于z = 0 平面内,顶点z = height,圆锥体围绕z 轴分割为slices 个数目,沿着z 轴分割为stacks个数目。,GLUT 物体4:圆环,实心/线框圆环glutSolidTorus(innerRadius, outerRadius, nside
12、s, rings); glutWireTorus(innerRadius, outerRadius, nsides, rings); 参数 innerRadius 圆环的内半径; outerRadius 圆环的外半径。 GLint nsides 沿着圆环方向的分割数。 GLint rings 圆环的环线数。 绘制中心位于模型坐标原点的圆环,轴线沿着z轴方向。,GLUT 物体5:犹他茶壶,实心茶壶glutSolidTeapot(GLdouble size); 线框茶壶glutWireTeapot(GLdouble size); 参数:size 茶壶的相对尺寸 说明 这两个函数分别绘制实心茶壶和线
13、框茶壶,茶壶的曲面法向量和纹理坐标也同时生成。 茶壶是用OpenGL 的求值器构建的。,GLUT 物体6:四面体,实心四面体void glutSolidTetrahedron(void); 线框四面体void glutWireTetrahedron(void); 说明 这两个函数分别绘制中心位于模型坐标原点的实心四面体和线框四面体,四面体的半径为3 。,GLUT 物体7:八面体,实心八面体void glutSolidOctahedron (void); 线框八面体void glutWireOctahedron (void); 说明 这两个函数分别绘制中心位于模型坐标原点的实心八面体和线框八面体
14、,八面体的半径为1.0。,GLUT 物体8:十二面体,实心十二面体void glutSolidDodecahedron (void); 线框十二面体void glutWireDodecahedron (void); 说明 这两个函数分别绘制中心位于模型坐标原点的实心12 面体和线框12 面体,12 面体的半径为 。,GLUT 物体9:二十面体,实心二十面体void glutSolidIcosahedron (void); 线框二十面体void glutWireIcosahedron (void); 说明 这两个函数分别绘制中心位于模型坐标原点的实心20 面体和线框20 面体,20 面体的半径为
15、1.0。,OpenGL光照与着色,4. 选择光照与着色参数 两面光照glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);,参exam 4-6:单双面,Bezier曲线(1/4),定义求值器(传递控制点,指明数据类型及u的值域) 启动求值器 给出u的区间划分(常用等分)即( u1=u0,u1,u2,un=u2 ) 在上述区间上选取u值求值(即曲线上的点),并用该点绘制曲线,glMaplf()glEnable() glMapGridlf()glEvalMeshl(),OpenGL中,曲线和曲面的构造借助于求值器完成。利用求值器可自动生成顶点坐标、法线坐标和
16、纹理坐标,其次,要激活求值器,使其进行曲线映射。最后,要将求值器生成的各顶点连接起来生成一条完整的曲线,参程序Bezier,Bezier曲线(2/4),应用程序将一系列控制点传给子程序glMaplf来建立一个一维求值器(参数空间中的一维:u) glMaplf(,); 符号常数指明控制点及求值器所产生的数据类型GL_MAP1_VERTEX_3表示xyz顶点坐标GL_MAP1_NORMAL表示法向量 指定u的值域umin,umax, 将被系统映射为标准值域0,1 控制点间的步幅(以GLfloat个数度量) 控制点的数量 指向一个含有一系列控制点的GLfloat数组指针启动求值器glEnable(G
17、L_MAP1_VERTEX_3)终止求值器glDisable(GL_MAP1_VERTEX_3),Bezier曲线,/绘制Bezier曲线 glMap1f(GL_MAP1_VERTEX_3, / 产生的数据类型0.0f, / 参数最小值100.0f, / 参数最大值3, /控制点间的步幅(以GLfloat个数度量)nNumPoints, / 控制点数目/ 保存控制点的数组,GLint nNumPoints = 4; GLfloat ctrlPoints43= -4.0f, -5.0f, 0.0f, / 控制点0 -2.0f, 4.0f, 0.0f, / 控制点1 2.0f, 4.0f, 0.0
18、f, / 控制点2 4.0f, -5.0f, 0.0f ;/ 控制点3,glEnable(GL_MAP1_VERTEX_3); /启动求值器,Bezier曲线(3/4),映射曲线,选择u并计算曲线上的点(方法一) 处理均匀分布的u值 glMapGridlf(Glint n,GLfloat u1, GLfloat u2); 指定一个从u1开始经过n次常数增值到达u2的格式 即区间u1, u2n等分 ( u1=u0,u1,u2,un=u2 ) 例: glMapGrid1d(100,0.0,100.0); /等分区间 通过调用glEvalMesh1计算u值并绘制曲线 glEvalMeshl( ,GL
19、int b, Glint e ); 符号常数GL_POINT画点,GL_LINE画折线 b和e让一维求值器在ub到ue的每个u值上求值,并用由此算出的曲线上点来画图 例:glEvalMesh1(GL_LINE,0,100); /用求值器计算曲线上点的值,并画图,Bezier曲线(4/4),可以处理均匀分布或者非均匀分布的u值(方法二) 映射曲线,选择u并计算曲线上的点 用适当的参数u调用glEvalCoord1f使每个已经启用的一维求值器都算出/产生一个曲线上对应于参数值u的有着相应数据类型的点 glEvalCoord1f(GLfloat u); 用u值让求值器计算出曲线上的一个点 通常在循环
20、结构中使用,并要指定绘制模式(点、线等),glBegin(GL_LINE_STRIP); /作用和上面2行一样for(i = 0; i = 100; i+)glEvalCoord1f(GLfloat) i); / 计算当前曲线点的坐标 glEnd();,B-样条(1/5),Glu子程序库提供一个B-样条接口,该接口支持不同形式的B-样条(均匀、开放、NURBS) 首先声明一个类型为GLUnurbsObj的指针, 调用gluNewNurbsRenderer来构造一个新的GLUnurbsObj对象,而且使该指针指向这个对象 然后 通过调用gluBeginNurbsCurve 来产生和画出该曲线 最
21、后调用gluEndCurve结束绘制,GLUnurbsObj *BSpline; /声明对象 BSpline=gluNewNurbsRenderer(); /构造对象 gluBeginCurve(BSpline); /绘制曲线gluNurbsCurve(BSpline,8,kv,3,ctrlPoints0,4,GL_MAP1_VERTEX_3); gluEndCurve(BSpline);,B-样条(2/5),B 样条绘制函数 gluNurbsCurve(,, ); 指向GLUnurbsObj对象的指针 指明节向量中节点的数量 指向节向量的指针 控制点间的步幅(以GLfloat个数度量) 指向
22、一个含有一系列控制点的GLfloat数组指针 B-样条的阶数 符号常数,指明产生的数据类型GL_MAP1_VERTEX_3表示xyz顶点坐标GL_MAP1_VERTEX_4表示xyzw坐标,B-样条(例),GLint nNumPoints = 4; GLfloat ctrlPoints43= 0, 0, 0, / 控制点0 1, 2, 0, / 控制点1 4, 2.5, 0, / 控制点2 7,-0.5,0 ; / 控制点3 GLfloat kv8=0,1,2,3,4,5,6,7; /均匀三次4阶B-样条 GLUnurbsObj *BSpline; BSpline=gluNewNurbsRen
23、derer(); gluBeginCurve(BSpline);gluNurbsCurve(BSpline, /指向GLUnurbsObj对象的指针8, /指明节向量中节点的数量kv, /指向节向量的指针3, /控制点间的步幅(以GLfloat个数度量)ctrlPoints0,/指向含有控制点的GLfloat数组指针4, / B-样条的阶数GL_MAP1_VERTEX_3);/符号常数,指明产生的数据类型 gluEndCurve(BSpline);,B-样条(3/5),均匀线性2阶B-样条 n=3,d=2 kv6=0,1,2,3,4,5,均匀二次3阶B-样条 n=3,d=3 kv7=0,1,2
24、,3,4,5,6,B-样条(4/5),均匀三次4阶B-样条 n=3,d=4 kv8=0,1,2,3,4,5,6,7;,非均匀三次4阶B-样条 n=3,d=4 kv8=0,1,1,3,4,4,5,6;,B-样条(5/5),开放型B-样条 节向量 n=3,d=4 kv8=0,0,0,0,1,1,1,1,B-样条(6/6)尖点例,/ 4个不同位置的控制点,其中控制点1使用了d次(d=3) GLfloat ctrlPoints63= 0, 0, 0, / 控制点0 1, 2, 0, / 控制点1 1, 2, 0, / 控制点1 1, 2, 0, / 控制点1 4, 2.5, 0, / 控制点2 7,-0.5,0 ; / 控制点3,/节向量, 3阶d=3,n=5 ,均匀3阶B样条 GLfloat kv9=0,1,2,3,4,5,6,7,8;,