欲以此分类来记录opengl的学习历程,此为第一篇,所以先来一个固定管线的例子,以及对双缓存的测试。

一、配置环境

写之前,先进行配置,然后再讲内容。

注:第一部分涉及的代码均忽略。

【环境配置传送门】

二、所需知识

1. opengl程序结构

main函数结构大体上由如下几个步骤:

1) glutInit(&argc, argv);读取命令行参数,初始化glut2) glutInitDisplayMode(unsigned int mode);设置显示模式(或窗口类型) (本节涉及参数如下)GLUT_RGB    GLUT_RGBA    GLUT_DOUBLE3) glutInitWindowSize(int, int);设置窗口规格4) glutInitWindowPosition(int, int);设置窗口初始位置5) glutCreateWindow(char*);6) if(glewInit()) ....判断glew是否初始化成功7) init()初始化数据 ,函数体自己写8) glutDisplayFunc(函数指针);系统自带的显示回调宏,在glut每次更新窗口内容的时候自动调用。9) glutMainLoop();无限循环,一直处理窗口消息,如:判断是否需要进行重绘,然后自动调用glutDisplayFunc()中注册的函数(即参数)。

2. 初始化数据

glGen*  系列函数,用于OpenGL 分配不同类型的对象名称。

glBind*  系列函数,将已分配的对象名称进行绑定,设定为当前活动对象。

以VBO(Vertex Buffer Object  顶点缓冲对象)为例,来理解上面两个函数的理念,其中VBO是一个GLuint对象,即无符号整型。

我们程序员想要操控缓冲区,怎么办呢,缓冲区位于系统硬件中,对编程人员是不可见的。所以,opengl建立了一个映射机制,以一个GLuint的数据对象来代表某一缓存区。

其中,缓存区为映射的一端,VBO为另一端,我们首先要创建所需的VBO对象,然后通过glGenBuffers(VBO数量,VBO取址);来激活VBO对象作为某一映射的映射端。

因为程序员创建的GLuint对象,系统默认为一个普通的对象,只有通过glGenBuffers(),才能使系统将其认定为缓存区映射的对象。

而glBindBuffer(分配缓冲区类型,已激活的VBO对象);用于建立此映射,将VBO绑定到一个缓冲区,将当前VBO代表的缓冲区作为当前活动对象。尔后的所有关于缓冲区的操作均对当前VBO对象代表的缓冲区进行操作。

glBufferData(缓冲区类型,大小,数据,数据的读写方式);

刚刚说到VBO映射到一块缓冲区,但是里面并没有信息数据,所以要将数据传到缓冲区中,就是上述函数的作用。

我们可以通过glBufferData将一组顶点位置坐标信息传入到VBO1代表的缓冲区中,然后将顶点的颜色信息传入到VBO2代表的缓冲区中,当我们渲染的时候,需要颜色信息对颜色信息进行处理加工的时候,我们就通过GLBindBuffer,将VBO2绑定为当前活动对象,反之,同理。

上述,以VBO为例讲述了相关的一些概念,其他类似的函数同理。

3. 渲染

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

参数解析表
参数名 数值 解释
index GLuint     如:0 顶点着色器中输入变量的location值,就是属性的索引
size GLint       如:2 每个顶点的属性数量,如:x、y
type GLenum  如:GL_FLOAT 顶点属性变量的数值类型
normalized GLboolean  如:GL_FALSE 设定了顶点数据存储前是否进行归一化
stride GLsizei     如:0 相邻属性变量之间间隔的比特长度
pointer GLvoid*    如:BUFFER_OFFSET(0) 数据读取时,开始位置的偏移量

通过该函数告诉管线怎样解析buffer中的数据

glDrawArrays(绘制方式,第一个顶点的索引,顶点数量);

void glFlush(void);

强制所有进行中的OpenGL命令立即完成并传输到OpenGL服务端处理。这样就可以保证它们在一定时间内全部完成。

但是,该函数只是强制所有运行中的命令送入服务端而已,它会立即返回,它并不会等待所有的命令完成,而等待确实我们需要做的。。。

glFinish();

它会一直等待所有当前的OpenGL命令立即执行,等待他们全部完成。但是可想而知,它会拖累程序整体性能。

