绘制一个正方形真的很简单,很显然,两个三角形铺在一起就可以了

一、绘制正方形

其实如果完全理解了前面的知识, 那么理论上不需要任何参考就可以绘制正方形,就如上所说,两个三角形只有顶点的位置不同而已……

那么绘制一个正方形需要多少个顶点呢?按照如上的方法,应该是需要6个,然而很明显只需要4个即可,因为有两个顶点它们在同一个位置,如果重复绘制会多出50%额外的开销,所以我们的解决方法就是:定义4个顶点,然后再定义2个绘制索引,也就是顶点复用,因此对于上一份输出三角形的代码,添加改动如下:

GLfloat 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,
};
GLuint indices[] =
{0, 1, 2,        //用前3个顶点绘制第一个三角形1, 2, 3         //用后3个顶点绘制第二个三角形
};
GLuint EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); while (!glfwWindowShouldClose(window))
{//......//glDrawArrays(GL_TRIANGLES, 0, 3);        --此行不要glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//......
}
glDeleteBuffers(1, &EBO);

这样就可以输出我们想要的结果:

二、索引缓冲对象 EBO

上面的EBO(Element Buffer Object)即索引缓冲区对象,这个缓冲区主要用来存储顶点的索引信息,可以看出,它的用法和VBO非常的像,除此之外,它也可以被VAO所绑定

和VBO不同的是,我们传递GL_ELEMENT_ARRAY_BUFFER当作缓冲目标,并且在绘制时使用glDrawElements来替换glDrawArrays函数,表示我们使用当前绑定的索引缓冲对象中的索引进行绘制

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0):第一个参数为绘制模式,第二个参数为绘制顶点个数,第三个参数为索引类型,第四个参数为EBO中的偏移量,一样填写0就好,当我们不再使用索引缓冲对象的时候,可以传递一个索引数组

三、线框模式

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE):配置OpenGL如何绘制图元,第一个参数表示我们打算将其应用到所有的三角形的正面和背面(其实对于我们的例子没有什么区别,可以暂时无视),第二个参数表示用线来绘制,之后的绘制调用会一直以线框模式绘制三角形,直到第二个参数传入GL_FILL后回到默认模式

四、测试

看可不可以在不参考任何文章和代码的情况下,仅通过修改之前生成的三角形的代码,生成如下图形:

参考代码:

#pragma comment(lib,"glew32.lib")
#include<iostream>
#include<opengl/glew.h>
#define GLEW_STATIC
#include<GLFW/glfw3.h>
#include<opengl/freeglut.h>void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
const GLuint WIDTH = 800, HEIGHT = 600;// Shaders
const GLchar* VShader =
"#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n""gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";const GLchar* FShaderY =
"#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n""color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";const GLchar* FShaderB =
"#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n""color = vec4(0.1f, 0.1f, 1.0f, 1.0f);\n"
"}\n\0";int main()
{glfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);glfwMakeContextCurrent(window);glfwSetKeyCallback(window, key_callback);glewExperimental = GL_TRUE;glewInit();int width, height;glfwGetFramebufferSize(window, &width, &height);glViewport(0, 0, width, height);GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &VShader, NULL);glCompileShader(vertexShader);GLuint fShaderY = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fShaderY, 1, &FShaderY, NULL);glCompileShader(fShaderY);GLuint fShaderB = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fShaderB, 1, &FShaderB, NULL);glCompileShader(fShaderB);GLuint shaderYellow = glCreateProgram();GLuint shaderBlue = glCreateProgram();glAttachShader(shaderYellow, vertexShader);glAttachShader(shaderYellow, fShaderY);glLinkProgram(shaderYellow);glAttachShader(shaderBlue, vertexShader);glAttachShader(shaderBlue, fShaderB);glLinkProgram(shaderBlue);glDeleteShader(vertexShader);glDeleteShader(fShaderY);glDeleteShader(fShaderB);GLfloat trangleY[] ={-0.5f, -0.5f, 0.0f,-0.5f, 0.5f, 0.0f,0.0f, 0.0f, 0.0f};GLfloat trangleB[] ={0.5f, -0.5f, 0.0f,0.5f, 0.5f, 0.0f,0.0f, 0.0f, 0.0f};GLuint VBO[2], VAO[2];glGenVertexArrays(2, VAO);glGenBuffers(2, VBO);glBindVertexArray(VAO[0]);glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(trangleY), trangleY, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);glBindVertexArray(VAO[1]);glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);glBufferData(GL_ARRAY_BUFFER, sizeof(trangleB), trangleB, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);while (!glfwWindowShouldClose(window)){glfwPollEvents();glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);glUseProgram(shaderYellow);glBindVertexArray(VAO[0]);glDrawArrays(GL_TRIANGLES, 0, 3);glUseProgram(shaderBlue);glBindVertexArray(VAO[1]);glDrawArrays(GL_TRIANGLES, 0, 3);glBindVertexArray(0);glfwSwapBuffers(window);}glDeleteVertexArrays(2, VAO);glDeleteBuffers(2, VBO);glfwTerminate();return 0;
}void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);
}

