renderer.cpp 16 KB

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