《OpenGL编程指南》第九版——2.绘制两个三角形

2019-06-18  本文已影响0人  祝你万事顺利

我将跟随OpenGL编程指南对每个例子进行详解,每个例子将贴出实验结果和实验代码,仅供参考,代码部分可能我会进行一些修改与官方代码不同。

实现效果:


TwoTriangles.PNG

1.Main函数

1.glfwInit初始化GLFW库
2.glfwCreateWindow设置程序所使用的窗口类型以及期望的窗口尺寸。还创建了一个与窗口关联的OpenGL设备环境。在使用环境之前,我们需要设置它为当前环境。在一个程序中我们可以设置多个设备环境,但是用户指令只会传递到当前设备环境中。
3.gl3wInit调用GL3W库,简化获取函数地址的过程
4.接下来调用Init函数初始化所有OpenGl相关数据,以便之后的渲染工作
5.无限循环指令,一直处理窗口和操作系统的用户输入,在循环中判断是否需要关闭窗口(glfwWindowShouldClose),重绘内容,并展现给用户(glfwSwapBuffers),然后查看操作系统返回的任何信息(glfwPollEvents)

//----------------------------------------------------------------------------
//
// main
//

#ifdef _WIN32
int CALLBACK WinMain(
  _In_ HINSTANCE hInstance,
  _In_ HINSTANCE hPrevInstance,
  _In_ LPSTR     lpCmdLine,
  _In_ int       nCmdShow
)
#else
int
main( int argc, char** argv )
#endif
{
    glfwInit();

    GLFWwindow* window = glfwCreateWindow(800, 600, "Triangles", NULL, NULL);

    glfwMakeContextCurrent(window);
    gl3wInit();

    init();

    while (!glfwWindowShouldClose(window))
    {
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);

    glfwTerminate();
}

2.Init

1.glCreateVertexArrays分配顶点数组对象
2.得到对象后将其绑定(bind)到OpenGL环境以便使用,glBindVertexArray函数创建并且绑定一个顶点数组对象,如果array变量非零,并且是glCreateVertexArrays所返回的,那么会激活这个顶点数组对象。总的来说,在两种情况下需要绑定对象:创建对象并初始化它所需的数据;以及每次我们准备使用此对象的时候。
在较大的程序里,通过调用3.glDeleteVertexArrays释放顶点数组对象。
4.为了保证完整性,调用gllsVertexArray检查某个名称是否已经被保留位一个定点数组对象了。

顶点数组对象保存一系列顶点的数据,这些数据保存到缓存对象中,并且由当前绑定的顶点数组对象管理。
1.glCreateBuffers创建顶点缓存对象,在例子中创建NumVBOs个对象到数组buffers当中。
2.调用glBindBuffer规定他们到OpenGL环境。
3.所有缓存对象都可以使用glDeleteBuffers直接释放。
4.glNamedBufferStorge分配顶点数据所需的存储空间,将数据从应用程序拷贝到内存中。
glNamedBufferStorge函数详细定义:作用于名为buffer的缓存区域,由于我们的数据是顶点属性数据,因此设置这个缓存目标为GL_ARRAY_BUFFER。制定内存分配的大小size,data指定客户端内存的指针,以便初始化对象,如果是NULL,那么将保留size大小的未初始化数据。,最后指定数据在OpenGL中的使用方式。

//----------------------------------------------------------------------------
//
// init
//

void
init( void )
{
    glGenVertexArrays( NumVAOs, VAOs );
    glBindVertexArray( VAOs[Triangles] );

    GLfloat  vertices[NumVertices][2] = {
        { -0.90f, -0.90f }, {  0.85f, -0.90f }, { -0.90f,  0.85f },  // Triangle 1
        {  0.90f, -0.85f }, {  0.90f,  0.90f }, { -0.85f,  0.90f }   // Triangle 2
    };

    glCreateBuffers( NumBuffers, Buffers );
    glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer] );
    glBufferStorage( GL_ARRAY_BUFFER, sizeof(vertices), vertices, 0);

    ShaderInfo  shaders[] =
    {
        { GL_VERTEX_SHADER, "media/shaders/triangles/triangles.vert" },
        { GL_FRAGMENT_SHADER, "media/shaders/triangles/triangles.frag" },
        { GL_NONE, NULL }
    };

    GLuint program = LoadShaders( shaders );
    glUseProgram( program );

    glVertexAttribPointer( vPosition, 2, GL_FLOAT,
                           GL_FALSE, 0, BUFFER_OFFSET(0) );
    glEnableVertexAttribArray( vPosition );
}

3.初始化顶点与片元着色器

通过LoadShaders函数指定两个着色器,使用GLSL语言编写着色器程序。

#version 400 core表示我们使用OpenGL4.5版本对应的GLSL语言
vPosition是输入变量被声明为in指定了数据进入着色器的流向,最后字段layout(location = 0),布局限定符为变量提供元数据。
main函数实现输入顶点位置复制到顶点着色器的指定输出位置gl_Position中,

#version 400 core

layout( location = 0 ) in vec4 vPosition;

void
main()
{
    gl_Position = vPosition;
}

片元着色器
声明变量fColor使用限定符out,这里着色器将fColor对应的数值输出,也就是片元对应的颜色值。

#version 450 core

out vec4 fColor;

void main()
{
    fColor = vec4(0.5, 0.4, 0.8, 1.0);
}

init中最后两个函数指定了顶点着色器变量与缓存对象中数据的关系。
glEnableVertexAttribArray启用顶点属性数组,

3.Display

1.首先清除帧缓存的数据再进行渲染。
2.选择准备绘制的定点数据,然后请求进行绘制。调用glBindVertexArray选择作为顶点数据使用的顶点数组。
3.glDrawArrays实现顶点数据向OpenGL管线的传输。

//----------------------------------------------------------------------------
//
// display
//

void
display( void )
{
    static const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };

    glClearBufferfv(GL_COLOR, 0, black);

    glBindVertexArray( VAOs[Triangles] );
    glDrawArrays( GL_TRIANGLES, 0, NumVertices );
}
上一篇下一篇

猜你喜欢

热点阅读