精华内容
下载资源
问答
  • 实现线段和其他对象显示函数的最后一步工作是设定帧缓存的颜色值.由于扫描转换算法以连接的单位间隔生成像素位置,因此扫描转化算法可 使用增量方法在每一步高效存取帧缓存。 作为一个特殊的例子,假设...
    实现线段和其他对象显示函数的最后一步工作是设定帧缓存的颜色值.由于扫描转换算法以连接的单位间隔生成像素位置,因此扫描转化算法可
    


    使用增量方法在每一步高效存取帧缓存。


    作为一个特殊的例子,假设帧缓存矩阵是以行为主要顺序进行编址,并且像素位置从屏幕左下方(0,0)变化右上方(Xmax,Ymax) 对于二级系统(


    每一个像素1位),像素位置(x,y)的帧缓存位地址可以这样计算:
    addr(x,y) = addr(0,0) + y(Xmax + 1) + x
    沿扫描线移动,像素(x+1,y)处的帧缓存地址可以根据位置(x,y)的地址偏移进行计算:
    addr(x+1,y) = addr(x,y) + 1
    从(x,y)按对角线方向转移到下一条扫描线,那么(x+1,y+1)的帧缓存地址的算式为:
    addr(x+1,y+1) = addr(x,y) + Xmax + 1 + 1
    展开全文
  • 实现线段和其他对象显示函数的最后一步工作是设定帧缓存的颜色值。由于扫描转换算法以连续的单位间隔生成像素位置,因此扫描转换算法可使用增量方法在每一步高效地存取帧缓存。作为一个特殊的例子,假设帧缓存矩阵是...
    帧缓存值的装载
    

     

           实现线段和其他对象显示函数的最后一步工作是设定帧缓存的颜色值。由于扫描转换算法以连续的单位间隔生成像素位置,因此扫描转换算法可使用增量方法在每一步高效地存取帧缓存。

           作为一个特殊的例子,假设帧缓存矩阵是以行为主要顺序进行编址,并且像素位置从屏幕左上 方((0,0)变化到屏幕右上方气(xmax, y max ) (参见图3.14)。对于二级系统(每个像素1位),像素位置(x, y) 的帧缓存位地址可以这样计算:

    沿扫描线移动,像素(x+l, y)处的帧缓存地址可以根据位置(x, y)的地址偏移进行计算:

    从(x, y)按对角线方向转移到下一条扫描线,那么(x+l, y+l)的帧缓存地址的算式为

    其中,常数xmxa+2对于所有线段只需计算一次。同样,从等式(3.23)中可以得到屏幕x和y负方 向单位步长的增量计算。这种地址计算仅包含一个整数加法。


        实现存储像素亮度值的setPixel程序的方法,取决于特定系统的能力以及软件包的设计需求。对于 能为每个像素显示一定范围亮度值的系统,帧缓存地址的计算包括像素宽度(位数)以及像素屏幕位置。
    展开全文
  • 帧缓存介绍

    千次阅读 2009-12-15 21:04:00
    帧缓存介绍 在opengl里经常看到帧缓存这个名词,可以是opengl的核心的吧。平时写程序由于只与它的子集颜色缓存,深度缓存,模板缓存,累积缓存打交道,很少想它们的父类的帧缓存的定义。今天在看gpu的流水线时,讲到...
     
    

    在opengl里经常看到帧缓存这个名词,可以是opengl的核心的吧。平时写程序由于只与它的子集颜色缓存,深度缓存,模板缓存,累积缓存打交道,很少想它们的父类的帧缓存的定义。
    今天在看gpu的流水线时,讲到片元的各种操作,突然想到自己对这个一直不是特别明白。
    在渲染过程中,图形加速器一般都有一个预先分配好的内存区域来维护显示列表内容(译者:注意,不一定是主内存)。它由显示内存和脱屏内存组成。随着OpenGL的渲染而改变内容的那一部分图形内存区域叫做帧缓存(frame buffer)。在窗口系统里,OpenGL通过帧缓存与窗口通信。窗口系统为OpenGL提供了一组工具来为窗口选择帧缓存特性,而这组工具,通常是系统相关的。

    一个支持OpenGL渲染的窗口 (即帧缓存) 可能包含以下的组合:

    · 至多4个颜色缓存

    · 一个深度缓存

    · 一个模板缓存

    · 一个积累缓存

    · 一个多重采样缓存

      为了能够执行双缓存构架,大多数图形硬件同时支持前后缓存。这将允许应用程序在显示前缓存(可见的)的时候渲染到后缓存(离屏缓存)。当渲染结束的时候,这两个缓存进行交换,以便已经完成渲染的缓存像前缓存一样进行显示,这样渲染就能在后缓存重新开始了。一旦使用双缓存,在绘制过程当中用户将不能看到图像。这种技术通常被用来实现实时交互的平滑动画。

      如果为左眼和右眼各实现一个颜色缓存的话,那么就可以支持立体视觉效果了。双缓存技术由前后缓存来支持。因此一个双缓存的立体视觉将会有4各颜色缓存:前左,前右,后左,后右。一个普通的(非立体的)双缓存窗口将会仅仅有前后两个缓存。一个单缓存的窗口将会只有一个缓存。

      如果绘制3D对象时需要剔除隐藏表面的话,深度缓存是必要的。这个缓存在每个象素上存储了显示对象的深度值。当绘制附加对象的时候,会在每个象素上进行深度比较,这样就能决定新的对象是否可见。

      模板缓存用来进行复杂的掩模(masking)操作。一个复杂的形状可以存储在模板缓存里,然后绘制子序列操作可以使用模板缓存里的内容来决定是否更新象素。

      积累缓存是一个颜色缓存,不过典型地它有比颜色缓存更高的精度。这就允许一些图像通过积累产生一些合成的图像。比如说一个作用就是可以在积累缓存里对一个对象随着他的运动绘制一些帧数。在积累缓存中的象素除以帧数以后,结果图像就展现出了运动模糊效果。相似的技巧也可以用来模拟景深效果以及高质量的全屏抗锯齿。

      而通常的,当一个对象被绘制的时候,对于某个图元是否影像屏幕上的象素,会做一个单独的决议。多重采样缓存正是这样一个缓存,它允许每个渲染的对象在象素内被采样多次,以进行高质量的全屏抗锯齿,而不必对这个对象渲染多次。每个象素内的采样包括:颜色,深度,模板信息。每个象素采样的次数当然是必须的。当窗口包含多重采样缓存的时候,它将不回包括单独的深度或者是模板缓存。随着对象的渲染,颜色样本会被组合生成一个单一的颜色值,然后这个颜色值被传递,并写入到颜色缓存里。因为他们包括窗口中每个象素的多个颜色、深度以及模板样本(通常是4,8或者是16),因此多重采样缓存会消耗相当数量的离屏缓存。

    展开全文
  • 第四章 颜色、像素和帧缓存 缓存以及用途 OpenGL包含以下三种缓存: 一个或者多个颜色缓存(color buffer) 深度缓存(depth buffer) 模板缓存(stencil buffer) 缓存的清除 设置缓存清除值 void glClearColor...

    第四章 颜色、像素和帧缓存

    缓存以及用途

    OpenGL包含以下三种缓存:

    • 一个或者多个颜色缓存(color buffer)
    • 深度缓存(depth buffer)
    • 模板缓存(stencil buffer)

    缓存的清除

    设置缓存清除值

    void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
    void glClearDepth(GLclampd depth);
    void glClearDepthf(GLclampf depth);
    void glClearStencil(GLint s);
    

    GLclamp*类型会被截断到0.0~1.0之间。默认的深度清除值是1.0,其他的都是0。

    清除缓存

    void glClear(GLbitfield mask);
    

    mask可以使GL_COLOR_BUFFER_BIT, GL_DPETH_BUFFER_BIT或GL_STENCIL_BUFFER_BIT的组合。

    缓存的掩码

    void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
    void glColorMaski(GLuint buffer, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
    void glDepthMask(GLboolean flag);
    void glStencilMask(GLboolean mask);
    void glStencilMaskSeparate(GLenum face, GLuint mask);
    

    如果设置为GL_TRUE则可以写入,否则不能写入。

    颜色的表达与OpenGL

    最通常情况下,OpenGL内部会使用浮点数来标识一个颜色分量,并且这些值总是要限制在[0.1, 1.0]之间称为归一化数值。颜色被写入到帧缓存之后,会被映射到帧缓存所支持的数据范围之内,例如红绿蓝分量都有8位,那么最后颜色分量的区间范围是[0, 255]。

    多重采样

    使用glGetIntegerv()函数来检查GL_SAMPLE_BUFFERS来判断是否请求成功,如果为1则可以使用多重采样光栅化的方法。
    使用glGetIntegerv()函数来获取GL_SAMPLES,返回每个像素有多少样本用于实现多重采样

    获取采样点在像素内的位置

    void glGetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
    

    设置pname为GL_SAMPLE_POSITION获取第index个采样点在像素内的便宜位置。在片元着色器内使用gl_SamplePosition获取相同的信息。可以使用gl_SampleID来判断所处的样本。

    如果只开启多重采样,那么每个像素的颜色值会分配给所有采样点,也就是所有颜色都是相同的,但经过光栅化之后会有不同的深度与模板值。如果片元着色器中使用了gl_Sample*变量或者用sample关键字限定了输入变量,那么片元着色器会在一个像素上执行多次,每个样本位置都会有不同的信息。

    如果不通过以上方法修改片元着色器,也可以通过glEnable()启动GL_SAMPLE_SHADING强制OpenGL使用采样着色的方式。

    控制样本数量

    void glMinSampleShading(GLfloat value);
    

    设置每个像素种独立着色的样本值数量,value表示一个比例,取值范围是[0,1],1表示所有样本都会使用唯一一组采样数据。

    片元的测试与操作

    剪切测试

    void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
    

    设置剪切矩形的位置与大小。首先需要glEnable()设置GL_SCISSOR_TEST来开启测试,如果开启那么所有的渲染包括窗口的清除都会被限制在剪切盒区域内。

    多重采样的片元操作

    默认情况下,多重采样在计算覆盖率时不会考虑alpha的影响,如果要考虑alpha那么需要使用glEnable开启:

    GL_SAMPLE_ALPHA_TO_CONVERAGE 使用片元的alpha值来计算采样覆盖率
    GL_SAMPLE_ALPHA_TO_ONE 将片元alpha值设为最大的alpha值,然后使用该值来进行覆盖率的计算
    GL_SAMPLE_COVERAGE 将使用glSampleCoverage()中设置的值,预覆盖率计算的结果进行与操作。
    
    void glSampleCoverage(GLfloat value, GLboolean invert);
    设置多重采样覆盖率的参数,如果开启GL_SAMPLE_ALPHA_TO_CONVERAGE或GL_SAMPLE_COVERAGE,那么value是一个临时的采样覆盖率值。invert用来设置这个临时覆盖值是否需要进行位反转,然后进行与操作。
    
    GL_SAMPLE_MASK 设置一个掩码值来计算覆盖率。
    void glSampleMaski(GLuint index, GLbitfield mask);
    设置一个32位的mask,掩码本身的索引位置通过index来设置,而新的掩码值通过mask来设置。当采样结果准备写入帧缓存时,只有当前掩码值中对应位的数据才会被更新,其他的被丢弃。
    也可以通过片元着色器中写入gl_SampleMask来设置。
    

    模板测试

    要开启深度测试需要调用glEnable()并传入GL_STENCIL_TEST

    void glStencilFunc(GLenum func, GLint ref, GLuint mask);
    void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
    
    void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
    void glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
    

    深度测试

    要开启深度测试需要调用glEnable()并传入GL_DEPTH_TEST,每次重绘场景时都要清除深度缓存数据。

    设置深度测试比较函数

    void glDepthFunc(GLenum func);
    

    可以使用的枚举类型包括:GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER或GL_NOTEQUAL。默认使用GL_LESS。

    多边形偏移

    启用多边形偏移的方法有三种:GL_FILL、GL_LINE和GL_POINT,对应的可以使用glEnable传入GL_POLYGON_OFFSET_FILL、GL_POLYGON_OFFSET_LINE和GL_POLYGON_OFFSET_POINT。

    设置当前多边形光栅化方式

    void glPolygonOffset(GLfloat factor, GLfloat units);
    

    开启之后,每个片元的深度值都会被修改,在执行深度测试之前添加一个偏移量:

    o f f s e t = m ∗ f a c t o r + r ∗ u n i t s offset = m * factor + r * units offset=mfactor+runits

    其中m是多边形的最大深度斜率(光栅化计算过程中得到),r是两个不同深度值之间的、可识别的最小差值,是一个与平台相关的常量。两个参数都可以是负数。

    深度斜率表示如图:

    在这里插入图片描述

    计算公式:

    m = ( ∂ z ∂ x ) 2 + ( ∂ z ∂ y ) 2 或 者 m = m a x ( ∂ z ∂ x , ∂ z ∂ y ) m = \sqrt{(\frac{\partial z}{\partial x})^2+(\frac{\partial z}{\partial y})^2} \\ \\ 或者 m = max(\frac{\partial z}{\partial x}, \frac{\partial z}{\partial y}) m=(xz)2+(yz)2 m=max(xz,yz)

    混溶

    要开启混溶需要调用glEnable()并传入GL_BLEND

    混溶参数

    ( S r , S g , S b , S a ) (S_r, S_g, S_b, S_a) (Sr,Sg,Sb,Sa)表示源混合参数, ( D r , D g , D b , D a ) (D_r, D_g, D_b, D_a) (Dr,Dg,Db,Da)表示目标混合参数, ( R s , G s , B s , A s ) (R_s, G_s, B_s, A_s) (Rs,Gs,Bs,As) ( R d , G d , B d , A d ) (R_d, G_d, B_d, A_d) (Rd,Gd,Bd,Ad)表示源和目标像素的颜色值。最终颜色值为:

    ( S r R s + D r R d , S g G s + D g G d , S b B s + D b B d , S a A s + D a A d ) (S_rR_s+D_rR_d, S_gG_s+D_gG_d, S_bB_s+D_bB_d, S_aA_s+D_aA_d) (SrRs+DrRd,SgGs+DgGd,SbBs+DbBd,SaAs+DaAd)

    其中源混合参数对应片元着色器的输出颜色,目标混合参数对应帧缓存中已有的颜色

    设置混溶参数

    void glBlendFunc(GLenum srcfactor, GLenum destfactor);
    void glBlendFunci(GLuint buffer, GLenum srcfactor, GLenum destfactor);
    

    对于无符号和有符号的归一化帧缓存格式,混溶参数将分别限制在[0, 1]或者[-1, 1]的区间。如果采用浮点数那么不存在上下限。

    void glBlendFuncSeparate(GLenum srcRGB, GLenum destRGB, GLenum srcAlpha, GLenum destAlpha);
    void glBlendFuncSeparatei(GLuint buffer, GLenum srcRGB, GLenum destRGB, GLenum srcAlpha, GLenum destAlpha);
    

    可以使用的参数:

    在这里插入图片描述

    如果使用GL_CONSTANT_COLOR那么需要使用:

    void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
    

    来设置对应常量的颜色值。

    如果设置GL_ONE作为源参数,GL_ZERO作为目标参数,那么与禁止混溶效果是一样的。

    逐缓存混溶设置可以使用glEnablei()和glDisablei()来开启跟关闭。

    混溶方程

    void glBlendEquation(GLenum mode);
    void glBlendEquationi(GLuint buffer, GLenum mode);
    

    设置帧缓存和源数据之间混合的方法。mode可以使用:

    混溶模式参数数学操作
    GL_FUN_ADD(默认值) C s S + C d D C_sS+C_dD CsS+CdD
    GL_FUN_SUBTRACT C s S − C d D C_sS-C_dD CsSCdD
    GL_FUN_REVERSE_SUBTRACT C d D − C s S C_dD-C_sS CdDCsS
    GL_MIN m i n ( C s S , C d D ) min(C_sS,C_dD) min(CsS,CdD)
    GL_MAX m a x ( C s S , C d D ) max(C_sS,C_dD) max(CsS,CdD)

    其中 C s C_s Cs C d C_d Cd分别表示源和目标的颜色, S S S D D D表示源融混参数和目标融混参数。

    void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
    void glBlendEquationSeparatei(GLuint buffer, GLenum modeRGB, GLenum modeAlpha);
    

    逻辑操作

    要开启逻辑操作罗需要调用glEnable()并传入GL_COLOR_LOGIC_OP。

    void glLogicOp(GLenum opcode);
    

    对于源(s)跟目标(d)之间进行逻辑操作,默认为GL_COPY

    在这里插入图片描述

    遮挡查询

    遮挡查询是在深度测试之后完成的。

    遮挡查询的步骤:

    • 为每个需要的遮挡查询对象生成一个ID
    • 调用glBeginQuery()开始遮挡查询
    • 渲染几何体以完成测试
    • 调用glEndQuery()完成遮挡查询
    • 获取通过深度测试的样本数

    为了提高效率,需要禁止所有渲染模式。

    生成查询对象

    void glGenQueries(GLsizei n, GLuint * ids);
    GLboolean glIsQuery(GLuint id);
    

    启用遮挡查询

    void glBeginQuery(GLenum target, GLuint id);
    

    target必须是GL_SAMPLES_PASSED、GL_ANY_SAMPLES_PASSED或者GL_ANY_SAMPLES_PASSED_CONSERVATIVE。

    结束遮挡查询

    void glEndQuery(GLenum target);
    

    查询方法:

    glBeginQuery(GL_SAMPLES_PASSED, Query);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glEndQuery(GL_SAMPLES_PASSED);
    

    判断结果

    void glGetQueryObjectiv(GLenum id, GLenum pname, GLint* params);
    void glGetQueryObjectuiv(GLenum id, GLenum pname, GLuint* params);
    

    id是查询物体名称,如果pname是GL_QUERY_RESULT那么通过深度测试的片元的数量将被写入params中,如果返回0那么全部被挡住了。

    查询结果可能会有一些延迟,可以首先通过查询GL_QUERY_RESULT_AVAIABLE,如果id已经可以查询那么params中会被写入GL_TRUE,否则GL_FALSE

    释放查询对象

    void glDeleteQueries(GLsizei n, const GLuint* ids);
    

    条件渲染

    如果遮挡查询的过程中,需要将查询结果返回应用程序,此时图形硬件设备会停止工作,为了避免这个问题,硬件可以使用条件渲染来使用遮挡查询。

    void glBeginConditionalRender(GLuint id, GLenum mode);
    void glEndConditionalRender(void);
    

    其中id为查询对象id,mode为如何使用遮挡查询结果可以是:

    mode意义
    GL_QUERY_WAITGPU等待查询结果然后判断是否继续渲染
    GL_QUERY_NO_WAITGPU不等待查询结果。如果没有返回,那么它将选择条件渲染区域内的一部分场景进行渲染
    GL_QUERY_BY_REGION_WAITGPU判断片元的结果是否对条件渲染有所贡献,并等待这些结果渲染完成。同时等待遮挡查询结果返回
    GL_QUERY_BY_REGION_NO_WAITGPU将会抛弃帧缓存中所有对遮挡查询没有贡献的区域,并且即使结果还没有返回,它也会开始渲染其它区域的内容

    如果在条件渲染队列已经开始执行时再次调用glBeginConditionalRender或者在条件渲染没有启动的时候调用glEndConditionalRender或者id对应的遮挡查询对象没有被设置为GL_SAMPLES_PASSED以外的模式,或者id对应的遮挡查询对象正在查询中,都会产生GL_INVALID_OPERATION。

    glBeginConditionalRender(Query, GL_QUERY_WAIT);
    glDrawArrays(GL_TRIANGLE_FAN, 0, NumVertices);
    glEndConditionalRender();
    

    如果大部分的渲染操作并不会受到场景遮挡查询的结果影响的话,那么从整体上来说使用NO_WAIT形式要快一些。

    逐图元的反走样

    覆盖值的设定

    void glHint(GLenum target, GLenum hint);
    

    target的取值:

    参数描述
    GL_LINE_SMOOTH_HINT线的反走样质量
    GL_POLYGON_SMOOTH_HINT多边形反走样质量
    GL_TEXTURE_COMPRESSION_HINT纹理图像压缩的质量和性能
    GL_FRAGMENT_SHADER_DERIVATIVE_HINT片元处理内置函数的导数精度,包括dFdx,fwidth

    hint的取值:

    参数描述
    GL_FASTEST效率最高
    GL_NICEST质量最高
    GL_DONT_CARE没有偏好

    该函数是与平台相关的,有的实现里可能会完全忽略。

    线段的反走样

    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
    

    多边形的反走样

    和线段反走样类似,多边形反走样使用的是GL_POLYGON_SMOOTH。为了保证混融方式的恰当,可以设置混融参数为GL_SRC_ALPHA_SATURATE, GL_ONE。

    帧缓存对象

    程序创建的帧缓存对象只能用于离屏渲染,不能用于显示器的显示。而且窗口系统缓存在窗口创建时就有缓存对象:颜色深度和模板,而程序创建的帧缓存对象需要创建额外的真缓存对象,并与之关联。

    创建帧缓存对象

    void glGenFrameBuffers(GLsizei n, GLuint * ids);
    

    绑定帧缓存对象

    void glBindFrameBuffer(GLenum target, GLuint framebuffer);
    

    如果target为GL_DRAW_FRAMEBUFFER,那么framebuffer设置的是绘制时的目标帧缓存,如果target设置为GL_READ_FRAMEBUFFER,那么framebuffer就是去读操作的源数据,如果target分为GL_FRAMEBUFFER,那么framebuffer所设置的帧缓存是可读可写的。如果framebuffer为0,那么绑定到窗口系统帧缓存

    释放帧缓存对象

    void glDeleteFramebuffers(GLsizei n, const GLuint * ids);
    

    判断是否是帧缓存对象

    GLboolean glIsFramebuffer(GLuint framebuffer);
    

    设置帧缓存对象参数

    void glFramebufferParameteri(GLenum target, GLenum pname, GLint param);
    

    target必须是DRAW_FRAMEBUFFER READ_FRAMEBUFFER或FRAMEBUFFER。FRAMEBUFFER与DRAW_FRAMEBUFFER是等价的(书上没有加GL_前缀,感觉是写错了)。
    pname必须是GL_FRAMEBUFFER_DEFAULT_WIDTH, GL_FRAMEBUFFER_DEFAULT_HEIGHT, GL_FRAMEBUFFER_DEFAULT_LAYERS, GL_FRAMEBUFFER_DEFAULT_SAMPLES或者GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS之一。

    第一次调用会分配这个对象的存储空间并将其初始化。

    渲染缓存

    渲染缓存(renderbuffer)是OpenGL所管理的一处高效的内存区域,它可以储存格式化的图像数据。渲染缓存需要关联到一个帧缓存对象才有意义,需要保证图像缓存的格式必须与OpenGL所要求的格式一致。

    创建渲染缓存

    void glGenRenderBuffers(GLsizei n, GLuint * ids);
    

    释放渲染缓存

    void glDeleteRenderbuffers(GLsizei n, const GLuint * ids);
    

    判断是否是渲染缓存

    void glIsRenderbuffer(GLuint renderbuffer);
    

    绑定渲染缓存

    void glBindRenderbuffer(GLenum target, GLuint renderbuffer);
    

    target必须是GL_RENDERBUFFER。

    创建渲染缓存的存储空间

    void glRenderbufferStorage(GLenum target, GLenum interalformat, GLsizei width, GLsizei height);
    void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
    

    为当前绑定的渲染缓存分配图像数据空间。对于一个颜色信息,internalformat可以使用的值为:

    在这里插入图片描述

    如果作为深度缓存使用,那么internalformat可以使用的值为:GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32或者是GL_DEPTH_COMPONENT32F。
    如果作为模板缓存使用,那么internalformat可以使用的值为:GL_STENCIL_INDEX, GL_STENCIL_INDEX1, GL_STENCIL_INDEX4, GL_STENCIL8或者GL_STENCIL_INDEX16。
    对于压缩的深度模板格式,只能为GL_DEPTH_STENCIL。
    width和height是渲染缓存像素大小。
    samples设置逐像素多重采样的样本个数。

    帧缓存附件

    开始渲染时,渲染结果可以保存到以下地方:

    • 如果使用多重渲染目标,则创建图像到颜色缓存,甚至多个颜色缓存。
    • 将遮挡信息保存到深度缓存。
    • 将逐像素的渲染掩码保存到模板缓存。
      这些缓存类型都表示一种缓存附件,就是将对应的图像缓存直接附加到帧缓存之上。可用的帧缓存附件(framebuffer attachment)点:
    附件名称描述
    GL_COLOR_ATTACHMENTi第i个颜色缓存。i的范围[0, GL_MAX_COLOR_ATTACHMENTS)
    GL_DEPTH_ATTACHMENT深度缓存
    GL_STENCIL_ATTACHMENT模板缓存
    GL_DEPTH_STENCIL_ATTACHEMNT用于保存压缩后的深度-模板缓存

    可以将这些附件关联到两种不同类型的渲染表面:渲染缓存和纹理图像的某个层级

    渲染缓存关联到帧缓存对象

    void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
    

    target必须是GL_DRAW_FRAMEBUFFER GL_READ_FRAMEBUFFER或GL_FRAMEBUFFER。
    attachment必须是上表列出的可用的帧缓存附件之一。
    renderbuffertarget必须是GL_RENDERBUFFER。

    帧缓存的完整性

    GLenum glCheckFramebufferStatus(GLenum target);
    

    返回信息:

    在这里插入图片描述

    清除独立缓存

    void glClearBuffer{fi ui}v(GLenum buffer, GLint drawbuffer, const TYPE* value);
    

    清除drawbuffer对应缓存中的数据,清除值为value,buffer必须是GL_COLOR, GL_DPETH或者GL_STENCIL之一。

    void glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
    

    buffer必须是GL_DEPTH_STENCIL。

    帧缓存的无效化

    void glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments);
    void glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
    

    设置绑定的帧缓存对象的一部分或者整体将不再保留。
    target必须是GL_DRAW_FRAMEBUFFER GL_READ_FRAMEBUFFER或GL_FRAMEBUFFER。
    attachments必须是上表列出的可用的帧缓存附件。
    numAttachments表示attachments中的附件数量。

    多重渲染缓存的同步写入

    帧缓存对象的多渲染缓存特性,也就是一个片元着色器中同时写入多个缓存的能力,也称为MRT(Multiple-Render Target)。

    如果需要设置out变量与帧缓存附件之间的关系,只需要将layout限定符将变量直接设置到正确的位置即可。

    layout(location = 0) out vec4 color;
    layout(location = 1) out vec4 norm;
    

    OpenGL中指定片元着色器输出值与帧缓存附件之间的联系:

    void glBindFragDataLocatoin(GLuint program, GLuint colorNumber, const GLchar* name);
    void glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar* name);
    

    使用colorNumber的值来对应片元着色器的变量name,从而与着色器程序program的输出位置进行关联。对于颜色索引的情形,index 可以用来同时设置输出索引值和位置。

    链接结束后,如果它们可用的话,则可以获取片元着色器的输出位置和变量了:

    GLint glGetFragDataLocation(GLuint program, const GLchar* name);
    GLint glGetFragDataIndex(GLuint program, const GLchar* name);
    

    获取片元着色器变量name的位置或者索引。

    着色器中的location设置优先级要高。

    选择颜色缓存来进行读写操作

    绘制或者读取操作的结果通常与以下几种颜色缓存的内容关联:

    • 默认帧缓存中的前、后、左前、左后、右前、右后缓存
    • 或者用户自定义帧缓存对象中的前缓存,或者是任意渲染缓存附件

    设置写入缓存

    void glDrawBuffer(GLenum mode)
    

    设置可以写入或者清除操作的颜色缓存,同时禁止前一次glDrawBuffer()或者glDrawBuffers()所设置的缓存。
    mode可以是GL_FRONT, GL_BACK, GL_LEFT, GL_RIGHT, GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT, GL_BACK_RIGHT, GL_NONE, GL_FRONT_AND_BACK, GL_COLOR_ATTACHMENTi。
    如果当前绑定了一个帧缓存对象,且不是默认帧缓存对象,那么只能用GL_NONE或者GL_COLOR_ATTACHMENTi,否则产生GL_INVALID_ENUM错误。
    默认情况下,mode为GL_BACK。

    void glDrawBuffers(GLsizei n, const GLenum * buffers);
    

    buffers只能接受GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT, GL_BACK_RIGHT, GL_NONE几种类型(书上这么写的,我记得好像也可以使用GL_COLOR_ATTACHMENTi)。

    如果要将双重缓冲窗口作为一个单缓冲窗口来使用,可以使用glDrawBuffer(GL_FRONT_AND_BACK)。

    void glReadBuffer(GLenum mode);
    

    设置用作像素读取的缓存,读取像素的函数包括glReadPixels(), glCopyTexImage*(), glCopyTexSubImage*()等。
    mode与glDrawBuffer可以使用的类型相同。

    开启关闭附件启用的功能

    void glEnable(GLenum capability, GLuint index);
    void glDisable(GLenum capability, GLuint index);
    GLboolean glIsEnablei(GLenum capability, GLuint index);
    

    双源混溶

    当使用混溶参数GL_SRC1_COLOR, GL_SRC1_ALPHA, GL_ONE_MINUS_SRC1_COLOR, GL_ONE_MINUS_SRC1_ALPHA时,混合方程会使用第二个源的数据进行混合。

    如果设置源参数为GL_SRC1_COLOR,目标参数为GL_ONE_MINUS_SRC1_COLOR那么混溶函数的本质就是片元着色器中建立一个逐通道的alpha计算机制。

    如果设置源参数为GL_ONE,目标参数为GL_ONE_MINUS_SRC1_COLOR这样第一个颜色输入会直接加到帧缓存内容上,第二个颜色的输出可以用来减弱帧缓存数据:

    R G B d s t = R G B s r c 0 + R G B s r c 1 ∗ R G B d s t RGB_{dst} = RGB_{src0}+RGB_{src1}*RGB_{dst} RGBdst=RGBsrc0+RGBsrc1RGBdst

    这个称为乘加运算,例如如果使用有色高光来渲染半透明物体,那么可以将物体颜色写入second_output,高光写入first_output。

    像素的读取和拷贝

    void glReadPixels(GLint x, GLint y, GLsizei width, GLsiezi height, GLenum format, glEnum type, void * pixels);
    

    从刻度取得帧缓存中读取像素数据,保存到pixels当中。
    format表示读取像素数据元素的类型:

    在这里插入图片描述

    type用于指定每个元素的数据类型:

    在这里插入图片描述

    返回值的截断

    void glClampColor(GLenum target, GLenum clamp);
    

    控制浮点数和定点数缓存的颜色截断方式,如果target设置为GL_CLAMP_READ_COLOR则开启截断,如果clamp为GL_TRUE,那么颜色将被阶段到[0,1],否则不会被截断。
    如果使用定点数与浮点数混合的方式,如果clamp设置为GL_FIXED_ONLY时,直接断定点数数据,而浮点数仍保留原始形式。

    拷贝像素矩形

    如果需要在一块缓存不同区域之间或者是不同帧缓存之间进行拷贝,需要使用glBlitFramebuffer。

    void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield buffers, GLenum filter);
    

    将矩形像素从刻度帧缓存的一出去与拷贝到可会知帧缓存的另一处区域中。
    buffers可以通过位或的方式设置GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT。
    filter用于当两个区域大小不同是,进行插值的方法,可以使用GL_NEAREST和GL_LINEAR。
    如果有多个颜色绘制缓存,那么每个缓存都会进行一次数据拷贝。
    如果srcX1 < srcX0或者desX1 < destX0 那么会进行一次水平翻转。
    如果源数据和目标数据类型不同,那么大多情况会进行数据的转换。但如果可读缓存是浮点数某个写入缓存不是或者可读缓存是有(无)符号整数,某个写入缓存不是,则会产生GL_INVALID_OPERTATION错误。
    如果源缓存是多重采样,目标缓存不是那么所有样本会被总到单一的像素值并存入目标缓存,反之元数据将被拷贝多次已匹配所有的样本值。如果都是多重采样,那么如果采样数相同则直接拷贝,不同会产生GL_INVALID_OPERATION错误。

    展开全文
  • 计算公式: 帧缓存容量(B) = 分辨率 * 灰度等级所占比特 / 8; 帧缓存容量(bit) = 分辨率 * 灰度等级所占比特; 其中分辨率、灰度等级要取2的指数幂的幂指数,不足的按进一位计算。 3、在下列性质中,哪一个不是...
  • 简述帧缓存与显示器分辨率的关系

    千次阅读 2019-12-29 21:17:50
    帧缓存=显示器分辨率位平面数/8 例如: 分辨率分别为640×480需要多少字节位平面数为24的帧缓存? 640480*24/8=961200字节
  • 精灵帧缓存 简介 SpriteFrameCache 主要服务于多张碎图合并出来的纹理图片。这种纹理在一张大图中包含了多张小图,直接通过TextureCache引用会有诸多不便,因而衍生出来精灵框帧的处理方式,即把截取好的纹理信息...
  • 计算机图形学考试复习

    千次阅读 多人点赞 2020-09-03 00:30:51
    帧缓冲存储器是用来存储屏幕上像素的颜色值的,显示颜色的种类与帧缓存中每个单元的位数有关: 如果屏幕上每个像素的颜色只用一位(Bit)表示,其值非0即1,屏幕只能显示黑白二色图像,称为黑白显示器,此时帧缓冲...
  • 帧缓存对象 Frame Buffer Object

    千次阅读 2018-08-18 16:39:08
    3. 创建 帧缓存附加图像 (framebuffer-attachable image) 3.1. 创建 纹理图像 (texture images) 3.2. 创建 Renderbuffer图像 (Renderbuffer images) 4. 绘制到纹理(Render to texture) 5. 使用后处理效果(post...
  • 文章目录颜色、像素和帧缓存4.1 基本颜色理论4.2 缓存及其用途颜色缓存深度缓存模板缓存4.2.1 缓存的清除4.2.2 缓存的掩码4.3 颜色与OpenGL4.3.1 颜色的表达与OpenGL4.3.2 顶点颜色4.3.3 光栅化4.4 多重采样4.4.1 ...
  • 灰度等级为256级,分辨率为1024*1024的显示器,至少需要的帧缓存容量为() A 512KB B 1MB C 2MB D 4MB 正确答案:B **科普:** 灰度是用来衡量像素颜色的指标,黑白色,非0即1,灰度等级为256级,即2^8是256,...
  • 帧缓存是由矩形的像素数组组成的,每个像素都可以在图像对应的一个点上显示一小块方形的颜色值。经过光栅化的阶段美也就是执行完片元着色器之后,得到的数据还不是一个真正的像素--只是候选的片元。每个片元都包含与...
  • //申请帧缓存对象的内存 glGenFramebuffers(1,FBOs);//产生帧缓存对象 glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);//绑定帧缓存对象 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_...
  • react 双缓存计算

    2021-02-09 16:57:48
    举个例子,使用 canvas 绘制动画时,在绘制每一前都会清除上一的画面,清除上一需要花费时间,如果当前画面计算量又比较大,又需要花费比较长的时间,这就导致上一清除到下一显示中间会有较长的间隙,就...
  • OpenGL学习四——帧缓存

    千次阅读 2011-11-21 09:56:43
     以统一的方式对每个像素的数据进行存储的空间被称为缓存,OpenGL中有四种缓存——颜色缓存、深度缓存、模板缓存以及累积缓存。  颜色缓存存储了颜色索引或RGB颜色数据,还存储了alpha值,主要用于图像像素颜色...
  • 对应于其他系统和此Renderbuffer相连接的FBO称为 窗口系统提供的"帧缓存区". 图4-2 CAEAGLLayer通过提供两个关键功能向OpenGL ES提供此支持。首先,它为renderbuffer分配共享存储。其次,它将渲染缓冲区...
  • OPENGL帧缓存和动画

    千次阅读 2017-01-10 23:06:37
    一般正规的动画制作在实现上都是通过双缓存实现的(硬件也好,软件也好)大家可以参考《家用...当前台显示缓存用于显示时,后台缓存已经进行计算计算完毕把所有内容通过缓存拷贝一次性完成,防止闪烁的出现。 
  • 帧缓存

    千次阅读 2013-08-08 11:06:57
    帧缓冲存储器(Frame Buffer):简称帧缓存或显存,...帧缓存的每一存储单元对应屏幕上的一个像素,整个帧缓存对应一帧图像。  一个支持OpenGL渲染的窗口 (即帧缓存) 可能包含以下的组合: · 至多4个颜色缓存 ·
  • 文章目录颜色、像素和帧缓存4.6 逐图元的反走样4.6.1 线段的反走样4.6.2 多边形的反走样4.7 帧缓存对象4.7.1 渲染缓存4.7.2 创建渲染缓存的存储空间4.7.3 帧缓存附件4.7.4 帧缓存的完整性4.7.5 帧缓存的无效化4.8 ...
  • 音频大小计算

    千次阅读 2018-09-30 10:23:09
    ACC帧率 (一秒播放数)= TotalByte/4096 = 43.06640625 2) MP3: nb_samples和frame_size = 1152 一数据量:1152*2*s16/8 = 4608个字节。 MP3帧率 (一秒播放数)= TotalByte/4608 = 38.28125 上面带...
  • 缓存大小的计算方法

    千次阅读 2016-08-17 12:28:00
    ...请根据实际需求评估缓存大小。基本公式示例: 目标用户总数 * 单个用户数据大小(字节) / 1024 / 1024 = 总容量(MB) 转载于:https://my.oschina.net/lxphemy/blog/733941
  • OpenGL 编程指南(第八版)学习笔记——4颜色 像素和帧缓存 缓存及其用途 所有图形程序的共同目标,在屏幕上绘制图像(或者绘制到屏幕的一处缓存中)。 帧缓存(通常就是屏幕)是由矩形的像素数组组成的,每个像素...
  • FPGA大赛【四】具体模块设计--图像缓存 【注】该项目是我们团队参加2019届全国大学生FPGA大赛的作品,系统主要实现视频任意角度旋转。该项目最终晋级决赛,并获得紫光同创企业特别奖。该系列文章介绍我们团队的...
  • OpenGL之缓冲

    千次阅读 2019-04-17 13:37:02
    本文主要包括缓冲的基本概念、函数使用,以及...几何数据(顶点坐标、纹理坐标等)和纹理经过一系列渲染管道最终计算出屏幕上的所有像素点,它们需要一个地方来存放,这个地方就是缓冲。缓冲中的数据会被显示...
  • 缓冲存储器

    2020-04-07 21:44:25
    帧缓冲存储器:一块用来存储像素的颜色或者灰度值的存储空间,又称帧缓存 颜色位面法 帧缓存被分成若干独立的存储区域 ,每个区域称为一个位面,将几个位面中的同一位组成一个像素 帧缓存容量 = 分辨率 * 颜色位面...
  • 1)灰度等级为256级,分辨率为1024*1024的显示模式,至少需要的帧缓存容量为Bbit A、7M B、8M C、10M D、16M 2)C是在高于显示分辨率的较高分辩率下用点取样方法计算,然后对几个像素的属性进行平均得到较低 分辨率下的...
  • 用rosbag录了一段数据,在rviz上...于是重新打开rviz,重新添加topic,这样不会缓存数据,然后又打开之前的.rviz配置,就不会缓存数据了。不知道原理是什么,作为暂时的解决方法吧。 还有一种方法,先放ba...
  • 举个例子,假如我在一个帧缓存中专门绘制了Phong光照模型的物体,在另一个帧缓存中专门绘制了Pbr光照模型的物体,在第三个帧缓存中只绘制了只有单一颜色的物体,等于现在我有三个离屏渲染的帧缓存,我需要把他们都...
  • 【原创】IP摄像头技术纵览(三)—图像数据在帧缓存设备(framebuffer)上的显示本文属于《IP摄像头技术纵览》系列文章之一:Author: chad Mail: linczone@163.com 本文可以自由转载,但转载请务必注明出处以及本...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 64,068
精华内容 25,627
关键字:

帧缓存计算

友情链接: select-or-trigger.rar