OpenGl 游戏编程笔记 第三章: OpenGL 状态和图元 (一)
OpenGl 游戏编程笔记 第三章: OpenGL 状态和图元 (三)

OpenGl 游戏编程笔记 第三章: OpenGL 状态和图元 (二)

皮贝贝 posted @ 2010年3月30日 07:25 in opengl with tags OpenGL game 游戏 , 10393 阅读

1 处理图元

在图元中, 点, 线, 面是最重要的, 几乎所有的游戏都可以用这三种图元来进行构建. 在介绍几种图元之前, 先来看看几个常用的相关函数. 第一个是 glBegin() :


void glBegin(GLenum mode);

glBegin() 会告诉 OpenGL 两件事: 1) 你已经准备好了绘图. 2) 你准备画的图元. 参数 mode 便是 指定要绘的图元, 可以是以下几种:


参数 描述
GL_POINTS 单独的一个点
GL_LINES 单独的一条有两个顶点构成的线段
GL_LINE_STRIP 一些连接的线段
GL_LINE_LOOP 许多连接的线段构成的闭合图形, 其中第一个顶点和最后一个顶点会自动连接成线段
GL_TRIANGLES 单独的一个三角形, 有三个顶点
GL_TRIANGLE_STRIP 一些连接起来的三角形
GL_TRIANGLE_FAN 一些三角形, 公用一个顶点
GL_QUADS 四边形, 有四个顶点
GL_QUADSTRIP 连接的四边形  
GL_POLYGON 任意顶点个数的凸边形. 通过 GLU 的相关函数可以创建凹边形

每一个 glBegin() 调用都要结对出现一个 glEnd():


void glEnd()

glEnd() 告诉 OpenGL 我已经绘完了我用 glBegin() 指定的图元.

注意, 并非所有函数都可以用在 glBegin()  glEnd() 中间. 事实上, 只有一部分, 下表列出. 使用其他的函数会产生一个 GL_INVALID_OPERATION 错误.


参数
glVertex*()
glColor*()
glSecondaryColor*()
glIndex*()
glNormal*()
glTexCoord*()
glMultiTexCoord*()
glFogCoord*()
glArrayElement()
glEvalCoord*()
glEvalPoint*()
glMaterial*()
glEdgeFlag*()
glCallList*()
glCallLists*()

 glVertex() 函数是下列形式的众多变体:


void glVertex{234}{dfis}(…);


void glVertex{234}{dfis}v(…);

你最常用的一个 glVertex() 版本是 glVertex3f(), 带有三个浮点型的顶点参数 x, y, z.

glVertex() 的一些使用例子:

 

glVertex2i(5, 29); // 在坐标 (5, 20) 处绘制一个顶点
glVertex3f(1.5, 0.5, 10.0);  //在坐标 (1.5, 0.5, 10.0) 处绘制一个顶点

GLfloat v[3] = {1.5, 0.5, 10.0};
glVertex3fv(v); // 同上. 只是形式上以数组形式来指定坐标


每次绘制一个顶点时, 会相应的应用当前 OpenGL 的状态.

1.1 在 3D 中绘制点

绘制一个点主要是下面代码:

 

glBegin(GL_POINTS);
        glVertex3f(0.0, 0.0, 0.0);
glEnd();


 

首先, 通过 GLPOINTS 传给 glBegin() 来告诉 OpenGL 你要开始绘制点. 第二行, 你告诉绘制的点在 什么位置. 最后, 用 glEnd() 告诉 OpenGL 你已经完成了绘制. 注意 glBegin() / glEnd()之间的 代码缩进不是必须的, 但是让代码更易读.

若要绘制第二个点怎么办? 你可以这样:

 

glBegin(GL_POINTS);
        glVertex3f(0.0, 0.0, 0.0);
glEnd();

glBegin(GL_POINTS);
        glVertex3f(0.0, 1.0, 0.0);
glEnd();


 

代码看起来有点乱. 仔细观察 GL_POINTS 是一个复数形式, 意味着 glBegin() / glEnd() 代码 块中可以绘制多个点:

 

glBegin(GL_POINTS);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(0.0, 1.0, 0.0);
glEnd();


 

这样更短, 也更快, 更好.

OpenGL 让你可以控制图元的绘制, 当然点也不例外. 你可以控制三类事情: 点的大小, 反走样, 点的尺寸和透明度效果

1.1.1 修改点的大小

欲更改点的大小, 使用:


void glPointSize(GLfloat size);

结果是在指定的点的坐标周围会画出一个 size * size 大小的正方形. 默认大小是 1.0. 如果反走样特性 被禁用(默认), 点的大小会调整到最接近的一个整数值上(最小为1). 你可以通过调用 glGet() 传入 GL_POINT_SIZE 来得到当前的大小. 下面是一个例子:

// 得到当前点的大小 GLfloat oldSize; glGetFloatv(GLPOINTSIZE);

// 如果点大小很小, 设为 5.0, 否则使用默认呢大小 1.0 if (oldSize < 1.0) glPointSize(5.0); else glPointSize(1.0);

