Monthly Archives: 

八月 2017

好玩的shader制作分享

前几天无聊随便写了几个shader来玩,觉得跳动的心和跳动的名字还是挺有趣的,做个代码分享吧。

跳动的心fragment shader:

 

跳动的名字跟跳动的心思路是一样的,不一样的地方是使用了图片来做mask命中判断,并抠掉了原来图片像素所在的颜色。

跳动的名字fragment shader

 

STL揭秘之外覆器integral_constant

首先上代码:

代码很简单,它只做了几件事:

  1. 定义了一个_TP类型的value成员变量并赋值为__v
  2. 用typedef声明了value_type和type
  3. 重载了value_type和()操作符

使用起来就像下面这样:

它其实就是一个常量包装类,看起来它似乎没什么用,比直接使用常量繁琐多了,那么我们究竟可以用它来做啥呢?

实际上对于模板元编程来说,它的用处可大了,在STL里面到处都是它的身影,我们来看一下type_traits里面定义的非常重要的两个integral_constant类型:

true_type即是常量true的包装类,false_type即是常量false的包装类。它们跟原来的常量最大的区别就是它们是类类型,我们可以通过继承来使用它们,例如:

到目前为止还是挺无聊的,但是我们别忘了,模板元编程是拥有编译期选择的特性的,接下来就开始变得有趣起来了:

我们通过简单的几行代码就实现了编译期两个类型是否一致的判断,下面我们就可以来尝试一下:

我们再来看下is_integral的实现:

我们现在可以在编译期判断一个类型是否为数值类型了呢,是不是很有趣!

它的用法还不止这些,还记得我们上一篇STL揭秘之编译期纯虚类判断__is_abstract_imp吗,实际它的完整实现是这样的:

is_abstract继承了__libcpp_abstract,__libcpp_abstract做了一次偏特化,当is_class<_TP>::value为false时它继承的是false_type,为true是它继承的是integral_constant<bool, sizeof(__is_abstract_imp::__test<_Tp>(0)) != 1>类型,并且它通过sizeof(__is_abstract_imp::__test<_Tp>(0)) != 1的编译期判断来动态的选择继承的是integral_constant<bool, false>还是integral_constant<bool, true>,于是,我们就能够使用is_abstract来在编译期判断一个类型是否为纯虚类了:

type_traits在基于integral_constant上还做了非常多的编译期判断实现,例如is_const,is_function,is_enum,is_member_pointer,is_member_function_pointer等等,有兴趣的小伙伴们也可以去看一下:)