上一篇的补充,通过绘制三角形来完成矩形的绘制。此外,完成章节后练习。

绘制矩形

一个矩形由两个三角形组成,因此绘制矩形需要绘制两个三角形,一共6个顶点,其中2个顶点重复画了两次。

为了减小开销,仅储存矩形的4个顶点来完成绘制,需要使用Element Buffer Object按照绘制顺序存储顶点索引。

举例说明:矩形四个顶点(a, b, c, d),EBO中存储的索引为(0, 1, 2, 0, 2, 3),表示矩形由三角形abc和acd组成。

创建和配置EBO的方法与VBO类似:

初始化顶点和索引数组

float vertices[] = {0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f};
unsigned int indices[] = {0, 1, 2,
1, 2, 3};

创建EBO

unsigned int EBO;
glGenBuffers(1, &EBO);

配置EBO

同样可以通过绑定VAO来保存EBO的配置。



但要注意,和VBO不同的是,在解绑VAO之前,不可以解绑EBO。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

渲染循环

在使用EBO时,调用glDrawElements函数代替glDrawArrays函数。

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

练习

1. Try to draw 2 triangles next to each other using glDrawArrays by adding more vertices.

float vertices[] = {0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
0.0f, 1.0f, 0.0f};
while(!glfwWindowShouldClose(window)){

    processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwSwapBuffers(window);
glfwPollEvents();
}

2. Create the same 2 triangles using two different VAOs and VBOs for their data.

float vertices1[] = {0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f}; float vertices2[] = {0.5f, 0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
0.0f, 1.0f, 0.0f};
unsigned int VBO[2];
unsigned int VAO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO); glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while(!glfwWindowShouldClose(window)){

    processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(VAO[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}

*3.Create two shader programs where the second program uses a different fragment shader that outputs the color yellow; draw both triangles again where one outputs the color yellow. *

int fragmentShader[2];
const char *fragmentShaderSource1 = "#version 330 core\n"
"out vec4 fragColor;"
"void main()"
"{fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);}";
const char *fragmentShaderSource2 = "#version 330 core\n"
"out vec4 fragColor;"
"void main()"
"{fragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);}";
fragmentShader[0] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader[0], 1, &fragmentShaderSource1, NULL);
glCompileShader(fragmentShader[0]); fragmentShader[1] = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader[1], 1, &fragmentShaderSource2, NULL);
glCompileShader(fragmentShader[1]); shaderProgram[0] = glCreateProgram();
glAttachShader(shaderProgram[0], vertexShader);
glAttachShader(shaderProgram[0], fragmentShader[0]);
glLinkProgram(shaderProgram[0]);
shaderProgram[1] = glCreateProgram();
glAttachShader(shaderProgram[1], vertexShader);
glAttachShader(shaderProgram[1], fragmentShader[1]);
glLinkProgram(shaderProgram[1]); glDeleteShader(vertexShader);
glDeleteShader(fragmentShader[0]);
glDeleteShader(fragmentShader[1]);
while(!glfwWindowShouldClose(window)){

    processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram[0]);
