HMDStereoRender::HMDStereoRender(irr::IrrlichtDevice *device, HMDDescriptor HMD, f32 worldScale) : _worldScale(worldScale), _renderTexture(NULL) { _smgr = device->getSceneManager(); _driver = device->getVideoDriver(); _timer = device->getTimer(); // Create perspectiva camera used for rendering _pCamera = _smgr->addCameraSceneNode(); // Init shader parameters _distortionCB.scale[0] = 1.0f; _distortionCB.scale[1] = 1.0f; _distortionCB.scaleIn[0] = 1.0f; _distortionCB.scaleIn[1] = 1.0f; _distortionCB.lensCenter[0] = 0.0f;_distortionCB.lensCenter[1] = 0.0f; _distortionCB.hmdWarpParam[0] = 1.0f;_distortionCB.hmdWarpParam[1] = 0.0f;_distortionCB.hmdWarpParam[2] = 0.0f;_distortionCB.hmdWarpParam[3] = 0.0f; // Plane _planeVertices[0] = video::S3DVertex(-1.0f, -1.0f, 1.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f); _planeVertices[1] = video::S3DVertex(-1.0f, 1.0f, 1.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f); _planeVertices[2] = video::S3DVertex( 1.0f, 1.0f, 1.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f); _planeVertices[3] = video::S3DVertex( 1.0f, -1.0f, 1.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f); _planeIndices[0] = 0; _planeIndices[1] = 1; _planeIndices[2] = 2; _planeIndices[3] = 0; _planeIndices[4] = 2; _planeIndices[5] = 3; // Create shader material _renderMaterial.Wireframe = false; _renderMaterial.Lighting = false; _renderMaterial.TextureLayer[0].TextureWrapU = ETC_CLAMP; _renderMaterial.TextureLayer[0].TextureWrapV = ETC_CLAMP; IGPUProgrammingServices* gpu = _driver->getGPUProgrammingServices(); _renderMaterial.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial(vertexShader, "main", EVST_VS_3_0, fragShader, "main", EPST_PS_3_0, &_distortionCB); setHMD(HMD); }
PostProcessing::PostProcessing(video::IVideoDriver* video_driver) { // Check if post-processing is supported on this hardware m_supported = false; if( irr_driver->isGLSL() ) { m_supported = true; } //Check which texture dimensions are supported on this hardware bool nonsquare = video_driver->queryFeature(video::EVDF_TEXTURE_NSQUARE); bool nonpower = video_driver->queryFeature(video::EVDF_TEXTURE_NPOT); if (!nonpower) { Log::warn("PostProcessing", "Only power of two textures are supported."); } if (!nonsquare) { Log::warn("PostProcessing", "Only square textures are supported."); } // Initialization if(m_supported) { // Render target core::dimension2du opt = video_driver->getScreenSize() .getOptimalSize(!nonpower, !nonsquare); m_render_target = video_driver->addRenderTargetTexture(opt, "postprocess"); if(!m_render_target) { Log::warn("PostProcessing", "Couldn't create the render target " "for post-processing, disabling it."); UserConfigParams::m_postprocess_enabled = false; } // Material and shaders IGPUProgrammingServices* gpu = video_driver->getGPUProgrammingServices(); s32 material_type = gpu->addHighLevelShaderMaterialFromFiles( (file_manager->getShaderDir() + "motion_blur.vert").c_str(), "main", video::EVST_VS_2_0, (file_manager->getShaderDir() + "motion_blur.frag").c_str(), "main", video::EPST_PS_2_0, this, video::EMT_SOLID); m_blur_material.MaterialType = (E_MATERIAL_TYPE)material_type; m_blur_material.setTexture(0, m_render_target); m_blur_material.Wireframe = false; m_blur_material.Lighting = false; m_blur_material.ZWriteEnable = false; } } // PostProcessing
/** Initialization */ void PostProcessing::init(video::IVideoDriver* video_driver) { // Check if post-processing is supported on this hardware m_supported = false; if( video_driver->queryFeature(video::EVDF_ARB_GLSL) && video_driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0) && video_driver->queryFeature(video::EVDF_RENDER_TO_TARGET)) { m_supported = true; } //Check which texture dimensions are supported on this hardware bool nonsquare = video_driver->queryFeature(video::EVDF_TEXTURE_NSQUARE); bool nonpower = video_driver->queryFeature(video::EVDF_TEXTURE_NPOT); if (!nonpower) { fprintf(stdout, "WARNING: Only power of two textures are supported.\n"); } if (!nonsquare) { fprintf(stdout, "WARNING: Only square textures are supported.\n"); } // Initialization if(m_supported) { // Render target m_render_target = video_driver->addRenderTargetTexture(video_driver->getScreenSize().getOptimalSize(!nonpower, !nonsquare), "postprocess"); if(!m_render_target) { fprintf(stderr, "Couldn't create the render target for post-processing, disabling it\n"); UserConfigParams::m_postprocess_enabled = false; } // Material and shaders IGPUProgrammingServices* gpu = video_driver->getGPUProgrammingServices(); s32 material_type = gpu->addHighLevelShaderMaterialFromFiles( (file_manager->getDataDir() + "shaders/motion_blur.vert").c_str(), "main", video::EVST_VS_2_0, (file_manager->getDataDir() + "shaders/motion_blur.frag").c_str(), "main", video::EPST_PS_2_0, this, video::EMT_SOLID); m_material.MaterialType = (E_MATERIAL_TYPE)material_type; m_material.setTexture(0, m_render_target); m_material.Wireframe = false; m_material.Lighting = false; m_material.ZWriteEnable = false; } }
// ---------------------------------------------------------------------------- void Terrain::initMaterials() { IVideoDriver* vd = Editor::getEditor()->getVideoDriver(); IGPUProgrammingServices* gpu = vd->getGPUProgrammingServices(); s32 material_type; material_type = gpu->addHighLevelShaderMaterial( vs, ps, this, EMT_SOLID); m_material.MaterialType = (E_MATERIAL_TYPE)material_type; m_material.setTexture(1, createSplattingImg()); m_material.setTexture(2, vd->getTexture(L"dirt.jpg")); m_material.setTexture(3, vd->getTexture(L"grass2.jpg")); m_material.setTexture(4, vd->getTexture(L"rock_brown.jpg")); m_material.setTexture(5, vd->getTexture(L"sand2.jpg")); m_material.setTexture(0, m_material.getTexture(1)); m_highlight_material.Lighting = false; m_highlight_material.MaterialType = EMT_TRANSPARENT_VERTEX_ALPHA; m_highlight_material.Wireframe = true; m_material.BackfaceCulling = false; }
int main( ) { // Boring stuff: set up the scene, object & camera as usual // To make things more interesting, we add many Sydneys and a textured floor this time IrrlichtDevice* device = createDevice( DRIVER, dimension2d<s32>( 640, 480 ), 16, false, false, false, 0 ); IVideoDriver* driver = device->getVideoDriver( ); ISceneManager* smgr = device->getSceneManager( ); IGUIEnvironment* guienv = device->getGUIEnvironment( ); device->getFileSystem( )->changeWorkingDirectoryTo( MEDIA_DIRECTORY ); guienv->addStaticText( L"Sandbox", rect<s32>( 10, 10, 260, 22 ), true ); IAnimatedMesh* mesh = smgr->getMesh("sydney.md2"); IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices( ); u32 matid; switch( driver->getDriverType( ) ) { case EDT_OPENGL: matid = gpu->addHighLevelShaderMaterial( GL_V_MAT, "main", EVST_VS_1_1, GL_PLAIN, "main", EPST_PS_1_1, new CTexturesShaderCallback( ), EMT_SOLID, 1 ); break; case EDT_DIRECT3D8: case EDT_DIRECT3D9: default: matid = gpu->addHighLevelShaderMaterial( DX_V_MAT, "main", EVST_VS_1_1, DX_PLAIN, "main", EPST_PS_2_0, new CTexturesShaderCallback( ), EMT_SOLID, 0 ); } for( u8 x = 0u; x != 2u; ++ x ) for( u8 i = 0u; i != 5u; ++ i ) { IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); node->setMaterialFlag(EMF_LIGHTING, false); node->setMD2Animation(scene::EMAT_STAND); node->setMaterialTexture( 0, driver->getTexture("sydney.bmp") ); node->setMaterialType( (E_MATERIAL_TYPE) matid ); node->setPosition( vector3df( -x * 20.0f, 0.0f, i * 40.0f ) ); } ISceneNode* nodeF = smgr->addTerrainSceneNode( "terrain-heightmap.bmp" ); nodeF->setMaterialFlag(EMF_LIGHTING, false); nodeF->setMaterialTexture( 0, driver->getTexture("terrain-heightmap.bmp") ); nodeF->setPosition( vector3df( -512.0f, -50.0f, -512.0f ) ); nodeF->setScale( vector3df( 4.0f, 0.2f, 4.0f ) ); nodeF->setMaterialType( (E_MATERIAL_TYPE) matid ); ICameraSceneNode* cam1 = smgr->addCameraSceneNode( 0, vector3df( 0.0f, 0.0f, -40.0f ), vector3df( 0.0f, 5.0f, 50.0f ) ); IPostProc* ppRenderer1 = new CRendererPostProc( smgr, dimension2di( 1024, 512 ), true, true, SColor( 255, 130u, 180u, 230u ) ); CWaterPostProc* ppWater = new CWaterPostProc( ppRenderer1, dimension2di( 1024, 512 ), -22.0f ); ppWater->setTimer( device->getTimer( ) ); wchar_t tmp[255]; u8 t = 0u; while( device->run( ) ) { // cam1->setPosition( vector3df( 40.0f, 60.0f - (device->getCursorControl( )->getPosition( ).Y - 240.0f) * 0.1f, -40.0f ) ); cam1->setPosition( vector3df( (device->getCursorControl( )->getPosition( ).X - 320.0f) * 0.1f, (device->getCursorControl( )->getPosition( ).Y - 240.0f) * 0.1f, -40.0f ) ); // cam1->setTarget( vector3df( (device->getCursorControl( )->getPosition( ).X - 320.0f) * 0.1f, (device->getCursorControl( )->getPosition( ).Y - 240.0f) * 0.1f, 0.0f ) ); // cam1->setTarget( cam1->getPosition( ) + vector3df( 0.0f, 0.0f, 10.0f ) ); // cam1->setTarget( vector3df( -(device->getCursorControl( )->getPosition( ).X - 320.0f) * 0.1f, (device->getCursorControl( )->getPosition( ).Y - 240.0f) * 0.2f, 50.0f ) ); driver->beginScene( false, driver->getDriverType( ) == video::EDT_DIRECT3D9 ); ppWater->render( NULL ); guienv->drawAll( ); driver->endScene( ); if( ++ t == 30u ) { t = 0u; swprintf(tmp, 255, L"%ls fps:%3d", driver->getName(), driver->getFPS() ); device->setWindowCaption( tmp ); } } delete ppWater; delete ppRenderer1; // Back to boring stuff device->drop(); return 0; }
int main( ) { // Boring stuff: set up the scene, object & camera as usual // To make things more interesting, we add many Sydneys and a textured floor this time IrrlichtDevice* device = createDevice( DRIVER, dimension2d<s32>( 640, 480 ), 16, false, false, false, 0 ); IVideoDriver* driver = device->getVideoDriver( ); ISceneManager* smgr = device->getSceneManager( ); IGUIEnvironment* guienv = device->getGUIEnvironment( ); device->getFileSystem( )->changeWorkingDirectoryTo( MEDIA_DIRECTORY ); guienv->addStaticText( L"Heat Haze (with Depth dependence)", rect<s32>( 10, 10, 260, 22 ), true ); IAnimatedMesh* mesh = smgr->getMesh("sydney.md2"); ISceneManager* smgr2 = smgr->createNewSceneManager( false ); ISceneNode* rootnode2 = smgr2->getRootSceneNode( ); IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices( ); u32 matid, matid2; switch( driver->getDriverType( ) ) { case EDT_OPENGL: matid = gpu->addHighLevelShaderMaterial( GL_V_MAT, "main", EVST_VS_1_1, GL_PLAIN, "main", EPST_PS_1_1, new CTexturesShaderCallback( ), EMT_SOLID, 1 ); matid2 = gpu->addHighLevelShaderMaterial( GL_V_MAT, "main", EVST_VS_1_1, GL_HEATSOURCE, "main", EPST_PS_1_1, new CTexturesShaderCallback( ), EMT_TRANSPARENT_ALPHA_CHANNEL, 1 ); break; case EDT_DIRECT3D8: case EDT_DIRECT3D9: default: matid = gpu->addHighLevelShaderMaterial( DX_V_MAT, "main", EVST_VS_1_1, DX_PLAIN, "main", EPST_PS_2_0, new CTexturesShaderCallback( ), EMT_SOLID, 0 ); matid2 = gpu->addHighLevelShaderMaterial( DX_V_MAT, "main", EVST_VS_1_1, DX_HEATSOURCE, "main", EPST_PS_2_0, new CTexturesShaderCallback( ), EMT_TRANSPARENT_ALPHA_CHANNEL, 0 ); } for( u8 x = 0u; x != 2u; ++ x ) for( u8 i = 0u; i != 5u; ++ i ) { IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); node->setMaterialFlag(EMF_LIGHTING, false); node->setMD2Animation(scene::EMAT_STAND); node->setMaterialTexture( 0, driver->getTexture("sydney.bmp") ); node->setMaterialType( (E_MATERIAL_TYPE) matid ); node->setPosition( vector3df( -x * 20.0f, 0.0f, i * 40.0f ) ); ISceneNode* node2 = smgr2->addBillboardSceneNode( rootnode2, dimension2df( 30.0f, 80.0f ), vector3df( -x * 20.0f, 30.0f, i * 40.0f ) ); node2->setMaterialFlag(EMF_LIGHTING, false); node2->setMaterialType( EMT_TRANSPARENT_ADD_COLOR ); node2->setMaterialTexture( 0, driver->getTexture("fireball.bmp") ); node2->setMaterialType( (E_MATERIAL_TYPE) matid2 ); } ISceneNode* nodeF = smgr->addMeshSceneNode( smgr->addHillPlaneMesh( "", dimension2df( 200.0f, 200.0f ), dimension2d<u32>( 10, 10 ), NULL, 0.0f, dimension2df( 0.0f, 0.0f ), dimension2df( 100.0f, 100.0f ) ) ); nodeF->setMaterialFlag(EMF_LIGHTING, false); nodeF->setMaterialTexture( 0, driver->getTexture("terrain-heightmap.bmp") ); nodeF->setPosition( vector3df( 0.0f, -22.0f, 0.0f ) ); nodeF->setMaterialType( (E_MATERIAL_TYPE) matid ); ICameraSceneNode* cam1 = smgr->addCameraSceneNode( 0, vector3df( 40.0f, 60.0f, -40.0f ), vector3df( 0.0f, 5.0f, 50.0f ) ); ICameraSceneNode* cam2 = smgr2->addCameraSceneNode( rootnode2, vector3df( 40.0f, 60.0f, -40.0f ), vector3df( 0.0f, 5.0f, 50.0f ) ); IPostProc* ppRenderer1 = new CRendererPostProc( smgr, dimension2di( 1024, 512 ), true, true, SColor( 255u, 100u, 101u, 140u ) ); IPostProc* ppRenderer2 = new CRendererPostProc( smgr2, dimension2di( 1024, 512 ), true, true, SColor( 255u, 0u, 0u, 0u ) ); CEffectPostProc* ppHaze = new CEffectPostProc( ppRenderer1, dimension2di( 1024, 512 ), PP_HAZEDEPTH ); ppHaze->setInput( 1, ppRenderer2 ); ppHaze->setTimer( device->getTimer( ) ); // These variables aren't important - they are just for showing the FPS wchar_t tmp[255]; u8 t = 0u; while( device->run( ) ) { cam1->setPosition( vector3df( 40.0f, 60.0f - (device->getCursorControl( )->getPosition( ).Y - 240.0f) * 0.1f, -40.0f ) ); cam1->setTarget( vector3df( -(device->getCursorControl( )->getPosition( ).X - 320.0f) * 0.1f, (device->getCursorControl( )->getPosition( ).Y - 240.0f) * 0.2f, 50.0f ) ); cam2->setPosition( cam1->getPosition( ) ); cam2->setTarget( cam1->getTarget( ) ); cam2->setUpVector( cam1->getUpVector( ) ); driver->beginScene( false, driver->getDriverType( ) == video::EDT_DIRECT3D9 ); ppHaze->render( NULL ); guienv->drawAll( ); driver->endScene( ); // Show the current FPS if( ++ t == 30u ) { t = 0u; swprintf(tmp, 255, L"%ls fps:%3d", driver->getName(), driver->getFPS() ); device->setWindowCaption( tmp ); } } delete ppHaze; delete ppRenderer1; delete ppRenderer2; // Back to boring stuff device->drop(); return 0; }
int main( ) { // Boring stuff: set up the scene, object & camera as usual // To make things more interesting, we add many Sydneys and a textured floor this time IrrlichtDevice* device = createDevice( DRIVER, dimension2d<s32>( 640, 480 ), 16, false, false, false, 0 ); IVideoDriver* driver = device->getVideoDriver( ); ISceneManager* smgr = device->getSceneManager( ); IGUIEnvironment* guienv = device->getGUIEnvironment( ); device->getFileSystem( )->changeWorkingDirectoryTo( MEDIA_DIRECTORY ); guienv->addStaticText( L"Depth of Field", rect<s32>( 10, 10, 260, 22 ), true ); IAnimatedMesh* mesh = smgr->getMesh("sydney.md2"); // Create the required material. This is a simple shader which draws the texture with no lights. // Use GL_PLAIN1 / DX_PLANE1 or GL_PLAIN2 / DX_PLANE2 to support 1 or 2 basic point-lights u32 matid; IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices( ); switch( driver->getDriverType( ) ) { case EDT_OPENGL: matid = gpu->addHighLevelShaderMaterial( GL_V_MAT, "main", EVST_VS_1_1, GL_PLAIN, "main", EPST_PS_1_1, new CTexturesShaderCallback( ), EMT_SOLID, 1 ); break; case EDT_DIRECT3D8: case EDT_DIRECT3D9: default: matid = gpu->addHighLevelShaderMaterial( DX_V_MAT, "main", EVST_VS_1_1, DX_PLAIN, "main", EPST_PS_2_0, new CTexturesShaderCallback( ), EMT_SOLID, 0 ); } for( u8 x = 0u; x != 2u; ++ x ) for( u8 i = 0u; i != 5u; ++ i ) { IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); node->setMaterialFlag(EMF_LIGHTING, false); node->setMD2Animation(scene::EMAT_STAND); node->setMaterialTexture( 0, driver->getTexture("sydney.bmp") ); node->setMaterialType( (E_MATERIAL_TYPE) matid ); node->setPosition( vector3df( -x * 20.0f, 0.0f, i * 40.0f ) ); } ISceneNode* node2 = smgr->addMeshSceneNode( smgr->addHillPlaneMesh( "", dimension2df( 200.0f, 200.0f ), dimension2d<u32>( 10, 10 ), NULL, 0.0f, dimension2df( 0.0f, 0.0f ), dimension2df( 100.0f, 100.0f ) ) ); node2->setMaterialFlag(EMF_LIGHTING, false); node2->setMaterialTexture( 0, driver->getTexture("terrain-heightmap.bmp") ); node2->setMaterialType( (E_MATERIAL_TYPE) matid ); node2->setPosition( vector3df( 0.0f, -22.0f, 0.0f ) ); ICameraSceneNode* cam = smgr->addCameraSceneNode( 0, vector3df( 40.0f, 60.0f, -40.0f ), vector3df( 0.0f, 5.0f, 50.0f ) ); IPostProc* ppRenderer = new CRendererPostProc( smgr, dimension2di( 1024, 512 ), true, true, SColor( 255u, 100u, 101u, 140u ) ); CEffectPostProc* ppBlurDOF = new CEffectPostProc( ppRenderer, dimension2di( 1024, 512 ), PP_BLURDOF ); // We could set parameters on creation, but no need since we will animate it anyway. // Parameters are: near blur, near focus, far focus, far blur, blur level // You can also use PP_BLURDOFNEAR or PP_BLURDOFFAR to have only near or far blurring // These variables aren't important - they are just for showing the FPS wchar_t tmp[255]; u8 t = 0u; while( device->run( ) ) { // Change the camera angle cam->setTarget( vector3df( -(device->getCursorControl( )->getPosition( ).X - 320.0f) * 0.1f, (device->getCursorControl( )->getPosition( ).Y - 240.0f) * 0.2f, 0.0f ) ); // Animate the depth of field: f32 p = sinf( device->getTimer( )->getTime( ) * 0.0005f ) * 0.5f - 0.2f; ppBlurDOF->setParameters( p * 100.0f + 80.0f, p * 100.0f + 110.0f, p * 100.0f + 160.0f, p * 100.0f + 240.0f, 0.01f ); driver->beginScene( false, driver->getDriverType( ) == video::EDT_DIRECT3D9 ); ppBlurDOF->render( NULL ); guienv->drawAll( ); driver->endScene( ); // Show the current FPS if( ++ t == 30u ) { t = 0u; swprintf(tmp, 255, L"%ls fps:%3d", driver->getName(), driver->getFPS() ); device->setWindowCaption( tmp ); } } delete ppBlurDOF; delete ppRenderer; // Back to boring stuff device->drop(); return 0; }
int main(int argc, char **argv) { // Help? if (argv[1] && argv[1][0] == '-') die(helpmsg); putenv((char *) "vblank_mode=0"); // No vsync for us, thanks. MyEventReceiver *r = new MyEventReceiver(); IrrlichtDevice *dev = createDevice(EDT_OPENGL, core::dimension2d<u32>(1024,768), 32, false, false, false, r); if (!dev) die("Can't initialize Irrlicht"); IVideoDriver *drv = dev->getVideoDriver(); ISceneManager *smgr = dev->getSceneManager(); IGPUProgrammingServices *gpu = drv->getGPUProgrammingServices(); ICameraSceneNode *cam = NULL; ITexture *pic = NULL; IMeshSceneNode *ball = NULL; bool showpic = false; IReadFile *areamap = createMemoryReadFile(AreaMap33, sizeof(AreaMap33), "AreaMap33", false); if (!areamap) die("Failed to load areamap"); ITexture *areamaptex = drv->getTexture(areamap); areamap->drop(); // If there's an argument, assume it is a pic to load; otherwise, draw a sphere if (argv[1] && access(argv[1], R_OK) == 0) { showpic = true; pic = drv->getTexture(argv[1]); if (!pic) die("Can't load image"); cam = smgr->addCameraSceneNode(); } else { cam = smgr->addCameraSceneNodeMaya(); cam->setTarget(vector3df(0, 0, 0)); ball = smgr->addSphereSceneNode(40, 8); int ballshader = gpu->addHighLevelShaderMaterial(rnd,0,EVST_VS_1_1,0); ball->setMaterialType((E_MATERIAL_TYPE) ballshader); ISceneNodeAnimator *cool = smgr->createRotationAnimator(vector3df(-0.1, 0.1, -0.1)); ball->addAnimator(cool); cool->drop(); } // Set up static defines, RTTs, quads dimension2d<u32> screensize = drv->getScreenSize(); char defines[128]; snprintf(defines, 128, "#define PIXEL_SIZE vec2(1.0f / %u.0, 1.0f / %u.0)\n" "#define MAX_SEARCH_STEPS 8.0\n#define MAX_DISTANCE 33.0\n", screensize.Width, screensize.Height); ITexture *rt1 = drv->addRenderTargetTexture(screensize, "rt1", ECF_A8R8G8B8); ITexture *rt2 = drv->addRenderTargetTexture(screensize, "rt2", ECF_A8R8G8B8); ITexture *rt3 = drv->addRenderTargetTexture(screensize, "rt3", ECF_A8R8G8B8); if (!rt1 || !rt2 || !rt3) die("No RTT"); ScreenQuad *def = new ScreenQuad(drv); ScreenQuad *sq = new ScreenQuad(drv); ScreenQuad *sq2 = new ScreenQuad(drv); ScreenQuad *sq3 = new ScreenQuad(drv); ScreenQuad *norm = new ScreenQuad(drv); if (showpic) def->SetTexture(pic); sq->SetTexture(rt1); sq->GetMaterial().setFlag(EMF_BILINEAR_FILTER, false); norm->SetTexture(rt1); norm->GetMaterial().setFlag(EMF_BILINEAR_FILTER, false); sq2->SetTexture(rt2); sq2->SetTexture(rt2, 1); sq2->SetTexture(areamaptex, 2); sq2->GetMaterial().TextureLayer[2].BilinearFilter = false; sq3->SetTexture(rt3); sq3->GetMaterial().setFlag(EMF_BILINEAR_FILTER, false); sq3->SetTexture(rt1,1); state_t state = MLAA_OFF; stringc tmp1, tmp2; tmp1 = defines; tmp1 += offsetvs; tmp2 = defines; tmp2 += color1fs; // Load shaders int edge = gpu->addHighLevelShaderMaterial(tmp1.c_str(),0,EVST_VS_1_1,tmp2.c_str()); sq->SetMaterialType((E_MATERIAL_TYPE) edge); tmp2 = defines; tmp2 += blend2fs; blendcb *bcb = new blendcb(); edge = gpu->addHighLevelShaderMaterial(tmp1.c_str(),0,EVST_VS_1_1,tmp2.c_str(),0,EPST_PS_1_1,bcb); sq2->SetMaterialType((E_MATERIAL_TYPE) edge); tmp2 = defines; tmp2 += neigh3fs; neighcb *ncb = new neighcb(); edge = gpu->addHighLevelShaderMaterial(tmp1.c_str(),0,EVST_VS_1_1,tmp2.c_str(),0,EPST_PS_1_1,ncb); sq3->SetMaterialType((E_MATERIAL_TYPE) edge); // Record start time int lastfps = -1, minfps = 10000; unsigned long long total_frames = 0, fxtimer = 0, tmplong, onframes = 0; struct timeval starttime, tick1, tick2; float glsltime = 0; gettimeofday(&starttime, NULL); wchar_t cap[20]; glEnable(GL_STENCIL_TEST); unsigned char firstrun = 1; // To avoid the glsl compiler in the timing // Main loop while (dev->run()) { gettimeofday(&tick1, NULL); drv->beginScene(); switch (state) { case MLAA_OFF: if (showpic) def->Render(false); else smgr->drawAll(); break; case MLAA_ON: if (showpic) def->Render(rt1); else { drv->setRenderTarget(rt1); smgr->drawAll(); } glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS, 1, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); sq->Render(rt2); glStencilFunc(GL_EQUAL, 1, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); sq2->Render(rt3); drv->setRenderTarget(rt1, false, false); // Overlay the smoothed edges on the initial image sq3->Render(false); // Blit the final image to the framebuffer glStencilFunc(GL_ALWAYS, 1, ~0); norm->Render(); break; } drv->endScene(); if (state == MLAA_ON) { gettimeofday(&tick2, NULL); if (!firstrun) { tmplong = (tick2.tv_sec - tick1.tv_sec) * 10000; tmplong += (tick2.tv_usec - tick1.tv_usec) / 100; fxtimer += tmplong; onframes++; } else { firstrun = 0; glsltime = tick2.tv_sec - tick1.tv_sec; glsltime += (tick2.tv_usec - tick1.tv_usec) / 1000000.0; } } int fps = drv->getFPS(); if (minfps > fps) minfps = fps; if (lastfps != fps) { swprintf(cap, 20, L"%d fps, MLAA %s", fps, state == MLAA_ON ? "on" : "off"); dev->setWindowCaption(cap); lastfps = fps; } if (r->IsKeyDown(KEY_KEY_M)) { if (state == MLAA_ON) state = MLAA_OFF; else state = MLAA_ON; lastfps++; } usleep(1); // 16? total_frames++; } dev->drop(); delete ncb; delete bcb; delete def; delete sq; delete sq2; delete sq3; delete norm; delete r; struct timeval endtime; gettimeofday(&endtime, NULL); float sec = endtime.tv_sec - starttime.tv_sec; sec += ((float) endtime.tv_usec - starttime.tv_usec) / 1000000; printf("\nRan %.3fs, ", sec); sec -= glsltime; printf("average fps %.2f, min %d\n", (float) total_frames/sec, minfps); if (onframes) { printf("\nAverage on fps %.2f, average off fps %.2f\n\n", (float) onframes/(fxtimer/10000.0), (float) (total_frames - onframes)/(sec - (fxtimer/10000.0))); // printf("MLAA took on average %.1fms\n", (float) (fxtimer / onframes) / 10.0); } return 0; }