友情提示:继续本节之前,需要保存此前的代码,本节为了试验,会对代码做一些修改,但后续的修改需要我们把代码返回之前的进度。

OpenGL内置支持Instancing,有专门的函数来处理这件事情。

为了方便,我们先使用最简单的三角形来学习

先修改sendDataToOpenGL()函数:

 void MyGlWindow::sendDataToOpenGL()
{
GLfloat tri[] = {
-1.0f,+0.0f,
-1.0f,+1.0f,
-0.9f,+0.0f
}; GLuint vertexBufferID;
glGenBuffers(, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(tri), tri, GL_STATIC_DRAW);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , ); GLushort indices[] = { ,, };
GLuint indexArrayBufferID;
glGenBuffers(, &indexArrayBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexArrayBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
numIndices = ;
}

相应的修改vertexshader

 #version                            

 in layout(location=) vec2 position;   

 out vec3 passingColor;

 void main()
{ gl_Position = vec4(position.xy,,);
passingColor= vec3(,,);
}

以及paintGL()函数:

 void MyGlWindow::paintGL()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glViewport(, , width(), height()); glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, );
}

进行了上述修改之后,会在画布左上角绘制一个简单的红色三角形。

假如我们现在需要达到这样的目的:复制这个三角形多次,每次都横向偏移一定的量。

为了使用OpenGL提供的Instancing 方法,避免每次都调用glDrawElements,我们可以提供一个数组,作为偏移信息数组。

在sendDataToOpenGL()函数中定义一个GLfloat数组,把它绑定到GL_ARRAY_BUFFER上,开启一个新的通道,把数据传输进去。

最后在paintGL中使用glDrawElementsInstanced函数来绘制多个实例。

具体代码如下:

 void MyGlWindow::sendDataToOpenGL()
{
GLfloat tri[] = {
-1.0f,+0.0f,
-1.0f,+1.0f,
-0.9f,+0.0f
}; GLuint vertexBufferID;
glGenBuffers(, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(tri), tri, GL_STATIC_DRAW);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , ); GLfloat offsets[] = {0.0f, 0.5f, 1.0f, 1.2f, 1.6f};
GLuint offsetsBufferID;
glGenBuffers(, &offsetsBufferID);
glBindBuffer(GL_ARRAY_BUFFER, offsetsBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(offsets), offsets, GL_STATIC_DRAW);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , );
glVertexAttribDivisor(, ); GLushort indices[] = { ,, };
GLuint indexArrayBufferID;
glGenBuffers(, &indexArrayBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexArrayBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
numIndices = ;
}

16-23行是新增内容。

16行定义了一个GLfloat数组,有5个元素。

17-20行我们已经很熟悉,不再解释了

21行开启了通道1

22行设定了通道1的数据格式,第一个参数表示通道1,第二个参数表示每1个数据作为一个单元

23行glVertexAttribDivsior是个新函数,它是配合实例化绘制的。没有它的情况下,tri数组每2个元素结合offsets数组的1个元素,也就是说offsets数组每个元素只用一次。有了这个函数之后,offsets数组的每个元素都要做一次循环,和tri数组的每组元素结合一次,形成5个批次。

修改VertexShader:

 #version                            

 in layout(location=) vec2 position;
in layout(location=) float offset; out vec3 passingColor; void main()
{ gl_Position = vec4(position.x + offset, + position.y,,);
passingColor= vec3(,,);
}

增加了第4行,对应sendDataToOpenGL的新增通道1.

第11行中,我们把position的x坐标进行了offset的偏移。

最后修改paintGL()函数:

 void MyGlWindow::paintGL()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glViewport(, , width(), height());
glDrawElementsInstanced(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, , );
}

第5行使用glDrawElementsInstanced函数代替glDrawElements函数,进行了批量绘制。

第五个参数表示绘制五个实例。

最后效果:

最新文章

  1. 找到第k个最小元----快速选择
  2. apache服务器安装
  3. Android之访问下载文件
  4. [转]ubuntu(12.04)下, 命令 ,内核 源代码的获取
  5. Visual C++内存泄露检测—VLD工具使用说明[转]
  6. 【转载】mysqldump的single-transaction和master-data
  7. Careercup - Facebook面试题 - 5733320654585856
  8. .Net程序员学习Linux(二)
  9. Python 字符、整型、列表字典等操作(二)
  10. 201521123024 《Java程序设计》第4周学习总结
  11. ssh 提示Connection closed by * 的解决方案
  12. 论文翻译:Neural Networks With Few Multiplications
  13. SearchScore
  14. 生产环境ssh登陆策略
  15. 目标检测算法(2)SPP-net
  16. Python 装饰器入门(下)
  17. 数链剖分(Housewife Wind )
  18. 【Spring学习笔记-MVC-12】Spring MVC视图解析器之ResourceBundleViewResolver
  19. express基础
  20. nginx配置【转】

热门文章

  1. spring boot-6.profile 多环境支持
  2. [转帖]小米手环采用RISC-V 指令集芯片
  3. Java Web - 笔记(1)
  4. T2 AC自动机
  5. 软考题型—PERT图(项目计划评审技术)
  6. 图片服务器期,利用一下园子练习一下markdown
  7. Python基础数据类型int
  8. python告诉你啥是佩奇
  9. javaweb:Response/Request的概述 (转发、重定向、get/post)转
  10. decodeURI decodeURIComponent