从设计纹理类所想到的

1.平台独立

    虽然我基本思想是借助D3D来实现我的渲染器,但是可能是潮流所致,让我在设计要用到的概念时考虑了将来如果我想玩一把OPGL会怎么样.通过纹理类的设计,我想理请我的思路,也请高手指教.

    在3D渲染时所谓纹理,需要考虑四个方面( 以我的认识来看 ):

    (1)纹理的存储位置与文件名

    (2)纹理的过滤方式

    (3)纹理的寻址方式

    (4)纹理的对应采样器Unit

    提取了基本成员后,就开始考虑类的设计问题,由于我希望平台独立,因此在这个类中,我不会存放资源(这里的资源指的是LPDIRECT3DTEXTURE这样对应于D3D平台的纹理存放单元),而是设计一种资源管理机制,在DX渲染器用到某纹理时,针对纹理实例的成员内容实时的申请资源,所以,在纹理类的设计时,只需要考虑抽象的概念,具体到DX时再进行映射就可以了.

 

2.映射到DX的例子

    假设在纹理类中,我定义了一个枚举类型来表示寻址方式如下:

    enum WrapType
   {
   CLAMP,
   REPEAT,
   MIRRORED_REPEAT,
   CLAMP_BORDER,
   CLAMP_EDGE,
   MAX_WRAP_TYPES
  };

  又假设当前的寻址类型为CLAMP,那么在DX中使用SetTexture前,针对纹理寻址方式的设置可以如下编写:

  (1)在DX渲染器中定义一个对应的数组
 DWORD JLY_1DxRenderer::ms_adwTexWrapMode[JLY_1Texture::MAX_WRAP_TYPES] =
 {
  D3DTADDRESS_CLAMP,      // Texture::CLAMP
  D3DTADDRESS_WRAP,       // Texture::REPEAT
  D3DTADDRESS_MIRROR,     // Texture::MIRRORED_REPEAT
  D3DTADDRESS_BORDER,     // Texture::CLAMP_BORDER
  D3DTADDRESS_CLAMP,      // Texture::CLAMP_EDGE
 };

(2)根据纹理的相关成员进行设置

ms_hResult = m_pqDevice->SetSamplerState(iTextureUnit,
     D3DSAMP_ADDRESSU,ms_adwTexWrapMode[pkTexObj->GetWrapType(0)]);
assert(SUCCEEDED(ms_hResult));
ms_hResult = m_pqDevice->SetSamplerState(iTextureUnit,
     D3DSAMP_ADDRESSV,ms_adwTexWrapMode[pkTexObj->GetWrapType(0)]);
assert(SUCCEEDED(ms_hResult));

 

  从上面可以看见,以后如果我想把这个纹理类应用到OPGL的平台下,只需要在OPGL渲染器中写出对应的映射就可以了.当然除了纹理,像顶点缓冲,索引缓冲,Shader等资源,都可以象上面一样写成平台独立的方式,你所要做的就是两步,一,在使用这个概念的时候完成资源申请,二,在渲染器中编写映射.

 

3.纹理的Sampler Unit

  好象在这里说这个有点突兀,但是我只是想说明为什么我在纹理类中要放一个这样的成员,我在刚开始接触DX时都没有注意到采样器对于纹理来说的重要性,但是随着shader的学习我发现,很多纹理的特殊效果要是离开Sampler Unit是不可想象的,比如两个纹理的混合,如果没有正确的匹配纹理与采样器,你会很痛苦( 我就痛苦过... )

  研究过Shader的人都知道,在shader中声明sampler的顺序决定了Sampler Unit,比如:

  Sampler2D s[ 2 ];

  那么s[ 0 ]的unit = 0, 而S[ 1 ]的unit = 1;

  在程序中,如果你希望纹理设置到对应的Sampler中,在调用SetTexture时,就必须填入对应的unit,这就是为什么我要在纹理类中加一个这样的属性的原因.因为你的纹理需要知道自己到底应该跟谁携手让世界变的更美丽^^

  Enjoy!! 

 

 

 

你可能感兴趣的:(存储,border,平台,shader,Types)