【CG】OpenGL3.3+IMGUI_绘制三角形并着色

@(CG)

参考LearnOpenGL:
你好,三角形:
https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/#_2

<https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/#_2>
着色器:https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/
<https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/>

LearnOpenGL是一个很好的学习OpenGL的网站,感谢作者和译者!

写在前面:
1. 本文参考上述2个OpenGL网站,绘制三角形并着色、并结合IMGUI,改变三角形的颜色。
2.
本文根据自己的课程作业整理,结合LearnOpenGL网站学习后,写下自己的一点理解,可能缺乏细节的详细解释(LearnOpenGL上面有),但是希望能帮助到需要的人。
3. 我的环境配置:win10+ VS2015+ OpenGL(3.3 or above)+ GLFW+
IMGUI。环境配置在LearnOpenGL的前几篇教程都有介绍。
4. ((早早做完了,之后才发现作业要求是更改GUI来改变画三角形还是点或者线,但是我直接把三角形和点和线一起画出来了,可以说更加直观?吧?
5. 代码地址:
https://github.com/sysuts13/CG/tree/master/OpenGL3-IMGUI_DrawTriangle
<https://github.com/sysuts13/CG/tree/master/OpenGL3-IMGUI_DrawTriangle>
代码很简陋,还有很多缺点,欢迎指教(抱拳.jpg)。

Basic

1. 使用OpenGL(3.3及以上)+GLFW或freeglut画一个简单的三角形。

安装配置完环境后,在画一个简单的三角形之前,需要了解很多知识,做很多准备。
首先是OpenGL的图形渲染管道(Graphics Pipeline),其就是3D数据转换为2D表示然后展示在屏幕的过程。包括两个部分:
1. 将3D坐标转换为2D坐标。
2. 将2D坐标转换为实际的有颜色的像素。

其具体过程如下:(图来自LearnOpenGL)


我的理解和简单解释如下:

*
顶点着色器:把输入的顶点坐标转换为标准化设备坐标。标准化设备坐标在通过glViewport函数后,进行视口变换变换为屏幕空间坐标。同时,在GPU上面储存顶点数据。
* 图元装配:将顶点装配成图元,如三角形等。
* 几何着色器:把图元形式的顶点输入,能够产生新顶点来构造新图元。
* 光栅化:将图元变为屏幕上的像素。
* 片段着色器:计算光栅化得到的每一个像素的最终颜色。
然后是根据图形渲染管道和Opengl的API来编程构造三角形。
为了表示清晰,我做出的流程图,如下:


其具体步骤和细节在参考网站中都写的很清楚。
最后简单解释下部分实现细节:

1.顶点输入使用VBO。对于VBO,我的理解是:主要作用是将CPU上定义的顶点数据,传进GPU,储存在显存中。

2.着色器编写使用的是GLSL(OpenGL Shading Language),这是一种类似于C的语言,用来编写OpenGL着色器。

3.顶点和片段着色器编写完成并编译后,要将它们链接为一个着色器程序对象。

4.将顶点数据传进GPU后,需要告诉OpenGL如何解释这些数据,需要链接解释顶点属性,核心函数是:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
5.生成配置VAO。对于 VAO,我的简单理解是:储存VBO和与之已经被链接配置的解释。
参考网站是详细解释如下:

一个顶点数组对象会储存以下这些内容:
glEnableVertexAttribArray和glDisableVertexAttribArray的调用。
通过glVertexAttribPointer设置的顶点属性配置。
通过glVertexAttribPointer调用与顶点属性关联的顶点缓冲对象。

经过以上步骤,就可以通过glDrawArrays函数来绘制我们的三角形了。
结果如下:

具体代码和解释在代码文件中体现。

2. 对三角形的三个顶点分别改为红绿蓝,并解释为什么会出现这样的结果。

在上面绘制了三角形后,已经踏出了重要的第一步。将顶点的颜色改变,需要修改以下步骤:
1. 添加颜色的顶点属性。
2. 重新编写顶点和颜色着色器,并编译、链接成程序。关于着色器编写详细细节在参考网站解释得很清楚。
3. 重新解释链接顶点属性。这里的重点仍旧是glVertexAttribPointer函数,这里需要改变和理解的就是步长的偏移量这两个函数输入。

最后结果如下:


出现这样的结果的原因:
LearnOpenGL上面的解释是:

这是在片段着色器中进行的所谓片段插值(Fragment
Interpolation)的结果。当渲染一个三角形时,光栅化(Rasterization)阶段通常会造成比原指定顶点更多的片段。光栅会根据每个片段在三角形形状上所处相对位置决定这些片段的位置。
基于这些位置,它会插值(Interpolate)所有片段着色器的输入变量。

我的理解
是:渲染三角形的时候,光栅化根据我们提供的3个顶点来选择三角形边和内部的像素点,当确定了形成三角形所有像素点的位置后,因为我们只提供了三角形的3个顶点的输入变量,OpenGL会将除了这3个顶点外的变量进行等比例插值。所以我们得到的结果类似与调色板,为3个顶点的值的线性组合值。


另外,在参考网站中,还指导我们编写“我们自己的着色器类”,其将着色器编译和链接成程序等步骤打包为一个类,需要使用着色器时只需要编写相应的着色器代码就好了,非常方便。

具体代码和解释在代码文件中体现。

3. 给上述工作添加一个GUI,里面有一个菜单栏,使得可以选择并改变三角形的颜色。

IMGUI:https://github.com/ocornut/imgui <https://github.com/ocornut/imgui>

首先下载IMGUI的source。IMGUI使用非常方便,只要将source加入到项目中就可以使用了。查看IMGUI的OpenGL3的example(IMGUI的example是非常重要的参考文件),将相关文件加入到项目中。最后文件结构如下:


IMGUI+OpenGL3的使用是,先配置和设置IMGUI的窗口参数,然后在render
loop里面利用IMGUI的接口创建Imgui界面,进行相关的逻辑操作,然后再进行OpenGL渲染。

结果如下:

勾选IF CHANGE THE WHOLE COLOR后,更所选的颜色改变整个三角形的颜色,如下所示:


我只用到了IMGUI两个很简单的接口,实现了简单的窗口,更多功能可以学习example的代码,可以实现更多的功能。

Bonus

1. 绘制其他的图元,除了三角形,还有点、线等。


绘制点和线,需要做的是在首先是输入顶点中添加需要绘制的点的位置和颜色、需要绘制的线的顶点的位置和颜色。然后应用着色器程序。最后利用glDrawArrays函数绘制,其中绘制点的第一个函数参数GL_POINTS,绘制线的第一个参数是GL_LINES、GL_LINE_LOOP或者GL_LINE_STRIP,查阅相关资料,可知它们的区别如下:
假设点有A、B、C、D,
1. GL_LINES:连线AB、CD,B和C之间没有连线。
2. GL_LINE_LOOP:连线AB、BC、CD、DA。
3. GL_STRIP:连线AB、BC、CD,D和A之间没有连线。

结果如下:

画出了两条绿色的线,在两条绿色的线中间有一系列的点。

2. 使用EBO(Element Buffer Object)绘制多个三角形。


关于EBO,我的理解如下:在绘制中,我们可能需要用到重复的顶点,如果都将它们储存则会浪费空间,EBO通过建立我们需要使用的顶点的索引,能够解决这个问题。我们只需要不重复这储存我们需要
的顶点数据,然后用EBO告诉OpenGL我们需要使用哪些顶点数据就好了。
另外如果使用EBO,要使用glDrawElements函数绘制。
对于EBO的使用和VBO类似,具体参见参考网站代码。

我的结果如下:


图中绘制了两个三角形,不使用VBO的话需要储存6个顶点信息,但是使用VBO的话只需要储存5个顶点信息(因为有一个顶点是公用/重复的)。
绘制三角形的函数就是:
// 第二个参数是绘制2个三角形实际需要的6个顶点 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信