ShaderProgramPrePreprocessor.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #ifndef ANKI_RESOURCE_SHADER_PROGRAM_PRE_PREPROCESSOR_H
  2. #define ANKI_RESOURCE_SHADER_PROGRAM_PRE_PREPROCESSOR_H
  3. #include "anki/util/Vector.h"
  4. #include "anki/util/StdTypes.h"
  5. #include "anki/util/StringList.h"
  6. #include "anki/util/Array.h"
  7. #include <limits>
  8. namespace anki {
  9. /// Shader type
  10. enum ShaderType
  11. {
  12. ST_VERTEX,
  13. ST_TC,
  14. ST_TE,
  15. ST_GEOMETRY,
  16. ST_FRAGMENT,
  17. ST_COMPUTE,
  18. ST_NUM
  19. };
  20. /// Helper class used for shader program loading
  21. ///
  22. /// The class fills some of the GLSL spec deficiencies. It adds the include
  23. /// preprocessor directive and the support to have all the shaders in the same
  24. /// file. The file that includes all the shaders is called
  25. /// PrePreprocessor-compatible.
  26. ///
  27. /// The preprocessor pragmas are:
  28. ///
  29. /// - #pragma anki start <vertexShader | tcShader | teShader |
  30. /// geometryShader | fragmentShader | computeShader>
  31. /// - #pragma anki include "<filename>"
  32. /// - #pragma anki transformFeedbackVaryings <separate|interleaved>
  33. /// <varName> <varName>
  34. ///
  35. /// @note The order of the "#pragma anki start" is important
  36. class ShaderProgramPrePreprocessor
  37. {
  38. public:
  39. enum XfbBufferMode
  40. {
  41. XFBBM_NONE,
  42. XFBBM_INTERLEAVED,
  43. XFBBM_SEPARATE
  44. };
  45. /// It loads a file and parses it
  46. /// @param[in] filename The file to load
  47. /// @exception Exception
  48. ShaderProgramPrePreprocessor(const char* filename)
  49. {
  50. parseFile(filename);
  51. }
  52. /// Destructor does nothing
  53. ~ShaderProgramPrePreprocessor()
  54. {}
  55. /// @name Accessors
  56. /// @{
  57. const StringList& getTranformFeedbackVaryings() const
  58. {
  59. return trffbVaryings;
  60. }
  61. const std::string& getShaderSource(ShaderType type)
  62. {
  63. if((type == ST_TC || type == ST_TE) && !enableTess)
  64. {
  65. return emptyString;
  66. }
  67. else
  68. {
  69. return shaderSources[type];
  70. }
  71. }
  72. XfbBufferMode getXfbBufferMode() const
  73. {
  74. return xfbBufferMode;
  75. }
  76. /// @}
  77. protected:
  78. /// The pragma base class
  79. struct Pragma
  80. {
  81. I32 definedLine = -1;
  82. Bool isDefined() const
  83. {
  84. return definedLine != -1;
  85. }
  86. };
  87. struct CodeBeginningPragma: Pragma
  88. {};
  89. /// Names and and ids for transform feedback varyings
  90. StringList trffbVaryings;
  91. XfbBufferMode xfbBufferMode = XFBBM_NONE;
  92. Array<std::string, ST_NUM> shaderSources;
  93. /// The parseFileForPragmas fills this
  94. StringList sourceLines;
  95. Array<CodeBeginningPragma, ST_NUM> shaderStarts;
  96. Bool enableTess = true;
  97. std::string emptyString;
  98. /// Parse a PrePreprocessor formated GLSL file. Use the accessors to get
  99. /// the output
  100. ///
  101. /// @param filename The file to parse
  102. /// @exception Ecxeption
  103. void parseFile(const char* filename);
  104. /// Called by parseFile
  105. void parseFileInternal(const char* filename);
  106. /// A recursive function that parses a file for pragmas and updates the
  107. /// output
  108. ///
  109. /// @param filename The file to parse
  110. /// @param depth The #line in GLSL does not support filename so an
  111. /// depth it being used. It also tracks the includance depth
  112. /// @exception Exception
  113. void parseFileForPragmas(const std::string& filename, U32 depth = 0);
  114. /// Self explanatory
  115. void parseStartPragma(U32 shaderType, const std::string& line);
  116. void printSourceLines() const; ///< For debugging
  117. };
  118. } // end namespace anki
  119. #endif