缓冲区对象对于OPENGL来说,很重要,虽然我并不经常用它,在红宝书上它属于高级话题。

“在许多OPENGL操作中,我们都向OPENGL发送一大块数据,例如向它传递需要处理得顶点数组数据。传输这种数据可能非常简单,例如把数据从系统的内存中复制到图形卡。但是,由于OPENGL是按照客户机-服务器模式设计的,在OPENGL需要数据的任何时候,都必须把数据从客户机内存传到服务器。如果数据并没有修改,或者客户机和服务器位于不同的计算机(分布式渲染),数据的传输可能会比较缓慢,或者是冗余的。
OPENGL 1.5版本增加了缓冲区对象(buffer object),允许应用程序显式地指定把哪些数据存储在图形服务器中。”

由此可知,缓冲区对象在个人PC上,它存在于图形卡的显存中。最近经常需要用到缓冲区,因为开始接触到CUDA。CUDA是NVIDIA推出的GPU上的通用计算产品。因为是在显卡上做计算,想要和OPENGL进行互操作,用缓冲区比较方便。当然,在这里,我没打算把这两者结合起来说。这里只是简单的理一下缓冲怎么用而已。

在OPENGL中,我们经常看到glGen*、glBind*这样的函数,缓冲区的操作也不例外。

1.创建缓冲区对象 void glGenBuffers(GLsizei n, GLuint *buffers);(这个函数。。。顾名思义,就不用解释了)

2.激活缓冲区对象 void glBindBuffer(GLenum target, GLuint buffer);

3.用数据分配和初始化缓冲区对象 void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);

  (data为NULL,则缓冲区仅仅分配了空间,没有有意义的初始值;如果不是NULL,那就是data所指向的大小为size的内存的数据)

上面的很机械,也很好理解。本人刚开始接触OPENGL的时候,创建和初始化都没问题,但老是搞不清楚该怎么用,尤其是如何把它和纹理联系在一起。后来发现关键在下面这个函数GLvoid *glMapBuffer(GLenum target, GLenum access),这个函数的返回值是一个指针,就是指向这个缓冲区的指针,只要注意设置,确实能返回指向缓冲区的指针。

缓冲一经具体使用之后,只需要改变缓冲区的内容,即在glMapBuffer和glUnmapBuffer之间改变数据即可。

下面是个简单程序,其实就是红宝书上的,我简单的修改了一下而已,-_-!

在键盘处理事件中可以看到如何更新缓冲区,让它放大,但如果改成缩小,貌似就会有问题,很奇怪的一个现象。

#include "stdafx.h"
#include "stdlib.h"
#include "gl/glew.h"
#include "gl/glut.h"

#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
#define VERTICES 0
#define INDICES 1
#define NUM_BUFFERS 2
GLuint buffers[NUM_BUFFERS];

GLfloat vertices[][3] = {
{-1.0f,-1.0f,-1.0f},
{1.0f,-1.0f,-1.0f},
{1.0f,1.0f,-1.0f},
{-1.0f,1.0f,-1.0f},
{-1.0f,-1.0f,1.0f},
{1.0f,-1.0f,1.0f},
{1.0f,1.0f,1.0f},
{-1.0f,1.0f,1.0f}
};
GLubyte indices[][4] = {
{0,1,2,3},
{4,7,6,5},
{0,4,5,1},
{3,2,6,7},
{0,3,7,4},
{1,5,6,2}
};

GLfloat* bdata;

void changeSize(int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,(double)w/(double)h,0.01,30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void keyDown(unsigned char key, int x, int y)
{
switch (key)
{
case'b':
bdata = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER,GL_READ_WRITE);
for (int i =0; i <24; i ++)
{
*(bdata + i) *=1.1f;
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glutPostRedisplay();
break;
}
}

void mouse(int button, int state, int x, int y)
{

}
void display(void)
{
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(30.0f,1.0f,1.0f,0.0f);

glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,BUFFER_OFFSET(0));

glutSwapBuffers();
}

void init(void)
{
glClearColor(0.0f,0.0f,0.0f,0.0f);
glShadeModel(GL_FLAT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glewInit();
glGenBuffers(NUM_BUFFERS,buffers);
glBindBuffer(GL_ARRAY_BUFFER,buffers[VERTICES]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_DYNAMIC_DRAW);
glVertexPointer(3,GL_FLOAT,0,BUFFER_OFFSET(0));

glEnableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,buffers[INDICES]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
}

int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GL_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutCreateWindow("Buffer Demo");
glutReshapeFunc(changeSize);
glutMouseFunc(mouse);
glutKeyboardFunc(keyDown);
glutDisplayFunc(display);
init();
glutMainLoop();
return0;
}

