renderer.cpp 16 KB

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