|
|
现在需要设计一个纹理类(Texture).我们知道纹理是对连续信号的采样保存,然后可以通过各种方式的插值运算取得该连续信号中任意一点的值.
按照这样的要求,一个纹理类的变化点有三个:
1.纹理的维度.纹理所保存的连续信号可能是1维的,2维的也可能是3维的甚至更高.
2.纹理所保存信号的数据类型,可能是一个整数,可能是浮点数,或者是保存的矢量.
3.纹理所进行的插值方式.纹理的插值运算跟纹理的维度和纹理的数据类型都有关系.
比如一般意义上的纹理是一张图片,那么这个纹理的维度是2,数据类型是4维的浮点数(代表r,g,b,a).但也有可能存在一维纹理或三维纹理,甚至立方体或球面纹理.而且纹理的数据也不一定是颜色值.有可能是法线(用于凹凸映射的).
因为这些变化点之间互相依赖,我觉得设计一个好用的纹理类的体系来包含以上变化点很困难.下面是一般图片纹理的基本接口:
class Texture
{
public:
virtual ~Texture() = 0{}
virtual Color sampling(float x, float y);
};
sampling是对该纹理信号的任意点采样函数.给定任意的x,y值都可以返回对应点的颜色值.如上讨论,首先根据纹理的维度不同,采样的地址也不一样.如果是一维
数组,则sampling的参数只需要一个float,但如果是三维纹理,立方体纹理或球面纹理,则参数需要有3个float作为地址.因此第一个变化点会引起sampling函数的参数
类型变化.
其次,sampling的返回值不确定.一般情况下,颜色纹理返回的是Color,其中包含4个float,r,g,b,a.而如果是对法线纹理的采样,返回的则应该是个三维矢量
Vector3.因此第二个变化点会引起sampling函数的返回值类型变化.
最后,对于第三个变化点,采样插值的算法是跟变化点1,变化点2都关联的.对于不同维度,不同数据类型的纹理,插值的方式也不一样.
最后我只有把Texture分了.分成Texture1D_Color, Texture2D_Color, Texture3D_Color, Texture1D_Normal, Texture2D_Normal, Texture3D_Normal.
并且为其中每一个实现不同种类的插值算法,比如最近点采样,线性插值等.
总觉得太uglily了.请教各位高人,碰到这种设计问题该如何解决? |
|