鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 软件教程 > 图形图像 > >

第四章 输出图元

来源:互联网 作者:佚名 时间:2017-09-12 11:02
读研之后就要开始进行图形学方面的研究了,我提前学习一下图形学的内容。 这是个开始,也是个大坑(我喜欢填坑 ( ̄︶ ̄))。 不知道为什么校园网csdn总是上不去,我就用作业部落写了发到这里,虽然好像不太好,不过没办法啦。 ps:cnblogs好像对公式的支持跟

读研之后就要开始进行图形学方面的研究了,我提前学习一下图形学的内容。
这是个开始,也是个大坑(我喜欢填坑 <( ̄︶ ̄)>)。
不知道为什么校园网csdn总是上不去,我就用作业部落写了发到这里,虽然好像不太好,不过没办法啦。
ps:cnblogs好像对公式的支持跟作业部落不太一样,将就着用吧。
-----------------------------------------------

原文链接:https://www.zybuluo.com/mdeditor#183293

下面是原文---------------------------------------------

第四章 输出图元

标签(空格分隔): 计算机图形学


[TOC]

4.1坐标系统

坐标范围又称为 包围盒、包围矩阵(2D)

4.1.1屏幕坐标

setPixel(x,y) //设置(x,y)处屏幕缓存器的颜色值
getPixel(x,y,color) //通过color返回(x,y)处的颜色

4.1.2绝对坐标和相对坐标

4.2OpenGL中指定二维世界坐标系统

gluOrtho2D(xmin,xmax,ymin,ymax); //设置包围矩阵

4.3OpenGL画点函数

  glVertex*(); //是指明空间的维数、坐标值变量的数据类型和可能的向量形式坐标描述
    
    /*
     *包括第一个2,3,4:4表示齐次坐标
      第二个i,s,f,d对应数据结构
      第三个v表示传入的参数是一个矩阵(向量)
    */

glVertex*()函数用法类似如下:

glBegin(GL_POINTS);
    glVertex*();
glEnd();
//glBegin函数包含参数,表示输出的图元类型,而glEnd函数没有参数

4.4OpenGL画线函数

与画点函数类似,只是在glBegin函数中的参数改为GL_LINES即可
另外
GL_LINE_STRIP表示折线
GL_LINE_LOOP表示封闭折线

4.7多边形填充区

4.7.1多边形分类

凸多边形convex polygon
凹多边形concave polygon
退化多边形 degenerate polygon

4.7.2识别凹多边形

  • 边向量叉积判断
  • 定点是否在边所在直线一侧判断

4.7.3分隔凹多边形

  • 向量方法判断出来某两条边的叉积与其他不同,则利用这两条边的第一条所在的直线分隔多边形,再执行向量方法的判断,直到所有边向量的叉积z分量同号。
  • 旋转法,将某一顶点移至坐标系原点,再按顺时针将接下来的边向量旋转至与x轴重合,此时如果下一个顶点在x轴下方,则为凹多边形。此时可依照x轴将多边形分隔。这个方法一直执行,直到凹多边形被完全分为凸多边形。

4.7.4将凸多边形分割成三将形集

4.7.5 内外测试

  • 奇偶规则
    从平面内任意一点P出发画一条射线(不能与多边形顶点相交),如果这条射线与多边形边的交点个数为奇数,则P在多边形内部。交点个数为偶数,则P在多边形外部。
  • 非零环绕规则
    为多边形赋予一个环绕方向,任一点P画一条射线(不语顶点相交)。初始时置环绕数为0,统计与这条射线相交的边的方向,令从一侧指向另一侧的方向使环绕数加一,相反方向使环绕数减一,看最后环绕数是否为0,为0则为多边形外,非0则为多边形内。
    环绕数规则中判断向量的方向可以用叉积和点积两种方法。

4.7.7平面方程