参考文献:https://learnopengl.com/#!Getting-started/OpenGL

OpenGL基础5:第一个正方形相关推荐

  1. OpenGL基础46:切线空间

    到这里,关于OpenGL基础的了解要接近尾声了,上一个节点是<OpenGL基础25:多光源>.在此章之后,学习openGL的各种教程的同时,可以转战想要了解的渲染引擎,也可以去github ...

  2. OpenGL基础17:颜色

    一.RGB三原色 回想一下初中物理知识: 三原色:自然界中所有的颜色都可以用红.绿.蓝(RGB)这三种颜色频率的不同强度组合而得,白色包含了所有颜色 能看到一个物体的颜色,是这个物体(Reflecte ...

  3. OpenGL基础12:进入3D世界

    前置:OpenGL基础11:空间 一.坐标系 我们都学过坐标系,根据z轴的方向,一般有两种不同的坐标系表示方法: 其中拇指是x轴正方向,食指是y轴正方向,中指是z轴正方形 OpenGL约定是右手坐标系 ...

  4. OpenGL基础8:SOIL库

    一.SOIL SOIL是简易OpenGL图像库(Simple OpenGL Image Library)的缩写,它支持大多数流行的图像格式,关于SOIL的介绍应该很多,这里就不说了,我们先装上 Ope ...

  5. OpenGL基础图形编程

    一.OpenGL与3D图形世界 1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个 ...

  6. OpenGL基础知识介绍和简单使用

    OpenGL基础知识介绍 OpenGL简介 OpenGL 专业词解析 1.OpenGL上下文[context] 2.渲染 3.顶点数组和顶点缓冲区 4.着色器程序Shader 5.顶点着色器(Vert ...

  7. OpenGL基础编程

    一.OpenGL与3D图形世界 1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个 ...

  8. 【转】OpenGL基础图形编程(一)

    原文:http://blog.chinaunix.net/uid-20638550-id-1909183.html  分类: 一.OpenGL与3D图形世界 1.1.OpenGL使人们进入三维图形世界 ...

  9. OpenGL基础图形编程(转)

    一.OpenGL与3D图形世界 1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个 ...

  10. OpenGL基础图形编程(一)

    一.OpenGL与3D图形世界 1.1.OpenGL使人们进入三维图形世界 我们生活在一个充满三维物体的三维世界中,为了使计算机能精确地再现这些物体,我们必须能在三维空间描绘这些物体.我们又生活在一个 ...

最新文章

  1. 南京大学潘天群教授:人类智能发展的宏大叙事
  2. sklearn快速入门教程:补充内容 -- sklearn模型评价指标汇总(聚类、分类、回归)
  3. display:flex 多栏多列布局
  4. real210移植记录-支持eMMC,增加菜单操作
  5. 0006-ZigZag Conversion(Z 字形变换)
  6. java 职责链模式_Java中的责任链模式
  7. 字符串在编号查询中的应用示例及常见问题.sql
  8. 【Linux使用】Centos 7安装图形界面/切换文本界面与图形界面
  9. 从小白到大数据技术专家的学习历程,你准备好了吗
  10. 机器学习第一回——初识监督学习和无监督学习
  11. CPU调度算法——FCFS算法/SJF算法/优先级调度算法/RR算法
  12. 【js】js传递对象
  13. 【信息系统项目管理师】项目管理十大知识领域速记
  14. git pull git push 报spawn ssh错误,vscode更换默认终端
  15. 【gloomyfish】数据分析之 – 离群值(Outliers) BoxPlot
  16. vector erase() and clear() in C++ -- vector的函数erase()和clear()
  17. android透明功能引导页,Android 利用PagerView做引导页
  18. B70极路由4增强版安装frps
  19. Cesium geojson 移除
  20. OCX控件全屏、恢复

热门文章

  1. python和c先学哪个-对于初学者而言,python和 c语言先学哪个好
  2. python画柱状图-python plotly画柱状图代码实例
  3. python中文版软件下载-Python IDLE(Python集成开发环境)v3.7中文版
  4. python菜鸟教程100例-Python 练习实例1
  5. python代码-我整理的Python代码规则
  6. flex实现最后一个元素居右
  7. JavaScript基础简单入门
  8. 使用原生js实现邮箱模糊查询的效果
  9. JavaScript-预解析(变量提升)
  10. 【深入理解JVM】运行时数据区域:java虚拟机栈