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.

Render.cpp 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*!
  2. * \file src/Render.cpp
  3. * \brief World Renderer
  4. *
  5. * \author Mongoose
  6. * \author xythobuz
  7. */
  8. #include <fstream>
  9. #include <sstream>
  10. #include "global.h"
  11. #include "Camera.h"
  12. #include "Log.h"
  13. #include "Menu.h"
  14. #include "StaticMesh.h"
  15. #include "World.h"
  16. #include "system/Font.h"
  17. #include "system/Shader.h"
  18. #include "system/Window.h"
  19. #include "Render.h"
  20. #include <glm/gtc/matrix_transform.hpp>
  21. #include <glbinding/gl/gl33.h>
  22. #include "imgui/imgui.h"
  23. #include "stb/stb_image_write.h"
  24. RenderMode Render::mode = RenderMode::LoadScreen;
  25. std::vector<Room*> Render::roomList;
  26. bool Render::displayViewFrustum = false;
  27. void Render::display() {
  28. gl::glClear(gl::GL_COLOR_BUFFER_BIT | gl::GL_DEPTH_BUFFER_BIT);
  29. if (mode == RenderMode::LoadScreen) {
  30. glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
  31. drawTexture(0.0f, 0.0f, Window::getSize().x, Window::getSize().y,
  32. color, TEXTURE_SPLASH, TextureStorage::SYSTEM);
  33. return;
  34. }
  35. if (mode == RenderMode::Wireframe) {
  36. gl::glPolygonMode(gl::GL_FRONT_AND_BACK, gl::GL_LINE);
  37. } else {
  38. gl::glPolygonMode(gl::GL_FRONT_AND_BACK, gl::GL_FILL);
  39. }
  40. if (Camera::update()) {
  41. int r = Camera::getRoom();
  42. clearRoomList();
  43. if (r < 0) {
  44. buildRoomList();
  45. } else {
  46. buildRoomList(r);
  47. }
  48. }
  49. glm::mat4 projection = Camera::getProjectionMatrix();
  50. glm::mat4 view = Camera::getViewMatrix();
  51. glm::mat4 VP = projection * view;
  52. for (int r = roomList.size() - 1; r >= 0; r--) {
  53. roomList.at(r)->display(VP);
  54. for (int i = 0; i < getWorld().sizeEntity(); i++) {
  55. auto& e = getWorld().getEntity(i);
  56. if (roomList.at(r)->getIndex() == e.getRoom()) {
  57. e.display(VP);
  58. }
  59. }
  60. }
  61. if (displayViewFrustum)
  62. Camera::displayFrustum(VP);
  63. if (mode == RenderMode::Wireframe) {
  64. gl::glPolygonMode(gl::GL_FRONT_AND_BACK, gl::GL_FILL);
  65. }
  66. }
  67. void Render::buildRoomList(int room, int budget) {
  68. if (room < -1) {
  69. // Check if the camera currently is in a room...
  70. for (int i = 0; i < getWorld().sizeRoom(); i++) {
  71. if (getWorld().getRoom(i).getBoundingBox().inBox(Camera::getPosition())) {
  72. buildRoomList(i, budget);
  73. return;
  74. }
  75. }
  76. buildRoomList(-1, budget);
  77. } else if (room == -1) {
  78. // Check visibility for all rooms!
  79. for (int i = 0; i < getWorld().sizeRoom(); i++) {
  80. if (Camera::boxInFrustum(getWorld().getRoom(i).getBoundingBox())) {
  81. roomList.push_back(&getWorld().getRoom(i));
  82. }
  83. }
  84. } else {
  85. // Check visibility of room and connected rooms, recursively
  86. if (Camera::boxInFrustum(getWorld().getRoom(room).getBoundingBox())) {
  87. roomList.push_back(&getWorld().getRoom(room));
  88. for (int i = 0; i < getWorld().getRoom(room).sizePortals(); i++) {
  89. int r = getWorld().getRoom(room).getPortal(i).getAdjoiningRoom();
  90. bool found = false;
  91. for (int n = 0; n < roomList.size(); n++) {
  92. if (roomList.at(n) == &getWorld().getRoom(r)) {
  93. found = true;
  94. break;
  95. }
  96. }
  97. if (!found) {
  98. if (budget > 0) {
  99. buildRoomList(r, --budget);
  100. }
  101. }
  102. }
  103. }
  104. }
  105. }
  106. void Render::screenShot(const char* filenameBase) {
  107. orAssert(filenameBase != nullptr);
  108. int w = Window::getSize().x;
  109. int h = Window::getSize().y;
  110. int sz = w * h;
  111. unsigned char* image = new unsigned char[sz * 3];
  112. gl::glReadPixels(0, 0, w, h, gl::GL_RGB, gl::GL_UNSIGNED_BYTE, image);
  113. unsigned char* buffer = new unsigned char[sz * 3];
  114. for (int x = 0; x < w; x++) {
  115. for (int y = 0; y < h; y++) {
  116. buffer[3 * (x + (y * w))] = image[3 * (x + ((h - y - 1) * w))];
  117. buffer[(3 * (x + (y * w))) + 1] = image[(3 * (x + ((h - y - 1) * w))) + 1];
  118. buffer[(3 * (x + (y * w))) + 2] = image[(3 * (x + ((h - y - 1) * w))) + 2];
  119. }
  120. }
  121. // Don't overwrite files
  122. static int count = 0;
  123. bool done = false;
  124. std::string f;
  125. while (!done) {
  126. std::ostringstream filename;
  127. filename << filenameBase << "-" << count++ << ".png";
  128. f = filename.str();
  129. std::ifstream fs(f);
  130. done = !fs.good();
  131. fs.close();
  132. }
  133. if (!stbi_write_png(f.c_str(), w, h, 3, buffer, 0)) {
  134. Log::get(LOG_ERROR) << "Error saving image \"" << f << "\"!" << Log::endl;
  135. }
  136. delete [] image;
  137. delete [] buffer;
  138. }
  139. void Render::drawTexture(float x, float y, float w, float h, glm::vec4 color,
  140. unsigned int texture, TextureStorage s) {
  141. std::vector<glm::vec2> vertices;
  142. std::vector<glm::vec2> uvs;
  143. vertices.push_back(glm::vec2(x, y + h));
  144. vertices.push_back(glm::vec2(x + w, y + h));
  145. vertices.push_back(glm::vec2(x, y));
  146. vertices.push_back(glm::vec2(x + w, y));
  147. vertices.push_back(glm::vec2(x, y));
  148. vertices.push_back(glm::vec2(x + w, y + h));
  149. uvs.push_back(glm::vec2(0.0f, 1.0f));
  150. uvs.push_back(glm::vec2(1.0f, 1.0f));
  151. uvs.push_back(glm::vec2(0.0f, 0.0f));
  152. uvs.push_back(glm::vec2(1.0f, 0.0f));
  153. uvs.push_back(glm::vec2(0.0f, 0.0f));
  154. uvs.push_back(glm::vec2(1.0f, 1.0f));
  155. static ShaderBuffer vert, uv;
  156. vert.bufferData(vertices);
  157. uv.bufferData(uvs);
  158. Shader::drawGL(vert, uv, color, texture, s);
  159. }
  160. static const int modeStringCount = 4;
  161. static const char* modeStrings[modeStringCount] = {
  162. "Splash", "Texture", "Wireframe", "Solid"
  163. };
  164. void Render::displayUI() {
  165. if (ImGui::CollapsingHeader("Render Settings##render")) {
  166. int item = 0;
  167. if (mode == RenderMode::Texture)
  168. item = 1;
  169. else if (mode == RenderMode::Wireframe)
  170. item = 2;
  171. else if (mode == RenderMode::Solid)
  172. item = 3;
  173. if (ImGui::Combo("Render Mode##render", &item, modeStrings, modeStringCount)) {
  174. if (item == 0)
  175. mode = RenderMode::LoadScreen;
  176. else if (item == 1)
  177. mode = RenderMode::Texture;
  178. else if (item == 2)
  179. mode = RenderMode::Wireframe;
  180. else if (item == 3)
  181. mode = RenderMode::Solid;
  182. }
  183. ImGui::Separator();
  184. ImGui::Text("Camera:");
  185. bool updateViewFrustum = Camera::getUpdateViewFrustum();
  186. if (ImGui::Checkbox("Update Frustum##render", &updateViewFrustum)) {
  187. Camera::setUpdateViewFrustum(updateViewFrustum);
  188. }
  189. ImGui::SameLine();
  190. ImGui::Checkbox("Show Frustum##render", &displayViewFrustum);
  191. ImGui::SameLine();
  192. bool showOverlay = Camera::getShowOverlay();
  193. if (ImGui::Checkbox("Overlay", &showOverlay)) {
  194. Camera::setShowOverlay(showOverlay);
  195. }
  196. if (ImGui::Button("Reset Room ID")) {
  197. Camera::setRoom(-1);
  198. }
  199. ImGui::Separator();
  200. ImGui::Text("Bounding Boxes:");
  201. bool showBoundingBox = Room::getShowBoundingBox();
  202. if (ImGui::Checkbox("Room##bbox", &showBoundingBox)) {
  203. Room::setShowBoundingBox(showBoundingBox);
  204. }
  205. ImGui::SameLine();
  206. bool showBoundingBox2 = StaticMesh::getShowBoundingBox();
  207. if (ImGui::Checkbox("StaticMesh##bbox", &showBoundingBox2)) {
  208. StaticMesh::setShowBoundingBox(showBoundingBox2);
  209. }
  210. ImGui::SameLine();
  211. bool showFontBox = Font::getShowFontBox();
  212. if (ImGui::Checkbox("Font##bbox", &showFontBox)) {
  213. Font::setShowFontBox(showFontBox);
  214. }
  215. ImGui::Separator();
  216. ImGui::Text("Renderable Objects:");
  217. ImGui::Text("Room: ");
  218. ImGui::SameLine();
  219. bool showRoomGeometry = Room::getShowRoomGeometry();
  220. if (ImGui::Checkbox("Geometry##renderroom", &showRoomGeometry)) {
  221. Room::setShowRoomGeometry(showRoomGeometry);
  222. }
  223. ImGui::SameLine();
  224. bool showRoomModels = Room::getShowRoomModels();
  225. if (ImGui::Checkbox("Models##renderroom", &showRoomModels)) {
  226. Room::setShowRoomModels(showRoomModels);
  227. }
  228. ImGui::SameLine();
  229. bool showRoomSprites = Room::getShowRoomSprites();
  230. if (ImGui::Checkbox("Sprites##renderroom", &showRoomSprites)) {
  231. Room::setShowRoomSprites(showRoomSprites);
  232. }
  233. ImGui::Text("Entity: ");
  234. ImGui::SameLine();
  235. bool showEntitySprites = Entity::getShowEntitySprites();
  236. if (ImGui::Checkbox("Sprites##renderentity", &showEntitySprites)) {
  237. Entity::setShowEntitySprites(showEntitySprites);
  238. }
  239. ImGui::SameLine();
  240. bool showEntityMeshes = Entity::getShowEntityMeshes();
  241. if (ImGui::Checkbox("Meshes##renderentity", &showEntityMeshes)) {
  242. Entity::setShowEntityMeshes(showEntityMeshes);
  243. }
  244. ImGui::SameLine();
  245. bool showEntityModels = Entity::getShowEntityModels();
  246. if (ImGui::Checkbox("Models##renderentity", &showEntityModels)) {
  247. Entity::setShowEntityModels(showEntityModels);
  248. }
  249. ImGui::Separator();
  250. if (ImGui::Button("New Splash##render")) {
  251. TextureManager::initializeSplash();
  252. }
  253. ImGui::SameLine();
  254. if (ImGui::Button("New Menu##render")) {
  255. Menu::initialize();
  256. }
  257. }
  258. }