Renderer.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <jpeglib.h>
  4. #include "Renderer.h"
  5. #include "Texture.h"
  6. #include "Scene.h"
  7. #include "Camera.h"
  8. #include "App.h"
  9. namespace R {
  10. /*
  11. =======================================================================================================================================
  12. data vars =
  13. =======================================================================================================================================
  14. */
  15. // misc
  16. uint w, h;
  17. uint framesNum = 0;
  18. float aspectRatio;
  19. int maxColorAtachments = 0;
  20. //float renderingQuality = 1.0;
  21. int screenshotJpegQuality = 90;
  22. static ShaderProg* shdr_final;
  23. // for the pps and is quad rendering
  24. float quad_vert_cords [][2] = { {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0} };
  25. /**
  26. * Standard shader preprocessor defines. Used to pass some global params to the shaders. The standard shader preprocessor defines
  27. * go on top of the shader code and its defines
  28. */
  29. string std_shader_preproc_defines;
  30. // texture
  31. bool mipmaping = true;
  32. int max_anisotropy = 8;
  33. int maxTextureUnits = -1;
  34. bool textureCompression = false;
  35. //=====================================================================================================================================
  36. // DrawQuad =
  37. //=====================================================================================================================================
  38. void DrawQuad( int vertCoords_uni_loc )
  39. {
  40. /*glEnableClientState( GL_VERTEX_ARRAY );
  41. glVertexPointer( 2, GL_FLOAT, 0, quad_vert_cords );
  42. glDrawArrays( GL_QUADS, 0, 4 );
  43. glDisableClientState( GL_VERTEX_ARRAY );*/
  44. glVertexAttribPointer( vertCoords_uni_loc, 2, GL_FLOAT, false, 0, quad_vert_cords );
  45. glEnableVertexAttribArray( vertCoords_uni_loc );
  46. glDrawArrays( GL_QUADS, 0, 4 );
  47. glDisableVertexAttribArray( vertCoords_uni_loc );
  48. }
  49. /*
  50. =======================================================================================================================================
  51. BuildStdShaderPreProcStr =
  52. I pass all the static vars (vars that do not change at all) with defines so I dont have to update uniform vars =
  53. =======================================================================================================================================
  54. */
  55. static void BuildStdShaderPreProcStr()
  56. {
  57. string& tmp = std_shader_preproc_defines;
  58. tmp = "#version 150 compatibility\n";
  59. tmp += "precision lowp float;\n";
  60. tmp += "#pragma optimize(on)\n";
  61. tmp += "#pragma debug(off)\n";
  62. tmp += "#define R_W " + Util::floatToStr(R::w) + "\n";
  63. tmp += "#define R_H " + Util::floatToStr(R::h) + "\n";
  64. //tmp += "#define R_Q " + floatToStr(R::renderingQuality) + "\n";
  65. tmp += "#define SHADOWMAP_SIZE " + Util::intToStr(R::Is::Shad::shadowResolution) + "\n";
  66. if( R::Is::Shad::pcf )
  67. tmp += "#define _SHADOW_MAPPING_PCF_\n";
  68. if( R::Pps::Ssao::enabled )
  69. {
  70. tmp += "#define _SSAO_\n";
  71. tmp += "#define SSAO_RENDERING_QUALITY " + Util::floatToStr(R::Pps::Ssao::renderingQuality) + "\n";
  72. }
  73. if( R::Pps::edgeaa::enabled )
  74. tmp += "#define _EDGEAA_\n";
  75. if( R::Pps::Hdr::enabled )
  76. {
  77. tmp += "#define _HDR_\n";
  78. tmp += "#define HDR_RENDERING_QUALITY " + Util::floatToStr(R::Pps::Hdr::renderingQuality) + "\n";
  79. }
  80. if( R::Pps::Lscatt::enabled )
  81. {
  82. tmp += "#define _LSCATT_\n";
  83. tmp += "#define LSCATT_RENDERING_QUALITY " + Util::floatToStr(R::Pps::Lscatt::renderingQuality) + "\n";
  84. }
  85. }
  86. /*
  87. =======================================================================================================================================
  88. init =
  89. =======================================================================================================================================
  90. */
  91. void init()
  92. {
  93. PRINT( "Renderer initializing..." );
  94. glewInit();
  95. if( !glewIsSupported("GL_VERSION_2_1") )
  96. WARNING( "OpenGL ver 2.1 not supported. The application may crash (and burn)" );
  97. if( !glewIsSupported("GL_EXT_framebuffer_object") )
  98. WARNING( "Framebuffer objects not supported. The application may crash (and burn)" );
  99. if( !glewIsSupported("GL_EXT_packed_depth_stencil") )
  100. WARNING( "GL_EXT_packed_depth_stencil not supported. The application may crash (and burn)" );
  101. if( !glewIsSupported("GL_ARB_vertex_buffer_object") )
  102. WARNING( "Vertex buffer objects not supported. The application may crash (and burn)" );
  103. if( !glewIsSupported("GL_ARB_texture_non_power_of_two") )
  104. WARNING( "Textures of non power of two not supported. The application may crash (and burn)" );
  105. if( !glewIsSupported("GL_ARB_vertex_buffer_object") )
  106. WARNING( "Vertex Buffer Objects not supported. The application may crash (and burn)" );
  107. w = App::windowW /* * renderingQuality*/;
  108. h = App::windowH /* * renderingQuality*/;
  109. aspectRatio = float(w)/h;
  110. glClearColor( 0.1, 0.1, 0.1, 0.0 );
  111. glClearDepth( 1.0 );
  112. glClearStencil( 0 );
  113. glDepthFunc( GL_LEQUAL );
  114. // query for maxColorAtachments
  115. glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &maxColorAtachments );
  116. // get max texture units
  117. glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits );
  118. // CullFace is always on
  119. glCullFace( GL_BACK );
  120. glEnable( GL_CULL_FACE );
  121. // defaults
  122. glDisable( GL_LIGHTING );
  123. glDisable( GL_TEXTURE_2D );
  124. glDisable( GL_BLEND );
  125. glPolygonMode( GL_FRONT, GL_FILL );
  126. // Hints
  127. //glHint( GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_FASTEST );
  128. //glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST );
  129. //glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
  130. //glHint( GL_POINT_SMOOTH_HINT, GL_FASTEST );
  131. //glHint( GL_POLYGON_SMOOTH_HINT, GL_FASTEST );
  132. //glHint( GL_TEXTURE_COMPRESSION_HINT, GL_NICEST );
  133. // execute this after the cvars are set and before the other inits (be cause these inits contain shader loads)
  134. BuildStdShaderPreProcStr();
  135. // misc
  136. shdr_final = rsrc::shaders.load( "shaders/final.glsl" );
  137. // init deferred stages
  138. // WARNING: the order of the inits is crucial!!!!!
  139. R::Ms::init();
  140. R::Is::init();
  141. R::Bs::init();
  142. R::Pps::init();
  143. R::Bs::init2();
  144. R::Dbg::init();
  145. PRINT( "Renderer initialization ends" );
  146. }
  147. /*
  148. =======================================================================================================================================
  149. render =
  150. =======================================================================================================================================
  151. */
  152. void render( const Camera& cam )
  153. {
  154. R::Ms::runStage( cam );
  155. R::Is::runStage( cam );
  156. R::Bs::runStage( cam );
  157. R::Pps::runStage( cam );
  158. R::Bs::runStage2( cam );
  159. R::Dbg::runStage( cam );
  160. //R::setViewport( 0, 0, App::windowW, App::windowH );
  161. R::setViewport( 0, 0, App::windowW, App::windowH );
  162. glDisable( GL_DEPTH_TEST );
  163. glDisable( GL_BLEND );
  164. shdr_final->bind();
  165. shdr_final->locTexUnit( shdr_final->GetUniLoc(0), R::Pps::fai, 0 );
  166. /*const int step = 100;
  167. if( R::framesNum < step )
  168. shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::diffuseFai, 0 );
  169. else if( R::framesNum < step*2 )
  170. shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::normalFai, 0 );
  171. else if( R::framesNum < step*3 )
  172. shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::specularFai, 0 );
  173. else if( R::framesNum < step*4 )
  174. shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::depthFai, 0 );
  175. else if( R::framesNum < step*5 )
  176. shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::pps::ssao::bluredFai, 0 );
  177. else if( R::framesNum < step*6 )
  178. {
  179. shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::pps::hdr::pass2Fai, 0 );
  180. }
  181. else
  182. shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::pps::fai, 0 );*/
  183. R::DrawQuad( shdr_final->getAttribLoc(0) );
  184. }
  185. /*
  186. =======================================================================================================================================
  187. setProjectionMatrix =
  188. =======================================================================================================================================
  189. */
  190. void setProjectionMatrix( const Camera& cam )
  191. {
  192. glMatrixMode( GL_PROJECTION );
  193. loadMatrix( cam.getProjectionMatrix() );
  194. }
  195. /*
  196. =======================================================================================================================================
  197. setViewMatrix =
  198. =======================================================================================================================================
  199. */
  200. void setViewMatrix( const Camera& cam )
  201. {
  202. glMatrixMode( GL_MODELVIEW );
  203. loadMatrix( cam.getViewMatrix() );
  204. }
  205. /*
  206. =======================================================================================================================================
  207. unproject =
  208. my version of gluUnproject =
  209. =======================================================================================================================================
  210. */
  211. bool unproject( float winX, float winY, float winZ, // window screen coords
  212. const Mat4& modelview_mat, const Mat4& projection_mat, const int* view,
  213. float& objX, float& objY, float& objZ )
  214. {
  215. Mat4 inv_pm = projection_mat * modelview_mat;
  216. inv_pm.invert();
  217. // the vec is in ndc space meaning: -1<=vec.x<=1 -1<=vec.y<=1 -1<=vec.z<=1
  218. Vec4 vec;
  219. vec.x = (2.0*(winX-view[0]))/view[2] - 1.0;
  220. vec.y = (2.0*(winY-view[1]))/view[3] - 1.0;
  221. vec.z = 2.0*winZ - 1.0;
  222. vec.w = 1.0;
  223. Vec4 final = inv_pm * vec;
  224. final /= final.w;
  225. objX = final.x;
  226. objY = final.y;
  227. objZ = final.z;
  228. return true;
  229. }
  230. /*
  231. =======================================================================================================================================
  232. ortho =
  233. =======================================================================================================================================
  234. */
  235. Mat4 ortho( float left, float right, float bottom, float top, float near, float far )
  236. {
  237. float difx = right-left;
  238. float dify = top-bottom;
  239. float difz = far-near;
  240. float tx = -(right+left) / difx;
  241. float ty = -(top+bottom) / dify;
  242. float tz = -(far+near) / difz;
  243. Mat4 m;
  244. m(0,0) = 2.0 / difx;
  245. m(0,1) = 0.0;
  246. m(0,2) = 0.0;
  247. m(0,3) = tx;
  248. m(1,0) = 0.0;
  249. m(1,1) = 2.0 / dify;
  250. m(1,2) = 0.0;
  251. m(1,3) = ty;
  252. m(2,0) = 0.0;
  253. m(2,1) = 0.0;
  254. m(2,2) = -2.0 / difz;
  255. m(2,3) = tz;
  256. m(3,0) = 0.0;
  257. m(3,1) = 0.0;
  258. m(3,2) = 0.0;
  259. m(3,3) = 1.0;
  260. return m;
  261. }
  262. /*
  263. =======================================================================================================================================
  264. prepareNextFrame =
  265. =======================================================================================================================================
  266. */
  267. void prepareNextFrame()
  268. {
  269. framesNum++;
  270. }
  271. /*
  272. =======================================================================================================================================
  273. printLastError =
  274. =======================================================================================================================================
  275. */
  276. void printLastError()
  277. {
  278. GLenum errid = glGetError();
  279. if( errid != GL_NO_ERROR )
  280. ERROR( "OpenGL Error: " << gluErrorString( errid ) );
  281. }
  282. //=====================================================================================================================================
  283. // getLastError =
  284. //=====================================================================================================================================
  285. const uchar* getLastError()
  286. {
  287. return gluErrorString( glGetError() );
  288. }
  289. /*
  290. =======================================================================================================================================
  291. TakeScreenshotTGA =
  292. =======================================================================================================================================
  293. */
  294. static bool TakeScreenshotTGA( const char* filename )
  295. {
  296. // open file and check
  297. fstream fs;
  298. fs.open( filename, ios::out|ios::binary );
  299. if( !fs.good() )
  300. {
  301. ERROR( "Cannot create screenshot. File \"" << filename << "\"" );
  302. return false;
  303. }
  304. // write headers
  305. unsigned char tga_header_uncompressed[12] = {0,0,2,0,0,0,0,0,0,0,0,0};
  306. unsigned char header[6];
  307. header[1] = R::w / 256;
  308. header[0] = R::w % 256;
  309. header[3] = R::h / 256;
  310. header[2] = R::h % 256;
  311. header[4] = 24;
  312. header[5] = 0;
  313. fs.write( (char*)tga_header_uncompressed, 12 );
  314. fs.write( (char*)header, 6 );
  315. // write the buffer
  316. char* buffer = (char*)calloc( R::w*R::h*3, sizeof(char) );
  317. glReadPixels( 0, 0, R::w, R::h, GL_BGR, GL_UNSIGNED_BYTE, buffer );
  318. fs.write( buffer, R::w*R::h*3 );
  319. // end
  320. fs.close();
  321. free( buffer );
  322. return true;
  323. }
  324. /*
  325. =======================================================================================================================================
  326. TakeScreenshotJPEG =
  327. =======================================================================================================================================
  328. */
  329. static bool TakeScreenshotJPEG( const char* filename )
  330. {
  331. // open file
  332. FILE* outfile = fopen( filename, "wb" );
  333. if( !outfile )
  334. {
  335. ERROR( "Cannot open file \"" << filename << "\"" );
  336. return false;
  337. }
  338. // set jpg params
  339. jpeg_compress_struct cinfo;
  340. jpeg_error_mgr jerr;
  341. cinfo.err = jpeg_std_error( &jerr );
  342. jpeg_create_compress( &cinfo );
  343. jpeg_stdio_dest( &cinfo, outfile );
  344. cinfo.image_width = R::w;
  345. cinfo.image_height = R::h;
  346. cinfo.input_components = 3;
  347. cinfo.in_color_space = JCS_RGB;
  348. jpeg_set_defaults( &cinfo);
  349. jpeg_set_quality ( &cinfo, screenshotJpegQuality, true );
  350. jpeg_start_compress( &cinfo, true );
  351. // read from OGL
  352. char* buffer = (char*)malloc( R::w*R::h*3*sizeof(char) );
  353. glReadPixels( 0, 0, R::w, R::h, GL_RGB, GL_UNSIGNED_BYTE, buffer );
  354. // write buffer to file
  355. JSAMPROW row_pointer;
  356. while( cinfo.next_scanline < cinfo.image_height )
  357. {
  358. row_pointer = (JSAMPROW) &buffer[ (R::h-1-cinfo.next_scanline)*3*R::w ];
  359. jpeg_write_scanlines( &cinfo, &row_pointer, 1 );
  360. }
  361. jpeg_finish_compress(&cinfo);
  362. // done
  363. free( buffer );
  364. fclose( outfile );
  365. return true;
  366. }
  367. /*
  368. =======================================================================================================================================
  369. takeScreenshot =
  370. =======================================================================================================================================
  371. */
  372. void takeScreenshot( const char* filename )
  373. {
  374. char* ext = Util::getFileExtension( filename );
  375. bool ret;
  376. // exec from this extension
  377. if( strcmp( ext, "tga" ) == 0 )
  378. {
  379. ret = TakeScreenshotTGA( filename );
  380. }
  381. else if( strcmp( ext, "jpg" ) == 0 )
  382. {
  383. ret = TakeScreenshotJPEG( filename );
  384. }
  385. else
  386. {
  387. ERROR( "File \"" << filename << "\": Unsupported extension. Watch for capital" );
  388. return;
  389. }
  390. if( !ret ) ERROR( "In taking screenshot" )
  391. else PRINT( "Screenshot \"" << filename << "\" saved" );
  392. }
  393. } // end namespace