\[ Ax + By + Cz + D = 0 \]
逆时针选择凸多边形的三个连续顶点
\[(x_1,y_1,z_1),(x_2,y_2,z_2),(x_3,y_3,z_3)\]
联立方程组求A/D,B/D,C/D
\[(A/D)x_k + (B/D)y_k + (C/D)z_k = -1\qquad k = 1,2,3\]
方程组的解可由Cramer规则以行列式形式求出:
\[ \begin{align} &A= \begin{vmatrix} 1 & y_1 & z_1 \\ 1 & y_2 & z_2 \\ 1 & y_3 & z_3 \\ \end{vmatrix} \qquad B= \begin{vmatrix} x_1 & 1 & z_1 \\ x_2 & 1 & z_2 \\ x_3 & 1 & z_3 \\ \end{vmatrix} \\ &C= \begin{vmatrix} x_1 & y_1 & 1 \\ x_2 & y_2 & 1 \\ x_3 & y_3 & 1 \\ \end{vmatrix} \qquad D= \, - \,\, \begin{vmatrix} x_1 & y_1 & z_1 \\ x_2 & y_2 & z_2 \\ x_3 & y_3 & z_3 \\ \end{vmatrix} \end{align} \]
展开
\[ \begin{align} A & =y_1(z_2-z_3)+y_2(z_3-z_1)+y_3(z_1-z_2)\\ B & =z_1(x_2-x_3)+z_2(x_3-x_1)+z_3(x_1-x_2)\\ C & =x_1(y_1-y_2)+x_2(y_3-y_1)+x_3(y_1-y_2)\\ D & =-x_1(y_2z_3-y_3z_2)-x_2(y_3z_1-y_1z_3)-x_3(y_1z_2-y_2z_1) \end{align} \]

4.7.8前向面和后向面

对于任意
\[ 一点P(x,y,z)和平面Ax+By+Cz+D=0 \]
可利用
\[ Ax+By+Cz+D \]
的值来判断是在平面后方还是前方
\[ Ax+By+Cz+D > 0 , P在前方\\ Ax+By+Cz+D < 0 , P在后方 \]
注意:以上在右手笛卡尔系统中有效,且ABCD使用从前向后观察时严格按照逆时针顺序选出的坐标值计算而得

4.8OpenGL多边形填充函数

OpenGL中的外部:
多边形按照从“外部”观察时它的逆时针方向描述

glRect*(x1,y1,x2,y2);

生成矩形时,多边形的边按照顶点序列(x1,y1),(x2,y1),(x2,y1),(x2,y2),再返回来(x1,y1)生成,此处应该注意不同的顺序(顺时针或者逆时针)影响着多边形的内外向面。

6个多边形填充图元的符号常量为:

GL_POLYGON
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
GL_QUADS
GL_QUAD_STRIP

分别代表相应的含义。

4.9 OpenGL顶点数组

普通对象可能包含数百上千的顶点,不可能一个个的去执行GL函数调用。OpenGL函数库给了解决方案——使用顶点数组。

glEnableClientStptate(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_INT, 0, pt);
  
GLubyte vertIndex[] = (6,2,3,7,5,1,0,4,7,3,1,5,4,0,2,6,2,0,1,3,7,5,4,6);
glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,vertIndex);

glVertexPointer函数的第二个参数还有其他值

GL_BYTE
GL_SHORT
GL_DOUBLE

glDrawElements函数的第一个参数表示输出图元方式,第三个参数还有其他值

GL_UNSIGNED_SHORT
GL_UNSIGNED_INT

4.10 像素阵列图元

4.11 OpenGL像素阵列函数

4.11.1 OpenGL位图函数

glBitmap(width,height,x0,y0,xoffset,yoffset,bitShape);

定义一个二值的阵列
bitshape 是一个光栅矩阵,每个元素是0或1
1表示此位的像素会受到前面设置的颜色的影响,0表示不会
相当于是一个开关阵列

4.11.2 OpenGL像素图函数

glDrawPixels(width,height,dataFormat,dataType,pixMap);

dataFromat赋值GL_DEPTH_COMPONENT或者GL_STENCIL_INDEX选择深度缓存或者模板缓存

