读书笔记

来源:互联网 发布:淘宝买家退款率50 编辑:程序博客网 时间:2024/05/21 19:30

使用glbegin()和glend()的限制

除了以下的函数外,glbegin()和glend()之间不能使用其他opengl函数。若使用其他函数,将产生未定义的行为,但不一定会产生错误。调试也非常困难。
这里写图片描述

点的细节

glpointsize(size) 以像素为单位,设置被渲染点的宽度。(点方块表示为size像素*size像素)size必须大于0.0,默认为1.0;
默认禁用抗锯齿,带小数的宽度值四舍五入为整型值。

直线细节

gllinewidth(width)以像素为单位设置宽度,用于直线的渲染。必须大于0.0,默认为1.0

  • 使用glgetfloatv()函数查询直线宽度范围的方法
    • 锯齿:gl_aliased_line_width_range
    • 抗锯齿:最小和最大宽度(gl_smooth_line_width_range),支持的直线宽度的粒度(gl_smooth_line_width_granularity)

点画线

使用gllinestipple()函数定影点画模式,然后调用glenable()启用点画功能。

gllinestipple(1,0x3F07);//重复因子,位为1的重复次数

这里写图片描述

查询状态变量的当前值

这里写图片描述

glenable(enum)和gldisable(enum)

启用和关闭一个功能。如果要查询某个状态的关闭或打开情况可以使用glisenable(enum);

点、轮廓或实心形式的多边形

默认情况下,多边形的正面和背面是按照相同的方式绘制的。

void glpolygonmode(glneum face, glneum mode)

控制多边形的正面和背面的绘图模式。

  • face

    • gl_front_and_back
    • gl_frony
    • gl_back
  • mode

    • gl_point//点
    • gl_line//轮廓
    • gl_file//填充

反转和剔除多边形表面

void glfrontface(glenum mode)//指定多边形正面

默认情况下,mode是

  • GL_CCW, 逆时针为正
  • GL_CW,顺时针为正
void glcullface(GLenum mode)//丢弃哪些不可见的正面或者背面多边形

使用glenable(GL_CULL_FACE)函数启用剔除功能。
mode是

  • GL_FRONT 正面多边形
  • GL_BACK 背面多边形
  • GL_FRONT_AND_BACK 所有多边形
    这里写图片描述

点画多边形

glpolygonstipple()函数指定多边形的点画模式。
启用glenable(gl_polygon_stipple)

void glpolygonstipple(const glubyte *mask)

mask参数是指向32X32位图的指针,后者被解释为0,1的掩码。1就绘制,0不绘制。
mask数据的解释受到
glpixelstore*()
gl_upack*模式的影响。

标记多边形的边界边

表示一个顶点是否应该被认为是多边形的一条边界的起点。如果flag是gl_true,边界标志就设置为true(默认),在此之后的所有顶点都被认为是边界边的起点。直到用gl_false为flag参数的值再次调用这个函数。

void gledgeflag(glboolean flag);void gledgeflagv(const glboolean *flag);///////////////////////////////////////////    float v0[] = {-0.9,0,0};    float v1[] = { 0, 0.9, 0 };    float v2[] = { 0, 0, 0 };    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);    glBegin(GL_POLYGON);    glEdgeFlag(GL_TRUE);    glVertex3fv(v0);    glEdgeFlag(GL_FALSE);    glVertex3fv(v1);    glEdgeFlag(GL_TRUE);    glVertex3fv(v2);    glEnd();    glPointSize(5);    glBegin(GL_POINTS);    glColor3f(1, 0, 0);    glVertex3fv(v0);     glColor3f(0, 1, 0);    glVertex3fv(v1);     glColor3f(0, 0, 1);    glVertex3fv(v2);    glEnd();

这里写图片描述

法线向量

  • 同一个多边形可能,共享同一条法线(平面),不共享的(曲面)。除了顶点外,不可能为多边形的其他地方分配法线。
  • 物体的法线向量定义了它的表面在空间中的方向。相对光源的方向。在执行光照计算之前,它的长度会转换为1 。
  • 如果进行不规则变换(如缩放或乘以剪切矩阵或指定非单位长度的法线),启用glenable(gl_normalize)。若提供单位长度法线,并执行均匀缩放,启用glenable(gl_rescale_normal),用一个常量因子(从模型视图变换矩阵得出)对法线进行缩放,使其变换后恢复为单位长度。
  • 默认下,法线的自动规范和重新缩放操作都是禁用的。

顶点数组

把数据放在顶点数组中可以提高应用程序的性能。

  • 使顶点数组可以减少函数调用的次数,提高性能。
  • 避免共享顶点的冗余处理。

对几何图形进行渲染的3个步骤:


1. 启用数组
调用glenableclientstate()(使用枚举值作为参数),不可能同时激活gl_color_array和gl_index_array 。
这里写图片描述
这里写图片描述

如果使用光照,可能需要为每个顶点定义一条法线向量。使用顶点数组时,需要同时激活法线数组和顶点数组坐标。
这里写图片描述

若关闭光照,只用一种颜色绘制几何图元。需要调用gldisable()函数关闭光照状态。在取消光照激活状态之后,需要停止更改表面法线状态的值(因为这种做法是完全浪费)。为此,可以调用:

