精华内容
下载资源
问答
  • 本文介绍OpenGL中的统一缓冲区对象(UBO)

    定义:

    统一缓冲区对象(Uniform Buffer Object)

    优点:

    1. 更新一组大量统一值 更简单
    2. 不同程序间的共享一组统一值

    以前的使用统一值,实际是默认的块中。

    Example:

    着色器代码如下:

    uniform TransformBlock
    {
        float scale;         
        vec3  translation;   
        float rotation[3];   
        mat4  projection_matrix; // 投影矩阵
    } Transform;

    Uniform 名为TransformBlock, 实例为Transform

    建立统一块种类:

    一般使用 glBufferData / glMapBuffer 缓冲区对象进行数据填充。数据存储在缓冲区中有一般有方式二种:

    1.共享布局(Shared layout)
    - 缓冲区的数据由OpenGL根据运行性能以及着色器访问最佳的方式决定将数据放在缓冲区的位置。
    - 当OpenGL在缓冲区中对数据进行排列时,这种排列在共用相同的统一块声明的多个程序和着色器之间相同的。也就是默认布局.
    这种方式对程序开发人员来说,需要处理位置偏移量等,比较繁琐,此处略过。

    2.标准布局(Standard Layout)
    - 缓冲区的数据由OpenGL提供的一组为各种数据指定大小和排列的规则决定将数据放在缓冲区的位置
    - 需使用布局限定符 std140
    缓冲区的位置定义:在缓冲区占用N个字节的类型都会在这个缓冲区中的一个N个字节的分界处开始。
    GLSL如下

    layout(std140) uniform TransformBlock
    {
        float scale;
        vec3  translation;
        float rotation[3];
        mat4  projection_matrix;
    } transform;

    标准布局步骤

    标准布局实际分二步步骤:
    - 统一块分配绑定点
    GLuint glGetUniformBlockIndex(GLuint program, const GLChar* uniformBlockName); 返回指定统一块的索引
    - 缓冲区绑定到绑定点上,从而匹配统一块.
    void glUniformBlockBinding(GLuint program, GLuint unifromBlockIndex, GLuint uniformBlockBinding);
    uniformBlockBinding 指统一块绑定点的索引

    • 将缓冲区绑定到相同的绑定点使缓冲区数据传递到统一块中.
      glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer);// index 绑定点索引,同UniformBlockBinding;
      // GL_UNIFORM_BUFFER 表示将一个缓冲区绑定到统一缓冲区的绑定点上。

    示例:

    不同的缓冲区对象绑定不同的统一值
    GLSL Shader 代码

    layout(std140) uniform Harry
    {
        float a;
        mat4  b;
    };
    
    layout(std140) uniform Bob
    {
        int    c;
        ivec4  d;
    };
    
    layout(std140) uniform Suan
    {
        mat4 e[10];
    };

    不同的缓冲区对象绑定不同的统一值
    C++的代码:

    // 使用glGetUniformBlockIndex 来得到统一块的索引
    GLuint harry_index = glGetUniformBlockIndex(program, "Harry");
    GLuint bob_index = glGetUniformBlockIndex(program, "Bob");
    GLuint susan_index = glGetUniformBlockIndex(program, "Susan");
    
    // 使用统一块的索引为它们分配缓冲区绑定
    glUniformBlockBinding(program, harry_index, 1);
    glUniformBlockBinding(program, bob_index, 3);
    glUniformBlockBinding(program, susan_index, 0);
    
    // 将缓冲区绑定到绑定点
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer_b);
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, buffer_c);
    glBindBufferBase(GL_UNIFORM_BUFFER, 3, buffer_a);

    优点

    可以通过标准的约定,为所有的Program 设定绑定,即使切换program时,仍可使缓冲区绑定。

    比如: 有一些相对固定的状态,如投影矩阵,视口大小等参数与Program不太相关的参数,我们可以将这个信息保留绑定到绑定点0上。然后,所有程序都在固定状态绑定设为0, b即使使用glUseProgram切换程序,这些统一值也会保留在缓冲区中备使用。

    展开全文
  • 创建统一缓冲区 译者注:示例代码点击此处 在Vulkan中着色器中使用的统一(uniform)变量不能放在全局命名空间中。它们只能在统一缓冲区中定义。我们还需要使用VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT创建缓冲区。 ...

    创建统一缓冲区

    译者注:示例代码点击此处

    在Vulkan中着色器中使用的统一(uniform)变量不能放在全局命名空间中。它们只能在统一缓冲区中定义。我们还需要使用VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT创建缓冲区。

    怎么做...

    1. 获取已创建的逻辑设备句柄并用其初始化名为logical_device的VkDevice变量。
    2. 创建一个名为uniform_buffer的VkBuffer类型变量。它将存储要创建的缓冲区。
    3. 使用logical_device变量创建缓冲区并指定所选的大小和用法。必须至少包含一个VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT标志。将缓冲区的句柄存储在uniform_buffer变量中(请参阅第4章,资源和内存中的创建缓冲区内容)。
    4. 使用VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT属性分配内存对象(或使用现有内存对象的部分范围)并将其绑定到缓冲区(请参阅第4章,资源和内存中的为缓冲区分配和绑定内存对象内容)。

    这个怎么运作...

    统一缓冲区用于为着色器内的只读uniform变量提供值。

    提示:统一缓冲区使用VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER或VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC描述符类型。

    通常,统一缓冲区包含不经常更改的参数数据即矩阵(对于少量数据,推荐使用压入式常量(push constants)因为更新它们通常要快得多,通过压入式常量向着着色器提供数据,有关压入式常量的信息可以在第9章命令中的命令记录与绘图)。

    创建一个缓冲区,其中将存储uniform变量的数据,这要求我们在缓冲区创建期间指定VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT标志。创建缓冲区时,我们需要准备一个内存对象并将其绑定到创建的缓冲区。(也可是使用现有的内存对象并将其一部分绑定到缓冲区):

    if( !CreateBuffer( logical_device, size, usage | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, uniform_buffer ) ) {
      return false;
    }
    
    if( !AllocateAndBindMemoryObjectToBuffer( physical_device, logical_device, uniform_buffer, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memory_object ) ) {
      return false;
    }
    return true;

    在缓冲区及其内存对象准备就绪后,我们可以像使用任何其他类型的缓冲区一样将数据上传到它们,只需记住uniform变量必须放在适当的偏移处。这些偏移量与GLSL语言中的std140布局相同,定义如下:

    • 大小为N的标量变量必须放在N的倍数的偏移处
    • 具有两个分量的向量,其中每个分量的大小为N,必须放在2N的倍数偏移处
    • 具有三个或四个分量的向量,其中每个分量的大小为N,必须放置在4N的偏移处
    • 具有大小为N个元素的数组放在N的倍数的偏移处,该偏移量必须被舍入到16的倍数。
    • 结构体必须被放置在与其成员的最大偏移量相同的偏移量处,该偏移量必须被舍入到16的倍数(具有最大偏移量要求的成员偏移量,舍入到16的倍数)
    • 行主序矩阵必须放置在等于向量偏移量的偏移处,其中分量数等于矩阵中的列数。
    • 列主序矩阵必须放置在与其列相同的偏移处

    动态统一(Dynamic uniform)缓冲区与普通缓冲区的不同之处在于它们指定地址的方式。在描述符集更新期间,我们指定应该用于统一缓冲区的内存大小以及从缓冲区内存开始的偏移量。对于普通的统一缓冲区这些参数保持不变。而对于统一动态缓冲区,指定的偏移量变为从基偏移量(base offset),稍后可以通过在描述符集绑定到命令缓冲区时添加的动态偏移量来修改基偏移。

    提示:在GLSL着色器中,统一缓冲区和动态统一缓冲区都使用uniform限定符和块语法定义。

    GLSL着色器中的统一缓冲区定义的示例如下:

    layout (set=m, binding=n) uniform <variable name> 
    {
      vec4 <member 1 name>; 
      mat4 <member 2 name>; 
      // ...
    };

     

    展开全文
  • 环形缓冲区

    千次阅读 2014-11-22 15:22:28
    环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。  1、环形缓冲区的实现原理  环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形...

    在通信程序中,经常使用环形缓冲区作为数据结构来存放通信中发送和接收的数据。环形缓冲区是一个先进先出的循环缓冲区,可以向通信程序提供对缓冲区的互斥访问。 

    1、环形缓冲区的实现原理 
    环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写人。在通常情况下,环形缓冲区的读用户仅仅会影响读指针,而写用户仅仅会影响写指针。如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。 
    1、图2和图3是一个环形缓冲区的运行示意图。图1是环形缓冲区的初始状态,可以看到读指针和写指针都指向第一个缓冲区处;图2是向环形缓冲区中添加了一个数据后的情况,可以看到写指针已经移动到数据块2的位置,而读指针没有移动;图3是环形缓冲区进行了读取和添加后的状态,可以看到环形缓冲区中已经添加了两个数据,已经读取了一个数据。 

    服务器公共组件实现----环形缓冲区 


      消息队列锁调用太频繁的问题算是解决了,另一个让人有些苦恼的大概是这太多的内存分配和释放操作了。频繁的内存分配不但增加了系统开销,更使得内存碎片不断增多,非常不利于我们的服务器长期稳定运行。也许我们可以使用内存池,比如SGI STL中附带的小内存分配器。但是对于这种按照严格的先进先出顺序处理的,块大小并不算小的,而且块大小也并不统一的内存分配情况来说,更多使用的是一种叫做环形缓冲区的方案,mangos的网络代码中也有这么一个东西,其原理也是比较简单的。 
      就好比两个人围着一张圆形的桌子在追逐,跑的人被网络IO线程所控制,当写入数据时,这个人就往前跑;追的人就是逻辑线程,会一直往前追直到追上跑的人。如果追上了怎么办?那就是没有数据可读了,先等会儿呗,等跑的人向前跑几步了再追,总不能让游戏没得玩了吧。那要是追的人跑的太慢,跑的人转了一圈过来反追上追的人了呢?那您也先歇会儿吧。要是一直这么反着追,估计您就只能换一个跑的更快的追逐者了,要不这游戏还真没法玩下去。 
      前面我们特别强调了,按照严格的先进先出顺序进行处理,这是环形缓冲区的使用必须遵守的一项要求。也就是,大家都得遵守规定,追的人不能从桌子上跨过去,跑的人当然也不允许反过来跑。至于为什么,不需要多做解释了吧。 
      环形缓冲区是一项很好的技术,不用频繁的分配内存,而且在大多数情况下,内存的反复使用也使得我们能用更少的内存块做更多的事。 
      在网络IO线程中,我们会为每一个连接都准备一个环形缓冲区,用于临时存放接收到的数据,以应付半包及粘包的情况。在解包及解密完成后,我们会将这个数据包复制到逻辑线程消息队列中,如果我们只使用一个队列,那这里也将会是个环形缓冲区,IO线程往里写,逻辑线程在后面读,互相追逐。可要是我们使用了前面介绍的优化方案后,可能这里便不再需要环形缓冲区了,至少我们并不再需要他们是环形的了。因为我们对同一个队列不再会出现同时读和写的情况,每个队列在写满后交给逻辑线程去读,逻辑线程读完后清空队列再交给IO线程去写,一段固定大小的缓冲区即可。没关系,这么好的技术,在别的地方一定也会用到的
       
    展开全文
  • “输出缓冲”的引入,使得这一过程更加快速、更加高效。缓冲区实际上是在内存中开辟了一块区域...当缓冲区被“刷新”的时候,再统一输入到用户浏览器。以下几种情况下,会引起缓冲区的“刷新”操作: 1、PHP 程序执行
  • 缓冲区对象是一个强大的概念,它允许应用程序迅速方便地将数据从一个渲染管线移动到另一个渲染管线,以及从一个对象绑定到另一个对象。 缓冲区缓冲区有很多不同的用途,它们能够保存顶点数据、像素数据、纹理数据...

    缓冲区对象是一个强大的概念,它允许应用程序迅速方便地将数据从一个渲染管线移动到另一个渲染管线,以及从一个对象绑定到另一个对象。

    缓冲区:缓冲区有很多不同的用途,它们能够保存顶点数据、像素数据、纹理数据、着色器处理的输入,或者不同阶段着色器阶段的输出。

    缓冲区保存在GPU内存中,它们提供高速和高效的访问。在OpenGL有缓冲区对象之前,应用程序只有有限的选择可以在GPU中存储数据。另外,在GPU中更新数据常常需要重新加载整个对象。在系统内存和GPU内存之前来回移动数据可能是一个缓慢的过程。

    创建缓冲区

    我们可以使用glGenBuffers来为我们所需的任何数量的新缓冲区创建名称。实际缓冲区对象将在第一次使用时创建。

    Gluint pixBufferObj[1];
    glGenBuffers(1,pixBufferObjs);

    当我们有了新的缓冲区名称,就可以对这些名称进行绑定来使用缓冲区。在OpenGL中有许多不同的绑定点,每个绑定点都允许我们为了不同的目的而使用某个缓冲区。我们可以将每个结合点或绑定点看作一个在同一时刻只能结合一个对象的槽。

    缓冲区对象绑定点
    名称描述
    GL_ARRAY_BUFFER数组缓冲区存储颜色、位置、纹理等顶点属性,或者其他自定义属性
    GL_COPY_READ_BUFFER缓冲区用作通过glCopyBufferSubData进行复制的数据源
    GL_COPY_WRITE_BUFFER缓冲区用作通过glCopyBufferSubData进行复制的目标
    GL_ELEMENT_ARRAY_BUFFER索引缓冲区用于保存glDrawElements、glDrawRangeElements和glDrawElementsInstanced的索引
    GL_PIXEL_PACK_BUFFERglReadPixels之类像素包装操作的目标缓冲区
    GL_PIXEL_UNPACK_BUFFERglTexImage1D、glTexImage2D、glTexImage3D、glTexSubImage1D、glTexSubImage2D和glTexSubImage3D之类纹理更新函数的缓冲区
    GL_TEXTURE_BUFFER着色器可以通过纹理单元拾取来访问的缓冲区
    GL_TRANSFORM_FEEDBACK_BUFFER变换反馈顶点着色器(transform feedback vertex shader)写入的缓冲区
    GL_UNIFORM_BUFFER着色器能够访问的UNiform值

    要绑定一个缓冲区以备用,我们可以以这个缓冲区名称为参数,以上表列出的缓冲区为目标来调用glBindBuffer。我们将新的缓冲区绑定到像素包装缓冲区绑定点之后,就可以使用glReadPixels将像素数据复制到缓冲区中了。

    glBindBuffer(GL_PIXEL_PACK_BUFFER,pixBuffer[0]);

    要从一个绑定中对一个缓冲解除绑定,可以再次调用以0为缓冲区名称、目标与上述调用相同的glBuffer。我们还可以只是将另外一个合法的缓冲区绑定到同一个目标上。

    当我们使用完一个缓冲区之后,这个缓冲区需要进行清除,在进行删除之前,我们要确保缓冲区没有被绑定到任何绑定点。

    glDeleteBuffer(1,pixBufferObjs);

    填充缓冲区

    使用glBufferData函数来简单地将数据直接上传到任何类型的缓冲区中。

    glBindBuffer(GL_PIXEL_PACK_BUFFER,pixBufferObjs[0]);
    glBufferData(GL_PIXEL_PACK_BUFFER,0);

    在调用glBufferData之前,我们必须将要使用的缓冲区进行绑定。对glBufferData使用的目标与我们为第一个参数绑定缓冲区时使用的目标相同。第二个参数是我们将要上传的数据大小,以字节(byte)为单位,而第三个参数则是将要被上传的数据本身。

    如果我们想要分配一个特定大小的缓冲区却不需要立即对它进行填充,那么这个指针也可能是NULL。glBufferData的第4个参数用来告诉OpenGL我们打算如何使用缓冲区。

    缓冲区对象使用方式
    缓冲区使用方式描述
    GL_STREAM_DRAW缓冲区的内容将由应用程序进行一次设置,并且经常用于绘制
    GL_STREAM_READ缓冲区的内容将作为一条OpenGL命令的输出来进行一次设置,并且经常用于绘制
    GL_STREAM_COPY缓冲区的内容将作为一条OpenGL命令的输出来进行一次设置,并且不经常用于绘制或复制到其他图像
    GL_STATIC_DRAW缓冲区的内容将有应用程序进行一次设置,并且经常用于绘制或复制到其他图像
    GL_STATIC_READ缓冲区的内容将作为一条OpenGL命令的输出来进行一次设置,并且由应用程序进行多次查询
    GL_STATIC_COPY缓冲区的内容将作为一条OpenGL命令的输出来进行一次设置,并且经常用于绘制或复制到其他图像
    GL_DYNAMIC_DRAW缓冲区的内容将会经常由应用程序进行更新,并且经常用于绘制或复制到其他图像
    GL_DYNAMIC_READ缓冲区的内容将作为OpenGL命令经常进行更新,并且由应用程序进行多次查询
    GL_DYNAMIC_COPY缓冲区的内容将作为OpenGL命令的输出来进行更新,并且经常用于绘制或复制到其他图像

    在我们不确定缓冲区的用途时,对于通常的缓冲区使用方式或条件来说,使用GL_DYNAMIC_DRAW是一个比较安全的值。我们总是可以再次调用glBufferData对缓冲区重新进行填充,还可以改变使用方式的提示。但是如果我们真的调用了lgBufferData,那么缓冲区中原来的所有数据都将被删除。

    可以使用glBufferSubData对已经存在的缓冲区中的一部分进行更新,而不会导致缓冲区其他部分的内容变为无效。

    void glBufferSubData(GLenum target,intptr offset,sizeiptr,const void *data);

    glBufferSubData的大多爱护参数和glBufferData的相应参数相同。新的offset参数允许我们从除开头部分以外的其他位置开始更新。我们也不能改变缓冲区的使用方式,因为内存已经被分配了。

    像素缓冲区对象(PBO)

    在存储像素/纹理单元方面,像素缓冲区对象与纹理缓冲区对象非常相似,并且它们也都存储在GPU内存中。可以使用与其他缓冲区对象类型一样的方法访问和填充像素缓冲区对象。实际上,只有在绑定到一个PBO缓冲区绑定点时,一个缓冲区才真正成为一个像素缓冲区。

    第一个像素缓冲区对象绑定点时GL_PIXEL_PACK_BUFFER。当一个像素缓冲区对象被绑定到这个目标上是,任何读取像素的OpenGL操作都会从像素缓冲区对象中获得它们的数据,这些擦偶哦在包括glReadPixels、glGetTexImage和glGetCompressedTexImage。通常这些擦欧总会从一个帧缓冲区或纹理中抽取数据,并将它们都会客户端内存中。当一个像素缓冲区对象被绑定到包装缓冲区时,像素数据在GPU内存中的像素缓冲区对象中的任务就结束了,而不会下载到客户端。

    第二个PBO绑定点时GL_PIXEL_UNPACK_BUFFER。当一个像素缓冲区对象被绑定到这个目标时。任何绘制像素的OpenGL操作都会向一个绑定的像素缓冲区对象中放入它们的数据。

    对初学者来说,任何从PBO中读取或写入PBO中的调用或任何缓冲区对象都用管线进行处理。这就意味着GPU不需要完成所有其他工作,之哟啊对数据复制进行初始化,等待复制完成,然后继续运行就可以了。

    像素缓冲区对象是一个很好的容器,可以暂时存储GPU本地像素数据,但是需要注意,在使用它们之前需要为它们分配存储空间。和其他所有缓冲区对象一样,要调用glBufferData为这个缓冲区分配内存空间并用数据填充。但是没必要提供数据,为数据指针传递NULL可以简单地分配内存而不进行填充,如果我们试图填充存储空间之前不对它进行分配,那么OpenGL将抛出一个错误。

    像素缓冲区经常用来存储来自一个渲染目标的2D图像、纹理或其他数据源。但是缓冲区对象本身是一维的,它们本质上没有宽度或者高度。在为2D图像分配存储空间时,我们可以只是将宽度与高度相乘,再与像素大小相乘。对于存储像素数据没有其他需要补充的;,但是缓冲区可以比戈丁的数据组所需的大小更大。

    当我们打算为多种数据大小使相同的PBO,最好马上关闭对数据大小上限的设定,而不是频繁地对它进行重新设定。

    纹理缓冲区对象

    一个纹理包含两个主要组成成分:纹理采样状态和包含纹理值的数据缓冲区。纹理缓冲区也称为texBO或TBO,允许我们完成一些传统纹理不能完成的工作。首先,纹理缓冲区能够直接填充来自其他渲染结果(例如变换反馈、像素读取操作或顶点数据)的数据。这样就节省了不少时间,因为应用程序能够直接从着色器以前的渲染调用中获取像素数据。texBO的另一个特性是宽松的大小限制。纹理缓冲区与传统的一维纹理相似,但要更大。TexBO向着色器提供了大量对多种不同风格和类型的数据访问,允许着色器以通常是预留给CPU的方式进行操作。纹理缓冲区能够用来提供对片段着色器和顶点着色器中的顶点数组的访问。这在着色需要关于临近几何图形的信息以作出运行时决策和计算的情况下可能会非常有用。但是为了做到这一点,我们通常需要将texBO大小作为一个统一值传递到着色器中。

    纹理缓冲区是作为普通的缓冲区来创建的,当它被绑定到一个纹理或者GL_TEXTURE_BUFFER绑定点时才会成为真正的纹理缓冲区。

    glBindBuffer(gl_texture_buffer,texBo[0]);
    glBufferData(GL_TEXTURE_BUFFER,xizeof(float)*count,fileData,GL_STATIC_DRAW);

    但是texBO必须绑定到一个纹理单元上才能真正变得有用。要将一个texBO绑定到一个纹理上,可以调用glBuffer,但首先要确保要使用的纹理已经进行了绑定。

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_BUFFER,texBOTexture);
    glTexBuffer(GL_TEXTURE_BUFFER,GL_R32F,texBO[0]);

    纹理缓冲区对象操作与普通纹理看似很像,但还有一些重要的不同点。纹理缓冲区不能在着色器中用普通的采样器-也就是sampler1D和sampler2D进行访问。取而代之的是,我们必须用一个新的采样器-samplerBuffer。由于采样器类型不同,用来从纹理缓冲区中获取值的采样函数也不同。

    帧缓冲对象

    一个OpenGL窗口的表面长期以来一直被称作“帧缓冲区”。但是现在OPenGL将绘制缓存区到一个对象所需要的状态进行了封装,称为帧缓存区对象(FBO)。默认的帧缓冲区对象是与创建的OpenGL窗口相关联的,并且在一个新的环境被绑定时自动进行绑定。可以创建多个帧缓冲区对象,也叫做FBO,并且直接渲染一个FBO而不是窗口。使用这种离屏渲染,应用程序就可以执行许多不同种类的渲染算法了,例如阴影贴图、应用辐射着色,反射、后期处理和许多其他特效。另外,帧缓冲区对象并不受窗口大小的限制,它可以包含多个颜色缓冲区。甚至可以将纹理绑定到一个FBO上,这就意味着可以直接渲染到一个纹理中。

    帧缓冲区根本不是缓冲区,并不存在与一个帧缓冲区对象相关联的真正内存存储空间。相反,帧缓冲区对象是一种容器,它可以保存其他确实有内存存储并且可以进行渲染的对象,例如纹理或渲染缓冲区。采用这种方式,帧缓冲区对象能够在保存OpenGL管线的输出时将需要的状态和表面绑定到一起。

    使用FBO

    先添加图像,才能渲染到一个FBO。一旦一个FBO被创建、设置和绑定,大多数OpenGL操作就将像是在渲染到一个窗口一样执行,但是输出结果将存储在绑定到FBO的图像中。

    要先生成FBO缓冲区名称(可以同时生成任意数量的名称),才创建FBO。再绑定一个新的FBO来修改和使用它

    GLuint fboName;
    glGenFramebuffers(1,&fboName);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,fboName);

    同一时间只有一个FBO可以绑定用来进行绘制,并且同一时间只有一个FBO可以绑定来进行读取。在绑定一个帧缓冲区时,glBindFramebuffer的第一个参数既可以是GL_DRAW_FRAMEBUFFER,也可以是GL_READ_FRAMEBUFFER。这就意味着我们可以使用一个帧缓冲区进行读取,而使用另一个不同帧缓冲区进行绘制。

    使用完FBO或者在退出前进行清除时,要删除FBO

    glDeleteFramebuffer(1,&fboName);

     

    展开全文
  • 缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区缓冲区根据其对应的是输入设备还是输出设备,分为...
  • nginx缓冲区链表chain

    千次阅读 2016-11-02 22:52:22
    nginx接收nginx服务器的http请求包头、包体,以及响应...一、chain链表缓冲区数据结构 //ngx_chain_t链表节点 struct ngx_chain_s { ngx_buf_t *buf; ngx_chain_t *next; };//缓冲区结构 struct ngx_buf_s {
  • JDK1.8源码分析:NIO缓冲区Buffer

    千次阅读 2018-12-30 23:25:37
    Buffer接口是Java NIO的缓冲区的基础接口,定义了缓冲区操作的相关控制属性和操作方法。缓冲区是一个存放特定基础类型数据,如byte, char, int, long, float, double(不能是boolean),的容器,物理上是一个有界的...
  • 文件系统的缓冲区

    2020-08-24 17:46:44
    什么是文件系统的缓冲区呢? 我们说缓冲区,它是内存空间的一个部分也就是说在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。在整个文件系统中有四种类型...
  • ByteBuf缓冲区

    千次阅读 2017-06-15 18:07:10
    转载自:...  Netty的ByteBuf缓冲区实现地比Java本身的ByteBuffer更加灵活,方便。可以参考:http://blog.csdn.net/zero__007/article/details/51326657  为什么要ByteBuf这个组件。主要
  • 在文件系统中,有三大缓冲为了提升效率:inode缓冲区、dentry缓冲区、块缓冲。 (内核:2.4.37)
  • 2.7 缓冲区对象

    2015-03-11 21:00:58
    缓冲区对象简介什么是缓冲区对象?缓冲区,通常是指一个内存块。而缓冲区对象呢?则是指位于图形服务器中的内存块。这样的内存块,通常都会用一个无符号的整型数值,对它进行标识。这个无符号整型标识,叫做缓冲区...
  • Qt 笔记:缓冲区操作与目录操作

    千次阅读 2018-09-17 15:10:46
    Qt中缓冲区的概念 -缓冲区的本质为一段连续的存储空间 -QBuffer是Qt中缓冲区相关的类 -在Qt中可以将缓冲区看做一种特殊的IO设备 -文件流辅助类可以直接用于操作缓冲区 QByteArray array; QBuffer buffer(&...
  • 一个缓冲区由两部分组成:一个含有磁盘上的数据的存储器数组及一个用来标示该缓冲区的缓冲头部。 缓冲区是磁盘块在主存中的拷贝,是临时的唯一映射关系。 缓冲头部包含了一个设备号字段和一个块号字段。缓冲头部还...
  • OpenGL缓冲区总结

    千次阅读 2016-11-04 15:05:40
    缓冲区  几乎每个图形程序的重要目标之一都是在屏幕上绘制图形。屏幕是由一个矩形像素数组组成的,每个像素都可以在图像的某一个点上显示一个某种颜色的微小方块。在光栅化阶段(包括纹理和雾)之后,数据就不再...
  • Q: 缓冲区究竟是什么概念? A: 缓冲: 顾名思义, 表示可以酌情商量有回旋余地. 可以想象一种只能强制遵守且说一不二的情形,一种可以协商开发此消彼长的模式. 区: 理解成可以协助存储/处理的物理位置,一般理解成...
  • 借助统一建模语言,概括近十年来利用缓冲区溢出进行攻击的攻击模式,从预防、发现、抵御缓冲区溢出攻击以及攻击后的程序恢复等方面对目前有代表性的防御、检测方法和攻击恢复技术进行了归纳、分析和比较,指出这些...
  • 文章目录什么是脱机技术假脱机技术—―输入/输出缓冲区共享打印机的实现原理缓冲区的管理缓冲区的工作过程单缓冲双缓冲循环缓冲区缓冲池 什么是脱机技术 在传统的批处理操作系统中, 我们将输入数据统一写到磁带中, ...
  • ID3D11DeviceContext::Map[1]函数--获取指向缓冲区中数据的指针并拒绝GPU对该缓冲区的访问 ID3D11DeviceContext::Unmap函数--让指向资源的指针无效并重新启用GPU对该资源的访问权限 DEFAULT更新 ID3D11DeviceContext...
  • Vulkan【8】创建Uniform缓冲区

    千次阅读 2018-09-01 13:57:19
    创建Uniform缓冲区 本节的代码是 07-init_uniform_buffer.cpp Uniform缓冲区是一个访问只读着色器的缓冲区,以便着色器可以读取常量参数数据。 这是另一个你必须在Vulkan程序中执行的步骤。在GLES中,你只需要做...
  • 【第二弹】OpenGL深入学习之缓冲区

    万次阅读 2013-11-24 18:08:17
    1. 《OpenGL超级宝典第5版》 2. 首先缓冲区在OpenGL的用处...帧缓冲区对象使我们可以离屏对想要的任意数据的缓冲区进行渲染。   缓冲区有很多不同的用途,它们能够保存顶点数据、像素数据、纹理数据、着色器处
  • 环形缓冲区的实现

    千次阅读 2015-01-05 09:47:27
    环形缓冲区的实现 消息队列锁调用太频繁的问题算是解决了,另一个让人有些苦恼的大概是这太多的内存分配和释放操作了。频繁的内存分配不但增加了系统开销,更使得内存碎片不断增多,非常不利于我们的服务器长期...
  • socket套接字及缓冲区详解

    千次阅读 多人点赞 2018-10-15 17:16:34
    文章目录 一、域(domain) 二、类型(type) 三、协议(protocol) 四、socket缓冲区以及阻塞模式 1、缓冲区简介 2、使用write()/send()发送数据 3、使用read()/recv()读取数据 4、系统调用read()的返回错误场景 五...
  • 提出了一种求解三维矢量缓冲区的算法,该算法以布尔运算为基础。算法通过对布尔运算进行深入研究的基础上,描述了布尔运算算法,分析了算法复杂度,提出了一种提高布尔运算稳定性的新方法。该稳定性方法采用了拓扑...
  • 环形缓冲区的实现原理

    千次阅读 2009-10-25 16:01:00
    1、环形缓冲区的实现原理 环形缓冲区通常有一个读指针和一个写指针。读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区。通过移动读指针和写指针就可以实现缓冲区的数据读取和写人。在通常...
  • 缓冲区(Buffer)定义 缓冲区(Buffer),它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的。 有...
  • Qt学习之路23--缓冲区QBuffer和目录QDir

    千次阅读 2018-09-03 23:39:07
    缓冲区 缓冲区的概念就是一段连续的存储空间 Qt中使用QBuffer类进行缓冲区相关操作 在Qt中可以将缓冲区看做是一种特殊的IO设备 文件流辅助类是针对IO设备的,可以像操作文件直接作用于缓冲区 只要有数据的读写和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,660
精华内容 33,464
关键字:

统一缓冲区