1.1.2 反走样处理

若想使用反走样, 通过使用 glEnable() 传入 GL_POINT_SMOOTH 参数(同样地, 可以使用 glDisable() 传入 GL_POINT_SMOOTH 参数来关掉). 若想得知当前是否启用, 可以使用 GL_POINT_SMOOTH 调用 glGet() 来取得状态, 或者使用 glIsEnabled(GL_POINT_SMOOTH) . 下面是一个例子:

 

if (!glIsEnabled(GL_POINT_SMOOTH))
        glEnable(GL_POINT_SMOOTH);


 

反走样开启时, 支持的点大小范围是离散,不连续的. 一般是 1.0 为一个大小步伐. 如果使用不支持的大小, 会自动转化为接近的一个支持的值. 要想知道你的OpenGL 实现支持范围, 你可以通过调用 glGet() 的 GL_POINT_SIZE_RANGE. 还可以 通过 GL_POINT_SIZE_GRANULARITY 来获知大小步伐.

 

GLfloat sizes[2];
GLfloat granularity;

glGetFloatv(GL_POINT_SIZE_RANGE, sizes);
GLfloat minPointSize = sizes[0];
GLfloat maxPointSize = sizes[1];

glGetFloatv(GL_POINTS_SIZE_GRANULARITY, &granularity);


NOTE:
需要开启混色(Blending)效果来保证反走样正常工作.

1.1.3 距离效果

有时我们根据特定的应用需要点间看起来远一些, 可以通过 glPointParameter() 实现:


void glPointParameter{if}(enum pname, type param);
void glPointParameter{if}v(enum pname, const type *params);

参数pname 可以取下面的值:


参数
GL_POINT_SIZE_MIN
GL_POINT_SIZE_MAX
GL_POINT_DiSTANCE_ATTENUATION
GL_POINT_FADE_THRESHOLD

1.1.4 一个绘点例子

截取主要的代码部分:

 

float pointSize = 0.5;

// 绘制一行大小递增的点
for (float point = -4.0; point < 5.0; point += 0.5)
{
    // 设置点的大小
    glPointSize(pointSize);

    // 绘制点
    glBegin(GL_POINTS);
    glVertex3f(point, 0.0, 0.0);
    glEnd();

    // 设置下一个点的大小
    pointSize += 1.0;
}

./image/opengl3_point.jpg

 

在这个例子中, 我们沿着 x 轴绘制了一行点. 每个点的大小递增 0.5. 对每个点, 我们先设定点的大小 (glPointSize()), 然后用 glBegin(GL_POINTS) 来开始绘点, 通过 glVertex3f() 来具体绘制 , 最后 glEnd() 表示绘制完成.

1.2 3D 绘线

绘制 3D 的线, 同 2D 一样, 有两个点组成, 只要通过 GL_LINES 绘制两个点就可以了:

 

glBegin( GL_LINES);
        glVertex3f(-2.0, -1.0, 0.0);
        glVertex3f(3.0, 1.0, 0.0);
glEnd();


 

同绘点一样, 也可以在 glBegin() / glEnd() 代码块中绘制多条线段, 当然如果中间的点中最后一个点没有 配对的点, 那么 OpenGL 将忽略最后这个点.

OpenGL 可以允许你修改线的显示效果. 除了可以设定线的宽度, 开启反走样处理之外, 你还可以指定点画模式.

1.2.1 修改线宽

默认线宽是 1.0. 获得当前线宽通过 glGet() 传入 gl_LINE_WIDTH 参数. 更改线宽通过 glLineWidth():


void glLineWidth(GLfloat width);

使用举例:

 

// 获得当前设置
GLfloat oldWidth;
glGetFloatv(GL_LINE_WIDTH, &oldWidth);

// 若线宽太小, 设置大
if (oldWidth < 1.0)
    glLineWidth(5.0);

 

1.2.2 反走样

如同点的反走样, 你可以通过 glEnable()  glDisable() 的 GL_LINE_SMOOTH 来开启或关闭; 通过 glGet() 的 GL_LINE_SMOOTH 或 glIsDisable() 来获取当前状态. 默认, 反走样特性是关闭的.

启用反走样时, OpenGL 的默认设置线宽是 1.0. 要确定支持的 范围和规模的粒度, 可以使用 glGet() 的 GL_LINE_WIDTH_RANGE 和 GL_LINE_WIDTH_GRANDULARITY 参数来获得. 使用例程:

 

GLfloat sizes[2];
GLfloat granularity;

glGetFloatv(GL_LINE_WIDTH_RANGE, sizes);
GLfloat minLineWidth = sizes[0];
GLfloat maxLineWidth = sizes[1];

glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &granularity);


 

看起来是不是和点的反走样例程一样?

1.2.3 指定点画模式

在使用点画模式之前, 需要通过 glEnable() 的 GL_LINE_STIPPLE 来开启. 然后, 通过 glLineStipple() 来使用:


