首页 > 系统相关 >漫谈C++内存和OpenGL各种缓冲对象(上)

漫谈C++内存和OpenGL各种缓冲对象(上)

时间:2022-12-31 21:01:30浏览次数:36  
标签:target OpenGL buffer 缓冲 漫谈 C++ 对象 GPU GL

1、C++内存管理
(1)常用数据类型占用内存大小:char 1字节;int 4字节;short 2字节;long 4字节;bool 1字节;float 4字节;double 8字节;
(2)堆栈的比较
  [1] 堆用于动态分配内存,容量大于栈。堆上内存可以随时申请、随时分配、随时释放。要分配的大小运行时才知道,只支持动态分配内存,容易造成内存泄漏。变量可以在进程内供多个线程访问,由开发者管理内存。
  [2] 栈用于函数和局部变量、返回值,编译器自动管理释放和分配。栈上内存是连续分布的,编译器在编译时就知道要分配的内存大小。调用函数栈上分配内存,调用结束回收给栈,先入后出。栈上分配内存要快于堆。每个线程都有一个栈,栈上对象不能跨线程访问,因此栈空间较小。栈不会产生内存碎片。
  [3] 全局变量和静态变量储存于数据区。
  [4] new申请动态堆内存,delete 标记该内存不可用
(3)结构体内存对齐
  [1] 有效对齐值为最宽成员大小和用户指定对齐值中较小的那个。
  [2] 结构体第一个成员偏移量为0,之后的为成员大小和有效对齐值的较小的那个的整数倍。
(4)结构体
2、OpenGL的Buffer创建、释放、使用
  (1)glGenBuffers(Glsizei n,Gluint* buffers);
命令GPU创建buffer对象标记,输入参数n为创建buffer的个数,默认大于0,buffers为buffer对象标记地址,类型为Gluint整型。glGenBuffers并没有真正分配一块GPU缓冲区,而只是创建了n个GPU未使用的buffer对象标记。
  (2)glBindBuffers(GLenum target,GLuint buffer);
命令GPU绑定缓冲区对象,输入参数target为buffer类型分别对应顶点缓冲VAO类型和顶点序号缓冲EBO类型(GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER),buffer为上一步创建的有效buffer对象标记。如果此buffer对象未绑定任何缓冲区则GPU会申请一块缓存并关联上当前对象标记。注意同一时间、线程、上下文只能有一个VBO和一个EBO对象被使用。
  (3)glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage)
写入数据到GPU缓冲区,输入参数target为缓冲类型;size为机器大小字节;data为写入数据内存地址,当data为null的时候,仍然会分配一块size大小的GPU缓存到这个buffer对象;usage为缓存使用方式,分别为:赋值一次多次被读取调用、多次赋值多次调用、赋值一次调用几次(GL_STATIC_DRAW,GL_DYNAMIC_DRAW,GL_STREAM_DRAW)。如果此buffer对象已有数据,再次调用函数则会覆盖掉原本的数据。
      glBufferSubData(GLenum target,GLintptr offset, GLsizeiptr size, const GLvoid * data)
写入数据到GPU一部分缓冲区,输入参数offset为到buffer对象所在显存起始地址的偏移量,size为所需显存字节大小。用于修改已经分配的缓冲区数据,不会重新分配显存。
  (4)glDeleteBuffers(GLsizei n,const GLuint* buffers)
删除GPU中buffer对象标记,输入参数n为删除的对象个数,buffers为buffer对象标记地址。删除时若对象正被绑定,GPU会先调用glBindBuffers解绑后删除对象标记及其对应的显存。

3、OpenGL的FrameBuffer创建、释放、使用
  (1)void glGenFramebuffers(GLsizei n, GLuint * framebuffers);
创建FBO,其中输入参数n为生成的fbo名称个数,framebuffers为缓冲对象名称。
  (2)void glBindFramebuffer(GLenum target, GLuint framebuffer);
绑定FBO,其中输入参数target为缓冲类型GL_FRAMEBUFFER,framebuffer为缓冲对象名称。一个FBO有一个color attachment挂载点,一个depth attachment挂载点,一个stencil attachment挂载点。GPU可以存放大量的fbo,但同一时间一个线程上下文只能有一个framebuffer能被使用着。FBO的挂载点可以修改。
  (3)void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
