阿升

V1

2022/07/02阅读:15主题:默认主题

使用CLion编译OGLPG-9th-Edition源码

  OpenGL是一种可以对图形硬件设备特性进行访问的软件库,它的1.0版本发布于1994年7月,主要用于计算机图形学。随着AR和VR的发展,计算机图形学算法会变的日益重要,比如光线追踪[RayTracing]。

一.编译源码

使用CLion打开OGLPG-9th-Edition源码[1],在根目录下创建build文件夹,然后cd build,执行命令cmake ..,报错如下所示: 解决方法是注释CMakeLists.txt文件中的92-94行代码:

二.遇到问题

  遇到无法打开文件glfw3_d.lib问题时,需要编译OGLPG-9th-Edition\lib\glfw源码[3]: 编译解决方案,在OGLPG-9th-Edition\lib\glfw\build\src\Debug中可以找到glfw3.lib和glfw3.pdb文件: 将glfw3.lib和glfw3.pdb重命名为glfw3_d.lib和glfw3_d.pdb后,拷贝到OGLPG-9th-Edition\lib目录下面:

三.运行例子

运行例子01-keypress.cpp如下所示: 运行例子01-triangles.cpp如下所示:

四.01-triangles.cpp源码分析

(1)顶点着色器和片元着色器
GLFW库是什么呢?GLFW是用来创建OpenGL上下文以及操作窗口的一个第三方库。那Glew库又是什么呢?由于各个平台和显卡厂家的OpenGL的API都有区别,Glew[OpenGL Extension Wrangler Library]就是把这些个API整合起来的一个库。顶点着色(包括细分和几何着色)决定了一个图元应该位于屏幕的什么位置,而片元着色使用这些信息来决定某个片元的颜色应该是什么。
(2)OpenGL和C数据类型对应关系

后缀 数据类型 C语言数据类型 对应的OpenGL类型
b 8位整型 signed char GLbyte
s 16位整型 signed short GLshort
i 32位整型 int GLint、GLsizei
f 32位浮点型 float GLfloat、GLclampf
d 64位浮点型 double GLdouble、GLclampd
ub 8位无符号整型 unsigned char GLubyte
us 16位无符号整型 unsigned short GLushort
ui 32位无符号整型 unsigned int GLuint、GLenum、GLbitfield

(3)01-triangles.cpp文件源码和注释

#include "vgl.h"
#include "LoadShaders.h"

enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };

GLuint  VAOs[NumVAOs];
GLuint  Buffers[NumBuffers];

const GLuint  NumVertices = 6;

void init( void )
{
    // n:指定要生成的顶点数组对象名字的数量
    // arrays:指定生成的顶点数组对象名字要存储的数组
    // 分配顶点数组对象:返回n个未使用的对象名到数组arrays中,用作顶点数组对象
    glGenVertexArrays( NumVAOs, VAOs );

    // array:指定绑定的顶点数组的名字
    // 创建并绑定一个顶点数组对象
    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
    };

    // void glCreateBuffers(GLsizei n, GLuint* buffers);
    // 返回n个当前未使用的缓存对象名称(每个都表示一个新创建的缓存对象),并保存到buffers数组中
    glCreateBuffers( NumBuffers, Buffers );

    // void glBindBuffer(GLenum target, GLuint buffer);
    // 将名称为buffer的缓存对象绑定到target所指定的缓存结合点。target必须是OpenGL支持的缓存绑定目标之一,buffer必须是通过glCreateBuffers()分配的名称。
    // 如果buffer是第一次被绑定,那么它所对应的缓存对象也将同时被创建。
    glBindBuffer( GL_ARRAY_BUFFER, Buffers[ArrayBuffer] );

    // void glBufferStorage(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags);
    // glBufferStorage为当前绑定到目标缓冲区对象创建新的不可变数据存储
    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(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
    // index:着色器中的属性位置
    // size:表示每个顶点需要更新的分量数目,可以是1、2、3、4或GL_BGRA
    // type:指定数组中每个元素的数据类型
    // normalized:设置顶点数据在存储前是否需要进行归一化
    // stride:数组中每两个元素之间的大小偏移值
    // pointer:表示缓存对象中,从起始位置开始计算的数组数据的偏移值,使用基本的系统单位byte
    glVertexAttribPointer( vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
    glEnableVertexAttribArray( vPosition );
}

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

    // 清除帧缓存中的数据再进行渲染
    // GL_COLOR:清除的缓存类型
    // 0:设置要清除的缓存索引
    // back:设置清除缓存之后的颜色
    glClearBufferfv(GL_COLOR, 0, black);

    // 选择作为顶点数据使用的顶点数组
    glBindVertexArray( VAOs[Triangles] );

    // 请求渲染几何图元
    glDrawArrays( GL_TRIANGLES, 0, NumVertices );
}

int main( int argc, char** argv )
{
    // glfw初始化和配置
    glfwInit();

    // 同时创建渲染窗口换个一个新的OpenGL环境,用来执行渲染指令
    GLFWwindow* window = glfwCreateWindow(800, 600, "Triangles", NULL, NULL);

    // 设置window中的窗口所关联的OpenGL环境为当前环境
    glfwMakeContextCurrent(window);
    // 初始化GL3W库,创建OpenGL环境前,这个方向必须调用一次
    gl3wInit();

    // 设置程序中用到的数据
    init();

    while (!glfwWindowShouldClose(window))
    {
        // 渲染工作
        display();
        // 交换该窗口前端和后端的缓存,重回内容并且显示出来
        glfwSwapBuffers(window);
        // 处理所有的等待事件,检查操作系统返回的任何信息
        glfwPollEvents();
    }

    // 销毁指定窗口和它的上下文环境,判断是否需要关闭窗口
    glfwDestroyWindow(window);

    // 关闭GLFW库
    glfwTerminate();
}

(4)顶点着色器triangles.vert文件代码和注释

#version 400 core //OpenGL着色语言版本

layout( location = 0 ) in vec4 vPosition; //保存顶点位置信息

void main()
{
    gl_Position = vPosition; //将输入顶点位置复制到顶点着色器的指定输出位置
}

(5)片元着色器文件代码和注释

#version 450 core

out vec4 fColor; //片元所对应的颜色值

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

参考文献:
[1]The OpenGL Programming Guide 9th Edition:http://www.opengl-redbook.com/
[2]OpenGL Red Book Example Code:https://github.com/openglredbook/examples
[3]GLFW源码下载-编译-使用:http://t.zoukankan.com/Doyoung-p-13690602.html
[4]OpenGL编程指南[第9版]

人工智能干货推荐 左边的图片1 专注于人工智能领域的技术分享

游戏元宇宙 右边的图片 专注于游戏领域的技术分享

分类:

人工智能

标签:

人工智能

作者介绍

阿升
V1

吾爱DotNet(公众号)