写在前面

从这节开始,会接触到很多基本概念,原书我也是读了很多遍,一遍一遍去理解其中的意思,以及他们之间的关系。

概念

顶点数组对象:VAO

顶点缓冲对象:VBO

索引缓冲对象:EBO|IBO

OpenGL是一个3D空间,而屏幕和窗口是2D的,所以OpenGL的大部分工作是将3D坐标转换为2D像素

转换的过程就是由图形渲染管线管理的。

图像渲染管线分为两部分:1.把3D坐标转换为2D坐标。2.把2D坐标转变为有颜色的像素

渲染的几个阶段:

顶点数据->顶点着色器->图元装配->几何着色器->光栅化->片段着色器->测试与混合

渲染的每一个阶段都有自己的程序,该程序是使用OpenGL着色器语言进行编写的,这些小程序叫做着色器(shader)

顶点着色器:把3D坐标转换为另一种3d坐标,同时对顶点属性进行一些基本处理

图元装配:将所有的点装配成指定的图元形状

几何着色器:通过产生新的点和新的图元来生成形状

光栅化:将图元映射为最终屏幕上相应的像素,生成片段着色器使用的片段,并裁切吊超过视图以外的像素

片段着色器:计算一个像素的最终颜色

测试与混合:检测片段对应的深度值,用来判断这个像素是其它物体的前面还是后面,决定是否丢弃

代码创建

首先,我们声明出来下面需要使用的着色器源码。

通过上述概念我们知道着色器,是运行在图像渲染管线上的小程序,代码风格类似c语言

 // 顶点着色器源码
const char *vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main(){\n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0f);\n"
"}\n\0"; //片段着色器源码
const char *fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main(){\n"
"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";

下边我们使用上述两个着色器,构建一个可以渲染的渲染管线

    //创建顶点着色器
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
// 第一个参数着色器对象,第二个参数传递的源码字符串,第三个参数顶点着色器的源码
glShaderSource(vertexShader, , &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// 判断编译是否成功
int sucess;
char infoLog[];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &sucess);
if(!sucess){
glGetShaderInfoLog(vertexShader, , NULL, infoLog);
std::cout<< "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"<< infoLog << std::endl;
}
    // 片段着色器,创建并编译
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, , &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, & sucess);
if(!sucess){
glGetShaderInfoLog(fragmentShader, , NULL, infoLog);
std::cout<<"ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"<< infoLog<<std::endl;
}

两个着色器创建,且编译之后,需要进行连接

//链接两个着色器对象到用来渲染的着色器程序中
// 创建着色器程序
int shaderProgram = glCreateProgram();
//链接
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetShaderiv(shaderProgram, GL_COMPILE_STATUS, & sucess);
if(!sucess){
glGetShaderInfoLog(shaderProgram, , NULL, infoLog);
std::cout<<"ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n"<< infoLog<<std::endl;
}

链接两个着色器到我们刚创建的着色器程序中,且进行了编译,这个时候,我们上面的两个着色器,已经在shaderProgram中了。

 //删除无用的顶点着色器以及片段着色器
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

我们知道,渲染的几个阶段,那么现在我们只需要创建顶点数据,然后使用上述着色器程序进行渲染

     // 定义三个顶点
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};

对于顶点的管理,我们使用顶点缓冲对象以及顶点数组对象进行管理。文章开头已经讲解了基本的概念

// 使用顶点缓冲对象进行缓存
unsigned int VBO, VAO;
glGenVertexArrays(, &VAO);
glGenBuffers(, &VBO);
// 缓冲对象进行绑定
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

缓冲对象的使用

     // 将定义的顶点数据复制到缓冲内存中
// 第一个参数,缓冲类型,第二个参数数据大小,第三个参数发送的数据,第四个参数,显卡如何管理给定的数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 解析顶点数据
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
// 启动顶点数据
glEnableVertexAttribArray(); glBindBuffer(GL_ARRAY_BUFFER, );
glBindVertexArray(); glDrawArrays(GL_TRIANGLES,,);

现在我们的顶点数组对象已经在内存中了

下面就是调用着色器程序进行启动

         //启用三角形
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 激活程序
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, , );
glfwSwapBuffers(window);

最后,不要忘了清楚我们使用的vao以及vbo对象

//清除对象
glDeleteVertexArrays(, &VAO);
glDeleteBuffers(, &VBO);

总结

通过上述的流程,应该是可以跑起来一个三角形的。OpenGL之路漫漫长,我们继续加油

