ShaderProgramPrePreprocessor.h 4.6 KB

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