OpenGl中有四个缓存用来作屏幕刷新,左前,右前,左后,右后四个缓存
不支持多个缓存时,单一的缓存为左前缓存
利用函数glDrawBuffer(buffer)指定缓存buffer包括

GL_FRONT_LEFT
GL_FRONT_RIGHT
GL_BACK_LEFT
GL_FRONT_RIGHT

或者

GL_FRONT
GL_BACK
GL_LEFT
GL_RIGHT

后四个分别选择一对缓冲器

GL_FRONT_BACK

选择所有的缓冲器

GL_AUXk

选择辅助缓冲器,k是0到3的一个整数

4.11.3 光栅操作

光栅操作 raster operation
块移动 block transfer
bitblt移动 bit-block transfer
pixblt

glReadPixels(xmin,ymin,width,height,dataFormat,dataType,array);

在指定缓存中选择一个矩形快的像素值
(xmin,ymin)表示像素的左下角位置
dataFormat和glDrawPixels中的相同

下列函数可将一块像素数据从一个位置复制到另一个位置

glCopyPixels(xmin,ymin,width,height,pixelValues);

xmin,ymin,width,height容易理解
pixelValues被赋以GL_COLOR,GL_DEPTH,GL_STENCIL来指定要复制的数据种类:颜色值、深度值或者模板值
上述函数的源缓存通过glReadBuffer(buffer)设置,目的缓存通过glDrawBuffer(buffer)指定
取出的颜色值可以和缓存中原有的像素值进行混合,混合的方式有与、或、异或三种。过以下函数实现

glEnable(GL_COLOR_LOGIC_OP);
glLogicOp(logicOp);

logicOp包括

GL_AND
GL_OR
GL_XOR
GL_COPY_INVERTED
GL_INVERTED
GL_CLEAR
GL_SET
GL_COPY

GL_COPY_INVERTED可以将取到的颜色位置颠倒( 0变为1,1变为0 )后再取代目标值
GL_INVERTED 则只将目标值的各位颠倒
GL_CLEAR,GL_SET清零和置一

4.12 字符图元

衬线serif
无衬线sans serif
单一宽度monospace
比例宽度proportional
位图字体bitmap font,光栅字体raster font
轮廓字体outline font,笔画字体stroke font

4.13 OpenGL字符函数

GLUT位图字体由OpenGL的glBitmap函数来绘制,轮廓字体由GL_LINE_STRIP生成

glutBitmapCharacter(font,character);

font是常量
character是要显示的ASCII字符

4.14 图形分隔

4.15OpenGL显示表

4.15.1创建和明明OpenGL显示表

以下代码创建OpenGL显示表

glNewList(listID, listMode);
.
.
.
glEndList();

listMode可以是

GL_COMPILE
GL_COMPILE_AND_EXECUTE

显示表的内容不可更改,所以不要存入诸如顶点表指针等OpenGL命令

glIsList(listID); 

查询listID是否已经是显示表的标识符,是则返回GL_TRUE,否则返回GL_FALSE

4.15.2执行OpenGL显示表

以下语句执行显示表

glCallList(listID);

以下语句只想多个显示表

glListBase(offsetValue);
glCallLists(nLists, arrayDataType, listIDArray);

glCallList函数中
nLists表示要运行的显示表的数目
listIDArray是存有显示表标识符的数组,无效的标识符会被忽略
arrayDataType包括

GL_BYTE
GL_INT
GL_FLOAT
...

表示数据类型
显示表标识符通过将listIDArray中的一个元素的值与OffsetValue相加而得。
OffsetValue的默认值为0

4.15.3删除显示表

glDeleteLists(startID,nLists);

startID 开始的标识符
nLists 从startID开始标识符的数量

glDeleteLists(5, 4);

会删除5,6,7,8四个显示表,如果无效则忽略

4.16 OpenGL显示窗口重定型函数

glutReshapeFunc(winReshapeFcn);
网友评论
<