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

先看第一种方法的代码

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. 20191106 Spring Boot官方文档学习(1-2)

    学习内容相关信息 最新版本:2.2.0 CURRENT GA 官网地址 官方文档地址 单页版文档地址 代码生成网址 2.入门 Spring Boot的主要目标是: 为所有Spring开发提供更快且入门 ...

  2. 关于telnet的妙用

    1 使用telnet查看某个端口是否可以访问

  3. Linux cd命令(4)

    可以说在Linux上的一切操作都是从 cd 命令开始的.cd 是change directory的简写,其作用就是更改当前工作目录. 使用cd 对于这个命令的使用,不用多说了.需要注意的两点就是: c ...

  4. Dp test solution

    Dp test solution 按照难易程度排序题解: Problem B Problem Description Tarzan 现在想要知道,区间 [L,R] 内有多少数是优美的.我们定义一个数是 ...

  5. [LeetCode] 212. 单词搜索 II

    题目链接:https://leetcode-cn.com/problems/word-search-ii/ 题目描述: 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在 ...

  6. gorpeln的个人博客 - gorpeln

    2019-10-18    App Store 审核指南 2019-10-03    锚点跳转距离顶部指定距离 2019-09-23    Jekyll 简单加密 (pwd=123456) 2019- ...

  7. Pure播放器

    我是的本地应用,并不会拿你的隐私数据.

  8. JavaScript回顾

    JavaScript是Web编程语言. JavaScript是一种基于对象的脚本语言 它是解释执行的 在客户端的浏览器中运行 可以被嵌入HTML文件中 代码以纯文本的形式存储在文件中 可以使用任何一种 ...

  9. dom的节点操作

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. Mysql批量更新的一个坑-&allowMultiQueries=true允许批量更新

    前言        实际上,我们经常会遇到这样的需求,那就是利用Mybatis批量更新或者批量插入,但是,实际上即使Mybatis完美支持你的sql,你也得看看你说操作的数据库是否支持,而阿福,最近就 ...