Compiler.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #pragma once
  2. #include <irrlicht/irrlicht.h>
  3. #include <iostream>
  4. #include <vector>
  5. #include <map>
  6. #include <nlohmann/json.hpp>
  7. #include <WallpaperEngine/FileSystem/utils.h>
  8. namespace WallpaperEngine::Render::Shaders
  9. {
  10. using json = nlohmann::json;
  11. /**
  12. * A basic shader loader that adds basic function definitions to every loaded shader
  13. */
  14. class Compiler
  15. {
  16. public:
  17. /**
  18. * Basic struct used to define all the shader variables
  19. * the compiler will replace in pre-processing time
  20. * to make sure the shaders compile under OpenGL
  21. */
  22. struct VariableReplacement
  23. {
  24. const char* original;
  25. const char* replacement;
  26. };
  27. struct TypeName
  28. {
  29. const char* name;
  30. int size;
  31. };
  32. struct ShaderParameter
  33. {
  34. std::string type;
  35. std::string variableName;
  36. std::string identifierName;
  37. void* defaultValue;
  38. void* range [2];
  39. };
  40. /**
  41. * Types of shaders
  42. */
  43. enum Type
  44. {
  45. Type_Vertex = 0,
  46. Type_Pixel = 1,
  47. };
  48. /**
  49. * List of variables to replace when pre-process is performed
  50. */
  51. static std::map<std::string, std::string> sVariableReplacement;
  52. /**
  53. * Types of variables the pre-processor understands
  54. */
  55. static std::vector<std::string> sTypes;
  56. /**
  57. * Compiler constructor, loads the given shader file and prepares
  58. * the pre-processing and compilation of the shader, adding
  59. * required definitions if needed
  60. *
  61. * @param file The file to load
  62. * @param type The type of shader
  63. * @param recursive Whether the compiler should add base definitions or not
  64. */
  65. Compiler (irr::io::path& file, Type type, std::map<std::string, int>* combos, bool recursive = false);
  66. /**
  67. * Performs the actual pre-compilation/pre-processing over the shader files
  68. * This step is kinda big, replaces variables names on sVariableReplacement,
  69. * ensures #include directives are correctly handled
  70. * and takes care of attribute comments for the wallpaper engine specifics
  71. *
  72. * @return The shader contents ready to be used by OpenGL
  73. */
  74. std::string precompile ();
  75. /**
  76. * Searches the list of parameters available for the parameter with the given value
  77. *
  78. * @param identifier The identifier to search for
  79. * @return The shader information
  80. */
  81. ShaderParameter* findParameter (std::string identifier);
  82. /**
  83. * @return The list of parameters available for this shader with their default values
  84. */
  85. std::vector <ShaderParameter*>& getParameters ();
  86. private:
  87. /**
  88. * Checks if there is "str" in the current position without advancing the
  89. * iterator in use
  90. *
  91. * @param str The string to check for
  92. * @param it The position to start checking at
  93. *
  94. * @return
  95. */
  96. bool peekString (std::string str, std::string::const_iterator& it);
  97. /**
  98. * Checks for a semicolon as current character, advancing the iterator
  99. * after finding it, otherwise returns an error
  100. *
  101. * @param it The position where to expect the semicolon
  102. *
  103. * @return
  104. */
  105. bool expectSemicolon (std::string::const_iterator& it);
  106. /**
  107. * Ignores contiguous space characters in the string advancing the iterator
  108. * until the first non-space character
  109. *
  110. * @param it The iterator to increase
  111. */
  112. void ignoreSpaces (std::string::const_iterator& it);
  113. /**
  114. * Ignores all characters until next line-fee (\n) advancing the interator
  115. *
  116. * @param it The iterator to increase
  117. */
  118. void ignoreUpToNextLineFeed (std::string::const_iterator& it);
  119. /**
  120. * Ignores all characters until a block comment end is found, advancing the iterator
  121. *
  122. * @param it The iterator to increase
  123. */
  124. void ignoreUpToBlockCommentEnd (std::string::const_iterator& it);
  125. /**
  126. * Parses the current position as a variable type, extracts it and compares it
  127. * to the registered types in the pre-processor, returning it's name if valid
  128. * increasing the iterator at the same time
  129. *
  130. * @param it The position to extract it from
  131. *
  132. * @return The type name
  133. */
  134. std::string extractType (std::string::const_iterator& it);
  135. /**
  136. * Parses the current position as a variable name, extractig it's name and
  137. * increasing the iterator as the name is extracted
  138. *
  139. * @param it The position to start extracting the variable name from
  140. *
  141. * @return The variable name
  142. */
  143. std::string extractName (std::string::const_iterator& it);
  144. /**
  145. * Parses the current position as a quoted value, extracting it's value
  146. * and increasing the iterator at the same time
  147. *
  148. * @param it The position to start extracting the value from
  149. *
  150. * @return The value
  151. */
  152. std::string extractQuotedValue (std::string::const_iterator& it);
  153. /**
  154. * Tries to find the given shader file and compile it
  155. *
  156. * @param filename The shader's filename
  157. *
  158. * @return The compiled contents
  159. */
  160. std::string lookupShaderFile (std::string filename);
  161. /**
  162. * Searches for the given symbol in the replace table
  163. *
  164. * @param symbol The symbol to look for
  165. *
  166. * @return The symbol it should be replaced with
  167. */
  168. std::string lookupReplaceSymbol (std::string symbol);
  169. /**
  170. * @return Whether the character in the current position is a character or not
  171. */
  172. bool isChar (std::string::const_iterator& it);
  173. /**
  174. * @return Whether the character in the current position is a number or not
  175. */
  176. bool isNumeric (std::string::const_iterator& it);
  177. /**
  178. * Parses a COMBO value to add the proper define to the code
  179. *
  180. * @param content The parameter configuration
  181. */
  182. void parseComboConfiguration (const std::string& content);
  183. /**
  184. * Parses a parameter extra metadata created by wallpaper engine
  185. *
  186. * @param type The type of variable to parse
  187. * @param name The name of the variable in the shader (for actual variable declaration)
  188. * @param content The parameter configuration
  189. */
  190. void parseParameterConfiguration (const std::string& type, const std::string& name, const std::string& content);
  191. /**
  192. * The shader file this instance is loading
  193. */
  194. irr::io::path m_file;
  195. /**
  196. * The original file content
  197. */
  198. std::string m_content;
  199. /**
  200. * The final, compiled content ready to be used by OpenGL
  201. */
  202. std::string m_compiledContent;
  203. /**
  204. * Whether there was any kind of error in the compilation or not
  205. */
  206. bool m_error;
  207. /**
  208. * Extra information about the error (if any)
  209. */
  210. std::string m_errorInfo;
  211. /**
  212. * The type of shader
  213. */
  214. Type m_type;
  215. /**
  216. * The parameters the shader needs
  217. */
  218. std::vector <ShaderParameter*> m_parameters;
  219. /**
  220. * The combos the shader should be generated with
  221. */
  222. std::map <std::string, int>* m_combos;
  223. /**
  224. * Whether this compilation is a recursive one or not
  225. */
  226. bool m_recursive;
  227. };
  228. }