本节将采用两种方法绘制两个三角形。

先看第一种方法的代码

MyGlWindow.cpp

 #include <gl\glew.h>
#include "MyGlWindow.h" void MyGlWindow::initializeGL()
{
glewInit(); GLfloat verts[] =
{
+0.0f, +0.0f,
+1.0f, +1.0f,
-1.0f, +1.0f, +0.0f, +0.0f,
-1.0f, -1.0f,
+1.0f, -1.0f,
};
GLuint myBufferID;
glGenBuffers(, &myBufferID);
glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , );
} void MyGlWindow::paintGL()
{
glViewport(, , width(), height());
glDrawArrays(GL_TRIANGLES, , );
}

和上一节的代码很相似,区别是verts数组增加了6个元素(能额外表示3个顶点),另外glDrawArrays()函数的最后一个参数变成了6,表示绘制六个顶点。这样当然就可以绘制2个三角形了。

但是这种方法造成了一个浪费,代码中可以看到两次出现了(0.0,0.0)点。

EBO

OpenGL允许我们提供一个索引数组用来指定三角形的顶点组成顺序。这个数组通常被称为EBO。

看第二种绘制三角形的方法:

 #include <gl\glew.h>
#include "MyGlWindow.h" void MyGlWindow::initializeGL()
{
glewInit(); GLfloat verts[] =
{
+0.0f, +0.0f, //
+1.0f, +1.0f, //
-1.0f, +1.0f, //
-1.0f, -1.0f, //
+1.0f, -1.0f, //
};
GLuint vertexBufferID;
glGenBuffers(, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, , ); GLushort indices[] =
{
,,,
,,,
};
GLuint indexBufferID;
glGenBuffers(, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
} void MyGlWindow::paintGL()
{
glViewport(, , width(), height());
glDrawElements(GL_TRIANGLES, , GL_UNSIGNED_SHORT, );
}

*注:为了区分两个Buffer,我们这里把之前的myBufferID改名为vertexBufferID

23-31行和顶点位置设置代码(8-19行)非常相似。

28-29行创建了另外一个BufferObject- indexBuffer

30行把indexBuffer绑定到GL_ELEMENT_ARRAY_BUFFER绑定点上

31行对其填充数据,其数据内容是一个GLushort类型的数组,每三个元素表示一个三角形的顶点索引,索引值是相对于verts数组来说的(参考verts中的注释)。这里使用GLushort而不使用GLint的原因是GLushort给了我们更大的数据存储量,索引始终都是正整数,所以使用unsigned类型更合理。

在paintGL函数中,这次不使用glDrawArrays函数了,改用glDrawElements()函数绘制

第二个参数表示6个顶点

第三个参数表示indices数组的类型

第四个参数表示偏移值

使用EBO在本例中仅节约了一个顶点位置数据,但是在复杂的模型中,会节约非常多的数据。

3D Computer Grapihcs Using OpenGL - 05 EBO的更多相关文章

  1. 3D Computer Grapihcs Using OpenGL - 09 Enable Depth Test

    启用Depth Test OpenGL是个3D绘图API,也就是说不只有xy坐标轴,还有第三个坐标轴z,z轴的方向是垂直于屏幕,指向屏幕内. 靠近人眼的方向是负方向,标准化设备坐标的最小值是-1, 最 ...

  2. 3D Computer Grapihcs Using OpenGL - 19 Vertex Array Object(顶点数组对象)

    大部分OpenGL教程都会在一开始就讲解VAO,但是该教程的作者认为这是很不合理的,因为要理解它的作用需要建立在我们此前学过的知识基础上.因此直到教程已经进行了一大半,作者才引入VAO这个概念.在我看 ...

  3. 3D Computer Grapihcs Using OpenGL - 16 使用DrawElementsInstanced绘制立方体

    我们使用15节学到的知识来绘制14节的立方体. 在第14节我们使用了两次glDrawElements实现了OpenGL实例化,发现这样仍然不太方便,如果需要绘制成千上万的立方体,就需要手写成千上万次的 ...

  4. 3D Computer Grapihcs Using OpenGL - 15 Draw Element Instanced

    友情提示:继续本节之前,需要保存此前的代码,本节为了试验,会对代码做一些修改,但后续的修改需要我们把代码返回之前的进度. OpenGL内置支持Instancing,有专门的函数来处理这件事情. 为了方 ...

  5. 3D Computer Grapihcs Using OpenGL - 14 OpenGL Instancing

    如果我们需要绘制两个(或者多个)一样的立方体(或者物体),只是位置.缩放.旋转不一样,那么我们可以不需要多次将这个物体的顶点信息.颜色信息等发送到显卡,而是发送一次,绘制多次,仅仅是每次绘制之前应用不 ...

  6. 3D Computer Grapihcs Using OpenGL - 11 Model View Projection Matrices

    本节我们将绘制一个3维物体,立方体. 如果要渲染3D物体,我们需要了解MVP(Model View Projection),它表示三个转换矩阵.实际上这个名字不够明确,更加确切的释义如下: Model ...

  7. 3D Computer Grapihcs Using OpenGL - 10 Color Buffer

    本节我们将尝试利用三角形制作一个“走马灯”效果. 一个三角形如图示方式,从左向右依次移动. 先看一下代码: MyGlWindow.cpp #include <gl\glew.h> #inc ...

  8. 3D Computer Grapihcs Using OpenGL - 06 Vertex and Fragment Shaders

    从这里就接触到了可编程图形渲染管线. 下面介绍使用Vertex Shader (顶点着色器)和 Fragment Shader(像素着色器)的方法. 我们的目标是使用这两个着色器给三角形填充绿色. 添 ...

  9. 3D Computer Grapihcs Using OpenGL - 04 First Triangle

    本节将绘制一个三角形 先看最终代码: MyGlWindow.cpp: #include <gl\glew.h> #include "MyGlWindow.h" void ...

随机推荐

  1. 函数 FUNCTION

    函数 FUNCTION 定义: 带名字的代码块,用于执行具体任务. 注意: 应给函数指定描述性名称,只是用小写字母和下划线. 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 (). 任何 ...

  2. webpack打包错误 ERROR in multi ./src/main.js ./dist/bundle.js

    webpack打包错误 ERROR in multi ./src/main.js ./dist/bundle.js:https://www.jianshu.com/p/a55fb5bf75e1

  3. C++中的const分析

    1,C 语言中的 const: 1,const 修饰的变量是只读的,本质还是变量: 1,C 语言中的 const 使变量具有只读属性: 2,const 只在编译期有用,在运行期无用: 3,const ...

  4. linux下定时器的实现

    简介: linux下经常有这样的需求,需要定时轮询执行某种任务,当然,用shell脚本的话,crontab和at就可以满足要求.如果从C语言的角度来看,实现定时器也是一个比较简单的任务,因为具有普遍性 ...

  5. Dire Wolf——HDU5115(区间DP)

    题意 就是有一对狼,每个狼有初始的攻击力,并且还能给左右两边的狼提供攻击力加成,当冒险家杀死一头狼的时候他也会受到这个狼目前攻击力的伤害 实例解析 33 5 78 2 0 有三头狼,刚开始第二头狼给他 ...

  6. [CodePlus 2018 3 月赛] 博弈论与概率统计

    link 题意简述 小 $A$ 与小 $B$ 在玩游戏,已知小 $A$ 赢 $n$ 局,小 $B$ 赢 $m$ 局,没有平局情况,且赢加一分,输减一分,而若只有 $0$ 分仍输不扣分. 已知小 $A$ ...

  7. 计算机体系结构总结_Pipeline

    Textbook:<计算机组成与设计——硬件/软件接口>  HI<计算机体系结构——量化研究方法>          QR 在前面一节里我们有了一块简单的RISC CPU,包括 ...

  8. 【nginx】上传文件error报413 Request Entity Too Large

    nginx配置增大上传文件限制 如果访问地址是通过nginx转发配置的 server{ ... ... client_max_body_size 50M; ... ... } ingress配置增大上 ...

  9. NSPredicate的使用,超级强大

    NSPredicate *ca = [NSPredicate predicateWithFormat:(NSString *), ...]; Format: (1)比较运算符>,<,==, ...

  10. 使ApacheBench支持multi-url

    目录 1.下载Apache httpd相关源码包以及针对ab工具的patch包 2.编译安装apr 3.编译安装apr-util 4.替换httpd源码里面的ab.c文件 5.编译安装httpd 6. ...