OpenGL 4.0 GLSL 基础教程概览——VAO和VBO常用操作接口
(一) OpenGL 4.3 最新渲染管线图
从OpenGL 2.0 到 OpenGL 3.0变化非常大,但从OpenGL 3.0 到OpenGL 4.0 变化不是太大。
着色器程序直接运行在GPU上,并且是并行的,一个片元着色器可能一次执行所有象素。
deprecation model, 在OpenGL3.0 提出,为了保持向后兼容,兼容模式compatibility profile.和核心模式core profile的概念在OpenGL 3.2 中提出。
在Qt 4.7以后版本,可以通过下列方式选择核心模式:
QGLFormat format;
format.setVersion(,);
format.setProfile(QGLFormat::CoreProfile);
QGLWidget *myWidget = new QGLWidget(format);
传送数据到GPU
1. 产生顶点数组对象(vertex-array object, VAO)的标识符glGenVertexArrays
2. 绑定(创建)顶点数组对象glBindVertexArray
3. 产生缓冲区对象的标识符glGenBuffers
4. 绑定(创建)缓冲区对象glBindBuffer
5. 为缓冲区对象分配存储空间,传送数据glBufferData
6. 更新缓冲区对象的数据glBufferSubData
(二) 顶点数组对象(VAO)
1. 顶点有多种属性值:位置, 颜色, 纹理坐标, 应用程序数据等. 顶点数组包含了这些数据.
2. OpenGL中用顶点数组对象打包了所有的顶点数据(位置、颜色等)
3. 生成顶点数组对象的标识符(或名字)然后绑定
产生顶点数组对象名
1. Void glGenVertexArrays(GLsizein,GLuint*arrays);
2. 返回n个当前未被使用的顶点数组对象名到数组arrays
3. 名字类似于C中的指针,只有指向已分配的内存才有意义
4. OpenGL中的分配方式称为对象绑定
绑定顶点数组对象
1. 当array首次使用从glGenVertexArrays()返回的非零值时,创建一个新的顶点数组对象并赋以该名字
2. 当绑定到已创建的顶点数组对象时,该对象变成当前活动对象
3. 当绑定到零值时,OpenGL停止使用应用程序分配的顶点数组对象并返回到顶点数组的默认状态
删除顶点数组对象
1. Void glDeleteVertexArrays(GLsizein,constGLuint*arrays);
2. 删除arrays中指定的n个顶点数组对象,使得这些名字可被重用
3. 如果一个当前绑定的顶点数组对象被删除,该顶点数组的绑定变为0,并且默认顶点数组成为当前活动对象
查询顶点数组对象名
1. GLboolean glIsVertexArray(GLuintarray);
2. 查询array是否对应到一个顶点数组对象
3. 返回GL_TRUE,如果array是一个之前glGenVertexArrays()产生的顶点数组对象名,且后来未被删除
4. 返回GL_FALSE,如果array是0,或者一个非顶点数组对象名的非零值
(三) 顶点缓冲区对象(VBO)
1. 顶点的各种数据存储在缓冲区对象中,并由当前绑定的顶点数组对象所管理
2. 缓冲区对象是由GPU分配并管理的内存创建、绑定、传送(或更新)数据
产生缓冲区对象名
1. void glGenBuffers(GLsizein,GLuint*buffers);
2. 返回n个当前未被使用的缓冲区对象名到数组buffers
3. 返回的名字不必是连续的
4. 缓冲区对象名是无符号整数,0是保留值
绑定缓冲区对象
1. Void glBindBuffer(GLenumtarget,GLuintbuffer);
2. 缓冲区对象的类型target有如下9种:
GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TEXTURE_BUFFER, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, GL_UNIFORM_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER
3. 当buffer是首次使用的从glGenBuffers()返回的非零值时,创建一个新的缓冲区对象并赋以该名字
4. 当绑定到以前创建的缓冲区对象时,该对象变成当前活动对象
5. 当绑定到零值时,OpenGL停止使用target类型的缓冲区对象
删除缓冲区对象
1. Void glDeleteBuffers(GLsizein,constGLuint*buffers);
2. 删除buffers中指定的n个缓冲区对象,使得这些名字可被重用
3. 如果一个当前绑定的缓冲区对象被删除,该对象的绑定重置为默认缓冲区对象
查询缓冲区对象名
1. GLbooleanglIsBuffer(GLuintbuffer);
2. 查询buffer是否对应到一个缓冲区对象
3. 返回GL_TRUE,如果buffer是一个已被绑定的缓冲区对象名,且后来未被删除
4. 返回GL_FALSE,如果buffer是0,或者一个不是缓冲区对象名的非零值
加载数据到缓冲区对象
1. void glBufferData(GLenumtarget, GLsizeiptr size,const GLvoid* data, GLenum usage);
2. 为target类型的当前绑定缓冲区对象分配size字节的服务器内存,并用data指向的数据来初始化。以前与当前绑定对象关联的数据都将删除。
3. size 是存储相关数据所需的内存数量,通常是数据元素的个数乘以各自的字节大小
4. data 可以是指向客户机内存的指针或NULL。如果是有效指针,size字节的数据从客户机复制到服务器;如果是NULL,只分配size字节的服务器内存
5. usage 指定数据存储区的使用方式,取值:
GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY,GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY.
更新缓冲区对象数据
1. void glBufferSubData(GLenumtarget, GLintprt offset,GLsizeiptr size, const GLvoid* data);
2. 用data指向的数据更新target类型的当前绑定缓冲区对象中从offset字节开始的size字节的数据。
3. 如果size或offset小于零,或者它们的和大于缓冲区对象创建时所指定的大小时,报错GL_INVALID_VALUE。
(五) 顶点属性变量
1. 顶点属性是顶点着色器中的attribute变量
2. 链接器生成一张属性变量的索引表
3. 应用程序从表中查询属性变量的索引值,并关联到应用程序中的变量
获取属性变量的索引
1. GLint glGetAttribLocation(GLuint program,const GLchar*name);
2. 返回与链接过的着色器程序program中属性变量name相关联的索引
3. 如果name不是program的一个活动属性变量,或是内置属性变量(以gl_开头) ,返回-1
4. 如果name是矩阵属性变量,返回矩阵第一列的索引。后一列的索引为前一列的索引加1
指定顶点属性数组值
1. void glVertexAttribPointer(GLuintindex,GLintsize,GLenum type, GLboolean normalized,GLsizei stride,constGLvoid*pointer);
2. 为索引值为index的顶点属性变量的数组指定位置pointer和数据格式
3. size每个顶点属性的分量个数,为1,2,3,4或GL_RGBA,初始值为4
4. type数组元素的数据类型,初始为GLfloat
5. normalized指定浮点数据值是否要规范化
6. stride数组中相邻元素的偏移字节,0表示数据连续存储
7. pointer指定顶点属性数组的第一个分量在当前绑定的GL_ARRAY_BUFFER缓冲区对象中的偏移量
启用/禁用顶点属性数组
1. voidglEnableVertexAttribArray(GLuintindex)
2. voidglDisableVertexAttribArray(GLuintindex)
3. 启用/禁用属性index的顶点属性数组
4. 启用后,就可用glDrawArrays()等来为顶点属性变量加载值
(六) ArrayDraw的方式:
void glDrawArrays(GLenum type, GLint start, GLint count)
{
for(GLint element = start; element < start + count; element++)
{
VertexShader(positionAttribArray[element], colorAttribArray[element]);
}
}
Indexed Draw 的方式
void glDrawElements(GLenum type, GLint count, GLenum type, GLsizeiptr indices)
{
GLtype *ourElementArray = (type*)((GLbyte *)elementArray + indices);
for(GLint elementIndex = ; elementIndex < count; elementIndex++)
{
GLint element = ourElementArray[elementIndex];
VertexShader(positionAttribArray[element], colorAttribArray[element]);
}
}
查询GLSL 和OpenGL所支持的版本
const GLubyte *renderer =glGetString( GL_RENDERER );
const GLubyte *vendor =glGetString( GL_VENDOR );
const GLubyte *version =glGetString( GL_VERSION );
const GLubyte *glslVersion =
glGetString( GL_SHADING_LANGUAGE_VERSION);
GLint major, minor;
glGetIntegerv(GL_MAJOR_VERSION,&major);
glGetIntegerv(GL_MINOR_VERSION,&minor);
printf("GL Vendor :%s\n", vendor);
printf("GL Renderer :%s\n", renderer);
printf("GL Version(string) : %s\n", version);
printf("GL Version(integer) : %d.%d\n", major, minor);
printf("GLSLVersion : %s\n", glslVersion);
用glGetString and glGetIntegerv两种方式查询系统支持OpenGL的版本,不过glGetIntegerv更利于编程使用
获得当前活动顶点属性和其索引
//获得当前活动顶点属性和其索引
GLint maxLength, nAttribs;
glGetProgramiv(shader.GetHandler(), GL_ACTIVE_ATTRIBUTES,&nAttribs);
glGetProgramiv(shader.GetHandler(), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,&maxLength);
GLchar * name = (GLchar *) malloc( maxLength );
GLint written, size, location;
GLenum type;
printf(" Index | Name\n");
printf("------------------------------------------------\n");
for( int i = ; i < nAttribs; i++ )
{
glGetActiveAttrib( shader.GetHandler(), i, maxLength, &written, &size, &type, name );
location = glGetAttribLocation(shader.GetHandler(), name);
printf(" %-5d | %s\n",location, name);
}
free(name);
printf("------------------------------------------------\n");
查询uniform变量
//查询uniform变量
GLint nUniforms, maxLen;
glGetProgramiv( shader.GetHandler(), GL_ACTIVE_UNIFORM_MAX_LENGTH,&maxLen);
glGetProgramiv( shader.GetHandler(), GL_ACTIVE_UNIFORMS,&nUniforms); GLchar * name = (GLchar *) malloc( maxLen ); GLint size, location;
GLsizei written;
GLenum type;
printf(" Location | Name\n");
printf("------------------------------------------------\n");
for( int i = ; i < nUniforms; ++i ) {
glGetActiveUniform( shader.GetHandler(), i, maxLen, &written,
&size, &type, name );
location = glGetUniformLocation(shader.GetHandler(), name);
printf(" %-8d | %s\n", location, name);
}
printf("------------------------------------------------\n");
free(name);
OpenGL 4.0 GLSL 框架 下载地址
http://download.csdn.net/detail/zhuyingqingfen/6852149
OpenGL 4.0 GLSL 基础教程概览——VAO和VBO常用操作接口的更多相关文章
- 『心善渊』Selenium3.0基础 — 11、Selenium对元素常用操作
目录 1.Selenium对元素常用操作 2.Selenium对元素的其他操作 1.Selenium对元素常用操作 操作 说明 click() 单击元素 send_keys() 模拟输入 clear( ...
- OpenGL 4.0 GLSL 实现 投影纹理映射(Projective Texture Mapping) (转)
http://blog.csdn.net/zhuyingqingfen/article/details/19331721 分类: GLSL 投影纹理映射 (projective texture ...
- MySQL8.0数据库基础教程(二)-理解"关系"
1 SQL 的哲学 形如 Linux 哲学一切都是文件,在 SQL 领域也有这样一条至理名言 一切都是关系 2 关系数据库 所谓关系数据库(Relational database)是创建在关系模型基础 ...
- [原]OpenGL基础教程(四)VBO+纹理绘制四边形
工程下载地址:http://pan.baidu.com/s/1ntr7NHv 提取码:yf1h 一.本文牵扯知识点梳理: (1)VBO (2)纹理 (3)libpng(加载png) (4)shader ...
- SpringCloud2.0 概述 基础教程(一)
1.SpringCloud简介 Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举 ...
- MySQL8.0关系数据库基础教程(三)-select语句详解
1 查询指定字段 在 employee 表找出所有员工的姓名.性别和电子邮箱. SELECT 表示查询,随后列出需要返回的字段,字段间逗号分隔 FROM 表示要从哪个表中进行查询 分号为语句结束符 这 ...
- 《python基础教程》笔记之 序列通用操作
索引 序列中的所有元素都是有编号的--从0开始递增.使用负数索引时,Python会从右边,也就是从最后一个元素开始计数,最后一个元素的位置编号是-1.此外,字符串是一个有字符组成的序列,字符串字面值可 ...
- mysql8.0 新特性,对json类型的常用操作
mysql8 新特性-json数据类型操作 -- 根据key(可多个)获取value SELECT JSON_EXTRACT('{"id": 14, "name" ...
- C#基础(六)--枚举的一些常用操作
本章将介绍以下几点: 1.如何把其它类型转换为枚举类型? 2.如何把枚举中的值添加到下拉菜单中? 一.如何把其它类型转换为枚举类型? 我们回顾一下有关字符串与数字之间的转换,如: ...
随机推荐
- js 笔记 数组(对象)
一.javascript push 的元素为指针 var data = {"test":{"201308":"23","20130 ...
- DataTable 字段值为空的时候报错的解决
在使用Datatable的时候,后台返回给前台的值会有空的时候,而这个时候,前台会报错,这里讲防治方法: $('#datatable1').DataTable( { ajax: { "url ...
- 【SVN/Visual Studio】清除/更换AnkhSVN的用户登录信息
问题: 在VS开发环境下,使用SVN做版本控制,用了TortoiseSVN和插件AnkhSVN.提交代码到SVN服务器时,发现用的是别人的SVN帐号,不是自己的号(比如该电脑之前是别人在使用).想要清 ...
- 【WPF/C#】拖拽Image图片控件
需求:使得Image图片控件能够被拖动. 思路:关键是重写Image控件的几个鼠标事件,实现控制. 前台: <Image Source="C:\Users\Administrator\ ...
- RESTful测试工具-RESTClient
很多测试人可能对RESTful的概念还是很模糊的,那么到底什么是RESTful?百度百科给出的一句话描述是一个架构样式的网络系统,似乎还是有点不懂?OK,说到Restful,我们一般从REST开始说起 ...
- 文件服务器和web应用分离的思路(转)
目前在做一个应用,有不同的客户端,包括web应用的客户端,其他的客户端,都要访问我的文件服务器,通过文件服务程序提供的服务来访问文件,但是对文件管理服务器这个应用,没有什么思路,请大家给点思路,谢谢: ...
- Android Wear Preview- 归档通知(Stacking Notifications)
---------------------------------------------------------------------------------------------------- ...
- Entity Framework应用:管理并发
理解并发 并发管理解决的是允许多个实体同时更新,实际上这意味着允许多个用户同时在相同的数据上执行多个数据库操作.并发是在一个数据库上管理多个操作的一种方式,同时遵守了数据库操作的ACID属性(原子性. ...
- e675. 翻转缓冲图像
// To create a buffered image, see e666 创建缓冲图像 // Flip the image vertically AffineTransform tx = Aff ...
- JAVA 多线程机制(二)
主要内容 1.理解线程的并发性 2.线程的同步 3.线程的常用方法 上一章中由于线程的并发性导致了多线程的执行总是会出现一些问题..线程的并发性是程序员不可控制 的,也是不可避免的,线程的并发性往 ...