ShaderProgramPrePreprocessor.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. return shaderSources[type];
  64. }
  65. XfbBufferMode getXfbBufferMode() const
  66. {
  67. return xfbBufferMode;
  68. }
  69. /// @}
  70. protected:
  71. /// The pragma base class
  72. struct Pragma
  73. {
  74. I32 definedLine = -1;
  75. Bool isDefined() const
  76. {
  77. return definedLine != -1;
  78. }
  79. };
  80. struct CodeBeginningPragma: Pragma
  81. {};
  82. /// Names and and ids for transform feedback varyings
  83. StringList trffbVaryings;
  84. XfbBufferMode xfbBufferMode = XFBBM_NONE;
  85. Array<std::string, ST_NUM> shaderSources;
  86. /// The parseFileForPragmas fills this
  87. StringList sourceLines;
  88. Array<CodeBeginningPragma, ST_NUM> shaderStarts;
  89. /// Parse a PrePreprocessor formated GLSL file. Use the accessors to get
  90. /// the output
  91. ///
  92. /// @param filename The file to parse
  93. /// @exception Ecxeption
  94. void parseFile(const char* filename);
  95. /// Called by parseFile
  96. void parseFileInternal(const char* filename);
  97. /// A recursive function that parses a file for pragmas and updates the
  98. /// output
  99. ///
  100. /// @param filename The file to parse
  101. /// @param depth The #line in GLSL does not support filename so an
  102. /// depth it being used. It also tracks the includance depth
  103. /// @exception Exception
  104. void parseFileForPragmas(const std::string& filename, U32 depth = 0);
  105. /// Self explanatory
  106. void parseStartPragma(U32 shaderType, const std::string& line);
  107. void printSourceLines() const; ///< For debugging
  108. };
  109. } // end namespace anki
  110. #endif