3D Computer Grapihcs Using OpenGL - 15 Draw Element Instanced
友情提示:继续本节之前,需要保存此前的代码,本节为了试验,会对代码做一些修改,但后续的修改需要我们把代码返回之前的进度。
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函数,进行了批量绘制。
第五个参数表示绘制五个实例。
最后效果:

3D Computer Grapihcs Using OpenGL - 15 Draw Element Instanced的更多相关文章
- 3D Computer Grapihcs Using OpenGL - 16 使用DrawElementsInstanced绘制立方体
我们使用15节学到的知识来绘制14节的立方体. 在第14节我们使用了两次glDrawElements实现了OpenGL实例化,发现这样仍然不太方便,如果需要绘制成千上万的立方体,就需要手写成千上万次的 ...
- 3D Computer Grapihcs Using OpenGL - 09 Enable Depth Test
启用Depth Test OpenGL是个3D绘图API,也就是说不只有xy坐标轴,还有第三个坐标轴z,z轴的方向是垂直于屏幕,指向屏幕内. 靠近人眼的方向是负方向,标准化设备坐标的最小值是-1, 最 ...
- 3D Computer Grapihcs Using OpenGL - 06 Vertex and Fragment Shaders
从这里就接触到了可编程图形渲染管线. 下面介绍使用Vertex Shader (顶点着色器)和 Fragment Shader(像素着色器)的方法. 我们的目标是使用这两个着色器给三角形填充绿色. 添 ...
- 3D Computer Grapihcs Using OpenGL - 03 OpenGL Buffer Data
本节绘制一个三角形,并讲解Buffer Object-缓冲对象 OpenGL的窗口坐标 屏幕中心为坐标原点,横向朝右为x正方向,纵向朝上为y正方向,最大值最小值分别为1,-1. Buffer Obje ...
- 3D Computer Grapihcs Using OpenGL - 19 Vertex Array Object(顶点数组对象)
大部分OpenGL教程都会在一开始就讲解VAO,但是该教程的作者认为这是很不合理的,因为要理解它的作用需要建立在我们此前学过的知识基础上.因此直到教程已经进行了一大半,作者才引入VAO这个概念.在我看 ...
- 3D Computer Grapihcs Using OpenGL - 14 OpenGL Instancing
如果我们需要绘制两个(或者多个)一样的立方体(或者物体),只是位置.缩放.旋转不一样,那么我们可以不需要多次将这个物体的顶点信息.颜色信息等发送到显卡,而是发送一次,绘制多次,仅仅是每次绘制之前应用不 ...
- 3D Computer Grapihcs Using OpenGL - 11 Model View Projection Matrices
本节我们将绘制一个3维物体,立方体. 如果要渲染3D物体,我们需要了解MVP(Model View Projection),它表示三个转换矩阵.实际上这个名字不够明确,更加确切的释义如下: Model ...
- 3D Computer Grapihcs Using OpenGL - 10 Color Buffer
本节我们将尝试利用三角形制作一个“走马灯”效果. 一个三角形如图示方式,从左向右依次移动. 先看一下代码: MyGlWindow.cpp #include <gl\glew.h> #inc ...
- 3D Computer Grapihcs Using OpenGL - 07 Passing Data from Vertex to Fragment Shader
上节的最后我们实现了两个绿色的三角形,而绿色是直接在Fragment Shader中指定的. 这节我们将为这两个三角形进行更加自由的着色——五个顶点各自使用不同的颜色. 要实现这个目的,我们分两步进行 ...
随机推荐
- 【6.10校内test】 noip模拟
题目链接: p1 FBI树 p2 医院设置 p3 加分二叉树 | | | | | | 分 界 线 | | | | | | 应该算是一篇反思博. 对于OI,我真的算不上是热爱(当然不热爱不代表就不 ...
- BZOJ 1303 中位数图 题解
题面 因为所求的是中位数,所以考虑改变原序列.把大于 b 的数全部变为 1,小于 b 的数变为 −1,等于 b 则为 0.问题就变为求存在几个包含 b的区间和为 0 . 根据乘法原理,我们枚举每一个l ...
- HDU 2586——How far away ?
Time limit 1000 ms Memory limit 32768 kB Description There are n houses in the village and some bidi ...
- 08、beta-actin和GAPDH的3'/5'比值
一.大部分的基因都有beta-action基因和GAPDH基因,很多Affymetrix芯片都将它们设为一组观察RNA降解程度的内参基因.mRNA是按照5’至3’的顺序来降解的,通过比较它们3’相对于 ...
- 使用filebeat收集日志传输到redis的各种效果展示
0 环境 Linux主机,cengtos7系统 安装有openresty软件,用来访问生成日志信息 1.15.8版本 安装有filebeat软件,用来收集openresty的日志 7.3版本 安装有r ...
- 史上最全的大厂Mysql面试题在这里
1.MySQL的复制原理以及流程 基本原理流程,3个线程以及之间的关联: 主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中: 从:io线程——在使用star ...
- 68. Text Justification (JAVA)
Given an array of words and a width maxWidth, format the text such that each line has exactly maxWid ...
- 关于 i++ 和 ++ i
先看一下代码,猜想一下输出值 @Testpublic void test() { int i =1; int a,b=0; i++; a=(i++); System.out.println(a); S ...
- 一、Core基于MVC的全局过滤器验证
一.Core基于MVC的过滤器验证 1.添加一个过滤器.在Startup 中ConfigureServices方法里添加一个Filters 即我们自己授权代码类. public void Config ...
- PAT Advanced 1048 Find Coins (25 分)
Eva loves to collect coins from all over the universe, including some other planets like Mars. One d ...