BasicShaderLoader.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include <irrlicht.h>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <string>
  5. #include "BasicShaderLoader.h"
  6. #include "nier_test.h"
  7. #include "common.h"
  8. BasicShaderLoader::BasicShaderLoader (irr::io::path file, Type type)
  9. {
  10. this->m_content = "#version 120\n"
  11. "#define texSample2D texture2D\n"
  12. "#define frac fract\n";
  13. std::ifstream _in (file.c_str ());
  14. this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
  15. this->m_type = type;
  16. }
  17. bool BasicShaderLoader::peekString(std::string str, std::string::const_iterator& it)
  18. {
  19. std::string::const_iterator check = str.begin();
  20. std::string::const_iterator cur = it + 1;
  21. while (cur != this->m_content.end () && check != str.end ())
  22. {
  23. if (*cur != *check) return false;
  24. cur ++; check ++;
  25. }
  26. if (check != str.end ())
  27. {
  28. return false;
  29. }
  30. it = cur;
  31. return true;
  32. }
  33. void BasicShaderLoader::ignoreSpaces(std::string::const_iterator &it)
  34. {
  35. while (it != this->m_content.end() && (*it == ' ' || *it == '\t')) it ++;
  36. }
  37. std::string BasicShaderLoader::extractQuotedValue(std::string::const_iterator& it)
  38. {
  39. std::string::const_iterator cur = it;
  40. if (*cur != '"')
  41. {
  42. m_error = true;
  43. m_errorInfo = "Expected opening \" but got " + (*cur);
  44. return "";
  45. }
  46. cur ++;
  47. while (cur != this->m_content.end () && *cur != '\n' && *cur != '"') cur ++;
  48. if (cur == this->m_content.end ())
  49. {
  50. m_error = true;
  51. m_errorInfo = "Expected closing \" not found";
  52. it = cur;
  53. return "";
  54. }
  55. std::string filename = std::string (++it, cur);
  56. it = cur;
  57. return filename;
  58. }
  59. std::string BasicShaderLoader::lookupShaderFile (std::string filename)
  60. {
  61. irr::io::path shaderTest = _example_base_folder; shaderTest += "/"; shaderTest += filename.c_str ();
  62. irr::io::IFileSystem *fs = device->getFileSystem ();
  63. // by default try to load from current folder
  64. // we might want, in the future, to load things from different folders
  65. // to provide standard functionality
  66. if (fs->existFile (shaderTest) == false)
  67. {
  68. this->m_error = true;
  69. this->m_errorInfo = "Cannot find file " + filename + " to include";
  70. return "";
  71. }
  72. // open the file, read content and close it
  73. irr::io::IReadFile* readFile = fs->createAndOpenFile (shaderTest);
  74. char* buffer = (char*) malloc (readFile->getSize () + 1);
  75. memset (buffer, 0, readFile->getSize() + 1);
  76. readFile->read (buffer, readFile->getSize ());
  77. readFile->drop ();
  78. std::string output = buffer;
  79. free (buffer);
  80. return output;
  81. }
  82. std::string* BasicShaderLoader::precompile ()
  83. {
  84. // parse the shader and find #includes and such things and translate them to the correct name
  85. // also remove any #version definition to prevent errors
  86. std::string::const_iterator it = this->m_content.begin ();
  87. // search preprocessor macros and parse them
  88. while (it != this->m_content.end () && this->m_error == false)
  89. {
  90. // TODO: on precompilation steps search for attributes and replace them
  91. // TODO: with the correct opengl shader variable
  92. if (*it == '#')
  93. {
  94. if (this->peekString ("include", it) == true)
  95. {
  96. std::string filename = "";
  97. // ignore whitespaces
  98. this->ignoreSpaces(it);
  99. // extract value between quotes
  100. filename = this->extractQuotedValue(it);
  101. // try to find the file first
  102. this->m_compiledContent += "// begin of included from file " + filename + "\r\n";
  103. this->m_compiledContent += this->lookupShaderFile (filename);
  104. this->m_compiledContent += "\r\n// end of included from file " + filename + "\r\n";
  105. }
  106. else
  107. {
  108. this->m_compiledContent += '#';
  109. }
  110. }
  111. else
  112. {
  113. this->m_compiledContent += *it;
  114. }
  115. it ++;
  116. }
  117. return &this->m_compiledContent;
  118. }