[OpenGL红宝书]第一章 OpenGL概述

第一章 OpenGL概述

标签(空格分隔): OpenGL

  • 第一章 OpenGL概述

    • 1 什么是OpenGL
    • 2 初识OpenGL程序
    • 3 OpenGL语法
    • 4 OpenGL渲染管线
      • 41 准备向OpenGL传输数据
      • 42 将传输数据到OpenGL
      • 43 顶点着色
      • 44 细分着色
      • 45 几何着色
      • 46 图元装配
      • 47 剪切
      • 48 光栅化
      • 49 片元着色
      • 410 逐片元的操作
    • 5 第一个程序深入分析
      • 51 进入main函数
      • 52 OpenGL的初始化过程
        • 初始化顶点数组对象
        • 分配顶点缓存对象
        • 将数据加载缓存对象
        • 初始化顶点与片元着色器
      • 53 第一次使用OpenGL进行渲染

1.1 什么是OpenGL

OpenGLwikipedia是一种应用程序编程接口(API),它是一种能够对图形硬件设备特性进行訪问的软件库。

一个用来渲染图像的OpenGL程序须要运行的主要操作例如以下:

1. 从OpenGL的几何图元中设置数据,用于构建形状。

2. 使用不同的着色器(shader)对输入的图元数据运行计算操作。推断它们的位置、颜色。以及其它渲染属性。

3. 将输入图元的数学描写叙述转化为与屏幕位置相应的像素片元(fragment)。这一步也称为光栅化(rasterization)。

4. 最后,针对光栅化过程产生的每一个片元,运行片元着色器(fragment shader),从而决定这个片元的终于颜色和位置。

5. 假设有必要,还须要对每一个片元运行一些额外的操作,比如推断片元相应的对象是否可见,或者将片元的颜色与当前屏幕位置的颜色进行融合。

何为光栅化(rasterization)?

将输入图元的数学描写叙述转换为与屏幕位置相应的像素片元。称为光栅化。

1.2 初识OpenGL程序

一些图形学名词:

1. 几何图元,包括点、线、三角形以及Patch。

2. 渲染(render),表示计算机从模型创建终于图像的过程。

3. 着色器(shader),专为图形处理单元(GPU)编译的一种小型程序。

4. 四种不同的着色阶段(shander stage),当中最经常使用的包括顶点着色器(vertex shader)以及片元着色器。前者用于处理顶点数据,后者用于处理光栅化后的片元数据。

全部OpenGL程序都须要用到这两类着色器。

5. 帧缓存(framebuffer)。像素(pixel),是显示器上最小的可见单元。计算机系统将全部的像素保存到帧缓存当中,后者是有图形硬件设备管理的一块独立内存区域,能够直接映射到终于的显示设备上。

例1.1 第一个OpenGL程序triangles.cpp

代码(坚果云)

在VS 2013上实现。当中包括了红书官网所提供的源文件里的头文件,以及当中的库文件。运行结果例如以下:

1.3 OpenGL语法

本书所使用的GLUT(OpenGL Utility Toolkit)版本号为Freeglut。是原始GLUT库的一个新变种。

1.4 OpenGL渲染管线

rendering pipeline,它是一系列数据处理过程,而且将应用程序的数据转换到终于渲染的图像。

下图为OpenGL4.3版本号的管线。包括:

顶点数据,顶点着色器,细分着色器(细分控制着色器。细分计算着色器),几何着色器。图元设置,剪切。光栅化。片元着色器

1.4.1 准备向OpenGL传输数据

OpenGL须要将全部的数据都保存到缓存对象(buffer object)中。