OpenGL(3)-三角形的更多相关文章

  1. OpenGL 用三角形模拟生成球面

    在看OpenGL红皮书,看到生成球体这节,讲了很多,总感觉不如自己动手写一些代码来的实在,用OpenGL中三角形模拟球形生成.主要要点,模型视图变换,多边形表面环绕一致性,矩阵堆栈.先贴上代码. 虽然 ...

  2. 【OpenGL】三角形

    步骤 初始化顶点数组对象VAO 分配顶点缓冲对象VBO 将顶点数据载入缓冲对象中 glBufferData() 链接顶点属性 glVertexAttribPointer(指定了顶点着色器的变量与我们存 ...

  3. opengl绘制三角形

    顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 索引缓冲对象:Element Buffer Object,EBO或Inde ...

  4. 1.opengl绘制三角形

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

  5. CSharpGL(31)[译]OpenGL渲染管道那些事

    CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...

  6. OpenGL2-绘制三角形

    代码下载 /*** 该例子展示如何使用OpenGL绘制三角形* 为什么说绘制三角形呢 ?三维空间里面,我们看到的机会大多数* 漂亮的模型,建筑,任务,机会都是有三角形网络组成.可以说三角形* 是组成三 ...

  7. 03->OpenGL多边形,glut实现三角形条带和三角形扇

    图形学中基本图元是多边形,一般要求是凸多边形,三角形是最简单的凸多边形,在图形渲染中比一般多边形其绘制速度快.今天学习OpenGL绘制三角形条带和三角形扇基础.编程环境! 1. 三角形条带 指定顶点序 ...

  8. 2.通过QOpenGLWidget绘制三角形

    参考:1.opengl绘制三角形 1.QOpenGLWidget的早先版本 QGLWidget是遗留Qt OpenGL模块的一部分,和其他QGL类一样,应该在新的应用程序中避免使用.相反,从Qt 5. ...

  9. [Modern OpenGL系列(三)]用OpenGL绘制一个三角形

    本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347008 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...

随机推荐

  1. JVM & GC 笔记

    0. 说明 转载并修改自JVM 1. JVM 1.1 什么是JVM JVM为Java虚拟机(Java Virtual Machine) Runtime data area,运行时数据区. 包含5个区域 ...

  2. Alpha事后诸葛亮(阳光普照队)

    Alpha事后诸葛亮 设想和目标 1.实现文字识别,以用户喜欢的图片做背景将其保存,生成新的图片. 2.时间比较赶,主要是因为队员对于Android开发方面的了解不多,可以说是几乎没有,需要一步一步的 ...

  3. [部署]VM11下CentOS7mini安装及配置

    最近使用了CentOS发现比Ubuntu更简洁,有些爱上CentOS了 1. 准备一版CentOS安装镜像文件 官网下载地址:http://www.centos.org/download/ 官方有三个 ...

  4. Nginx实践--安全升级

    之前写了一些nginx的东西,这次继续,主要使用upstream针对proxy_pass转发做个处理 一般情况下我们在使用nginx反向代理的时候,都是如下配置, ... location /api ...

  5. PID控制本版二

    https://gist.github.com/bradley219/5373998 特色: 比起第一版,加入了 最大最小值限制,暂无测试. PIDImpl( double dt, double ma ...

  6. ELK日志收集分析平台 (Elasticsearch+Logstash+Kibana)使用说明

    使用ELK对返回502的报警进行日志的收集汇总 eg:Server用户访问网站返回502 首先在zabbix上找到Server的IP 然后登录到elk上使用如下搜索条件: pool_select:X. ...

  7. 开源仓库Harbor搭建及配置过程

    1.Harbor介绍 Harbor是Vmvare中国团队开发的开源registry仓库,相比docker官方拥有更丰富的权限权利和完善的架构设计,适用大规模docker集群部署提供仓库服务. 2.安装 ...

  8. vmware中装的ubuntu上不了网

    背景 上周末重装了windows主机的系统,之后就重新安装了vmware软件,今天使用的时候就发现git pull代码仓库的时候,发现代码仓库无法获取,检查后发现是虚拟机上不了网了. 查看了一系列教程 ...

  9. 理解javascript观察者模式(订阅者与发布者)

    什么是观察者模式? 观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察着对象.它是由两类对象组成,主题和观察者 ...

  10. 【转】阿里云Ubuntu系统搭建SVN服务器

    ##SVN服务器相关软件安装 1.使用SSH远程服务器 (1)对于MAC OS/Liunx的用户直接打开终端输入 ssh  用户名@实例名,例如 ssh root@192.168.1.100 执行上面 ...