使用宏定义实现函数替换

有时候需要制作一些公用的函数供不同的需求场景使用, 以降低代码量和维护成本。

但流程里的某些函数,我们希望在某些场合替换为特定版本,以满足特定需求。

可以通过宏定义机制来完成。

  1. //example.chunk
  2. #ifndef CC_USER_MODIFY_SOMETHING
  3. void ModifySomething(){
  4. //do something here
  5. }
  6. #endif
  7. void Before(){
  8. //do something here
  9. }
  10. void After(){
  11. //do something here
  12. }
  13. void myFunc(){
  14. Before();
  15. ModifySomething();
  16. After();
  17. }

可以看到,在上面的代码中,myFunc 拥有完整的调用流程。如果想修改 ModifySomething 的实现,只需要在 #include example.chunk 之前,定义 CC_USER_MODIFY_SOMETHING 宏,并实现自己的 ModifySomething 函数即可。

  1. #define CC_USER_MODIFY_SOMETHING
  2. void ModifySomething(){
  3. //do what you want
  4. }
  5. #include <example.chunk>

注意,重载函数定义要放在 include 前面

这个机制在 Surface Shader 系统中被广泛应用,比如前面提到的 lighting-models/includes/common 中的 SurfacesFragmentModifySharedData 函数。

  1. // user-defined-common-surface.chunk:
  2. // base surface function
  3. #ifndef CC_SURFACES_FRAGMENT_MODIFY_SHARED_DATA
  4. #define CC_SURFACES_FRAGMENT_MODIFY_SHARED_DATA
  5. void SurfacesFragmentModifySharedData(inout SurfacesMaterialData surfaceData)
  6. {
  7. .................
  8. }
  9. #endif
  10. // effect
  11. // this function needs overriding
  12. #define CC_SURFACES_FRAGMENT_MODIFY_SHARED_DATA
  13. void SurfacesFragmentModifySharedData(inout SurfacesMaterialData surfaceData)
  14. {
  15. .............
  16. }
  17. // base functions should place after override functions
  18. #include <user-defined-common-surface.chunk>