glBindVertexArray(VAO[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(shaderProgram[1]);
glBindVertexArray(VAO[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}

OpenGL学习(2)——绘制三角形(补)的更多相关文章

  1. Android OpenGL 入门示例----绘制三角形和正方形

    Android上对OpenGl的支持是无缝的,所以才有众多3D效果如此逼真的游戏,在Camera的一些流程中也有用到GLSurfaceView的情况.本文记录OpenGL在Android上的入门级示例 ...

  2. Linux OpenGL 实践篇-3 绘制三角形

    本次实践是绘制两个三角形,重点理解顶点数组对象和OpenGL缓存的使用. 顶点数组对象 顶点数组对象负责管理一组顶点属性,顶点属性包括位置.法线.纹理坐标等. OpenGL缓存 OpenGL缓存实质上 ...

  3. iOS OpenGL ES简单绘制三角形

    OpenGL 是用于2D/3D图形编程的一套基于C语言的统一接口. windows,Linux,Unix上均可兼容. OpenGL ES 是在OpenGL嵌入式设备上的版本, android/iOS ...

  4. OpenGL学习(2)——绘制三角形

    在创建窗口的基础上,添加代码实现三角形的绘制. 声明和定义变量 在屏幕上绘制一个三角形需要的变量有: 三角形的三个顶点坐标: Vertex Buffer Object 将顶点数据存储在GPU的内存中: ...

  5. OpenGL学习进程(11)第八课:颜色绘制的详解

        本节是OpenGL学习的第八个课时,下面将详细介绍OpenGL的颜色模式,颜色混合以及抗锯齿.     (1)颜色模式: OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. R ...

  6. OpenGL学习进程(10)第七课:四边形绘制与动画基础

        本节是OpenGL学习的第七个课时,下面以四边形为例介绍绘制OpenGL动画的相关知识:     (1)绘制几种不同的四边形: 1)四边形(GL_QUADS) OpenGL的GL_QUADS图 ...

  7. OpenGL学习进程(4)第二课:绘制图形

    本节是OpenGL学习的第二个课时,下面介绍如何用点和线来绘制图形:     (1)用点的坐标来绘制矩形: #include <GL/glut.h> void display(void) ...

  8. 1.opengl绘制三角形

    顶点数组对象:Vertex Array Object,VAO,用于存储顶点状态配置信息,每当界面刷新时,则通过VAO进行绘制. 顶点缓冲对象:Vertex Buffer Object,VBO,通过VB ...

  9. Android OpenGL ES(十)绘制三角形Triangle .

    三角形为OpenGL ES支持的面,同样创建一个DrawTriangle Activity,定义6个顶点使用三种不同模式来绘制三角形: float vertexArray[] = { -0.8f, - ...

随机推荐

  1. It was not possible to find any compatible framework version

    It was not possible to find any compatible framework version The specified framework 'Microsoft.NETC ...

  2. 后台线程下的WinFrom窗体控件操作 Invoke

    Invoke(new MethodInvoker(delegate { ControllerLogout(controller_id, is_successful, description, cont ...

  3. 声明式编程:程序=数据+逻辑(what)+算法(控制+计算)

    接口:what: 实现:算法:指令: 编程语言中,凡是不涉及到算法的部分,都可以认为是声明式编程. 命令式编程可以与算法划等号:算法要求严格的计算逻辑和控制,是实施细节的精准描述: 命令式编程与声明式 ...

  4. 恶意代码技术第一二部分——P201421410029

    学   号:201421410029   中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告   实验四 恶意代码技术   ...

  5. WorldWind源码剖析系列:可渲染对象列表类RenderableObjectList

    可渲染对象列表类RenderableObjectList用来存储与一个星球体相关联的全部的可渲染对象,继承自可渲染对象类RenderableObject.RenderableObjectList的类图 ...

  6. iis配置绑定二级域名的问题

    最近用destoon给客户做一个网站,涉及到站内企业网站的二级域名解析的问题,iis怎么配置绑定子目录绑定二级域名呢,查了好多资料,没有一个给出具体步骤的 基本是一些概念,不过看了这些东西基本理解了泛 ...

  7. Android DatePickerDialog使用案例

    DatePickerDialog提供了一个弹出的Dialog供用户选择日期. 在这里分享一下其使用方法,效果图如下: DatePickerActivity.java package com.yw.my ...

  8. Android soundpool初探

    内容:本编播客主要讲解一下“即时音效”: 特点:快,短. 在播放这类时间短但是要求反应迅速的的音效,就不能够用不能够使用播放时间较长的音乐播放技术了,而应该采取soundpool技术来播放. soun ...

  9. [Lydsy1805月赛]对称数 BZOJ5361

    分析: 这个题,还是蛮有趣的.考虑,如果l,r区间内的所有数出现奇数次,那么[l-1,r]的抑或和等于所得抑或和. 之后怎么维护呢,主席树维护区间抑或和,记得将每个点附上一个ull级别的随机数,之后抑 ...

  10. 2.3《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——重命名,复制,删除

    最常用的文件操作除了将文件列出来外,就应该是重命名,复制,删除了.正如将文件列出来一样,大多数现代操作系统为这些任务提供了用户图形界面,但是在许多场景中,用命令行还是会更方便. 使用mv命令重命名一个 ...