我们能够使用多种方式创建这种数据缓存,最经常使用的是glBufferData()wiki

Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (aka: the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.

–from wiki

1.4.2 将传输数据到OpenGL

当将缓存初始化完毕后,通过调用OpenGL的一个绘制命令来请求渲染几何图元。

glDrawArrays()wiki就是一个经常使用的绘制命令。

OpenGL的绘制通常就是将顶点传输数据到OpenGL服务端。

1.4.3 顶点着色

对于绘制命令传输的每一个顶点,OpenGL都会调用一个顶点着色器来处理顶点相关的数据。

仅仅是将数据复制并传递到下一个着色阶段,叫做传递着色器(pass-through shader)。

通常来说。一个复杂的应用程序可能包括很多顶点着色器,但在同一时刻仅仅能有一个顶点着色器起作用。

1.4.4 细分着色

顶点着色器处理每一个顶点的关联数据之后。假设同一时候激活了细分着色器,那么它将进一步处理这些数据。

(第9章介绍)

细分着色器阶段会用到两个着色器来分别管理Patch数据并产生终于的形状。

1.4.5 几何着色

第10章介绍。

1.4.6 图元装配

图元装配将顶点及相关的集合图元之间组织起来。准备下一步剪切和光栅化操作。

1.4.7 剪切

顶点可能落在视口(viewport)之外,此时与顶点相关的图元会做出修改,以保证相关的像素不会在视口外绘制。剪切(clipping)由OpenGL自己主动完毕。

1.4.8 光栅化

将更新后的图元(primitive)传递到光栅化单元。生成相应的片元(fragment)。我们将一个片元是为一个“候选的像素”。

也就是能够放置在帧缓存(framebuffer)中的像素,可是它也可能被终于剔除,不再更新相应的像素位置。之后两个阶段将会运行片元的处理。

1.4.9 片元着色

最后一个能够通过编程控制屏幕上显示颜色的阶段。在Fragment Shader阶段中,我们使用着色器计算片元的终于颜色和它的深度值。

顶点着色器与片元着色器之间的差别:

顶点着色(包括细分和几何着色)决定了一个图元应该位于屏幕的什么位置,而片元着色使用这些信息来决定某个片元的颜色应该是什么。

1.4.10 逐片元的操作

在这个阶段会使用深度測试(depth test,或者通常也称为z-bufffering)和模板測试(stencil test)的方式来决定一个片元是否是可见的。

1.5 第一个程序:深入分析

1.5.1 进入main()函数

int main (int argc, char ** argv)
{
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_RGBA);
    glutInitWindowSize (512, 512);
    glutInitContextVersion (4, 3);
    glutInitContextProfile (GLUT_CORE_PROFILE);
    glutCreateWindow (argv[0]);
    glewExperimental = GL_TRUE;     

    if (glewInit ()) {
        cerr << "Unable to initialize GLEW ... exiting..." << endl;
        exit (EXIT_FAILURE);
    }

    init ();

    glutDisplayFunc (display);

    glutMainLoop ();

前面的6行使用GLUT(OpenGL Utility Toolkit)初始化和打开了一个渲染用的窗体:

1. glutInit()负责初始化GLUT库,负责设置其它GLUT例程所必须的数据结构。

2. glutInitDisplayMode()设置了程序所使用的窗体的类型。在这个样例中仅仅设置了窗体使用的RGBA颜色空间。

3. glutInitWindowSize()设置所需的窗体大小。

4. glutInitContextVersion()、glutInitContextProfile设置所需的OpenGL环境(context)的类型。这个样例中使用OpenGL 4.3版本号的核心模式(core profile)来创建环境。这个模式确保使用的仅仅是OpenGL的最新特性。否则也能够使用兼容模式,这样自OpenGL 1.0以来的全部特性都能够在程序中使用。

5. glutCreateWindow(),假设当前的系统环境能够满足glutInitDisplayMode()的显示模式要求,这里就会创建一个窗体(此时会调用计算机窗体系统的接口)。仅仅有GLUT创建了一个窗体之后(当中包括创建创建OpenGL环境的过程),我们才干够使用OpenGL相关的函数。

接下来会调用glewInit()函数,属于还有一个辅助库GLEW(OpenGL Extention Wrangler)。

GLEW能够简化获取函数地址的过程,而且包括了能够跨平台使用的其它一些OpenGL编程方法。

到这,完毕了使用OpenGL之前的全部设置工作。

之后init()函数初始化OpenGL相关的全部数据。

在之后完毕渲染工作。

  1. glutDisplayFunc(),它设置了一个显示回调(diplay callback),即GLUT在每次更新窗体内容的时候回自己主动调用该例程。
  2. glutMainLoop(),这是一个无限运行的循环,它会负责一直处理窗体和操作系统的用户输入等操作。(注意:不会运行在glutMainLoop()之后的全部命令。)

1.5.2 OpenGL的初始化过程

void init (void)
{
    glGenVertexArrays (NumVAOs, VAOs);
    glBindVertexArray (VAOs[Triangles]);
    GLfloat vertices[NumVertices][2] = {
        { -0.90, -0.90 },       // Triangle 1
        { 0.85, -0.90 },
        { -0.90, 0.85 },
        { 0.90, -0.85 },        // Triangle 2,
        { 0.90,  0.90 },
        { -0.85, 0.90 }
    };

    glGenBuffers (NumBuffers, Buffers);
    glBindBuffer (GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
    ShaderInfo shaders[] = {
        { GL_VERTEX_SHADER, "triangles.vert" },
        { GL_FRAGMENT_SHADER, "triangles.frag" },
        { GL_NONE, NULL }
    };

    GLuint program = LoadShaders (shaders);
    glUseProgram (program);
    glVertexAttribPointer (vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET (0));
    glEnableVertexAttribArray (vPosition);
}

初始化顶点数组对象

  • glGenVertexArrays(NumVAOs, VAOs)分配顶点数组对象(vertext array object)。OpenGL会因此分配一部分(NumVAOs个)顶点数组对象的名称供我们使用,保存到数组VAOs中。

void glGenVertexArrays(GLsizei n?, GLuint *arrays?);

n

Specifies the number of vertex array object names to generate.

arrays

Specifies an array in which the generated vertex array object names are stored.

The names returned in arrays? are marked as used, for the purposes of glGenVertexArrays only, but they acquire state and type only when they are first bound.

非常多OpenGL命令都是glGen*的形式,它们负责分配不同类型的OpenGL对象的名称。这里的名称相似C语言中的指针变量。必须分配内存而且用名称引用它之后,名称才有意义。

在OpenGL中。这个分配的机制叫做绑定对象(bind an object)。这通过一系列glBind*形式的OpenGL函数集合去实现。

  • glBindVertexArray (VAOs[Triangles])创建一个顶点数组对象,并与其名称(VAOs[Triangles])关联起来。

    void glBindVertexArray(GLuint array?);

    array

    Specifies the name of the vertex array to bind.

  • 当我们第一次绑定对象时(比如,第一次用指定的对象名作为參数调用glBind*()),OpenGL内部会分配这个对象所需的内存而且将它作为当前对象。即后继的操作都会作用于这个被绑定的对象。比如,这里的顶点数组对象就会被后面运行的代码所改变。

    有两种情况我们须要绑定一个对象:

    1. 创建对象并初始化它所相应的数据时。
    2. 每次我们准备使用这个对象。而它并非当前绑定的对象时。

  • (未使用)glDeleteVertexArrays()。当我们完毕对顶点数组对象的操作之后。能够调用此函数将它(们)释放。

    void glDeleteVertexArrays(GLsizei n?, const GLuint *arrays?);

    n

    Specifies the number of vertex array objects to be deleted.

    arrays

    Specifies the address of an array containing the n? names of the objects to be deleted.

  • (未使用)glIsVertexArray(),检查某个名称是否已经关联到一个顶点数组对象了。

    GLboolean glIsVertexArray(GLuint array?);

    array

    Specifies a value that may be the name of a vertex array object.

分配顶点缓存对象

顶点数组对象(VAO)负责保存一系列顶点的数据。

这些数据保存到缓存对象(Buffer Object)中,而且由当前绑定的顶点数组对象管理。

官方解释:A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects providing the vertex data arrays.

  • glGenBuffers (NumBuffers, Buffers) 返回NumBuffers个当前未使用的缓存对象名称到数组Buffers中。(名称不一定是连续的整型数据)

    void glGenBuffers(GLsizei n?, GLuint * buffers?);

    n

    Specifies the number of buffer object names to be generated.

    buffers

    Specifies an array in which the generated buffer object names are stored.

    No buffer objects are associated with the returned buffer object names until they are first bound by calling glBindBuffer?.

  • glBindBuffer (GL_ARRAY_BUFFER, Buffers[ArrayBuffer])在分配缓存的名称之后。就能够调用glBindBuffer()来绑定它们了。由于OpenGL中有非常多种不同类型的缓存对象,因此绑定一个缓存时,须要指定它所相应的类型。此例中由于是将顶点数据保存到缓存中(故为顶点缓存对象VBO),因此使用GL_ARRAY_BUFFER类型。

    void glBindBuffer(GLenum target?, GLuint buffer?);

    target

    Specifies the target buffer object. The symbolic constant must be GL_ARRAY_BUFFER, GL_ATOMIC_COUNTER_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_DRAW_INDIRECT_BUFFER, GL_DISPATCH_INDIRECT_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_QUERY_BUFFER, GL_SHADER_STORAGE_BUFFER, GL_TEXTURE_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, or GL_UNIFORM_BUFFER.

    buffer

    Specifies the name of a buffer object.

    When a buffer object is bound to a target, the previous binding for that target is automatically broken.

  • (未使用)glDeleteBuffers(),全部的缓存对象都能够使用glDeleteBuffers()直接释放。

    void glDeleteBuffers(GLsizei n?, const GLuint * buffers?);

    n

    Specifies the number of buffer objects to be deleted.

    buffers

    Specifies an array of buffer objects to be deleted.

  • glIsBuffer(),使用此函数来推断一个整数值是否为缓存对象的名称。

    GLboolean glIsBuffer(GLuint buffer);

    buffer

    Specifies a value that may be the name of a buffer object.

    A name returned by glGenBuffers?, but not yet associated with a buffer object by calling glBindBuffer?, is not the name of a buffer object.

将数据加载缓存对象

  • glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW),初始化顶点缓存对象之后(VBO)。我们须要把顶点传输数据到缓存对象中。它主要有两个任务:分配顶点数据所需的存储空间(内存中)。然后将数据从应用程序的数组中复制到OpenGL服务端的内存中。

    void glBufferData(GLenum target?, GLsizeiptr size?, const GLvoid * data?, GLenum usage?);

    target

    Specifies the target buffer object. The symbolic constant must be GL_ARRAY_BUFFER, GL_ATOMIC_COUNTER_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_DRAW_INDIRECT_BUFFER, GL_DISPATCH_INDIRECT_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_QUERY_BUFFER, GL_SHADER_STORAGE_BUFFER, GL_TEXTURE_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, or GL_UNIFORM_BUFFER.

    size

    Specifies the size in bytes of the buffer object’s new data store.

    data

    Specifies a pointer to data that will be copied into the data store for initialization, or NULL if no data is to be copied.

    usage

    Specifies the expected usage pattern of the data store. The symbolic constant must be GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY.

初始化顶点与片元着色器

  • 对于每一个OpenGL程序,当它所使用的OpenGL版本号高于或等于3.1时,就须要指定至少两个着色器:顶点着色器和片元着色器。这个样例中,我们使用LoadShaders()来实现这个要求。

    对于OpenGL程序猿而言,着色器就是使用OpenGL着色语言(GLSL,OpenGL Shading Language)编写的一个小型函数。

例1.2 triangles.cpp相应的顶点着色器:triangles.vert

#version 430 core
layout (location = 0) in vec4 vPosition;
void
main ()
{
        gl_Position = vPosition;
}

其实这就是我们所说的传递着色器(pass-through shader)。它仅仅负责将输入数据复制到输出数据中。

第一行

 #version 430 core

指定了OpenGL着色语言的版本号。

每一个着色器的第一行都应该设置#version,否则就会假设使用“110”版本号。

下一步,分配了一个着色器变量。着色器变量是着色器与外部世界的联系所在。着色器并不知道自己的数据从哪里来。它仅仅是在每次运行时直接获取数据相应的输入变量。而我们必须自己完毕着色管线的装配。然后才干够将应用程序中的数据与不同的OpenGL着色阶段相互关联。

layout (location = 0) in vec4 vPosition;
  • vPosition 是变量的名称。

    这个变量保存的是顶点的位置信息。(字符“v”作为这个顶点属性名称的前缀)

  • vec4,是vPosition的类型。在这里它是一个GLSL的四维浮点数向量。、
  • in。它指定了数据进入着色器的流向。
  • layout(location = 0)。叫做布局限定符(layout qualifier)。目的是为变量提供元数据(meta data)。这里设置vPosition的位置属性location为0。这个设置与init()函数的最后两行会共同起作用。

最后。在着色器的main()函数中实现它的主体部分。对于这个着色器而言。它所实现的就是将输入的顶点位置(存在vPosition中)复制到顶点着色器的指定输出位置gl_Position

例1.3 triangles.cpp相应的片元着色器:triangles.frag

@version 430 core
out vec4 fColor
void
main()
{
    fColor = vec4(0.0, 0.0, 1.0, 1.0);
}
  • 变量名为fColor,使用了out限定符,在这里着色器将会把fColor相应的数值输出,而这也就是片元所相应的颜色值。

    (因此这里前缀“f”)

  • OpenGL使用了RGBA颜色空间,A即aplha值(透明度)。1.0为不透明。

init()中的最后两个函数指定了顶点着色器的变量与我们存储在缓存对象中的数据的关系。这也就是我们所说的着色管线的装配过程,即将程序与着色器之间,以及不同着色阶段之间的数据通道连接起来。

  • glVertexAttribPointer (vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET (0));

    为了输入顶点着色器所需的数据。也就是OpenGL将要处理的全部顶点数据,须要在着色器中声明一个in变量,然后使用glVertexAttribPointer()将它关联到一个顶点属性数组。

    glVertexAttribPointer()是一个非常灵活的命令,仅仅要内存中的数据是规范组织的(保存在一个连续的数组中,不使用其它基于节点的容器,如链表)。我们就能够使用glVertexArrtibPointer()告诉OpenGL直接从内存中获取数据。

    void glVertexAttribPointer(GLuint index?, GLint size?, GLenum type?, GLboolean normalized?, GLsizei stride?, const GLvoid * pointer?);

    void glVertexAttribIPointer(GLuint index?, GLint size?, GLenum type?, GLsizei stride?, const GLvoid * pointer?);

    void glVertexAttribLPointer(GLuint index?, GLint size?, GLenum type?, GLsizei stride?, const GLvoid * pointer?);

    index

    Specifies the index of the generic vertex attribute to be modified.

    size

    Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4. Additionally, the symbolic constant GL_BGRA is accepted by glVertexAttribPointer. The initial value is 4.

    type

    Specifies the data type of each component in the array. The different functions take different values.

    glVertexAttribPointer and glVertexAttribIPointer both take: GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, and GL_UNSIGNED_INT

    glVertexAttribPointer also can take: GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, and GL_UNSIGNED_INT_10F_11F_11F_REV.

    glVertexAttribLPointer takes only GL_DOUBLE.

    The initial value is GL_FLOAT.

    normalized

    For glVertexAttribPointer, specifies whether fixed-point data values should be normalized (GL_TRUE) or converted directly as fixed-point values (GL_FALSE) when they are accessed.

    stride

    Specifies the byte offset between consecutive generic vertex attributes. If stride? is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.

    pointer

    Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. The initial value is 0.

  • glEnableVertexAttribArray (vPosition);

    我们通过glEnableVertexAttribArray()来启用顶点属性数组。

    glVertexAttribPointer()初始化的属性数组指针索引传入这个函数。

    void glEnableVertexAttribArray(GLuint index?);

    void glDisableVertexAttribArray(GLuint index?);

    index

    Specifies the index of the generic vertex attribute to be enabled or disabled.

1.5.3 第一次使用OpenGL进行渲染

void display (void)
{
    glClear (GL_COLOR_BUFFER_BIT);
    glBindVertexArray (VAOs[Triangles]);
    glDrawArrays (GL_TRIANGLES, 0, NumVertices);
    glFlush ();
}
  • glClear(GL_COLOR_BUFFER_BIT),清除帧缓存的数据。

void glClear(GLbitfield mask?);

mask

Bitwise OR of masks that indicate the buffers to be cleared. The three masks are GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, and GL_STENCIL_BUFFER_BIT.

  • (未使用)glClearColor(GLfloat red?, GLfloat green?, GLfloat blue?, GLfloat alpha?),设置当前使用的清除颜色值,用于RGBA模式下对颜色缓存的清除工作。

    清除颜色本身也是OpenGL状态机制的一个样例,它的数值会一直保留在当前OpenGL环境当中。

    OpenGL有一个庞大的状态量列表。

    当创建一个新的OpenGL环境时。全部的状态量都会被初始化为默认值。由于OpenGL会保留全部更改的状态值,所以我们能够降低设置状态数值的次数。

    故而。在设置清除颜色为白色时,能够在display()函数中调用glClearColor(1, 1, 1, 1)。也能够在init()函数中调用glClearColor(1, 1, 1, 1),后者效率更高,由于能够避免冗余的状态切换。

  • glBindVertexArray (VAOs[Triangles]),选择作为顶点数据使用的顶点数组。我们能够使用这个函数来切换程序中保存的多个顶点数据对象集合。
  • glDrawArrays (GL_TRIANGLES, 0, NumVertices),使用当前绑定的顶点数组元素来建立一系列的几何图元。

    实现顶点数据向OpenGL管线的传输。

    glDrawArrays: render primitives from array data

    void glDrawArrays(GLenum mode?, GLint first?, GLsizei count?);

    mode

    Specifies what kind of primitives to render. Symbolic constants GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_LINE_STRIP_ADJACENCY, GL_LINES_ADJACENCY, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_TRIANGLE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY and GL_PATCHES are accepted.

    first

    Specifies the starting index in the enabled arrays.

    count

    Specifies the number of indices to be rendered.

  • glFlush (),强制全部进行中的OpenGL命令马上完毕并传输到OpenGL服务端处理。

    glFlush: force execution of GL commands in finite time

    void glFlush(void?);

  • (未使用)glFinish(),会等待全部当前的OpenGL操作完毕。

    而glFlush()则仅仅是强制全部运行中的命令送入OpenGL服务端而已。不会等待全部的命令完毕。因此当我们须要了解OpenGL是在是么时候完毕操作的时候使用glFinish()。

    glFinish: block until all GL execution is complete

    void glFinish(void?);

    glFinish does not return until the effects of all previously called GL commands are complete. Such effects include all changes to GL state, all changes to connection state, and all changes to the frame buffer contents.

  • (未使用)glEnable(),glDisable(),启用或禁用OpenGL的操作模式。

    glEnable: enable or disable server-side GL capabilities

    void glEnable(GLenum cap?);

    void glDisable(GLenum cap?);

    cap

    Specifies a symbolic constant indicating a GL capability.

  • (未使用)glIsEnabled(),返回是否启用指定模式。

    glIsEnabled, glIsEnabledi: test whether a capability is enabled

    GLboolean glIsEnabled(GLenum cap?);

    GLboolean glIsEnabledi(GLenum cap?, GLuint index?);

    cap

    Specifies a symbolic constant indicating a GL capability.

    index

    Specifies the index of the capability.



  • 相关链接:

    - OpenGL WIKI

    - 关于VAO && VBO官方

    - 关于VAO && VBO博客

    - GLUT API

    - FreeGLUT API

    - GLEW 官网

    时间: 2024-10-05 00:13:29

    [OpenGL红宝书]第一章 OpenGL概述的相关文章

    OPENGL 红宝书实验笔记

    第一个程序triangles的配置过程,原文链接. OpenGL的东西快忘光了,把角落的第八版红宝书拿出来复习一下 从书中的地址下了个示例代码结果新系统(Win10+VS2015)各种跑不起来,懊恼之后在网上疯狂搜索资料终于跑起来了,记录一下 一.环境搭建指南 书中的地址 http://www.opengl-redbook.com/ 去这里打包下载OpenGL红宝书的示例代码,解压后是这样 虽然没有第一章的代码但第一章的内容好歹算一个完整的例子,网上各种环境搭建教程也都以第一章的代码为例,我们就

    【转载】关于在vs2013中配置opengl红宝书第八版环境

     本文为转载 原文地址 http://blog.csdn.net/qq821869798/article/details/45247241 本人刚开始学习opengl,买了一本opengl红宝书第八版, 第一个例子研究了一段时间终于可以运行了,不知道有没有童鞋跟我遇到一样的问题. 下面说说我怎么配置的: 首先去 http://www.opengl-redbook.com/ 下载红宝书的源代码,解压得到这个 然后打开vs2013新建一个空的win32控制台项目, 然后点项目右键属性,点击vc++目

    VS2012通过makefile编译OpenGL红宝书的示例代码

    > 通过创建新VC项目,然后设置一堆属性,对于懒人来说还是太复杂了.既然它自带了makefile,可以尝试下使用nmake. 需要注意的是VS2012的安装目录里面已经没有GL的头文件和库文件.这个改动应该在VS2010或者更早就已经采用了. 现在有了VS SDK.VS2010自动的SDK目录是C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A,更高的版本可能使用v8.0.v8.0A,反正都在这个目录下面.这个目录下面有include.lib文

    OpenGL红宝书学习笔记(1)

    OpenGL对场景中的图像进行渲染时所执行的主要操作: 1.根据几何图元创建形状,从而建立物体的数学描述,(OpenGL把点,直线,多边形和位图作为基本的图元) 2.在三维空间中排列物体,并选择观察复合场景中的视角 3. 计算所有物体的颜色.颜色可以由应用程序明确指定,可以根据特定的光照条件确定,也可以通过把纹理贴到物体的表面而获得,或者是上述三种操作的混合产物, 这些操作可能使用着色器来执行,这样可以显式的控制所有的颜色计算,或者可能使用OpenGL的预编程算法在其内部执行(我盟常用术语固定功

    OpenGL红宝书附带源码编译问题集锦

    以下所有源码均在win7,VS2008环境下测试.下不再赘述. 1.所有的.c扩展名请改为.cpp扩展名,以避免不可预测的错误. 想知道会出现什么不可预测的错误..请见我上一篇Blog... 2.如果有的文件无法识别标示符,在头文件部分加上#include <glext.h>这是因为部分特性从gl库中移除到其他扩展库了.比如glext,glew,都是扩展库. 3.blendeqn在头文件部分加上#include <glext.h> PFNGLBLENDEQUATIONPROC gl

    第一章 HTML5 概述

    这是一本关于 HTML5 编程的书.不过在学习之前,有必要先了解一下背景知识,什么是 HTML5?它经历了怎样的发展历程?HTML4 和 HTML5 有什么区别?本章中,我们会集中讨论大家关注的一些实际问题.为什么是 HTML5?为什么它能掀起风潮?是什么设计理念使得 HTML5 真正具有革命性的进步?HTML5 如何在大幅改动的同时保持高度兼容?无插件范式意味着什么?HTML5 包含什么,不包含什么?HTML5 新增加了哪些特性,为什么能揭开整个 Web 开发新时代的序幕?下面我们一起来了解一

    第一章:Http概述

    第一章:Http概述 引言 web浏览器.服务器和相关的web应用程序都是通过http相互通信的,http是现代全球英特网中使用的公共语言. 本章主要内容 1.web客户端与服务器是如何通信的 2.资源(表示web内容)来自何方 3.web事务(请求与响应)是怎样工作的 4.http通信所使用的报文(请求报文/响应报文) 5.底层TCP网络协议 6.不同的http协议变体 1.2web客户端与服务器 web内容都是存储在web服务器上的.web服务器所使用的是http协议,因此也经常称web服务

    Laxcus大数据管理系统(2)- 第一章 基础概述 1.1 基于现状的一些思考

    第一章 基础概述 1.1 基于现状的一些思考 在过去十几年里,随着互联网产业的普及和高速发展,各种格式的互联网数据也呈现爆炸性增长之势.与此同时,在数据应用的另一个重要领域:商业和科学计算,在各种新兴技术和产业需求的推动下,对数据存储和计算要求也日益提高,并且对计算数据的准确性和精度也远高于互联网数据.而在这些现象的背后,当前的数据计算早已经突破MB量级,GB成为常态,TB变得流行,正在向PB迈进的时候,面对如此庞大的数据量,如果管理和使用它们,满足各种计算需求,发现和筛选其中有价值的信息,通常

    学习笔记:第一章——计算机网络概述

    学习笔记:第一章--计算机网络概述 1.0 计算机网络的定义:一些互相连接的,自治的计算机的集合称为计算机网路. 1.1 计算机网络在信息时代中的作用:连通和共享. 1.2 因特网概述:       网络的概念:网络(network)是由若干个结点(node)和连接这些结点的链路(link)组成. 网络中的结点可以是计算机,集线器,交换机和路由器: 网络和网络是通过路由器连接: 因特网是世界上最大的网络. 1.3 因特网的组成: 从因特网的工作方式上将其分为以下两大快: (1)边缘部分:由所有的