| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- #include <stdlib.h>
- #include <stdio.h>
- #include <jpeglib.h>
- #include "Renderer.h"
- #include "Texture.h"
- #include "Scene.h"
- #include "Camera.h"
- #include "App.h"
- namespace R {
- /*
- =======================================================================================================================================
- data vars =
- =======================================================================================================================================
- */
- // misc
- uint w, h;
- uint framesNum = 0;
- float aspectRatio;
- int maxColorAtachments = 0;
- //float renderingQuality = 1.0;
- int screenshotJpegQuality = 90;
- static ShaderProg* shdr_final;
- // for the pps and is quad rendering
- float quad_vert_cords [][2] = { {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0} };
- /**
- * Standard shader preprocessor defines. Used to pass some global params to the shaders. The standard shader preprocessor defines
- * go on top of the shader code and its defines
- */
- string std_shader_preproc_defines;
- // texture
- bool mipmaping = true;
- int max_anisotropy = 8;
- int maxTextureUnits = -1;
- bool textureCompression = false;
- //=====================================================================================================================================
- // DrawQuad =
- //=====================================================================================================================================
- void DrawQuad( int vertCoords_uni_loc )
- {
- /*glEnableClientState( GL_VERTEX_ARRAY );
- glVertexPointer( 2, GL_FLOAT, 0, quad_vert_cords );
- glDrawArrays( GL_QUADS, 0, 4 );
- glDisableClientState( GL_VERTEX_ARRAY );*/
- glVertexAttribPointer( vertCoords_uni_loc, 2, GL_FLOAT, false, 0, quad_vert_cords );
- glEnableVertexAttribArray( vertCoords_uni_loc );
- glDrawArrays( GL_QUADS, 0, 4 );
- glDisableVertexAttribArray( vertCoords_uni_loc );
- }
- /*
- =======================================================================================================================================
- BuildStdShaderPreProcStr =
- I pass all the static vars (vars that do not change at all) with defines so I dont have to update uniform vars =
- =======================================================================================================================================
- */
- static void BuildStdShaderPreProcStr()
- {
- string& tmp = std_shader_preproc_defines;
- tmp = "#version 150 compatibility\n";
- tmp += "precision lowp float;\n";
- tmp += "#pragma optimize(on)\n";
- tmp += "#pragma debug(off)\n";
- tmp += "#define R_W " + Util::floatToStr(R::w) + "\n";
- tmp += "#define R_H " + Util::floatToStr(R::h) + "\n";
- //tmp += "#define R_Q " + floatToStr(R::renderingQuality) + "\n";
- tmp += "#define SHADOWMAP_SIZE " + Util::intToStr(R::Is::Shad::shadowResolution) + "\n";
- if( R::Is::Shad::pcf )
- tmp += "#define _SHADOW_MAPPING_PCF_\n";
- if( R::Pps::Ssao::enabled )
- {
- tmp += "#define _SSAO_\n";
- tmp += "#define SSAO_RENDERING_QUALITY " + Util::floatToStr(R::Pps::Ssao::renderingQuality) + "\n";
- }
- if( R::Pps::edgeaa::enabled )
- tmp += "#define _EDGEAA_\n";
- if( R::Pps::Hdr::enabled )
- {
- tmp += "#define _HDR_\n";
- tmp += "#define HDR_RENDERING_QUALITY " + Util::floatToStr(R::Pps::Hdr::renderingQuality) + "\n";
- }
- if( R::Pps::Lscatt::enabled )
- {
- tmp += "#define _LSCATT_\n";
- tmp += "#define LSCATT_RENDERING_QUALITY " + Util::floatToStr(R::Pps::Lscatt::renderingQuality) + "\n";
- }
- }
- /*
- =======================================================================================================================================
- init =
- =======================================================================================================================================
- */
- void init()
- {
- PRINT( "Renderer initializing..." );
- glewInit();
- if( !glewIsSupported("GL_VERSION_2_1") )
- WARNING( "OpenGL ver 2.1 not supported. The application may crash (and burn)" );
- if( !glewIsSupported("GL_EXT_framebuffer_object") )
- WARNING( "Framebuffer objects not supported. The application may crash (and burn)" );
- if( !glewIsSupported("GL_EXT_packed_depth_stencil") )
- WARNING( "GL_EXT_packed_depth_stencil not supported. The application may crash (and burn)" );
- if( !glewIsSupported("GL_ARB_vertex_buffer_object") )
- WARNING( "Vertex buffer objects not supported. The application may crash (and burn)" );
- if( !glewIsSupported("GL_ARB_texture_non_power_of_two") )
- WARNING( "Textures of non power of two not supported. The application may crash (and burn)" );
- if( !glewIsSupported("GL_ARB_vertex_buffer_object") )
- WARNING( "Vertex Buffer Objects not supported. The application may crash (and burn)" );
- w = App::windowW /* * renderingQuality*/;
- h = App::windowH /* * renderingQuality*/;
- aspectRatio = float(w)/h;
- glClearColor( 0.1, 0.1, 0.1, 0.0 );
- glClearDepth( 1.0 );
- glClearStencil( 0 );
- glDepthFunc( GL_LEQUAL );
- // query for maxColorAtachments
- glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &maxColorAtachments );
- // get max texture units
- glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits );
- // CullFace is always on
- glCullFace( GL_BACK );
- glEnable( GL_CULL_FACE );
- // defaults
- glDisable( GL_LIGHTING );
- glDisable( GL_TEXTURE_2D );
- glDisable( GL_BLEND );
- glPolygonMode( GL_FRONT, GL_FILL );
- // Hints
- //glHint( GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_FASTEST );
- //glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST );
- //glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
- //glHint( GL_POINT_SMOOTH_HINT, GL_FASTEST );
- //glHint( GL_POLYGON_SMOOTH_HINT, GL_FASTEST );
- //glHint( GL_TEXTURE_COMPRESSION_HINT, GL_NICEST );
- // execute this after the cvars are set and before the other inits (be cause these inits contain shader loads)
- BuildStdShaderPreProcStr();
- // misc
- shdr_final = rsrc::shaders.load( "shaders/final.glsl" );
- // init deferred stages
- // WARNING: the order of the inits is crucial!!!!!
- R::Ms::init();
- R::Is::init();
- R::Bs::init();
- R::Pps::init();
- R::Bs::init2();
- R::Dbg::init();
- PRINT( "Renderer initialization ends" );
- }
- /*
- =======================================================================================================================================
- render =
- =======================================================================================================================================
- */
- void render( const Camera& cam )
- {
- R::Ms::runStage( cam );
- R::Is::runStage( cam );
- R::Bs::runStage( cam );
- R::Pps::runStage( cam );
- R::Bs::runStage2( cam );
- R::Dbg::runStage( cam );
- //R::setViewport( 0, 0, App::windowW, App::windowH );
- R::setViewport( 0, 0, App::windowW, App::windowH );
- glDisable( GL_DEPTH_TEST );
- glDisable( GL_BLEND );
- shdr_final->bind();
- shdr_final->locTexUnit( shdr_final->GetUniLoc(0), R::Pps::fai, 0 );
- /*const int step = 100;
- if( R::framesNum < step )
- shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::diffuseFai, 0 );
- else if( R::framesNum < step*2 )
- shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::normalFai, 0 );
- else if( R::framesNum < step*3 )
- shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::specularFai, 0 );
- else if( R::framesNum < step*4 )
- shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::Ms::depthFai, 0 );
- else if( R::framesNum < step*5 )
- shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::pps::ssao::bluredFai, 0 );
- else if( R::framesNum < step*6 )
- {
- shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::pps::hdr::pass2Fai, 0 );
- }
- else
- shdr_final->locTexUnit( shdr_final->getUniLoc(0), R::pps::fai, 0 );*/
- R::DrawQuad( shdr_final->getAttribLoc(0) );
- }
- /*
- =======================================================================================================================================
- setProjectionMatrix =
- =======================================================================================================================================
- */
- void setProjectionMatrix( const Camera& cam )
- {
- glMatrixMode( GL_PROJECTION );
- loadMatrix( cam.getProjectionMatrix() );
- }
- /*
- =======================================================================================================================================
- setViewMatrix =
- =======================================================================================================================================
- */
- void setViewMatrix( const Camera& cam )
- {
- glMatrixMode( GL_MODELVIEW );
- loadMatrix( cam.getViewMatrix() );
- }
- /*
- =======================================================================================================================================
- unproject =
- my version of gluUnproject =
- =======================================================================================================================================
- */
- bool unproject( float winX, float winY, float winZ, // window screen coords
- const Mat4& modelview_mat, const Mat4& projection_mat, const int* view,
- float& objX, float& objY, float& objZ )
- {
- Mat4 inv_pm = projection_mat * modelview_mat;
- inv_pm.invert();
- // the vec is in ndc space meaning: -1<=vec.x<=1 -1<=vec.y<=1 -1<=vec.z<=1
- Vec4 vec;
- vec.x = (2.0*(winX-view[0]))/view[2] - 1.0;
- vec.y = (2.0*(winY-view[1]))/view[3] - 1.0;
- vec.z = 2.0*winZ - 1.0;
- vec.w = 1.0;
- Vec4 final = inv_pm * vec;
- final /= final.w;
- objX = final.x;
- objY = final.y;
- objZ = final.z;
- return true;
- }
- /*
- =======================================================================================================================================
- ortho =
- =======================================================================================================================================
- */
- Mat4 ortho( float left, float right, float bottom, float top, float near, float far )
- {
- float difx = right-left;
- float dify = top-bottom;
- float difz = far-near;
- float tx = -(right+left) / difx;
- float ty = -(top+bottom) / dify;
- float tz = -(far+near) / difz;
- Mat4 m;
- m(0,0) = 2.0 / difx;
- m(0,1) = 0.0;
- m(0,2) = 0.0;
- m(0,3) = tx;
- m(1,0) = 0.0;
- m(1,1) = 2.0 / dify;
- m(1,2) = 0.0;
- m(1,3) = ty;
- m(2,0) = 0.0;
- m(2,1) = 0.0;
- m(2,2) = -2.0 / difz;
- m(2,3) = tz;
- m(3,0) = 0.0;
- m(3,1) = 0.0;
- m(3,2) = 0.0;
- m(3,3) = 1.0;
- return m;
- }
- /*
- =======================================================================================================================================
- prepareNextFrame =
- =======================================================================================================================================
- */
- void prepareNextFrame()
- {
- framesNum++;
- }
- /*
- =======================================================================================================================================
- printLastError =
- =======================================================================================================================================
- */
- void printLastError()
- {
- GLenum errid = glGetError();
- if( errid != GL_NO_ERROR )
- ERROR( "OpenGL Error: " << gluErrorString( errid ) );
- }
- //=====================================================================================================================================
- // getLastError =
- //=====================================================================================================================================
- const uchar* getLastError()
- {
- return gluErrorString( glGetError() );
- }
- /*
- =======================================================================================================================================
- TakeScreenshotTGA =
- =======================================================================================================================================
- */
- static bool TakeScreenshotTGA( const char* filename )
- {
- // open file and check
- fstream fs;
- fs.open( filename, ios::out|ios::binary );
- if( !fs.good() )
- {
- ERROR( "Cannot create screenshot. File \"" << filename << "\"" );
- return false;
- }
- // write headers
- unsigned char tga_header_uncompressed[12] = {0,0,2,0,0,0,0,0,0,0,0,0};
- unsigned char header[6];
- header[1] = R::w / 256;
- header[0] = R::w % 256;
- header[3] = R::h / 256;
- header[2] = R::h % 256;
- header[4] = 24;
- header[5] = 0;
- fs.write( (char*)tga_header_uncompressed, 12 );
- fs.write( (char*)header, 6 );
- // write the buffer
- char* buffer = (char*)calloc( R::w*R::h*3, sizeof(char) );
- glReadPixels( 0, 0, R::w, R::h, GL_BGR, GL_UNSIGNED_BYTE, buffer );
- fs.write( buffer, R::w*R::h*3 );
- // end
- fs.close();
- free( buffer );
- return true;
- }
- /*
- =======================================================================================================================================
- TakeScreenshotJPEG =
- =======================================================================================================================================
- */
- static bool TakeScreenshotJPEG( const char* filename )
- {
- // open file
- FILE* outfile = fopen( filename, "wb" );
- if( !outfile )
- {
- ERROR( "Cannot open file \"" << filename << "\"" );
- return false;
- }
- // set jpg params
- jpeg_compress_struct cinfo;
- jpeg_error_mgr jerr;
- cinfo.err = jpeg_std_error( &jerr );
- jpeg_create_compress( &cinfo );
- jpeg_stdio_dest( &cinfo, outfile );
- cinfo.image_width = R::w;
- cinfo.image_height = R::h;
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
- jpeg_set_defaults( &cinfo);
- jpeg_set_quality ( &cinfo, screenshotJpegQuality, true );
- jpeg_start_compress( &cinfo, true );
- // read from OGL
- char* buffer = (char*)malloc( R::w*R::h*3*sizeof(char) );
- glReadPixels( 0, 0, R::w, R::h, GL_RGB, GL_UNSIGNED_BYTE, buffer );
- // write buffer to file
- JSAMPROW row_pointer;
- while( cinfo.next_scanline < cinfo.image_height )
- {
- row_pointer = (JSAMPROW) &buffer[ (R::h-1-cinfo.next_scanline)*3*R::w ];
- jpeg_write_scanlines( &cinfo, &row_pointer, 1 );
- }
- jpeg_finish_compress(&cinfo);
- // done
- free( buffer );
- fclose( outfile );
- return true;
- }
- /*
- =======================================================================================================================================
- takeScreenshot =
- =======================================================================================================================================
- */
- void takeScreenshot( const char* filename )
- {
- char* ext = Util::getFileExtension( filename );
- bool ret;
- // exec from this extension
- if( strcmp( ext, "tga" ) == 0 )
- {
- ret = TakeScreenshotTGA( filename );
- }
- else if( strcmp( ext, "jpg" ) == 0 )
- {
- ret = TakeScreenshotJPEG( filename );
- }
- else
- {
- ERROR( "File \"" << filename << "\": Unsupported extension. Watch for capital" );
- return;
- }
- if( !ret ) ERROR( "In taking screenshot" )
- else PRINT( "Screenshot \"" << filename << "\" saved" );
- }
- } // end namespace
|