三、代码

  1 //配置代码
  2 #if _MSC_VER>=1900
  3 #include "stdio.h"
  4 _ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned);
  5 #ifdef __cplusplus
  6 extern "C"
  7 #endif
  8 FILE* __cdecl __iob_func(unsigned i) {
  9     return __acrt_iob_func(i);
 10 }
 11 #endif /* _MSC_VER>=1900 */
 12
 14 #include <iostream>
 15 using namespace std;
 16
 17 //我们需要包含 "val.h"  和  "LoadShaders.h"
 18 //如果你按照之前配置环境那样做了,需要:
 19 //#include "vgl.h"
 21
 22 //我这里是自己将两个文件放到VS库目录里面了,总之,只要正确引用两个文件即可
 23 #include <vgl.h>
 26
 27 //顶点缓冲对象初始下标、缓冲对象数量、顶点属性数量、顶点数量
 28 enum {Arraybuffers, Numbuffers, AttriNum = 3, VerNum};
 29
 30 GLuint buffers[Numbuffers]; //顶点缓冲对象数组  the array of VBOs
 31
 32 void init();
 33 void Display();
 34
 35 int main(int argc, char** argv)
 36 {
 37     //命令行初始化glut
 38     glutInit(&argc, argv);
 39
 40     //初始化显示模式
 41     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 42
 43     //初始化windows
 44     glutInitWindowSize(900, 600);
 45     glutInitWindowPosition(20, 20);
 46     glutCreateWindow("my work 1");
 47
 48     //检查glew是否就绪
 49     if (glewInit())
 50     {
 51         cout << "glew didn't go work!" << glewGetErrorString(glewInit()) << endl;
 52         exit(EXIT_FAILURE);
 53     }
 54
 55     //初始化数据
 56     init();
 57
 58     //渲染
 59     glutDisplayFunc(Display);
 60
 61     glutMainLoop();
 62
 63     return 0;
 64 }
 65
 66 void init()
 67 {
 68     //顶点数据
 69     GLfloat vertices[VerNum][AttriNum]
 70     {
 71         { 0.8,0.8,0 },
 72         { -0.1,0,0},
 73         {0.8,-0.8,0},
 74         {-0.8,0,0},
 75     };
 76
 77     //创建缓冲器
 78     glGenBuffers(Numbuffers, buffers);
 79     //绑定缓冲器
 80     glBindBuffer(GL_ARRAY_BUFFER, buffers[Arraybuffers]);
 81     //向缓冲区传递数据
 82     glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
 83
 84     //设置清除颜色
 85     glClearColor(0, 0, 0, 0);
 86 }
 87
 88 void Display()
 89 {
 90     //清空颜色缓存
 91     glClear(GL_COLOR_BUFFER_BIT);
 92
 93     //开启顶点属性数组
 94     glEnableVertexAttribArray(0);
 95
 96     glBindBuffer(GL_ARRAY_BUFFER, buffers[Arraybuffers]);
 97
 98     glVertexAttribPointer(0, AttriNum, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
 99
100     //绘制 两个三角形
101     glColor4f(1, 0, 0, 0.3);    //设置颜色
102     glDrawArrays(GL_TRIANGLES, 0, VerNum);
103     glColor4f(0, 0, 1, 0.8);
104     glDrawArrays(GL_TRIANGLES, 1, VerNum);
105     //1. 将绘制好的两个三角形放到屏幕前面
106     glutSwapBuffers();
107
108     //在后面的帧缓存中继续绘制 一个四边形 边框
109     glColor4f(1, 0.1, 0.8, 0.0);
110     glDrawArrays(GL_LINE_LOOP, 0, VerNum);
111
112     //2. 将后面的四边形边框帧缓存放到屏幕前面
113     glutSwapBuffers();
114
115     //此时,理论上讲,后台的帧缓存应该为原来绘制的两个三角形
116     glColor4f(1, 0.1, 0.8, 0.0);
117     //我们在其基础上,加上边框
118     glDrawArrays(GL_LINE_LOOP, 0, VerNum);
119
120     //3. 显示的是两个三角形+边框
121     glutSwapBuffers();
122
123     //禁用顶点属性数组           这个要最后禁用
124     glDisableVertexAttribArray(0);
125
126     glFlush();
127 }

四、效果

标号为1.处得到的效果:(将107-122注释掉)

标号2.处得到的效果(将114-122注释)

标号3.处的效果,即将后面帧缓存中的效果添加到原来帧缓存的图形中得到的效果

通过这一节的测试,我们真正的看到了双缓存的工作过程,以及内部数据信息。

感谢您的阅读,生活愉快~

转载于:https://www.cnblogs.com/lv-anchoret/p/9221504.html

OpenGL 笔记1 固定管线实例 + 双缓存测试实例相关推荐

  1. 从固定管线到可编程管线:十段代码入门OpenGL

    文章目录 1. 最简单的OpenGL应用程序 2. 视点系统和投影矩阵 3. 深度缓冲区和深度测试 4. 模型的旋转和平移 5. VBO和顶点混合数组 6. 纹理映射和纹理坐标 7. 光照和法向量计算 ...

  2. (二)unity shader基础之——————shader一些专业术语的解释(OpenGL/DirectX、HLSL/GLSL/Cg、Draw Call、固定管线渲染等)

    一.什么是OpenGL/DirectX 我们直接访问GPU是一件非常麻烦的事情,可能需要各自寄存器.显存打交道而图像编程接口在这些硬件的基础上实现了一层抽象. OpenGL和DirectX就是这些图像 ...

  3. 7_DoubleBuffer 游戏编程中的双缓存模式

    ### double buffer 双缓存简单说: 当一个缓存被读取的时候,往另一个缓存里写入, 如此交替#### the pattern 有两个缓存实例,一个是 current buffer, 一个 ...

  4. [OpenGL笔记]glut入门(1)

    开头 写在开头,推荐看一下这篇文章涨涨知识OpenGL库文件的区别(glut/glew/glfw/glad/freeglut)和环境配置 不知道从哪扒来的glut的参考文档 代码初识 其实之前学的是g ...

  5. Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(编码实现)...

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8797740 这篇是基于上一篇Android仿人人客户端(v5.7.1)--对从服务器 ...

  6. OPENGL笔记(3)——shader

    一 Shader 记录一下这几十年来曲面细分着色器的使用 OPENGL 4.x 当前支持5种着色器,分别为: (1)顶点着色器 处理单位为点(vertex),接受cpu端传入的顶点数据,输出为gl_V ...

  7. OpenGL笔记-1.OpenGL概念基础入门

    OpenGL是一个3D图形绘制库,相较于一般的2D图形,在高(长)宽的概念上引入了深度的概念,也即是在2D效果上加一个维度用来模拟3D效果 常见的3D术语解释: 光栅化:图片从内存绘制到每个像素点的过 ...

  8. 【openGL2021版】固定管线光照

    [openGL2021版]固定管线光照       大家好,我是Lampard猿奋~       欢迎来到船新的openGL基础系列的博客,今天记录的是固定管线的光照  (一)光学模型 通常物体表面的 ...

  9. UE5 Shader基础学习笔记——01-12 图形管线/创建shader/数学节点/贴图压缩/LerpDotUV/常用向量/坐标空间/MinMaxClampSaturate/法线贴图混合

    UE5 Shader基础学习笔记--01-12 图形管线/创建shader/数学节点/贴图压缩/LerpDotUV/常用向量/坐标空间/MinMaxClampSaturate/法线贴图混合 Lec01 ...

最新文章

  1. PS5 发布,揭秘真假难辨的虚拟和现实
  2. libsybcomn64.dll php,libsybcomn.dll下载|
  3. springboot的yml配置文件绑定时必须和相应的类中的属性类型对应,不然启动报错
  4. dojo Quick Start/dojo入门手册--开始使用dojo.js
  5. Visual Studio fatal error C1902: 程序数据库管理器不匹配;请检查安装
  6. 上传html 0字节,HTML ajax 上传文件限制文件的类型和文件大小
  7. html:(29):伪选择符和分组选择符
  8. DevOps交付模式下,软件测试的那些事
  9. 基于JAVA+SpringMVC+Mybatis+MYSQL的网络投票系统
  10. 字体文件夹_下载了各种五花八门的CAD字体,为什么打开图纸还是找不到字体?...
  11. CCNP精粹系列之十七--路由映射实战,博主推荐
  12. 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)
  13. 浏览器tab切换最小化,当前页面无操作刷新页面
  14. 编程恶搞项目——无限弹窗.exe版
  15. centos长ping输出日志的脚本
  16. Sphinx/coreseek/mysql全文检索
  17. python turtle绘制漫天雪花_科赫雪花渲染时间(以及如何使用海龟绘制雪花)
  18. 路由表是干什么的?底层原理是什么?
  19. pve rust 能拆家吗_文明重启有哪些游戏模式应该怎么玩
  20. 树莓派基础实验34:L298N模块驱动直流电机实验

热门文章

  1. vue脚手架安装步骤vue-cli
  2. 201621123021《JAVA程序设计》第五周学习总结
  3. C++使用Windows API CreateMutex函数多线程编程
  4. RobotFramework自动化4-批量操作案例
  5. MindManager脑图之项目管理甘特图
  6. IOS 关于ipad iphone5s崩溃 解决
  7. Hystrix之外健壮微服务的新选择:Sentinel 发布首个生产版本 1
  8. jQuery 3.3.1已经发布,开发团队正在准备4.0版本
  9. (十)如何查找端口被那个程序占用
  10. 0913作业(冒泡排序、二分查找法、模拟摇乐游戏)