ShaderProgramPrePreprocessor.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #ifndef ANKI_RESOURCE_SHADER_PROGRAM_PRE_PREPROCESSOR_H
  2. #define ANKI_RESOURCE_SHADER_PROGRAM_PRE_PREPROCESSOR_H
  3. #include "anki/resource/ShaderProgramCommon.h"
  4. #include "anki/util/Vector.h"
  5. #include "anki/util/StdTypes.h"
  6. #include <limits>
  7. namespace anki {
  8. /// Helper class used for shader program loading
  9. ///
  10. /// The class fills some of the GLSL spec deficiencies. It adds the include
  11. /// preprocessor directive and the support to have all the shaders in the same
  12. /// file. The file that includes all the shaders is called
  13. /// PrePreprocessor-compatible.
  14. ///
  15. /// The preprocessor pragmas are:
  16. ///
  17. /// - #pragma anki start <vertexShader | tcShader | teShader |
  18. /// geometryShader | fragmentShader>
  19. /// - #pragma anki include "<filename>"
  20. /// - #pragma anki transformFeedbackVarying <varName>
  21. ///
  22. /// @note The order of the "#pragma anki start" is important
  23. class ShaderProgramPrePreprocessor
  24. {
  25. public:
  26. /// It loads a file and parses it
  27. /// @param[in] filename The file to load
  28. /// @exception Exception
  29. ShaderProgramPrePreprocessor(const char* filename)
  30. {
  31. parseFile(filename);
  32. }
  33. /// Destructor does nothing
  34. ~ShaderProgramPrePreprocessor()
  35. {}
  36. /// @name Accessors
  37. /// @{
  38. const Vector<std::string>& getTranformFeedbackVaryings() const
  39. {
  40. return trffbVaryings;
  41. }
  42. const std::string& getShaderSource(ShaderType type)
  43. {
  44. return output.shaderSources[type];
  45. }
  46. /// @}
  47. protected:
  48. /// The pragma base class
  49. struct Pragma
  50. {
  51. I32 definedLine = -1;
  52. Bool isDefined() const
  53. {
  54. return definedLine != -1;
  55. }
  56. };
  57. struct IncludePragma: Pragma
  58. {
  59. std::string filename;
  60. };
  61. struct TrffbVaryingPragma: Pragma
  62. {
  63. StringList names;
  64. };
  65. struct CodeBeginningPragma: Pragma
  66. {};
  67. /// The output of the class packed in this struct
  68. struct Output
  69. {
  70. friend class PrePreprocessor;
  71. /// Names and and ids for transform feedback varyings
  72. Vector<TrffbVaryingPragma> trffbVaryings;
  73. Array<std::string, ST_NUM> shaderSources;
  74. };
  75. Output output; ///< The most important variable
  76. StringList trffbVaryings;
  77. /// The parseFileForPragmas fills this
  78. Vector<std::string> sourceLines;
  79. Array<CodeBeginningPragma, ST_NUM> shaderStarts;
  80. /// Parse a PrePreprocessor formated GLSL file. Use
  81. /// the accessors to get the output
  82. /// @param filename The file to parse
  83. /// @exception Ecxeption
  84. void parseFile(const char* filename);
  85. /// A recursive function that parses a file for pragmas and updates
  86. /// the output
  87. /// @param filename The file to parse
  88. /// @param depth The #line in GLSL does not support filename so an
  89. /// depth it being used. It also tracks the
  90. /// includance depth
  91. /// @exception Exception
  92. void parseFileForPragmas(const std::string& filename, int depth = 0);
  93. /// @todo
  94. void parseStartPragma(scanner::Scanner& scanner,
  95. const std::string& filename, uint depth,
  96. const Vector<std::string>& lines);
  97. /// @todo
  98. void parseIncludePragma(scanner::Scanner& scanner,
  99. const std::string& filename, uint depth,
  100. const Vector<std::string>& lines);
  101. /// @todo
  102. void parseTrffbVarying(scanner::Scanner& scanner,
  103. const std::string& filename, uint depth,
  104. const Vector<std::string>& lines);
  105. /// Searches inside the Output::attributes or Output::trffbVaryings
  106. /// vectors
  107. /// @param vec Output::uniforms or Output::trffbVaryings
  108. /// @param what The name of the varying or attrib
  109. /// @return Iterator to the vector
  110. template<typename Type>
  111. typename Vector<Type>::const_iterator findNamed(
  112. const Vector<Type>& vec,
  113. const std::string& what) const;
  114. void printSourceLines() const; ///< For debugging
  115. /// Add a in the source lines a: #line <line> <depth> // cmnt
  116. void addLinePreProcExpression(uint line, uint depth, const char* cmnt);
  117. };
  118. template<typename Type>
  119. typename Vector<Type>::const_iterator
  120. ShaderProgramPrePreprocessor::findNamed(
  121. const Vector<Type>& vec, const std::string& what) const
  122. {
  123. typename Vector<Type>::const_iterator it = vec.begin();
  124. while(it != vec.end() && it->name != what)
  125. {
  126. ++it;
  127. }
  128. return it;
  129. }
  130. } // end namespace anki
  131. #endif