gldiableclientstate(GL_NORMAL_ARRAY);

glenable()和gldisable()可以存储在显示列表中,但顶点数组却不可以(数据被保存在客户端)。


2.指定数组数据
共有8个不同的函数可以指定数组,每个函数用于指定不同类型的数组。

void glvertexpointer(glint size,glenum type,glsizei stride,const glvoid *pointer);void glcolorpointer(glint size,glenum type,glsizei stride,const glvoid *pointer);void glsecondarycolorpointer(glint size,glenum type,glsizei stride,const glvoid *pointer);void glindexpointer(glenum type,glsizei stride,const glvoid *pointer);void glnormalpointer(glenum type,glsizei stride,const glvoid *pointer);void glfogcoordpointer(glenum type,glsizei stride,const glvoid *pointer);void gltexcoordpointer(glint size,glenum type,glsizei stride,const glvoid *pointer);void gledgeflagpointer(glsizei stride,const glvoid *pointer);

这里写图片描述

    //启用多个顶点数组    static GLfloat vertices[] = {    -0.9,0,    0.9,0,    0.5,0.5,    0,0.9    };    static GLfloat colors[] = {    1,0,0,    0,1,0,    0,0,1,    1,1,0    };    glEnableClientState(GL_COLOR_ARRAY);    glEnableClientState(GL_VERTEX_ARRAY);    glColorPointer(3, GL_FLOAT, 0, colors);    glVertexPointer(2, GL_FLOAT, 0, vertices);    glBegin(GL_LINES);    glArrayElement(0);    glArrayElement(1);    glArrayElement(2);    glArrayElement(3);    glEnd();
    //解引用顶点数组    static GLfloat interwined[] =    {        1, 0, 0, -0.9, 0,        0, 1, 0, 0.9, 0,        0, 0, 1, 0.9, 0,        1, 1, 0, 0, 0.9    };    GLubyte index[] = {0,1,2,3};    glEnableClientState(GL_COLOR_ARRAY);    glEnableClientState(GL_VERTEX_ARRAY);    glColorPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), &interwined[0]);    glVertexPointer(2, GL_FLOAT, 5 * sizeof(GL_FLOAT), &interwined[3]);    glDrawElements(GL_LINES, 4, GL_UNSIGNED_BYTE, index);

以上两端代码实现的效果相同,如下图:
这里写图片描述

  • void glArryElement(GLint ith):
    获取当前所有已启用数组的一个顶点(第ith个)的数据。glarrayElement()通常是在glBegin()和glEnd()之间调用。否则,glArrayElement()函数就会设置所有启用的数组的当前状态。对于每个顶点只调用1次,因此它可能会减少函数调用的数量,提高程序的总体性能。

  • void glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid *indices):
    mode:和glbegin参数相同。
    count:定义一个几何图元序列,元素的索引值保存在indices数组中。
    type:必须是GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT或GL_UNSIGNED_INT,表示indices数组的类型。

    • 把gldrawelements()放在glbegin()与glend()之间是错误的做法。
      这里写图片描述
  • void glMultiDrawElements(GLenum mode,GLsizei *count,GLenum type,const GLvoid **indices ,GLsizei primcount )
    这里写图片描述
    这里写图片描述

  • void glDrawRangeElements(GLenum mode,GLUint start,GLuint end,GLsizei count,GLenum type,const GLvoid *indices )

    这里写图片描述

  • glDrawArrays(GLenum mode, GLint first,GLsizei count)

下面的这篇文章介绍的非常详细,但是想了解的更多还是看下opengl编程指南吧。
http://www.cnblogs.com/Clingingboy/archive/2010/10/16/1853304.html

创建缓冲区对象

  • void glenbuffers(glsizei n,gluint *buffers)

    1. 在buffer数组中返回n个当前未使用的名称,表示缓冲区对象。在buffers数组中返回的名称并不需要是连续的整数。
    2. 返回的名称被标记为已使用,以便分配给缓冲区对象。但是,当他们被绑定之后,只是会的一个合法的状态。
    3. 零是一个被保留的缓冲区对象名称,从来不会被glgenbuffers()作为缓冲区对象返回。
    4. 调用glisbuffer()函数,判断标志符是否是当被使用的缓冲区对象的标识符。这里写图片描述

激活缓冲区对象

这里写图片描述

用数据分配和初始化缓冲区对象

一旦绑定缓冲区对象,就需要保留空间以存储数据。glbufferdata()。

  • void glbufferdata(glenum target,glsizeiptr size,const glvoid *data,glenum usage)
    分配size个存储单位(通常是字节)的opengl服务器内存,用于存储顶点数据或索引。

更新缓冲区对象的数据值

  • void glbuffersubdata(glenum target,glintptr offset,glsizeiptr size,const glvoid *data)
    用data指向的数据更新与target相关联的当前绑定缓冲区对象中从offset(以字节为单位)开始的size个字节数据。size小于0或size+offset大于缓冲区对象创建时指定的大小,glbuffersubdata()将产生gl_invalid_value错误。

  • glvoid *glmapbuffer(glenum target,glenum access)
    返回一个指针,指向target相关联的当前绑定缓冲区对象的数据存储。
    在完成对数据存储的访问之后,可以调用glunmapbuffer()取消对这个缓冲区的映射。

0 0
原创粉丝点击