转载于:https://www.cnblogs.com/unsigned/archive/2011/02/24/1963875.html

OPENGL学习笔记整理(三):缓冲区对象相关推荐

  1. 小朱opengl学习笔记(三)------着色器的详细学习

    上篇博客,主要是介绍了Opengl的大致使用流程,由于中间过程可能比较复杂, 所以今天笔者首先梳理一遍整个的流程. 祭宝图哈. 上篇博客我们的重点是放在由 顶点数据-->顶点着色器 的这个过程上 ...

  2. Python学习笔记整理(三)Python中的动态类型简介

    Python中只有一个赋值模型 一.缺少类型声明语句的情况 在Python中,类型是在运行过程中自动决定的,而不是通过代码声明.这意味着没有必要事声明变量.只要记住,这个概念实质上对变量,对象和它们之 ...

  3. opengl学习笔记(三)

    一致变量 一致变量就是在shader中运行时不变的量,像是全局常量.往往是一些变化矩阵,比如顶点处理器中存在着坐标变换,并且对于每一个顶点的处理都相同,那么就用uniform定义. gScaleLoc ...

  4. Deep Learning(深度学习)学习笔记整理系列三

    Deep Learning(深度学习)学习笔记整理系列 声明: 1)该Deep Learning的学习系列是整理自网上很大牛和机器学习专家所无私奉献的资料的.具体引用的资料请看参考文献.具体的版本声明 ...

  5. Deep Learning(深度学习)学习笔记整理系列之(三)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  6. Kafka入门篇学习笔记整理

    Kafka入门篇学习笔记整理 Kafka是什么 Kafka的特性 应用场景 Kafka的安装 单机版部署 集群部署环境准备 Kafka 2.x集群部署 Kafka 3.x集群部署 监听器和内外网络 K ...

  7. 【mysql学习笔记整理】

    /*mysql学习笔记整理*/ /*常用的数据库操作对象*/ #库的操作 #创建 #数据库的创建 USE mysql; CREATE DATABASE db_x; #删除 #删除数据库 DROP DA ...

  8. Java NIO 学习笔记(三)----Selector

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  9. OpenCV学习笔记(三十一)——让demo在他人电脑跑起来 OpenCV学习笔记(三十二)——制作静态库的demo,没有dll也能hold住 OpenCV学习笔记(三十三)——用haar特征训练自己

    OpenCV学习笔记(三十一)--让demo在他人电脑跑起来 这一节的内容感觉比较土鳖.这从来就是一个老生常谈的问题.学MFC的时候就知道这个事情了,那时候记得老师强调多次,如果写的demo想在人家那 ...

  10. jvm学习笔记(三)

    jvm学习笔记(三) 文章目录 jvm学习笔记(三) 1.全部笔记链接 2.堆 2.1堆的划分 使用JVM参数查看划分 Hotspot堆内存划分图(JDK8之前) 2.2 GC对堆的回收 GC的种类 ...

最新文章

  1. Microsoft Teams快速上手系列-06邀请组织外部用户加入团队
  2. SIGIR 2019 开源论文 | 基于图神经网络的协同过滤算法
  3. boost::fusion::unfused_typed用法的测试程序
  4. Day 62 Django第三天
  5. mysql的for循环_MySQL中的For循环示例
  6. 前端后台管理系统梳理
  7. bash: go: 未找到命令_golang快速入门[2.3]-go语言开发环境配置-linux
  8. AIX 6.1 连接DS4700,多路径mpio,mpio_get_config -Av 需要打补丁。
  9. linux下面桌面的安装
  10. 千层浪软件下载_千层浪app聚合
  11. oracle 时间转换 1970,oracle 中将unix/linux时间戳进行转换(转)
  12. solidworks2014可否保存成以前版本?--问题解决
  13. 2021-06-08实验室如何正确选择和确认检测方法?
  14. jQuery中的end()方法
  15. 我国历史上经历了哪些主要朝代,各有多少年?
  16. 01: tornado基础篇
  17. 高清地图(一) - 什么是自动驾驶未来的方向
  18. 谷粒商城高级篇之ik分词器
  19. 关于微服务的一些了解
  20. RA-CNN算法笔记

热门文章

  1. 公司的摄像头密码要统一
  2. 也谈谈古代一两银子相当于今天的价格
  3. 导航可与红绿灯结合起来
  4. win2012 定时自动备份mysql_SQL SERVER 2012数据库自动备份的方法
  5. c语言printf * abd bc,C语言练习题_答案版本
  6. java demo类_《java语言程序设计》初步学习——各种小Demo
  7. WIN32_FIND_DATA详解
  8. NetBeans 成为 Apache 软件基金会顶级项目
  9. P3161 [CQOI2012]模拟工厂
  10. Flume系列一之架构介绍和安装