zoukankan      html  css  js  c++  java
  • [D3D] DirectX SDK 2006学习笔记4——纹理

    来源:http://www.cnblogs.com/fence/archive/2010/03/12/1683918.html


      纹理在D3D中是一个非常重要的概念,它的出现改变了以前3D物体表面不真实的状况,为程序员提供了将2维图像应用到3维物体上去的功能。请做 好心理准备,因为新的概念将像暴风骤雨般的袭来,而在没有弄懂基本概念之前是不可能进行下一步的学习的。下面是一些术语的大致概念:

    • 纹理( Textrue ):将要应用到3维(或者2维)模型中的图片,可以有dds, hdr, bmp, tga, jpg, png等多种格式,各种格式可以有8位,16位,32位,64位以及128位的色彩位深
    • 纹理坐标( Textrue Coordinates ):x,y轴分别以[0,1]为区间的2维坐标。将纹理的长和宽分别认作单位1,用u和v来表示纹理上的每一个色彩的坐标。
    • 图素( Texel ):纹理上每一个色彩点称为图素。每个图素都有自己的纹理坐标。
    • 纹理寻址模式( Textrue Addressing Modes ):系统映射[0, 1] 区间以外的图素坐标的模式。纹理寻址模式共有五种,它们分别是包装纹理寻址模式、镜像纹理寻址模式、夹持纹理寻址模式,边框纹理寻址模式和一次镜像纹理寻址模式。

                     包装纹理寻址模式:D3D默认寻址模式。效果如下:

                     镜像纹理寻址模式:每两个相邻的单位纹理都是镜像效果的。如下:

                     夹持纹理寻址模式:只映射在区间[0, 1]中的纹理,然后在其他空间中涂上和纹理边界相反的颜色,如图:

                     边框颜色纹理寻址模式:在区间[0, 1]之外涂上指定颜色,例如:

                     一次镜像纹理寻址模式:纹理在[-1.0, 1.0]范围内作镜像,在该范围外作夹持。

    • 纹理包装:决定如何在纹理坐标之间做插值计算。
    • 纹 理过滤:通过给定的uv坐标从纹理贴图中获得图素的一种方法。为了抗锯齿,D3D中采用了3中技术来实现纹理过滤,它们分别是最近点采样,线性纹理过滤, 各向异性(anisotropic)纹理过滤。而现在游戏中看到的图像高级选项中,一般都有点采样、双线过滤(即D3D的线性纹理过滤),三线过滤(即 D3D中的线性过滤加上mipmap),以及各向异性过滤。

                     mipmap:由一系列纹理组成,其中每张纹理的高宽都是前一级高宽的一半。D3D在渲染时会自动挑选出一个图素与像素的比值最接近于1的mip层级。

                     最近点采样:将纹理坐标对齐到最接近的整数,再将那个位于整数坐标上的纹理像素作为最终的颜色。缺点:容易在图像边界上造成错误,优点:快。

                     线性纹理过滤:(即双线纹理过滤),计算相对于采样点最近的4各图素(上下左右4个点)的平均值。缺点:有各项异性失真可能。

                     三线过滤:对于每个像素,三线过滤会先选择两张最接近的mipmap,将它们双线过滤为两张理想大小的mipmap,然后根据理想的mip级组合这两张过滤后的mipmap中的对应像素。缺点:有各项异性失真可能。

                     各项异性过滤:根据屏幕像素的伸张度来测量各项异性,再将屏幕像素反向映射到纹理空间中。效果:在非水平的渲染时要比三线过滤更加锐化。

    • 抗锯齿:有全屏多采样和可屏蔽多采样之分。全屏多采样对每个像素进行多次采样,这些不同的样本被混合后输出到屏幕。可屏蔽多采样仅影响三角形和三角形组,不影响直线。
    • Alpha混合:可将图元颜色和先前的帧缓冲器像素的颜色组合起来,用于实现透明效果。有个很著名的alpha混合计算公式:
    FinalColor = SourceColor * SourceBlendFactor + DestColor * DestBlendFactor

          如果使SourceBlendFactor + DestBlendFactor = 1,那么就可以实现透明效果。

    • Example 1           Simple Texture & Wrap Texture Address Mode
       一个简单的贴图是很容易实现的,因为它可以简单的建立FVF基础之上,整个过程是这样的:在顶点缓冲之中添加纹理坐标信息,然后在 OnCreateDevice中添加纹理创建代码,在OnFrameRender中添加纹理的设置,最后在OnDestoryDevice中添加纹理资源 释放代码。
    定义:在顶点缓冲定义中添加纹理坐标信息
    LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Texture
    structCUSTOMVERTEX
    {
    FLOATx, y, z, rhw;
    // The transformed position for the vertex
    //DWORD color; // The vertex color, no use here
    FLOATtu, tv; // The texture coordinates
    };
    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX1)
    OnCreateDevice:添加纹理创建代码,在顶点缓冲中添加纹理坐标信息,横向复制两遍纹理
    V_RETURN( D3DXCreateTextureFromFile(pd3dDevice, L"DaNing_Hudie.jpg", &g_pTexture) );
    CUSTOMVERTEXvertices[]
    =
    {
    {
    0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,}, // x, y, z, rhw, color
    { (float)pBackBufferSurfaceDesc->Width, 0.0f, 0.5f, 1.0f, 2.0f, 0.0f,},
    { (
    float)pBackBufferSurfaceDesc->Width, (float)pBackBufferSurfaceDesc->Height, 0.5f, 1.0f, 2.0f, 1.0f,},
    {
    0.0f, (float)pBackBufferSurfaceDesc->Height, 0.5f, 1.0f, 0.0f, 1.0f, },
    };

    OnFrameRender:在BeginScene和EndScene中间添加如下代码。因为D3D默认使用包装纹理寻址模式,所以不必调用 SetSampleState来设置纹理模式。
    pd3dDevice->SetTexture( 0, g_pTexture );

    OnDestroyDevice:添加释放代码

    SAFE_RELEASE( g_pTexture);

    • Example 2           Texture Address Mode
    包装寻址模式见Example 1。接下来是镜像寻址模式。
    顶点缓冲的初始化:横向复制四遍,纵向复制两遍,一共是八个纹理单元
    CUSTOMVERTEX vertices[] =
    {
    {
    0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,}, // x, y, z, rhw, color
    { (float)pBackBufferSurfaceDesc->Width, 0.0f, 0.5f, 1.0f, 4.0f, 0.0f,},
    { (
    float)pBackBufferSurfaceDesc->Width, (float)pBackBufferSurfaceDesc->Height, 0.5f, 1.0f, 4.0f, 2.0f,},
    {
    0.0f, (float)pBackBufferSurfaceDesc->Height, 0.5f, 1.0f, 0.0f, 2.0f, },
    };

    OnFrameRender:添加在u方向和v方向的镜像纹理寻址模式代码
    pd3dDevice->SetTexture( 0, g_pTexture );
    pd3dDevice
    ->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
    pd3dDevice
    ->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
    其余函数和Example 1相同。效果如下:
    类似的夹持纹理寻址模式效果图
    边框颜色纹理寻址模式需要再加一个SetSampleState
    pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER );
    pd3dDevice
    ->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER );
    pd3dDevice
    ->SetSamplerState( 0, D3DSAMP_BORDERCOLOR, 0xff88aa66 );

    一次镜像纹理寻址模式效果,范围之外填黑色,并不是想象中的夹持@.@
    • Example 3           Texture Wrapping
    v方向上的纹理包装,在OnFrameRender添加
    pd3dDevice->SetRenderState( D3DRS_WRAP0, D3DWRAP_V );

     
    其余函数和Example 2类似
    u方向上的代码类似,效果图略
  • 相关阅读:
    第九周:关于程序的历史
    第八周
    第八周2
    关于bom和dom的概念及用法应用
    关于css中position的两个属性值sticky和fixed的不同
    css颜色表示法
    atan2(x,y)与pow(x,y)
    第9周作业
    第8周作业
    第⑦周作业
  • 原文地址:https://www.cnblogs.com/hcbin/p/1748623.html
Copyright © 2011-2022 走看看