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

绘制矩形

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

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

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

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

初始化顶点和索引数组

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

创建EBO

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

配置EBO

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



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

  1. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  2. 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.

  1. float vertices[] = {0.5f, 0.5f, 0.0f,
  2. 0.5f, -0.5f, 0.0f,
  3. -0.5f, 0.5f, 0.0f,
  4. 0.5f, 0.5f, 0.0f,
  5. -0.5f, 0.5f, 0.0f,
  6. 0.0f, 1.0f, 0.0f};
  1. while(!glfwWindowShouldClose(window)){
  2. processInput(window);
  3. glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
  4. glClear(GL_COLOR_BUFFER_BIT);
  5. glUseProgram(shaderProgram);
  6. glBindVertexArray(VAO);
  7. glDrawArrays(GL_TRIANGLES, 0, 6);
  8. glfwSwapBuffers(window);
  9. glfwPollEvents();
  10. }

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

  1. float vertices1[] = {0.5f, 0.5f, 0.0f,
  2. 0.5f, -0.5f, 0.0f,
  3. -0.5f, 0.5f, 0.0f};
  4. float vertices2[] = {0.5f, 0.5f, 0.0f,
  5. -0.5f, 0.5f, 0.0f,
  6. 0.0f, 1.0f, 0.0f};
  1. unsigned int VBO[2];
  2. unsigned int VAO[2];
  1. glGenVertexArrays(2, VAO);
  2. glGenBuffers(2, VBO);
  3. glBindVertexArray(VAO[0]);
  4. glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
  5. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
  6. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
  7. glEnableVertexAttribArray(0);
  8. glBindBuffer(GL_ARRAY_BUFFER, 0);
  9. glBindVertexArray(VAO[1]);
  10. glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
  11. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
  12. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
  13. glEnableVertexAttribArray(0);
  14. glBindBuffer(GL_ARRAY_BUFFER, 0);
  15. glBindVertexArray(0);
  1. while(!glfwWindowShouldClose(window)){
  2. processInput(window);
  3. glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
  4. glClear(GL_COLOR_BUFFER_BIT);
  5. glUseProgram(shaderProgram);
  6. glBindVertexArray(VAO[0]);
  7. glDrawArrays(GL_TRIANGLES, 0, 3);
  8. glBindVertexArray(VAO[1]);
  9. glDrawArrays(GL_TRIANGLES, 0, 3);
  10. glfwSwapBuffers(window);
  11. glfwPollEvents();
  12. }

*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. *

  1. int fragmentShader[2];
  2. const char *fragmentShaderSource1 = "#version 330 core\n"
  3. "out vec4 fragColor;"
  4. "void main()"
  5. "{fragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);}";
  6. const char *fragmentShaderSource2 = "#version 330 core\n"
  7. "out vec4 fragColor;"
  8. "void main()"
  9. "{fragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);}";
  1. fragmentShader[0] = glCreateShader(GL_FRAGMENT_SHADER);
  2. glShaderSource(fragmentShader[0], 1, &fragmentShaderSource1, NULL);
  3. glCompileShader(fragmentShader[0]);
  4. fragmentShader[1] = glCreateShader(GL_FRAGMENT_SHADER);
  5. glShaderSource(fragmentShader[1], 1, &fragmentShaderSource2, NULL);
  6. glCompileShader(fragmentShader[1]);
  7. shaderProgram[0] = glCreateProgram();
  8. glAttachShader(shaderProgram[0], vertexShader);
  9. glAttachShader(shaderProgram[0], fragmentShader[0]);
  10. glLinkProgram(shaderProgram[0]);
  11. shaderProgram[1] = glCreateProgram();
  12. glAttachShader(shaderProgram[1], vertexShader);
  13. glAttachShader(shaderProgram[1], fragmentShader[1]);
  14. glLinkProgram(shaderProgram[1]);
  15. glDeleteShader(vertexShader);
  16. glDeleteShader(fragmentShader[0]);
  17. glDeleteShader(fragmentShader[1]);
  1. while(!glfwWindowShouldClose(window)){
  2. processInput(window);
  3. glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
  4. glClear(GL_COLOR_BUFFER_BIT);
  5. glUseProgram(shaderProgram[0]);
  6. glBindVertexArray(VAO[0]);
  7. glDrawArrays(GL_TRIANGLES, 0, 3);
  8. glUseProgram(shaderProgram[1]);
  9. glBindVertexArray(VAO[1]);
  10. glDrawArrays(GL_TRIANGLES, 0, 3);
  11. glfwSwapBuffers(window);
  12. glfwPollEvents();
  13. }

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. C#调用免费天气预报WebService

    using System; using System.Collections; using System.Configuration; using System.Data; using System. ...

  2. oracle like模糊查询简单用法

    like  用法介绍: 1.“_”:匹配单个任意字符 select * from bqh3 where name like '_崔'; 2.“%”:匹配0个或多个任意字符.但有三种情况如下: like ...

  3. VC Debug和Release区别

    https://msdn.microsoft.com/en-us/library/xz7ttk5s.aspx   Optimizing Your Code Visual Studio 2015 The ...

  4. [Redis_1] Redis 介绍 && 安装

    0. 说明 Redis 介绍 && 安装 1. Redis 介绍 2. Redis 安装(Windows 10) [2.1 解压 redis-2.2.2-win32-win64.rar ...

  5. [Python_5] Python 线程

    0. 说明 Python 线程笔记 1. 低级 API # -*-coding:utf-8-*- """ 线程 """ "&quo ...

  6. Win7下的C盘重新划分为两个盘

    Win 7分盘 注意事项:操作之前,先备份好重要数据,以免误操作导致数据丢失 . 方法步骤如下: 1.在桌面右键点击"计算机"-"管理": 2.鼠标左键单击选& ...

  7. 关于mybatis反向生成为什么有时候实体类会变成两个

    一般来说,将TEXT字段,从一张操作频繁的表中拆分出去,成为一个Key-Value结构的独立表是 好处颇多的. 其有利之处主要体现在下面三个方面: PS:以下的讨论对象均基于Innodb引擎 1. 便 ...

  8. EF5.0中的跨数据库操作

    以前在用MVC + EF 的项目中,都是一个数据库,一个DbContext,因此一直没有考虑过在MVC+EF的环境下对于多个数据库的操作问题.等到要使用时,才发现这个问题也不小(关键是有个坑).直接说 ...

  9. glViewport()函数和glOrtho()函数的理解(转)

    http://www.cnblogs.com/yxnchinahlj/archive/2010/10/30/1865298.html 在OpenGL中有两个比较重要的投影变换函数,glViewport ...

  10. Debian apt-get 用法

    (说明:sudo--使用超级管理员权限进行apt-get ; packagename--代表安装的软件包名) sudo apt-get update —— 在修改/etc/apt/sources.li ...