精华内容
下载资源
问答
  • 深度缓冲

    千次阅读 2012-03-02 22:52:52
    1. 什么是深度缓冲   2. 使用深度缓冲 使用深度缓冲    Direct3D立即模式教程中提供了有关使用深度缓冲的更多的内容。            一个深度缓冲,统称被称为 z-...

    http://blog.csdn.net/sck5711/article/details/4056957

     

    1. 什么是深度缓冲

     

    2.

    使用深度缓冲

    使用深度缓冲

     

      Direct3D立即模式教程中提供了有关使用深度缓冲的更多的内容。

     

     

     

     

     

      一个深度缓冲,统称被称为

    z-bufferw-buffer,是一个DirectDraw表面,它保存着Direct3D使用的深度信息。当Direct3D渲染一个三维场景时,它可将深度缓冲作为一个工作区来决定光栅的多边形中的像素如何吸收掉其它的像素。Direct3D使用一个离屏(off-screenDirectDraw表面作为写最终颜色值的目标。与这个渲染目标表面相关的深度缓冲表面被用来存储深度信息,它通知Direct3D,场景中的可见像素有多深。

     

      当一个

    3-D场景经过光栅,并且深度缓冲有效时,渲染表面上的每一个点都会被检查。深度缓冲中的值被作为一个点的z坐标或是等同的w坐标。使用z值的深度缓冲被称为“z-buffer”,使用w值的称为“w-buffer”。每种深度缓冲都有各自的优缺点。

     

      在检测开始时,深度缓冲中的深度值被设置为场景中的最大可能值。渲染表面的颜色值被设置为背景颜色或者那一点的背景纹理的颜色值。场景中的每一个多边形都要进行检查,看它是否和渲染表面上的当前坐标

    (x,y)相交叉。如果交叉,那么就检查当前点的深度值(z-buffer中的z,或w-buffer中的w),看它是否小于已经存储在深度缓冲中的深度值。如果多边形的深度值较小,那么就将它存储深度缓冲中,并将多边形的颜色值写到渲染表面的当前点上。如果多边形的深度值较大,那么接着检查下一个多边形。整个过程如下图所示:

    注:我们可以改变Direct3D所用的比较关系,来决定将哪些值放在深度缓冲中以及紧接着的渲染目标表面中。要这样做,只要改变D3DRENDERSTATE_ZFUNC渲染状态的值就可以了。但是,这种方法我们一般并不采用。

      几乎所有的

    3-D加速卡都支持z-buffering,这样就使得z-buffers成为现在最常用的深度缓冲类型。但是,z-buffers也有它本身的缺陷。由于它所使用的数学方法,使得一个z-buffer中产生的z值在它允许的范围内(通常为0.01.0之间,包括它们)并不是均匀分布的。特别是靠近剪切面与远离剪切面处的比例,更是影响了z值的均匀分布。如果远平面的距离与近平面的距离的比为100,那么深度缓冲范围的90%就只消耗在了场景深度范围。一般的娱乐程序或视觉仿真程序要求远近平面的距离比在100010000之间。比值为1000时,98%的范围消耗在深度范围开始的2%上,并且随着比值的增大,分布将变得更糟。这样可能会使较远距离的物体上的隐藏表面产生失真,特别是当使用16-bit深度缓冲时。

     

      w深度缓冲比z-buffer能更均匀地在远近剪切面之间进行分配。使用它的最大好处就是远近剪切面的距离比不再是关键因素。这样就允许程序使用更大的距离范围,同时仍能保持深度缓冲与观察位置间的精确联系。w-buffer也不是完美的,有时也会使近处物体的隐藏表面产生失真。w-buffer的另一个缺点是不能得到硬件的广泛支持。

     

      DirectDraw HEL可以创建用于Direct3D或其它3-D渲染软件的执行缓冲。HEL支持16-bit深度缓冲。3-D加速卡的DirectDraw设备驱动器允许在显存中创建深度缓冲,要使用DDSCAPS_ZBUFFER标志。你可以通过调用IDirect3D3::EnumZBufferFormats方法来查询硬件支持的深度缓冲的位深度(bit-depth)。

     

      创建一个

    z-buffer表面时,程序应该保留指向这个z-buffer的指针,直到关闭Direct3D系统时为止。在释放渲染表面之前,应该先释放z-buffer表面。

     

      在渲染过程中,

    z-buffering会有一定的系统开销。使用z-buffer时,我们可以采用一些优化措施,详情见“Z-Buffer的性能”部分。

    注:一个深度值的实际解释要视不同的3-D渲染器而定。

     

     

     

     

     

      下面我们来详细讨论深度缓冲的用法:

     

    2.1 查询是否支持深度缓冲 2.2 创建深度缓冲 2.3 启动深度缓冲 2.4 清空深度缓冲 2.5 改变深度缓冲写访问 2.6 改变深度缓冲比较函数 2.7 使用Z偏移使用Z偏移

     

     

     

     

      和其它一些特性一样,我们不能假定所使用的驱动器能够支持深度缓存运算;而应该查询驱动器的能力。几乎所有的驱动器都支持z深度缓存运算。如果试图使一个不支持的配置有效的话,驱动器并不会出现故障,而是返回到另一个深度缓存方法,有时也可能使深度缓存运算无效,这样就会使场景产生深度上的失真。

      在创建一个Direct3D设备之前,可以通过向DirectDraw查询所使用的显示设备来检查对深度缓冲的总体支持能力。如果DirectDraw对象报告支持深度缓存运算,那么从这个DirectDraw对象创建的任何硬件设备都将支持z-buffering(但是,我们仍然无法知道驱动器是否支持w-buffering)。

     

    查询深度缓冲的总体支持能力

     

    1. 对显示设备调用DirectDraw对象的IDirectDraw4::GetCaps方法,将初始化过的DDCAPS结构作为参数。调用之后,DDCAPS结构就包含了有关DirectDraw的硬件和仿真能力的信息。

    1. 检查作为第一个参数的结构的ddsCaps成员。如果这个成员——一个DDSCAPS2结构——包含DDSCAPS_ZBUFFER标志,那么就表示驱动器支持使用z-buffer的深度缓存运算。

      知道了驱动器支持z-buffer之后,就可以来检查w-buffer的支持能力了。所有的软件光栅都支持z-buffer,但是某些参考光栅也支持w-buffer,虽然它几乎不适用于real-world程序来使用。无论我们使用什么类型的设备我们都应该在使用w-based深度缓存运算之前,对w-buffer的支持能力进行检查。

      确定是否支持

      w-buffer

      1. 创建设备之后(HAL或仿真设备),调用IDirect3DDevice3::GetCaps方法,并将初始化过的D3DDEVICEDESC结构传递给它的两个参数。
    1. 调用之后,dpcTriCapsdpcLineCaps成员(D3DPRIMCAPS结构)包含了有关设备对图元渲染的支持能力的信息。
    2. 如果这些结构的dwRasterCaps成员包含了D3DPRASTERCAPS_WBUFFER标志,那么对这种图元类型驱动器就支持基于w的深度缓存运算。

       

      通常,我们在创建一个Direct3D设备对象之前的程序的启动阶段来创建深度缓冲。我们用下面的步骤来创建一个深度缓冲,并将它配属到渲染目标表面:

     

    1. 调用IDirect3D3::EnumZBufferFormats方法来决定深度缓冲的像素格式。

    1. 准备一个DDSURFACEDESC2结构,来描述一个与渲染目标表面大小相配的DirectDraw表面,包含DDSCAPS_ZBUFFER能力标志,并使用一种支持的深度缓冲像素格式(由步骤1得到)。
    2. 在显存或系统内存中创建表面,这要视程序使用的渲染设备的类型而定。(见“注”部分)
    3. IDirectDrawSurface4::AddAttachedSurface方法将深度缓冲配属于渲染表面。
    4.   创建了深度缓冲并将它配属与渲染目标表面之后,调用IDirect3D3::CreateDevice方法来创建一个使用渲染目标表面和深度缓冲的渲染设备。

        当程序使用硬件驱动器时(HAL设备),在显存中创建深度缓冲——使用DDSCAPS_VIDEOMEMORY标志;使用软件仿真驱动器时(MMXRGB设备),在系统内存中创建深度缓冲——使用DDSCAPS_SYSTEMMEMORY标志。如果在适当的内存中创建深度缓冲失败了,那么就会导致CreateDevice方法的失败。

    注:有些常用的硬件设备要求渲染目标与深度缓冲表面使用相同的位深度。丢与这些硬件,如果使用16-bit的渲染目标表面,那么相应的深度缓冲也要是16-bit的。对于32-bit渲染表面,深度缓冲必须是32-bit的;8-bit渲染表面要使用模板缓冲(如果需要的话)。

    如果程序没有满足硬件的这些要求,那么使用非适应(non-compliant)表面来创建一个渲染设备的尝试将是失败的。你可以使用IDirectDraw4::GetDeviceIdentifier来跟踪硬件的这些限制。

     

      创建了一个深度缓冲之后,只要调用IDirect3DDevice3::SetRenderState方法就可以启动深度缓冲。通过设置D3DRENDERSTATE_ZENABLE渲染状态来使之有效。使用D3DZB_TRUE(或TRUE)使z-buffering有效,使用D3DZB_USEW使w-buffering有效,或者使用D3DZB_FALSE(或FALSE)使深度缓冲无效。.

    注:要使用w-buffering,程序必须设置一个适当的投影矩阵,即使它不使用Direct3D变换管道,并且必须要使透视修正纹理映射有效。要时透视修正纹理映射有效,要将D3DRENDERSTATE_TEXTUREPERSPECTIVE渲染状态设置为TRUE。对于DirectX 6.0来说,这个值是默认的。

     

     

     

    2.4 清空深度缓冲

     

      每次渲染一个新框架时,都应该将深度缓冲清空。可以使用IDirect3DViewport3::ClearIDirect3DViewport3::Clear2方法来进行这一操作。Clear方法在清空时使用“最深的”值,Clear2方法则允许你来设定一个任意的深度值。

      也可以使用DirectDraw来清空一个深度缓冲,调用深度缓冲表面的IDirectDrawSurface4::Blt方法来进行。DDBLT_DEPTHFILL标志会显示一个清空的深度缓冲正在使用blit。当这个标志声明了时,被传递给IDirectDrawSurface4::Blt方法的DDBLTFX结构应该已经经过初始化,并且它的dwFillDepth成员应该被设定为需要的深度。

      如果一个3-D硬件的DirectDraw设备驱动器被设计为能够对深度缓冲进行硬件清空操作,那么它会报告DDCAPS_BLTDEPTHFILL标志,并处理DDBLT_DEPTHFILL blit操作。一个深度填充的blit操作目的表面必须是一个深度缓冲表面。

     

     

     

      缺省情况下,Direct3D系统允许对深度缓冲进行写入操作。大多数的程序都会允许对深度缓冲进行些操作,但是有时也需要禁止写深度缓冲。

     

      调用IDirect3DDevice3::SetRenderState方法,并将dwRenderStateType参数设定为D3DRENDERSTATE_ZWRITEENABLE,将

    dwRenderState参数设定为0,这样就可以使写深度缓冲操作无效。.

     

     

    2.6 改变深度缓冲比较函数

      缺省情况下,在对一个渲染表面执行深度测试时,如果相应的每个点的深度值(zw)比深度缓冲中的值小,那么Direct3D系统会更新渲染目标表面。调用IDirect3DDevice3::SetRenderState方法,并将dwRenderStateType参数设定为D3DRENDERSTATE_ZFUNC,这样,我们就可以改变系统执行比较操作的方式。dwRenderState参数应该被设定为D3DCMPFUNC枚举类型中的一个值。

     

     

     

    2.7 使用Z-偏移量

     

      在一个三维场景中,我们可以对共面的多边形使用z-偏移量来使它们不再共面。这项技术通常用于在场景中正确的显示阴影。例如,一堵墙上的阴影与这堵墙的深度值是相同的,如果我们先渲染了墙再来渲染阴影,那么阴影就有可能看不到,或者会出现一些深度上的失真。这时,我们可以颠倒渲染的顺序希望能使得到的效果也产生相应的颠倒,但是深度上的失真仍然无法避免。

      在渲染共面的多边形时,我们可以给z值增加一些偏移量,这样就能正确的显示共面的多边形了。要给多边形增加一个z-偏移量,我们可以在渲染前调用IDirect3DDevice3::SetRenderState方法,并将dwRenderStateType参数设定为D3DRENDERSTATE_ZBIAS,将dwRenderState参数设定为016之间的一个值(包括016)。如果我们将z-偏移量设的较高,那么与其它共面的多边形一同渲染时,就有可能使它更加明显。

     

     

     

     

     

    九.模板缓冲

    下面我们来讨论模板缓冲的用法以及相关内容。

    1. 什么是模板缓冲 2. 模板缓冲如何工作 3. 定制模板缓冲定制模板缓冲

     

     

     

    1. 什么是模板缓冲?

     

      模板缓冲用来控制是否向渲染目标表面一个像素一个像素的绘制场景。在模板缓冲最基本的一级上,它能够使程序掩盖住被渲染图象的一部分,使它不能显示。我们可以使用模板缓冲来得到一些特殊的效果,如淡入淡出(dissolve)、贴纸(decaling)和勾画轮廓(outlining)等。详细内容件“模板缓冲技术”。

      模板缓冲的信息嵌入在z-buffer数据中。程序可以调用IDirect3D3::EnumZBufferFormats方法测试用户的硬件,看它是否支持模板缓冲。要得到有关z-buffer数据的详细格式的信息,可以调用IDirectDrawSurface4::GetPixelFormat方法,它将一个DDPIXELFORMAT结构传递给你的程序。相关的信息在dwZBufferBitDepthdwStencilBitDepthdwZBitMaskdwStencilBitMask成员中。

     

     

     

    2. 模板缓冲如何工作

     

      Direct3D在模板缓冲上执行一个基于pixel-by-pixel的测试。对于目标表面上的每一个像素,它使用模板缓冲中相应的值——模板参考值(stencil reference value)——和模板掩模值(stencil mask value)来执行测试。如果测试通过,Direct3D就会执行一个动作。测试使用下面的步骤来进行:

     

    1. 将模板参考值与模板掩模进行逐位AND运算。

    1. 将当前像素的模板缓冲置于模板掩模进行逐位AND运算。
    2. 用比较函数比较前两步得到的结果。

      如果写成伪代码形式,步骤如下:

      (StencilRef & StencilMask) CompFunc (StencilBufferValue & StencilMask)

        上式中,StencilBufferValue是当前像素的模板缓冲的内容;伪代码使用&符号来表示逐位AND操作;StencilMask表示模板掩模的值;StencilRef表示模板参考值;CompFunc是比较函数。

        如果模板测试通过了,那么当前像素就会被写到目标表面,如果没有通过,则会将当前像素忽略掉。默认的比较行为是无论每个逐位操作得到什么结果都执行写像素操作*D3DCMP_ALWAYS标志)。我们可以改变D3DRENDERSTATE_STENCILFUNC渲染状态来改变这一行为,通过传递D3DCMPFUNC枚举类型的一个成员来声明我们所需的比较函数。

       

      程序可以对模板缓冲操作进行定制。可以设置比较函数,设置模板掩模和模板参考值。也可以控制在模板测试通过或失败时Direct3D所采取的措施。详细内容见“模板缓冲状态”。

     

     

     

     

    十.顶点缓冲

     

      这一部分我们介绍在使用和理解顶点缓冲时需要了解的一些内容:

     

    1.

    什么顶点缓冲

     

    2.

    顶点缓冲描述

     

    3.

    顶点缓冲与设备类型

     

    4. 使用顶点缓冲

     

     

    1. 什么是顶点缓冲?

     

      顶点缓冲,由IDirect3DVertexBuffer接口表示,实际就是用来包含顶点数据的简单的内存缓冲器。它可以包含任何顶点类型——transformed或者untransformed以及lit或者unlit。我们也可以在顶点缓冲中执行顶点操作,如变换、光线处理或产生裁剪标志等。(变换操作总要执行。)

      顶点缓冲对于要重复利用几何变换的分段顶点来说是比较理想的。我们可以只创建一个顶点缓冲,并且变换、光线处理和顶点裁剪都包含在其中,然后不再需要进行变换就可以对模型进行多次的渲染,甚至在交叉渲染状态(interleaved render state)发生变化时也可以。这在使用多个纹理渲染模型时是非常有用的:只需要进行一次几何变换,然后它的一部分就可以根据需要进行渲染,随着所需纹理的变化进行交叉存取。顶点处理之后的渲染状态改变会影响接下来的顶点处理。详细内容见“处理顶点”。

      我们可以对顶点缓冲的几何处理进行优化,使顶点操作与渲染达到最佳的性能。件“对顶点缓冲进行细节优化”。

    注:顶点缓冲使用DirectDrawSurface对象来进行内存管理服务。这样,顶点缓冲的访问就与DirectDrawSurface对象的访问比较相似了。实际上,IDirect3DVertexBuffer::Lock方法接受与IDirectDrawSurface4::Lock方法一样的标志。详细内容见“访问顶点缓冲内存”。

     

     

    2. 顶点缓冲的描述

     

      我们用一个顶点缓冲的能力来对它进行描述:是否它只能存在于系统内存中,是否它只能使用写操作,它包含的顶点类型和数量,以及在创建时是否进行了优化。所有的这些特性都包含在一个

    D3DVERTEXBUFFERDESC

    结构中。

      对顶点缓冲的描述会告诉系统如何来创建一个顶点缓冲,并告诉程序一个已经存在的顶点缓冲是如何创建的(以及是否经过了优化)。在创建一个顶点缓冲时应该声明一个完整的描述,还要为系统提供一个空的描述结构体,使系统能将一个先前创建的顶点缓冲的描述填充在其中。有关的详细内容见“创建顶点缓冲”与“获得顶点缓冲描述”。

     

      dwSize成员是DirectX中最常用的,它用来确定结构的方案,并要在结构使用之前被设定为结构的大小。dwCaps结构成员包含了一般的能力标志。D3DVBCAPS_SYSTEMMEMORY标志表示系统应该在系统内存中创建(或者已经创建了)顶点缓冲。如果程序使用软件渲染设备,那么就要创建一个显式模式的(explicit

    )系统内存顶点缓冲;否则,最好通过省略标志来让系统决定最佳的创建位置。关于显式系统内存顶点缓冲,请看“顶点缓冲与设备类型”部分。

     

      dwCaps中的D3DVBCAPS_WRITEONLY标志的存在就表示顶点缓冲内存只能进行写操作。这样就可以使驱动器能够自由的对顶点数据进行最好的内存定位,使处理和渲染的速度得以提高。使用这个标志时,从顶点缓冲中读数据会使内存访问速度变得很慢。如果不使用D3DVBCAPS_WRITEONLY

    标志,驱动器可能为了读操作而将数据放在效率不是很好的地方,从而损失了一定的处理和渲染速度。如果没有声明标志,也就是假定程序会在顶点缓冲中执行读和写数据操作。

    注:在创建顶点缓冲过程中,不使用D3DVBCAPS_OPTIMIZED标志。在对顶点缓冲进行优化时,系统才使用这一标志。

     

      最后两个

    D3DVERTEXBUFFERDESC结构成员用来描述其它的特性。dwFVF成员包含了一个可塑(flexible)顶点格式标志的组合,用来确认顶点的类型。顶点缓冲的容量用它所包含的所有顶点的数量来表示,在dwNumVertices

    成员中给出。

     

     

    3. 顶点缓冲与设备类型

     

      一个

    Direct3D软件渲染设备只能使用显式(explicit)系统内存顶点缓冲。要在系统内存中创建顶点缓冲,就要在提供给IDirect3D3::CreateVertexBuffer方法的描述结构体中包含D3DVBDESC_SYSTEMMEMORY

    标志。

     

      如果程序使用硬件加速设备,最好忽略掉

    D3DVBDESC_SYSTEMMEMORY

    标志。这样就可以使系统根据性能的需要在内存中来安排顶点缓冲的位置,但是设备在使用顶点缓冲时又可以不用考虑它的位置。

     

     

    4. 使用顶点缓冲

     

      下面我们讨论如何使用顶点缓冲:

     

    4.1

    创建顶点缓冲

     

    4.2

    访问顶点缓冲内存

     

    4.3

    处理顶点

     

    4.4

    优化顶点缓冲

     

    4.5

    从顶点缓冲开始渲染

     

    4.6 恢复顶点缓冲的描述

     

    4.1 创建一个顶点缓冲

     

      下图展示了创建一个顶点缓冲所需的一些步骤:

    pic92.gif (5678 bytes)

      调用IDirect3D3::CreateVertexBuffer方法创建一个顶点缓冲对象,它有四个参数。第一个参数是一个D3DVERTEXBUFFERDESC结构的地址,同它来描述顶点的格式、缓冲器的大小和其它一些特性。通常,系统会为顶点缓冲安排最佳的内存位置(安排在显存或系统内存中)。但是,软件渲染设备只能使用显式系统内存顶点缓冲。

     

      第二个参数是一个变量的地址,如果函数调用成功的话,这个变量是一个指向顶点缓冲对象的新的

    IDirect3DVertexBuffer接口的指针。第三个参数用来决定顶点缓冲是否有能力包含裁剪信息——以裁剪标志的形式。将它设置为0表示创建一个“有裁剪能力”的顶点缓冲;如果使用D3DDP_DONOTCLIP标志,就表示不包含裁剪标志。如果程序指明了包含transformed顶点(D3DFVF_XYZRHW标志包含在描述结构体的dwFVF成员中),那么就只能使用D3DDP_DONOTCLIP标志。如果指明了将包含untransformed顶点(D3DFVF_XYZ标志),那么CreateVertexBuffer方法将会忽略D3DDP_DONOTCLIP标志。裁剪标志需要占用额外的内存,这就使得有裁剪能力的顶点缓冲要比不包含裁剪标志的顶点缓冲大一些。由于这些资源要在创建顶点缓冲时进行分配,因此必需提早请求一个有裁剪能力的顶点缓冲。

    注:创建一个包含裁剪标志的顶点缓冲并不意味着一定要在顶点处理或进行渲染时来产生裁剪标志。每一个顶点缓冲渲染方法都可以使用D3DDP_DONOTCLIP标志在渲染时将裁剪操作绕过,并且IDirect3DVertexBuffer::ProcessVertices方法还接受D3DVOP_CLIP标志,它可以在渲染顶点时被忽略,从而阻止系统产生裁剪标志。

    如果一个顶点缓冲不支持裁剪标志,那么我们也就没有办法再为它产生裁剪标志了。尝试使用IDirect3DVertexBuffer::ProcessVertices方法来为它产生裁剪标志会在调试时出现错误,会得到一个D3DERR_INVALIDVERTEXFORMAT错误标志。当从一个不包含裁剪标志的transformed顶点缓冲来渲染时,渲染方法会忽略所有的裁剪请求。

     

      CreateVertexBuffer的最后一个参数用来提供给将来的COM聚合特性使用。目前,它是不支持聚合的,因此这个参数应该被设定为NULL

     

      下面是创建一个顶点缓冲的例子:


    /*
    * For the purposes of this example, the g_lpD3D variable is the
    * address of an IDirect3D3 interface exposed by a Direct3D
    * object, and the fIsAHardwareDevice variable is a BOOL variable
    * that is assumed to be set during application initialization.
    */

    D3DVERTEXBUFFERDESC vbdesc;
    ZeroMemory(&vbdesc, sizeof(D3DVERTEXBUFFERDESC));
    vbdesc.dwSize = sizeof(D3DVERTEXBUFFERDESC);
    vbdesc.dwCaps = 0L;
    vbdesc.dwFVF = D3DFVF_VERTEX;
    vbdesc.dwNumVertices = NUM_FLAG_VERTICES;

    // If this isn't a hardware device, make sure the
    // vertex buffer uses system memory.
    if( !fIsAHardwareDevice )
     vbdesc.dwCaps |= D3DVBCAPS_SYSTEMMEMORY;

    // Create a clipping-capable vertex buffer.
    if(FAILED(g_lpD3D->CreateVertexBuffer(&vbdesc,&g_pvbVertexBuffer, 0L,NULL)))
     return E_FAIL;

     

     

    4.2 访问顶点缓冲内存

     

      顶点缓冲对象允许程序直接访问放置顶点数据的内存空间。调用

    IDirect3DVertexBuffer::Lock方法可以得到一个指向顶点缓冲内存的指针,然后,可以根据需要访问内存,将新数据添入缓冲器,或者读出其中包含的数据。

     

      IDirect3DVertexBuffer::Lock方法有3个参数。第一个参数是dwFlags,它通知系统内存应该如何被锁定,还被用来提示程序将如何访问缓冲器中的数据。(可以提示只读或只写访问,这样就允许驱动器将内存锁定,从而为所需的访问类型提供最佳的性能。这些提示并不是必需的,但却能在一定程度上提高内存访问的性能。)由于顶点缓冲使用DirectDrawSurface对象来包含顶点数据,因此IDirect3DVertexBuffer::Lock方法接受的标志就与IDirectDrawSurface4::Lock方法接受的标志是一样的,并且有相同的结果。

     

      第二参数是

    lplpData,它是一个LPVOID变量的地址,如果调用成功的话,变量就会包含一个指向顶点缓冲内存的指针。最后一个参数是lpdwSize,它也是一个变量的地址,这个变量包含了缓冲器的大小(字节形式)。如果程序不需要有关缓冲大小的信息的话,可以将lpdwSize设置为NULL

    性能注释

    :如果程序只从顶点缓冲内存中读数据,可以使用DDLOCK_READONLY标志。使用这个标志可以使Direct3D优化它的内部程序以提高效率,也就是只对内存进行只读访问。我们也可以对使用DDLOCK_READONLY标志的锁定的内存进行写操作,但是这样会得到难以预料的结果。另外,试图从一个使用D3DVBCAPS_WRITEONLY标志创建的顶点缓冲中读出数据会非常的慢,即使你将缓冲器锁定为只读访问。

      顶点缓冲内存本身只是一个很简单的顶点数组,它们以可塑

    (flexible)顶点格式来进行声明。如果程序使用遗留的顶点结构体D3DVERTEXD3DLVERTEXD3DTLVERTEX,那么跨距(stride)就是结构体的大小(字节形式)。如果使用不同于遗留格式的顶点格式,那么就要使用你所定义的顶点格式结构体的跨距。可以通过检查顶点缓冲描述中的可塑(flexible)顶点格式标志来计算每个顶点的跨距。下表显示了每种顶点成分的大小:

     

    顶点格式标志

    大小

    D3DFVF_DIFFUSE

    sizeof(DWORD)

    D3DFVF_NORMAL

    sizeof(float) × 3

    D3DFVF_SPECULAR

    sizeof(DWORD)

    D3DFVF_TEXn

    sizeof(float) × 2 × n

    D3DFVF_XYZ

    sizeof(float) × 3

    D3DFVF_XYZRHW

    sizeof(float) × 4

     

      顶点格式中纹理坐标的序号用

    D3DFVF_TEXn标志来表示(n08

    )。由于每个纹理坐标设置都占用两个浮点变量的空间,因此将一个纹理坐标设置所占的大小乘以纹理坐标设置的序号,就得到了这一纹理坐标设置所占用的内存的大小。

      根据具体的顶点的需要,我们将内存指针加上或者减去顶点跨距的总和。

     

     

    4.3 处理顶点

     

      处理顶点缓冲中的顶点时,可以使用设备的当前变换矩阵,也可以随意的使用其它顶点操作,如光线处理、产生裁剪标志以及修正范围(

    updating extent)等等。IDirect3DVertexBuffer接口提供了IDirect3DVertexBuffer::ProcessVertices方法来处理顶点。

     

     

      当我们要将一个源顶点缓冲中的顶点处理到一个目的顶点缓冲中时,我们应该调用目的缓冲器的

    ProcessVertices方法,而不是源顶点缓冲该方法。这个方法有7个参数,它们分别用来描述要执行的操作、源缓冲器的IDirect3DVertexBuffer

    接口的位置、执行顶点操作的渲染设备、以及方法所指向的顶点的位置及数量。调用之后,目的缓冲器中就包含了处理过的顶点,而源缓冲器中的内容没有变化。

     

      准备处理顶顶点时,先设置第一个参数

    dwVertexOp,指明想要执行的顶点操作。必需包含D3DVOP_TRANSFORM标志,否则方法将会调用失败,但是剩下的操作都是可选的。在处理时,可以包含其它可选标志,光线处理、产生裁剪标志、修正范围(update extent

    )等等,的任意的组合。

     

      第二和第三个参数,

    dwDestIndexdwCount,反映了目的缓冲器中的索引以及要进行处理的顶点的总数。第四个参数,lpSrcBuffer,应该被设置为包含源顶点的顶点缓冲对象的IDirect3DVertexBuffer接口的地址。dwSrcIndex声明了方法开始处理顶点时所用的索引。(源顶点的总数隐含在dwCount参数中。)lpD3DDevice参数应该被设定为进行顶点处理的渲染设备的IDirect3DDevice3接口的地址。最后一个参数是为了将来使用而保留的,应该被设定为0

     

      在创建顶点缓冲时要注意使用一致的顶点格式。至少源顶点缓冲应该包含

    untransformed顶点(使用缓冲器描述中的D3DFVF_XYZ 标志),目的缓冲器应该包含transformed顶点(使用D3DFVF_XYZRHW

    标志)。另外,光线处理或裁剪处理都应有适当的作用域。例如,当顶点格式不包含顶点法向量时,就不需要进行光线处理。同样的,如果一个目的缓冲器没有裁剪能力,我们也不能要求对它产生裁剪标志。任何不兼容的操作都会在调试时出现错误。

      当源或目的缓冲器被锁定时,不能进行顶点处理。

     

     

     

    4.4 优化顶点缓冲

      对顶点缓冲进行优化可以使系统调整缓冲器的内容,使得在处理或渲染顶点时能有更好的性能。顶点如何来进行优化与具体的平台有关,并有不同的变化。因此,我们不能锁定或者另外访问一个优化了的顶点缓冲的内容。

     

      调用

    IDirect3DVertexBuffer::Optimize方法来进行顶点缓冲的优化。IDirect3DVertexBuffer::Optimize方法有两个参数,但是只有一个是可用的。lpD3DDevice参数应该被设定为进行顶点优化的设备的地址,另一个参数应该设定为0。锁定的顶点缓冲不能进行优化。

     

      通过顶点优化可以提高程序的性能。但是,经过优化的顶点缓冲只能用来进行静态几何处理(

    static geometry),这是因为,一旦缓冲器进行了优化,我们就不能锁定它来改变优化的内容了。缓冲器经过优化之后,只能使用IDirect3DVertexBuffer::ProcessVertices方法和顶点缓冲渲染方法。

     

     

    4.5   从顶点缓冲开始渲染

    4.5   从顶点缓冲开始渲染

     

      我们在“渲染”部分中曾经讨论过,

    IDirect3DDevice3接口中包含了从顶点缓冲渲染图元的方法。这些方法与接口中的其它渲染方法的工作方式是一样的,但是使用的参数是不同的。

    4.5.1 关于顶点缓冲渲染 4.5.2 调用顶点缓冲渲染方法

     

    调用顶点缓冲渲染方法

     

     

     

    4.5.1 关于顶点缓冲渲染

     

      一般有两种情况我们要使用顶点缓冲进行渲染。从最基本的层次来讲,这两种情况根据顶点缓冲中顶点的类型来进行分类,但是间接上,程序使用的过程也决定了何时使用顶点和渲染操作。下图中展示了从一个

    untransformed顶点缓冲来进行渲染的过程。

    pic93.gif (8106 bytes)

     

      如上图所示,

    IDirect3DDevice3::DrawPrimitiveVBIDirect3DDevice3::DrawIndexedPrimitiveVB方法有能力从一个non-transformed顶点缓冲来进行渲染。这样,每次调用一个渲染方法时,系统就执行顶点和渲染操作。对于DirectX 6.0,使用这种方法并不比使用传统的DrawPrimitive渲染方法能提高多少性能,但是,它却更适于某些情况。如果可能的话,我们可以通过重新利用transformed顶点数据来进行性能优化,如下图所示:

    pic94.gif (15782 bytes)

     

     

     

      在这种情况下,程序创建了两个顶点缓冲:一个用于

    untransformed几何处理,另一个用于transformed几何处理。当调用IDirect3DVertexBuffer::ProcessVertices方法时,第二个顶点缓冲接收到transformed顶点数据。ProcessVertices方法从源缓冲器中读出顶点,对它们执行所需的顶点操作,并将结果放置在目的缓冲器中。你可以对transformed顶点调用与untransformed顶点同样的渲染方法。但是,与untransformed顶点不同的是,Direct3D自动检验顶点缓冲中的顶点是transformed

    ,然后传递给光栅。通过减少不必要的变换使性能消耗达到最小。

    有关优化的详细内容见“优化顶点缓冲”。

     

     

     

    4.5.2 调用顶点缓冲渲染方法

      IDirect3DDevice3::DrawPrimitiveVB方法与IDirect3DDevice3::DrawPrimitive方法相对应。DrawPrimitiveVB方法假定顶点以它在顶点缓冲中的连续的顺序。

     

      DrawPrimitiveVB方法有5个参数。使用D3DPRIMITIVETYPE枚举类型的成员来设置d3dptPrimitiveType参数,它用来指明正在被渲染的图元的类型。第二个参数lpd3dVertexBuffer用来声明包含顶点的顶点缓冲的地址,然后设置dwStartVertexdwNumVertices参数的值,它们分别表示要进行渲染的第一个顶点和顶点的总数。我们并不一定要渲染缓冲器中所有的顶点,但是必须使用与图元类型(在D3DPRIMITIVETYPE中)相符的顶点类型。最后一个参数是dwFlags,它用来决定渲染行为。这里使用的标志与其它渲染方法使用的标志是一样的。我们可以通过设置标志来打开光线和裁剪处理,或者在渲染时更新视口的内容。

     

      IDirect3DDevice3::DrawIndexedPrimitiveVB方法通过索引使用顶点缓冲中的顶点来绘制图元。它的第一、第二个参数与DrawPrimitiveVB方法的参数相同。第三个参数lpwIndices,是一个有顺序的WORD索引数组,函数用它来访问要被渲染的顶点。第四个参数dwIndexCount,是数组包含的索引值的总数。dwFlags参数与DrawPrimitiveVB

    方法中相应的参数相同。

     

      如果缓冲器中的顶点格式不包含顶点法向量的话,那我们也就不能要求顶点画缓冲器渲染方法来执行光线操作。同样的,当我们从一个由

    D3DDP_DONOTCLIP标志创建的transformed顶点缓冲进行渲染时,我们也不能要求渲染方法对顶点进行裁剪。(对于untransformed

    顶点缓冲,允许进行裁剪操作。)如果我们要求了无效的操作,不会在调试编译阶段出现失败,但是操作将不会得到执行。

     

      一个软件渲染设备只能从以

    D3DVBCAPS_SYSTEMMEMORY

    标志创建的顶点缓冲来进行渲染。详细内容,请参看“顶点缓冲与设备类型”。

     

     

     

    4.6 获得顶点缓冲描述

      在运行时,程序往往需要得到已经存在的顶点缓冲的信息。这时,我们可以使用IDirect3DVertexBuffer::GetVertexBufferDesc方法。使用顶点缓冲的IDirect3DVertexBuffer接口来调用这个方法可以得到缓冲器的描述。

      GetVertexBufferDesc只有一个参数:一个正确初始化的D3DVERTEXBUFFERDESC结构的地址。要初始化这个结构体,要将dwSize设置为结构体的大小(字节形式),将其他成员都设置为0

    。函数返回后,结构体中就包含了有关顶点缓冲的能力、缓冲器中顶点的格式以及顶点总数等信息。

    注:在D3DVERTEXBUFFERDESC结构的dwFlags成员中设置D3DVBCAPS_OPTIMIZED能力标志可以优化一个顶点缓冲。如果设置了这个能力标志,缓冲器就不能被锁定了,并且它的内容将只对渲染方法和IDirect3DVertexBuffer::ProcessVertices方法有效。

     

    展开全文
  • 深度缓冲

    2019-03-21 14:28:40
    深度缓冲深度缓冲区是Direct3D用来存储绘制到屏幕上每一个像素点的深度信息的—块内存缓冲区。 它为每个像素存储一个深度值(z值),这个深度值是从摄像机到对应该像素点的顶点之间的距离。 深度缓冲区的大小...

    深度缓冲区

    深度缓冲区是Direct3D用来存储绘制到屏幕上每一个像素点的深度信息的—块内存缓冲区。

    它为每个像素存储一个深度值(z值),这个深度值是从摄像机到对应该像素点的顶点之间的距离。

    深度缓冲区的大小和颜色缓冲区(Frame Buffer)的大小一致。

    例如:

    如果要绘制一个640×480分辨率的图片,则在深度缓冲区中就将存储640×480个深度信息。

    深度缓冲区的格式决定着深度测试的精确性,一个24位的深度缓冲区比16位的深度缓冲区更为精确。

    通常应用程序在24位的深度缓冲区下就能得到比较精确的结果。Direct3D最高可以支持32位的深度缓冲区。

    并不是所有的硬件都能支持32位的深度缓冲区。在确定深度缓冲区的格式之前,需要检查硬件支持的深度缓冲区格式。

    深度缓冲区格式
    深度缓冲区格式 描述

    D3DFMT_D32

    32位的深度缓冲区

    D3DFMT_D15S1

    15位的深度缓冲区和1位的模版缓冲区

    D3DFMT_D24S8

    32位的深度缓冲区,24位存储深度值,8位存储模板值

    D3DFMT_D24X8

    32位的深度缓冲区,24位存储深度值,8位保留位

    D3DFMT_D24X4S4

    32位的深度缓冲区,24位存储深度值,4位存储模板值,4位保留位

    D3DFMT_D16

    16位的深度缓冲区

    检查硬件支持的缓冲区格式

    并不是所有的硬件都能支持32位的深度缓冲区。在确定深度缓冲区的格式之前,需要检查硬件支持的深度缓冲区格式。

    D3DDISPLAYMODE d3ddm;
    if(FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))//通过引擎指针获得显卡的显示模式的结构体都d3ddm并通过检测它的格式支持几位
    	return false;
    //选择深度缓冲区格式
    if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE, D3DFMT_D32) == D3D_OK)
    //选择32位深度缓冲区
    {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
        d3dpp.EnableAutoDepthStencil = TRUE;
    }
    else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
    	d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8) == D3D_OK)
    {//选择24位深度缓冲区
    	d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
        	d3dpp.EnableAutoDepthStencil = TRUE;
    }
    else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
    	d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16) == D3D_OK)
    {//选择16位深度缓冲区
    	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
        	d3dpp.EnableAutoDepthStencil = TRUE;
    }
    Else{
        d3dpp.EnableAutoDepthStencil = FALSE;
    }
    

    深度测试

    Direct3D通过比较当前绘制的像素点的深度和对应深度缓冲区的点的深度值来决定是否绘制当前像素。如果深度测试为TRUE,则绘制当前像素,并用当前像素点深度值更新深度缓冲区,反之则不予绘制。

    深度缓冲能确定哪个对象在前,哪一个对象在后,从而正确的渲染对象。

    深度测试的算法有很多种,并不是只能设置深度值小的点通过深度测试,Direct3D中可以由程序员选择需要的深度测试算法。调用IDirect3DDevice9::SetRenderState()函数设置深度测试函数,将第一个参数设为D3DRS_ZFUNC,第二个参数设为想要设置的深度测试算法,它属于D3DCMPFUNC枚举类型。

    typedef enum _D3DCMPFUNC {
        D3DCMP_NEVER = 1,     	 //深度测试函数总是返回FALSE
        D3DCMP_LESS = 2,         	//测试点深度值小于深度缓冲的值时返回TRUE
        D3DCMP_EQUAL = 3,    	 //测试点深度值等于深度缓冲的值时返回TRUE
        D3DCMP_LESSEQUAL = 4,	//测试点深度值小于等于深度缓冲的值时返回TRUE
        D3DCMP_GREATER = 5,	//测试点深度值大于深度缓冲的值时返回TRUE
        D3DCMP_NOTEQUAL = 6, 	//测试点深度值不等于深度缓冲的值时返回TRUE
        D3DCMP_GREATEREQUAL = 7, //测试点深度值大于等于深度缓冲的值时返回TRUE
        D3DCMP_ALWAYS = 8,	//深度测试函数总是返回TRUE
        D3DCMP_FORCE_DWORD = 0x7fffffff
    } D3DCMPFUNC;
    

    通常情况下,深度测试算法总是设置为D3DCMP_LESS,表示当测试点深度值小于深度缓冲中的相应值时返回TRUE,即距离摄像机更近的点通过深度测试并绘制相应的像素点

    // g_pDevice为有效的Direct3D设备
    g_pDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESS );
    

    深度缓冲的使用

    为了正确地绘制场景中的物体需要使用深度缓冲。一般按照一下步骤就可以实现:

    1)创建深度缓冲区

    若要在Direct3D图形程序中应用深度测试,首先必须在创建Direct3D渲染设备时创建深度缓冲区,并设置深度缓冲区的格式。

        // 表示由Direct3D创建并管理一个深度缓冲区
        d3dpp.EnableAutoDepthStencil  = true;
        //深度缓冲区的每一个像素由16位的整数值表示
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
        //在d3dpp是设备参数结构体的实例 ,可用检查硬件支持的缓冲区格式代替
    

    2)激活深度测试

    Direct3D渲染设备创建好后,调用Direct3D中渲染状态设置的函数,SetRenderState()来激活深度测试。

    // g_pd3dDevice为有效的D3D设备
    g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    

    3)设置深度测试函数

    调用IDirect3DDevice9::SetRenderState()设置深度测试函数,将第一个参数设为D3DRS_ZFUNC,第二个参数设为想要设置的深度测试算法。

    // g_pd3dDevice为有效的Direct3D设备
    g_pd3dDevice ->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESS );
    

    4)设置深度缓冲区更新

    设置了深度测试函数后,还需要设置深度测试成功时对深度缓冲区如何操作,是保持原来的深度值,还是用当前像素的深度值更新对应的数值。

    调用函数SetRenderState()设置深度缓冲区的更新,将第一个参数设为D3DRS_ZWRITEENABLE,第二个参数设为TRUE,表示允许应用程序在绘制像素时更新深度缓冲区。

    // 设置深度缓冲区更新
    g_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
    

    5)清空深度缓冲区

    因为场景内的物体是可以动得,另外摄像机也可以随便移动,所以物体的深度值是在不停的更新的。所以在绘制图形之前,把深度缓冲区全部清空一次,以便于重新更新图形的深度。

    g_pd3dDevice->Clear(0,0,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0xffffffff,1.0f,0.0f)
    

     

    展开全文
  • 深度以及深度缓冲区什么是深度什么是深度缓冲区为什么需要深度缓冲区深度测试:ZFighting 闪烁问题的原因使用深度测试:开启深度测试:在绘制场景时,清除颜色缓存区,深度缓冲 什么是深度 深度其实就是该像素点在3D...

    什么是深度

    深度其实就是该像素点在3D世界中距离摄像机的距离、 Z值

    什么是深度缓冲区

    深度缓冲区,就是一块内存区域,专门存储每个像素点(绘制在屏幕上的点)深度值、深度值(z值)越大,离摄像机就越远

    为什么需要深度缓冲区

    在不使用深度缓冲区测试的时候,如果我们先绘制一个距离比较近物体,再绘制一个距离比较远的物体,那么后绘制的物体就会挡住前面绘制的物体,但是有了深度缓冲区之后,物体的绘制顺序就不那么重要了

    深度测试:

    深度缓冲区和颜色缓冲区是一一对应的,颜色缓冲区存储像素的颜色信息。而深度缓冲区储存像素的深度信息,在决定是否绘制一个物体表面时,首先要将表面对应的像素的深度值与当前的深度缓冲区的值进行比较。如果大于深度缓冲区的值,说明是离得比较远的,则丢弃这部分,否则利用这个像素对应的深度只和颜色值,分别更新深度缓冲区和颜色缓冲区。这个过程叫深度测试

    
    

    ZFighting 闪烁问题的原因

    因为开启深度测试后,OpenGL就不会再去绘制模型被遮挡的部分,这样实现的显示更加真实,但是由于深度缓冲区精度的限制对于深度相差非常小的情况下(例如在同一平面上进行2次绘制),OpenGL就可能出现不能正确判断两者的深度值,会导致深度测试的结果不可预测,显示出来的现象是交错闪烁,也就是像个画面,交错出现
    在这里插入图片描述

    使用深度测试:

    深度缓冲区,一般由窗口管理系统,GLFW创建,深度值一般由16位,24位,32位值表示。通常是24位,位数越高,深度精确度越好

    开启深度测试:

    glEnable(GL_DEPTH, TEST);
    

    在绘制场景时,清除颜色缓存区,深度缓冲

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR, BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    

    清除深度缓冲区默认值为1.0,表示最大的深度值,深度值的范围为(0,1)之间,值越小表示越靠近观察者,值越大表示越远离观察者

    展开全文
  • 深度缓冲区:与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确。(注意区分深度测试和背面剔除)模板缓冲区:与深度缓冲区类似,通过...
    • 颜色缓冲区:就是帧缓冲区(图形设备的内存),需要渲染的场景的每一个像素都最终写入该缓冲区,然后由他渲染到屏幕上显示。

    • 深度缓冲区:与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确。(注意区分深度测试和背面剔除)

    • 模板缓冲区:与深度缓冲区类似,通过设置模板缓冲每个像素的值,我们可以在渲染的时候只渲染后写模板缓存对应的值,从而在后续的其他绘制可以通过配置模板缓存的参数来决定是否丢弃该片元和如何操作对应该片段对应的模板缓存值。
      模板缓冲区可以为屏幕上的每个像素点保存一个无符号的整数值,在渲染过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值。模板测试发生在透明度测试之后,深度测试之前,如果模板测试通过,则相应的像素点更新,否则不更新。

    • 累积缓冲区:允许在渲染到颜色缓冲区之后,不是把结果显示到窗口上,而是把内容复制到累积缓冲区,这样就可以把颜色缓冲区与累积缓冲区中的内容反复进行混合,可以用来进行模糊处理和抗锯齿。

    以上的总结部分转于,且部分在此基础上做了调整:颜色缓冲区、深度缓冲区、模板缓冲区和累积缓冲区

    于是有了自己的总结:
    在这里插入图片描述

    展开全文
  • 第一篇 【颜色缓冲区】 ... 深度缓冲区(DEPTH_BUFFER)与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确. 【模板缓冲区】  ...
  • OpenGL学习笔记:深度缓冲

    万次阅读 2019-09-09 17:24:11
    我们观察空间中的两个物体,后面的物体被前面的物体挡住,我们是看不到被挡住的部分的,而深度缓冲可以简单理解为就是标识这个“前后”的值。 缓冲测试 OpenGL是一个3D世界,但显示设备通常是2D的。前面介绍过,要将...
  • 深度缓冲是一个表面(表面是一个像素点阵,用于存储2D图形数据),用于记录一个像素的深度信息 前缓冲与后缓冲用于交换链,由于应用程序的帧率与显示器的刷新速度不同,为了显示全部帧动画,在前缓冲的帧数据显示之后...
  • 深度缓冲详解(DepthBuffer)

    万次阅读 2018-05-16 11:42:02
    1. 深度缓冲概念 深度缓冲区与帧缓冲区相对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确。 2. 何为深度 深度其实就是该象素点在3d世界中...
  • 深度缓冲是可选的,如果要绘制3D图形,可使用深度缓冲。即使交换链以后多个图像,也只需要一个深度缓冲,因为深度缓冲在绘制交换链的每个图片时,深度缓冲是可重用的。 与交换链不同,交换链是Vulkan创建内存,深度...
  • Unity深度缓冲区指令

    2021-01-05 14:52:30
    每个顶点的深度信息,在光栅化阶段被差值,并写入到深度缓冲中。 ZWrite 默认ZWrite On ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Never | Always Offset 深度偏移 Offset Factor, Units 深度...
  • opengl深度缓冲

    千次阅读 2017-02-26 12:07:50
    深度缓冲是一个与你的渲染目标(render target)相同大小的缓冲,这个缓冲记录每个像素的深度。当一个像素第二次被绘制时– 例如当一个物体在另一个物体之后被绘制-深度缓冲要么保留前面的深度值,要么使用第二个...
  • webgl 中渲染到纹理需要用到帧缓冲区,但是同时想使用深度缓冲区和模板缓冲区需要的步骤如下,直接上代码 var width = 800; var height = 600; //创建帧缓冲区对象 var frameBuffer = gl.createFramebuffer();
  • OpenGL的深度缓冲区 什么是深度缓冲区 所谓深度,就是在openGL坐标系中,像素点Z坐标距离摄像机的距离。摄像机可能放在坐标系的任何位置,那么,就不能简单的说Z数值越大或越小,就是越靠近摄像机。 深度缓存区,就是...
  • OpenGL: 深度缓冲区-Z缓冲区

    千次阅读 2014-02-26 20:37:56
    深度缓冲区】 深度缓冲区(DEPTH_BUFFER)与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确.【模板缓冲区】 模版缓冲(STENCIL
  • C++ opengl 深度缓冲

    千次阅读 2018-07-27 23:23:07
    GL_DEPTH_BUFFER_BIT 每一次清除之前,都要清空深度缓冲区 启动深度测试glEnable(GL_DEPTH_TEST):离视野近的物体会挡住离视野远的物体。   运行截图如下: 源码如下: void Init() { glMatrixMode(GL_...
  • Vulkan【7】创建深度缓冲

    千次阅读 2018-08-23 14:53:54
    创建深度缓冲区 本节的代码是 06-init_depth_buffer.cpp 深度缓冲区是可选的,但在示例最后渲染3D方块时,你需要一个深度缓冲区。而且在渲染每帧时,你只需要一个,即使交换链里有不止一个图像。因为深度缓冲区在...
  • 对数深度缓冲

    2010-01-14 03:02:00
    在超大型场景下,远近裁剪平面一半要很远的距离,使用普通的深度缓冲经常会因为误差,造成一些很难看的锯齿,本来不相交的图元相互穿透,Z-fighting等现象。 普通的Z/W深度缓冲,深度值不是线性的。在近处,深度...
  • opengl深度缓冲区简介

    千次阅读 2013-08-31 17:19:32
    【颜色缓冲区】 ... 深度缓冲区(DEPTH_BUFFER)与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确. 【模板缓冲区】
  • 深度缓冲: 绘制多个图像时,会按顺序进行绘制并显示,而不是按空间坐标的关系,有两种方式可以解决这个问题: • 按照深度坐标对绘制调用进行排序 • 使用深度测试 通常我们使用第一种方式来绘制需要透明的对象。使用...
  • 2.深度缓冲区原理:就是把一个距离观察平面,也就是所谓的近裁剪面的深度值与窗口中每一个像素关联起来,这个深度值我么哦你吧它存储在一个统一的缓冲区中,那么这个缓冲区就被称为深度缓冲区。 3.深度值的产生过程...
  • 如果不使用深度缓冲,创建的立方体的某些本应被遮挡住的面被绘制在了这个立方体其他面之上。OpenGL是一个三角形一个三角形地来绘制你的立方体的,所以即便之前那里有东西它也会覆盖之前的像素。因为这个原因,有些...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 58,236
精华内容 23,294
关键字:

深度缓冲