MainRenderer.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #include <cstdlib>
  2. #include <cstdio>
  3. #include <jpeglib.h>
  4. #include <fstream>
  5. #include <boost/filesystem.hpp>
  6. #include <boost/algorithm/string.hpp>
  7. #include "anki/gl/GlException.h"
  8. #include "anki/renderer/MainRenderer.h"
  9. #include "anki/core/App.h"
  10. #include "anki/renderer/RendererInitializer.h"
  11. #include "anki/renderer/Ssao.h"
  12. #include "anki/core/Logger.h"
  13. #include "anki/gl/TimeQuery.h"
  14. #include "anki/renderer/Deformer.h"
  15. #define glewGetContext() (&glContext)
  16. namespace anki {
  17. //==============================================================================
  18. // Constructors & destructor =
  19. //==============================================================================
  20. MainRenderer::MainRenderer():
  21. dbg(*this),
  22. screenshotJpegQuality(90)
  23. {}
  24. MainRenderer::~MainRenderer()
  25. {}
  26. //==============================================================================
  27. // init =
  28. //==============================================================================
  29. void MainRenderer::init(const RendererInitializer& initializer_)
  30. {
  31. ANKI_INFO("Initializing main renderer...");
  32. initGl();
  33. sProg.loadRsrc("shaders/Final.glsl");
  34. dbgTq.reset(new TimeQuery);
  35. //
  36. // init the offscreen Renderer
  37. //
  38. RendererInitializer initializer = initializer_;
  39. renderingQuality = initializer.mainRendererQuality;
  40. initializer.width = AppSingleton::get().getWindowWidth() *
  41. renderingQuality;
  42. initializer.height = AppSingleton::get().getWindowHeight() *
  43. renderingQuality;
  44. Renderer::init(initializer);
  45. dbg.init(initializer);
  46. deformer.reset(new Deformer(*this));
  47. ANKI_INFO("Main renderer initialized");
  48. }
  49. //==============================================================================
  50. // initGl =
  51. //==============================================================================
  52. void MainRenderer::initGl()
  53. {
  54. glewExperimental = GL_TRUE;
  55. GLenum err = glewInit();
  56. if(err != GLEW_OK)
  57. {
  58. throw ANKI_EXCEPTION("GLEW initialization failed");
  59. }
  60. // Ignore re first error
  61. glGetError();
  62. // print GL info
  63. ANKI_INFO("OpenGL info: OGL " <<
  64. reinterpret_cast<const char*>(glGetString(GL_VERSION)) <<
  65. ", GLSL " << reinterpret_cast<const char*>(
  66. glGetString(GL_SHADING_LANGUAGE_VERSION)));
  67. // get max texture units
  68. //glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAtachments);
  69. int& tun = Texture::getTextureUnitsNum();
  70. glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &tun);
  71. glClearColor(0.1, 0.1, 0.0, 1.0);
  72. glClearDepth(1.0);
  73. glClearStencil(0);
  74. glDepthFunc(GL_LEQUAL);
  75. // CullFace is always on
  76. glCullFace(GL_BACK);
  77. GlStateMachineSingleton::get().enable(GL_CULL_FACE);
  78. // defaults
  79. //glDisable(GL_LIGHTING);
  80. //glDisable(GL_TEXTURE_2D);
  81. GlStateMachineSingleton::get().enable(GL_BLEND, false);
  82. GlStateMachineSingleton::get().disable(GL_STENCIL_TEST);
  83. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  84. glDepthMask(true);
  85. glDepthFunc(GL_LESS);
  86. try
  87. {
  88. ANKI_CHECK_GL_ERROR();
  89. }
  90. catch(std::exception& e)
  91. {
  92. throw ANKI_EXCEPTION("OpenGL initialization failed: " + e.what());
  93. }
  94. }
  95. //==============================================================================
  96. // render =
  97. //==============================================================================
  98. void MainRenderer::render(Camera& cam_)
  99. {
  100. Renderer::render(cam_);
  101. if(getStagesProfilingEnabled())
  102. {
  103. dbgTq->begin();
  104. dbg.run();
  105. dbgTime = dbgTq->end();
  106. }
  107. else
  108. {
  109. dbg.run();
  110. }
  111. //
  112. // Render the PPS FAI to the framebuffer
  113. //
  114. glBindFramebuffer(GL_FRAMEBUFFER, 0); // Bind the window framebuffer
  115. GlStateMachineSingleton::get().setViewport(
  116. 0, 0, AppSingleton::get().getWindowWidth(),
  117. AppSingleton::get().getWindowHeight());
  118. GlStateMachineSingleton::get().enable(GL_DEPTH_TEST, false);
  119. GlStateMachineSingleton::get().enable(GL_BLEND, false);
  120. sProg->bind();
  121. //sProg->getUniformVariableByName("rasterImage").set(ms.getDiffuseFai(), 0);
  122. //sProg->getUniformVariableByName("rasterImage").
  123. // set(is.getFai(), 0);
  124. sProg->getUniformVariableByName("rasterImage").set(pps.getPostPassFai(), 0);
  125. drawQuad();
  126. }
  127. //==============================================================================
  128. // takeScreenshotTga =
  129. //==============================================================================
  130. void MainRenderer::takeScreenshotTga(const char* filename)
  131. {
  132. // open file and check
  133. std::fstream fs;
  134. fs.open(filename, std::ios::out | std::ios::binary);
  135. if(!fs.is_open())
  136. {
  137. throw ANKI_EXCEPTION("Cannot create screenshot. File \"" + filename + "\"");
  138. }
  139. // write headers
  140. unsigned char tgaHeaderUncompressed[12] = {0, 0, 2, 0, 0, 0, 0, 0,
  141. 0, 0, 0, 0};
  142. unsigned char header[6];
  143. header[1] = getWidth() / 256;
  144. header[0] = getWidth() % 256;
  145. header[3] = getHeight() / 256;
  146. header[2] = getHeight() % 256;
  147. header[4] = 24;
  148. header[5] = 0;
  149. fs.write((char*)tgaHeaderUncompressed, 12);
  150. fs.write((char*)header, 6);
  151. // write the buffer
  152. char* buffer = (char*)calloc(getWidth()*getHeight()*3, sizeof(char));
  153. glReadPixels(0, 0, getWidth(), getHeight(), GL_BGR, GL_UNSIGNED_BYTE,
  154. buffer);
  155. fs.write(buffer, getWidth()*getHeight()*3);
  156. // end
  157. fs.close();
  158. free(buffer);
  159. }
  160. //==============================================================================
  161. // takeScreenshotJpeg =
  162. //==============================================================================
  163. void MainRenderer::takeScreenshotJpeg(const char* filename)
  164. {
  165. // open file
  166. FILE* outfile = fopen(filename, "wb");
  167. if(!outfile)
  168. {
  169. throw ANKI_EXCEPTION("Cannot open file \"" + filename + "\"");
  170. }
  171. // set jpg params
  172. jpeg_compress_struct cinfo;
  173. jpeg_error_mgr jerr;
  174. cinfo.err = jpeg_std_error(&jerr);
  175. jpeg_create_compress(&cinfo);
  176. jpeg_stdio_dest(&cinfo, outfile);
  177. cinfo.image_width = getWidth();
  178. cinfo.image_height = getHeight();
  179. cinfo.input_components = 3;
  180. cinfo.in_color_space = JCS_RGB;
  181. jpeg_set_defaults(&cinfo);
  182. jpeg_set_quality (&cinfo, screenshotJpegQuality, true);
  183. jpeg_start_compress(&cinfo, true);
  184. // read from OGL
  185. char* buffer = (char*)malloc(getWidth()*getHeight()*3*sizeof(char));
  186. glReadPixels(0, 0, getWidth(), getHeight(), GL_RGB, GL_UNSIGNED_BYTE,
  187. buffer);
  188. // write buffer to file
  189. JSAMPROW row_pointer;
  190. while(cinfo.next_scanline < cinfo.image_height)
  191. {
  192. row_pointer = (JSAMPROW)&buffer[(getHeight() - 1 -
  193. cinfo.next_scanline) * 3 * getWidth()];
  194. jpeg_write_scanlines(&cinfo, &row_pointer, 1);
  195. }
  196. jpeg_finish_compress(&cinfo);
  197. // done
  198. free(buffer);
  199. fclose(outfile);
  200. }
  201. //==============================================================================
  202. // takeScreenshot =
  203. //==============================================================================
  204. void MainRenderer::takeScreenshot(const char* filename)
  205. {
  206. std::string ext = boost::filesystem::path(filename).extension().string();
  207. boost::to_lower(ext);
  208. // exec from this extension
  209. if(ext == ".tga")
  210. {
  211. takeScreenshotTga(filename);
  212. }
  213. else if(ext == ".jpg" || ext == ".jpeg")
  214. {
  215. takeScreenshotJpeg(filename);
  216. }
  217. else
  218. {
  219. throw ANKI_EXCEPTION("File \"" + filename +
  220. "\": Unsupported extension");
  221. }
  222. //ANKI_INFO("Screenshot \"" << filename << "\" saved");
  223. }
  224. } // end namespace