ShaderProgramPrePreprocessor.h 4.6 KB

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