Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Window.cpp 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*!
  2. * \file src/Window.cpp
  3. * \brief windowing implementation
  4. *
  5. * \author xythobuz
  6. */
  7. #include "global.h"
  8. #include "Log.h"
  9. #include "TextureManager.h"
  10. #include "utils/strings.h"
  11. #include "system/Window.h"
  12. unsigned int Window::getWidth() {
  13. return mWidth;
  14. }
  15. unsigned int Window::getHeight() {
  16. return mHeight;
  17. }
  18. bool Window::getFullscreen() {
  19. return mFullscreen;
  20. }
  21. bool Window::getMousegrab() {
  22. return mMousegrab;
  23. }
  24. bool Window::getTextInput() {
  25. return mTextInput;
  26. }
  27. // ----------------------------------------------------------------------------
  28. Shader Window::textShader;
  29. Shader Window::imguiShader;
  30. unsigned int Window::vertexArrayID = 0;
  31. int Window::initializeGL() {
  32. getLog() << "GL Ven.: " << glGetString(GL_VENDOR) << Log::endl;
  33. getLog() << "GL Ren.: " << glGetString(GL_RENDERER) << Log::endl;
  34. getLog() << "GL Ver.: " << glGetString(GL_VERSION) << Log::endl;
  35. getLog() << "GLSL V.: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << Log::endl;
  36. glGenVertexArrays(1, &vertexArrayID);
  37. glBindVertexArray(vertexArrayID);
  38. // Set background to black
  39. glClearColor(BLACK[0] / 256.0f, BLACK[1] / 256.0f, BLACK[2] / 256.0f, BLACK[3] / 256.0f);
  40. // Set up Z buffer
  41. glEnable(GL_DEPTH_TEST);
  42. // Accept fragment if closer to camera
  43. glDepthFunc(GL_LESS);
  44. // Set up culling
  45. //glEnable(GL_CULL_FACE); //! \todo Transparency?
  46. if (textShader.compile(textShaderVertex, textShaderFragment) < 0)
  47. return -1;
  48. if (textShader.addUniform("screen") < 0)
  49. return -2;
  50. if (textShader.addUniform("textureSampler") < 0)
  51. return -3;
  52. if (textShader.addUniform("colorVar") < 0)
  53. return -4;
  54. textShader.addBuffer(2);
  55. if (imguiShader.compile(imguiShaderVertex, imguiShaderFragment) < 0)
  56. return -5;
  57. if (imguiShader.addUniform("screen") < 0)
  58. return -6;
  59. if (imguiShader.addUniform("textureSampler") < 0)
  60. return -7;
  61. imguiShader.addBuffer(3);
  62. glEnable(GL_BLEND);
  63. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  64. return 0;
  65. }
  66. void Window::shutdownGL() {
  67. glDeleteVertexArrays(1, &vertexArrayID);
  68. }
  69. void Window::resizeGL() {
  70. // new matrix?
  71. }
  72. void Window::drawTextGL(std::vector<glm::vec2>& vertices, std::vector<glm::vec2>& uvs,
  73. glm::vec4 color, unsigned int texture) {
  74. assert(vertices.size() == uvs.size());
  75. assert((vertices.size() % 3) == 0);
  76. glBindBuffer(GL_ARRAY_BUFFER, textShader.getBuffer(0));
  77. glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec2), &vertices[0], GL_STATIC_DRAW);
  78. glBindBuffer(GL_ARRAY_BUFFER, textShader.getBuffer(1));
  79. glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
  80. textShader.use();
  81. glUniform2f(textShader.getUniform(0), getWindow().getWidth(), getWindow().getHeight());
  82. getTextureManager().bindTextureId(texture, TextureManager::TextureStorage::SYSTEM, 0);
  83. glUniform1i(textShader.getUniform(1), 0);
  84. glUniform4fv(textShader.getUniform(2), 1, &color.r);
  85. glEnableVertexAttribArray(0); // Vertices
  86. glBindBuffer(GL_ARRAY_BUFFER, textShader.getBuffer(0));
  87. glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
  88. glEnableVertexAttribArray(1); // UVs
  89. glBindBuffer(GL_ARRAY_BUFFER, textShader.getBuffer(1));
  90. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
  91. glDisable(GL_DEPTH_TEST);
  92. glDrawArrays(GL_TRIANGLES, 0, vertices.size());
  93. glEnable(GL_DEPTH_TEST);
  94. glDisableVertexAttribArray(0);
  95. glDisableVertexAttribArray(1);
  96. }
  97. // ----------------------------------------------------------------------------
  98. Shader::~Shader() {
  99. if (programID >= 0)
  100. glDeleteProgram(programID);
  101. if (!buffers.empty())
  102. glDeleteBuffers(buffers.size(), &buffers[0]);
  103. }
  104. int Shader::addUniform(const char* name) {
  105. assert(programID >= 0);
  106. int r = glGetUniformLocation(programID, name);
  107. if (r < 0) {
  108. getLog() << "Can't find GLSL Uniform \"" << name << "\"!" << Log::endl;
  109. return -1;
  110. }
  111. uniforms.push_back(r);
  112. return uniforms.size() - 1;
  113. }
  114. unsigned int Shader::getUniform(int n) {
  115. assert(n >= 0);
  116. assert(n < uniforms.size());
  117. return uniforms.at(n);
  118. }
  119. void Shader::addBuffer(int n) {
  120. int s = buffers.size();
  121. for (int i = 0; i < n; i++)
  122. buffers.push_back(0);
  123. glGenBuffers(n, &buffers[s]);
  124. }
  125. unsigned int Shader::getBuffer(int n) {
  126. assert(n >= 0);
  127. assert(n < buffers.size());
  128. return buffers.at(n);
  129. }
  130. void Shader::use() {
  131. assert(programID >= 0);
  132. glUseProgram(programID);
  133. }
  134. int Shader::compile(const char* vertex, const char* fragment) {
  135. assert(vertex != nullptr);
  136. assert(fragment != nullptr);
  137. GLuint vertexID = glCreateShader(GL_VERTEX_SHADER);
  138. GLuint fragmentID = glCreateShader(GL_FRAGMENT_SHADER);
  139. GLint result = GL_FALSE;
  140. GLint logLength = 0;
  141. // Compile vertex shader
  142. glShaderSource(vertexID, 1, &vertex, nullptr);
  143. glCompileShader(vertexID);
  144. // Check vertex shader
  145. glGetShaderiv(vertexID, GL_COMPILE_STATUS, &result);
  146. glGetShaderiv(vertexID, GL_INFO_LOG_LENGTH, &logLength);
  147. if (logLength > 0) {
  148. std::vector<char> message(logLength + 1);
  149. glGetShaderInfoLog(vertexID, logLength, nullptr, &message[0]);
  150. if (result != GL_TRUE)
  151. getLog() << "Vertex Shader compilation error:" << Log::endl;
  152. getLog() << &message[0] << Log::endl;
  153. glDeleteShader(vertexID);
  154. glDeleteShader(fragmentID);
  155. return -1;
  156. }
  157. // Compile fragment shader
  158. glShaderSource(fragmentID, 1, &fragment, nullptr);
  159. glCompileShader(fragmentID);
  160. // Check fragment shader
  161. glGetShaderiv(fragmentID, GL_COMPILE_STATUS, &result);
  162. glGetShaderiv(fragmentID, GL_INFO_LOG_LENGTH, &logLength);
  163. if (logLength > 0) {
  164. std::vector<char> message(logLength + 1);
  165. glGetShaderInfoLog(fragmentID, logLength, nullptr, &message[0]);
  166. if (result != GL_TRUE)
  167. getLog() << "Fragment Shader compilation error:" << Log::endl;
  168. getLog() << &message[0] << Log::endl;
  169. glDeleteShader(vertexID);
  170. glDeleteShader(fragmentID);
  171. return -2;
  172. }
  173. // Link both shaders
  174. programID = glCreateProgram();
  175. glAttachShader(programID, vertexID);
  176. glAttachShader(programID, fragmentID);
  177. glLinkProgram(programID);
  178. // Check resulting program
  179. glGetProgramiv(programID, GL_LINK_STATUS, &result);
  180. glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLength);
  181. if (logLength > 0) {
  182. std::vector<char> message(logLength + 1);
  183. glGetProgramInfoLog(programID, logLength, nullptr, &message[0]);
  184. if (result != GL_TRUE)
  185. getLog() << "Shader link error:" << Log::endl;
  186. getLog() << &message[0] << Log::endl;
  187. glDeleteShader(vertexID);
  188. glDeleteShader(fragmentID);
  189. glDeleteProgram(programID);
  190. return -3;
  191. }
  192. glDeleteShader(vertexID);
  193. glDeleteShader(fragmentID);
  194. return programID;
  195. }
  196. // ----------------------------------------------------------------------------
  197. // *INDENT-OFF*
  198. const char* Window::textShaderVertex = R"!?!(
  199. #version 330 core
  200. layout(location = 0) in vec2 vertexPosition_screen;
  201. layout(location = 1) in vec2 vertexUV;
  202. out vec2 UV;
  203. uniform vec2 screen;
  204. void main() {
  205. vec2 halfScreen = screen / 2;
  206. vec2 vertexPosition_homogenous = (vertexPosition_screen - halfScreen) / halfScreen;
  207. gl_Position = vec4(vertexPosition_homogenous.x, -vertexPosition_homogenous.y, 0, 1);
  208. UV = vertexUV;
  209. }
  210. )!?!";
  211. const char* Window::textShaderFragment = R"!?!(
  212. #version 330 core
  213. in vec2 UV;
  214. out vec4 color;
  215. uniform sampler2D textureSampler;
  216. uniform vec4 colorVar;
  217. void main() {
  218. color = texture(textureSampler, UV) * colorVar;
  219. }
  220. )!?!";
  221. // --------------------------------------
  222. const char* Window::imguiShaderVertex = R"!?!(
  223. #version 330 core
  224. layout(location = 0) in vec2 vertexPosition_screen;
  225. layout(location = 1) in vec2 vertexUV;
  226. layout(location = 2) in vec4 vertexColor;
  227. out vec2 UV;
  228. out vec4 FragColor;
  229. uniform vec2 screen;
  230. void main() {
  231. vec2 halfScreen = screen / 2;
  232. vec2 vertexPosition_homogenous = (vertexPosition_screen - halfScreen) / halfScreen;
  233. gl_Position = vec4(vertexPosition_homogenous.x, -vertexPosition_homogenous.y, 0, 1);
  234. UV = vertexUV;
  235. FragColor = vertexColor;
  236. }
  237. )!?!";
  238. const char* Window::imguiShaderFragment = R"!?!(
  239. #version 330 core
  240. in vec2 UV;
  241. in vec4 FragColor;
  242. out vec4 color;
  243. uniform sampler2D textureSampler;
  244. void main() {
  245. color = texture(textureSampler, UV) * FragColor;
  246. }
  247. )!?!";
  248. // *INDENT-ON*