挂载纹理到FBO上。输入参数target为GL_FRAMEBUFFER,attachment为GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT 或者GL_STENCIL_ATTACHMENT,textarget为0或者GL_TEXTURE_2D ,texture为纹理缓冲名称,level为0。
4、OpenGL的Uniform Buffer创建、释放、使用
    Uniform buffer用于整块写入shader中uniform变量,uniform数据被认为是vertex shader和fragment shader的全局变量。使用uniform buffer的优点:可以一次写入大量数据到GPU;多个shader可以共享一块buffer;shader中uniform数量受到限制,使用的uniform buffer的uniform数量更大
  (1)创建Uniform buffer:glGenBuffers(1,&object);
  (2) 使用Uniform buffer:
    绑定缓冲对象 glBindBuffer(GL_UNIFORM_BUFFER,object);
    分配足够内存 glBufferData(GL_UNIFORM_BUFFER,152,NULL,GL_STATIC_DRAW)
    解绑缓冲对象 glBindBuffer(GL_UNIFORM_BUFFER,0);
    获取shader中uniform变量绑定点,然后将变量链接到绑定点unsigned int light_index=glGetUniformBlockIndex(shaderA.ID,"Liaghts");
    glUniformBlockBinding(shaderA.ID,light_index,2);
    绑定Uniform 缓冲到相同的绑定点。
    glBindBufferBase(GL_UNIFORM_BUFFER,2,object)其中输入参数2为绑定点索引,object为缓冲对象。
    glBindBufferRange(GLenum target,GLuint index,GLuint buffer,GLintptr offset,Glisizeptr size)其中输入参数 target为uniform类型GL_UNIFORM_BUFFER,index 为绑定点索引,buffer为缓冲对象名称,offset为到缓冲区起始位置偏移量,size为读取的缓冲区大小。
    更新Uniform buffer数据:
    glBindBuffer(GL_UNIFORM_BUFFER, this->ubo);
    glBufferSubData(GL_UNIFORM_BUFFER,sizeof(glm::mat4),sizeof(glm::mat4),glm::value_ptr(view));
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

标签:target,OpenGL,buffer,缓冲,漫谈,C++,对象,GPU,GL
From: https://www.cnblogs.com/wangxydela/p/17017257.html

相关文章

  • Unified tutorial for dynamic and static compilation of Qt projects for C++
    EnvironmentinstallationRequirementsdownloadRequirementsLinksQt5.7dynamiccompilerqt-opensource-windows-x86-msvc2015-5.7.1CompiledQt5.......
  • C++通讯录管理程序[2022-12-31]
    C++通讯录管理程序[2022-12-31]问题描述:编写一个简单的通讯录管理程序。通讯录记录有姓名,地址(省、市(县)、街道),电话号码,邮政编码等四项。基本要求:程序应提供的基......
  • C++日志类
    我们在写一些小项目时,封装一个log类,无论是在debug,还是运行信息输出,都可以带来不小的便利。1.信息分类我们的输出信息可能时debug信息,错误信息,或者是运行状态信息,所以,我......
  • C++中IO封装
    之前在写一个分布式计算小项目时,频繁地使用文件IO,为简化代码,减少重复操作,降低出错可能性,便将I/O模块进行封装。当时我的需求是对大文本文件进行读写,而且该文本文件是规整......
  • 【win编程】- 在C/C++中调用obj文件
    问题思考:有没有一种方式,让别人用你源码实现的功能,只给你声明,不给你源码?程序编译过程:预编译-编译-链接,编译生成obj文件,最后链接生成可执行文件。那么就可以把源码......
  • C++图书收藏模拟系统[2022-12-31]
    C++图书收藏模拟系统[2022-12-31]课题名称:图书收藏模拟系统的设计与实现课题简介目前有一些著名的网上图书购买系统,比如当当网、亚马逊等,他们都有收藏和购买图书的功......
  • C/C++杂志订阅管理系统[2022-12-31]
    C/C++杂志订阅管理系统[2022-12-31]题目26“杂志订阅管理系统设计”1、问题描述使用计算机对杂志进行管理,该杂志最多拥有订阅用户不超过50人,每个订户的信息包括:编......
  • C++银行账户管理仿真软件[2022-12-31]
    C++银行账户管理仿真软件[2022-12-31]3.4银行账户管理仿真软件设计一个银行账户管理软件,可以实现:用户登录,账户管理,存取款等功能,要求通过读写文件来读取数据和保存数......
  • C/C++学生管理系统(单链表)[2022-12-31]
    C/C++学生管理系统(单链表)[2022-12-31]利用数据结构的单链表的框架实现学生管理系统以下功能要求:1)学生个人信息:姓名、学号、专业、性别、年龄、联系方式、成绩。2)学......
  • C/C++学生成绩管理系统[2022-12-31]
    C/C++学生成绩管理系统[2022-12-31]课题三:学生成绩管理系统设计学生成绩信息包括:学期,学号,班级,姓名,四门课程成绩(语文、数学、英语和计算机)等。主要功能:(1)系统以菜......