void glLineStipple(GLint factor, GLushort pattern);

参数 factor 默认是 1, 取值区间是 1~256, 指定了每个位的绘制 次数.

参数 pattern 指定了 16 位模式. 模式中的设定位会设定相应的像素; 否则他们不会被绘制出来. 值得注意的是, 整数的二进制表示是反序的, , 所以效果如下图:

下面是一个使用点画模式的例子:

 

glEnable(GL_LINE_STIPPLE);
GLushort stipplePattern = 0xFAFA; // 1111 1010 1111 1010

// 点画效果: 0101 1111 0101 1111
glLineStipple(2, stipplePattern);


 

要想知道当前的点画模式, 可以调用 glGet() 的 GL_LINE_STIPPLE_PATTERN 和 GL_LINE_STIPPLE_REPEAT. 下面是一个例子:

 

GLushort currentStipplePattern;
GLint currentStippleRepeat;

glGetShortv(GL_LINE_STIPPLE_PATTERN, &currentStipplePattern);
glGetIntv( GL_LINE_STIPPLE_REPEAT, &currentStippleRepeat);

 

1.2.4 绘线例程

你会看到有两列线, 左边一列是递增宽度的实线, 右边一列是设定点画模式 下的递增大小的线. 主要代码如下:

 

float lineWidth = 0.5;

// 绘制递增大小宽度的线
for (float line = 0.0; line < 7.0; line += 0.5)
{
    // 设定线宽
    glLineWidth(lineWidth);

    // 绘线
    glBegin(GL_LINES);
    glVertex3f(-5.0f, 0.0f, line-3.0);
    glVertex3f(-1.0f, 0.0f, line-3.0);
    glEnd();

    // 线宽递增
    lineWidth += 1.0;
}

 


接下来是点画模式的线:

 

// 重设线宽
lineWidth = 0.5;

// 开启点画模式
glEnable(GL_LINE_STIPPLE);

// 设置点画模式
// 0xAAAA = 1010 1010 1010 1010
short stipplePattern = 0xAAAA;
glLineStipple(2, stipplePattern);

// 绘制点画模式的线
for (float line = 0.0; line < 7.0; line += 0.5)
{
    // 设置线宽
    glLineWidth(lineWidth);

    // 绘线
    glBegin(GL_LINES);
    glVertex3f(1.0f, 0.0f, line-3.0);
    glVertex3f(5.0f, 0.0f, line-3.0);
    glEnd();

    // 递增线宽
    lineWidth += 1.0;
}



 

代码的不同之处在于开启了点画模式 (glEnable(GL_STIPPLE_PATTERN)), 然后设置(glLineStipple()).

 


Date: 2010-03-29 23:14:29

HTML generated by org-mode 6.30c in emacs 23

 

Avatar_small
BSEB Matric Social Q 说:
2022年9月25日 14:42

Leading educational institutions and subject experts of the state provided sample guess paper with practice question bank in chapter wise important questions and answer solutions through newspapers and model sets, BSEB Matric Social Question Paper we have recommended to every student can download expert questions of Bihar Board 10th Model Paper 2023 for Social Science to practice regular mock test.Leading educational institutions and subject experts of the state provided sample guess paper with practice question bank in chapter wise important questions and answer solutions through newspapers and model sets.

Avatar_small
ver mi actividad 说:
2023年7月27日 00:37

Puede eliminar los resultados individuales del historial de búsqueda de la lista instantánea de la página de búsqueda de Google junto con Mi actividad de Google en todos los productos de Google en ver mi actividad . Es esencial proteger nuestro historial de búsqueda y otras actividades de otros por motivos personales. Todos pueden usar la página Mi actividad de Google para eliminar una gran parte o la totalidad de su historial de búsqueda.

Avatar_small
SCERT Kerala 1st Cl 说:
2023年9月25日 16:04

Kerala 1st Standard Malayalam, English, Tamil, and Kannada Medium Textbook Available in SCERT Kerala Official Website, Students can Download Latest Edition, SCERT Kerala Standard Books are Prepared by a Group of Subject Expert, These SCERT Kerala Textbooks 2024 are an Excellent Resource for Students, as they can learn and revise through Different Chapters Present in the syllabus for SCERT Kerala 1st Class Textbook 2024 Subjects like Maths, Science, Social Science, Hindi, English and Malayalam.This is Kerala Textbook.

Avatar_small
boardmodelpaper.com 说:
2024年1月19日 01:22

Board Model Papers 2024 provide all states of 6th to 10th text books 2024 Candidates who are Searching for 6th to 10th and 11th to 12th text books and syllabus, sample questions, exam pattern, and Co-Curricular Subject textbooks can refer to this entire article. boardmodelpaper.com and question papers for following the website and Arts, Science, Commerce Stream Subject Wise Solved Question Bank for Hindi & English Medium Students with Exam Pattern & Blueprint and subject Wise with 11th & 12th Question Bank 2024 for General & Vocational Course. Here, we have gathered all subjects of Board textbooks for all Class along with the direct download links.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter