From 746b0d60cc3f6323c13e1e727e0dfca7339305e0 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier Date: Tue, 1 May 2012 08:27:13 +0200 Subject: [PATCH] Add the ability to record depth in color buffer. This should solve depth buffer resolution problem for older NVidia cards. --- src/Viewer/CameraGroup.hxx | 101 +++++++++++++++++++------------------ src/Viewer/renderer.cxx | 43 ++++++++++++---- src/Viewer/renderer.hxx | 2 + 3 files changed, 85 insertions(+), 61 deletions(-) diff --git a/src/Viewer/CameraGroup.hxx b/src/Viewer/CameraGroup.hxx index 606bfc347..3966bcfe6 100644 --- a/src/Viewer/CameraGroup.hxx +++ b/src/Viewer/CameraGroup.hxx @@ -50,49 +50,50 @@ namespace flightgear class GraphicsWindow; struct RenderBufferInfo { - enum Kind { - DEPTH_BUFFER, - NORMAL_BUFFER, - DIFFUSE_BUFFER, - SPEC_EMIS_BUFFER, - LIGHTING_BUFFER, + enum Kind { + REAL_DEPTH_BUFFER, // Only used if depth buffer is a color texture + DEPTH_BUFFER, + NORMAL_BUFFER, + DIFFUSE_BUFFER, + SPEC_EMIS_BUFFER, + LIGHTING_BUFFER, SHADOW_BUFFER - }; + }; - RenderBufferInfo(osg::Texture2D* t = 0, float s = 1.0 ) : texture(t), scaleFactor(s) {} - osg::ref_ptr texture; - float scaleFactor; + RenderBufferInfo(osg::Texture2D* t = 0, float s = 1.0 ) : texture(t), scaleFactor(s) {} + osg::ref_ptr texture; + float scaleFactor; }; typedef std::map RenderBufferMap; typedef std::map AttachmentMap; struct RenderStageInfo { - RenderStageInfo(osg::Camera* camera_ = 0, int si = -1, bool fs = false) - : camera(camera_), slaveIndex(si), scaleFactor(1.0f), fullscreen(fs) - , resizable(true) - { - } + RenderStageInfo(osg::Camera* camera_ = 0, int si = -1, bool fs = false) + : camera(camera_), slaveIndex(si), scaleFactor(1.0f), fullscreen(fs) + , resizable(true) + { + } - osg::ref_ptr camera; - AttachmentMap buffers; - int slaveIndex; - float scaleFactor; - bool fullscreen; - bool resizable; + osg::ref_ptr camera; + AttachmentMap buffers; + int slaveIndex; + float scaleFactor; + bool fullscreen; + bool resizable; }; enum CameraKind { - MAIN_CAMERA, - FAR_CAMERA, - GEOMETRY_CAMERA, - SHADOW_CAMERA, - BLOOM_CAMERA_1, - BLOOM_CAMERA_2, - AO_CAMERA_1, - AO_CAMERA_2, - AO_CAMERA_3, - LIGHTING_CAMERA, - DISPLAY_CAMERA + MAIN_CAMERA, + FAR_CAMERA, + GEOMETRY_CAMERA, + SHADOW_CAMERA, + BLOOM_CAMERA_1, + BLOOM_CAMERA_2, + AO_CAMERA_1, + AO_CAMERA_2, + AO_CAMERA_3, + LIGHTING_CAMERA, + DISPLAY_CAMERA }; typedef std::map CameraMap; @@ -115,10 +116,10 @@ struct CameraInfo : public osg::Referenced { } - /** Update and resize cameras - */ - void updateCameras(); - void resized(double w, double h); + /** Update and resize cameras + */ + void updateCameras(); + void resized(double w, double h); /** The name as given in the config file. */ std::string name; @@ -146,19 +147,19 @@ struct CameraInfo : public osg::Referenced /** the camera objects */ - CameraMap cameras; - void addCamera( CameraKind k, osg::Camera* c, int si = -1, bool fs = false ) { cameras[k].camera = c; cameras[k].slaveIndex = si; cameras[k].fullscreen = fs; } - void addCamera( CameraKind k, osg::Camera* c, bool fs ) { cameras[k].camera = c; cameras[k].fullscreen = fs; } - void addCamera( CameraKind k, osg::Camera* c, float s ) { cameras[k].camera = c; cameras[k].scaleFactor = s; } - osg::Camera* getCamera(CameraKind k) const; - int getMainSlaveIndex() const; - RenderStageInfo& getRenderStageInfo( CameraKind k ) { return cameras[k]; } + CameraMap cameras; + void addCamera( CameraKind k, osg::Camera* c, int si = -1, bool fs = false ) { cameras[k].camera = c; cameras[k].slaveIndex = si; cameras[k].fullscreen = fs; } + void addCamera( CameraKind k, osg::Camera* c, bool fs ) { cameras[k].camera = c; cameras[k].fullscreen = fs; } + void addCamera( CameraKind k, osg::Camera* c, float s ) { cameras[k].camera = c; cameras[k].scaleFactor = s; } + osg::Camera* getCamera(CameraKind k) const; + int getMainSlaveIndex() const; + RenderStageInfo& getRenderStageInfo( CameraKind k ) { return cameras[k]; } - /** the buffer objects - */ - RenderBufferMap buffers; - void addBuffer(RenderBufferInfo::Kind k, osg::Texture2D* tex, float scale = 1.0 ) { buffers[k] = RenderBufferInfo(tex,scale); } - osg::Texture2D* getBuffer(RenderBufferInfo::Kind k) const; + /** the buffer objects + */ + RenderBufferMap buffers; + void addBuffer(RenderBufferInfo::Kind k, osg::Texture2D* tex, float scale = 1.0 ) { buffers[k] = RenderBufferInfo(tex,scale); } + osg::Texture2D* getBuffer(RenderBufferInfo::Kind k) const; osg::ref_ptr shadowTexGen[4]; @@ -170,9 +171,9 @@ struct CameraInfo : public osg::Referenced osg::ref_ptr du; osg::ref_ptr dv; - void setMatrices( osg::Camera* c ); + void setMatrices( osg::Camera* c ); - osgUtil::RenderBin::RenderBinList savedTransparentBins; + osgUtil::RenderBin::RenderBinList savedTransparentBins; /** The reference points in the parents projection space. */ osg::Vec2d parentReference[2]; diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx index f6ca1e94d..4e11982c1 100644 --- a/src/Viewer/renderer.cxx +++ b/src/Viewer/renderer.cxx @@ -416,7 +416,8 @@ FGRenderer::FGRenderer() : _fogColor( new osg::Uniform( "fg_FogColor", osg::Vec4f(1.0, 1.0, 1.0, 1.0) ) ), _fogDensity( new osg::Uniform( "fg_FogDensity", 0.0001f ) ), _shadowNumber( new osg::Uniform( "fg_ShadowNumber", (int)4 ) ), - _shadowDistances( new osg::Uniform( "fg_ShadowDistances", osg::Vec4f(5.0, 50.0, 500.0, 5000.0 ) ) ) + _shadowDistances( new osg::Uniform( "fg_ShadowDistances", osg::Vec4f(5.0, 50.0, 500.0, 5000.0 ) ) ), + _depthInColor( new osg::Uniform( "fg_DepthInColor", false ) ) { #ifdef FG_JPEG_SERVER jpgRenderFrame = updateRenderer; @@ -519,6 +520,8 @@ FGRenderer::init( void ) updateCascadeFar(1, _cascadeFar[1]); updateCascadeFar(2, _cascadeFar[2]); updateCascadeFar(3, _cascadeFar[3]); + _useColorForDepth = fgGetBool( "/sim/rendering/use-color-for-depth", false ); + _depthInColor->set( _useColorForDepth ); _scenery_loaded = fgGetNode("/sim/sceneryloaded", true); _scenery_override = fgGetNode("/sim/sceneryloaded-override", true); @@ -770,14 +773,16 @@ osg::Texture2D* buildDeferredBuffer(GLint internalFormat, GLenum sourceFormat, G return tex; } -void buildDeferredBuffers( flightgear::CameraInfo* info, int shadowMapSize, bool normal16 ) +void buildDeferredBuffers( flightgear::CameraInfo* info, int shadowMapSize, bool useColorForDepth ) { - info->addBuffer(flightgear::RenderBufferInfo::DEPTH_BUFFER, buildDeferredBuffer( GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, osg::Texture::CLAMP_TO_BORDER) ); - if (false) - info->addBuffer(flightgear::RenderBufferInfo::NORMAL_BUFFER, buildDeferredBuffer( 0x822C /*GL_RG16*/, 0x8227 /*GL_RG*/, GL_UNSIGNED_SHORT, osg::Texture::CLAMP_TO_BORDER) ); - else - info->addBuffer(flightgear::RenderBufferInfo::NORMAL_BUFFER, buildDeferredBuffer( GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, osg::Texture::CLAMP_TO_BORDER) ); - + if (useColorForDepth) { + info->addBuffer(flightgear::RenderBufferInfo::REAL_DEPTH_BUFFER, buildDeferredBuffer( GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, osg::Texture::CLAMP_TO_BORDER) ); + info->addBuffer(flightgear::RenderBufferInfo::DEPTH_BUFFER, buildDeferredBuffer( GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, osg::Texture::CLAMP_TO_BORDER) ); + } + else { + info->addBuffer(flightgear::RenderBufferInfo::DEPTH_BUFFER, buildDeferredBuffer( GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, osg::Texture::CLAMP_TO_BORDER) ); + } + info->addBuffer(flightgear::RenderBufferInfo::NORMAL_BUFFER, buildDeferredBuffer( GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, osg::Texture::CLAMP_TO_BORDER) ); info->addBuffer(flightgear::RenderBufferInfo::DIFFUSE_BUFFER, buildDeferredBuffer( GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, osg::Texture::CLAMP_TO_BORDER) ); info->addBuffer(flightgear::RenderBufferInfo::SPEC_EMIS_BUFFER, buildDeferredBuffer( GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, osg::Texture::CLAMP_TO_BORDER) ); info->addBuffer(flightgear::RenderBufferInfo::LIGHTING_BUFFER, buildDeferredBuffer( GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, osg::Texture::CLAMP_TO_BORDER) ); @@ -805,13 +810,21 @@ osg::Camera* FGRenderer::buildDeferredGeometryCamera( flightgear::CameraInfo* in camera->setClearDepth( 1.0 ); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setViewport( new osg::Viewport ); - attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::DEPTH_BUFFER ); attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER0, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::NORMAL_BUFFER ); attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER1, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::DIFFUSE_BUFFER ); attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER2, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::SPEC_EMIS_BUFFER ); + if (_useColorForDepth) { + attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::REAL_DEPTH_BUFFER ); + attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER3, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::DEPTH_BUFFER ); + } else { + attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::DEPTH_BUFFER ); + } camera->setDrawBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT); + osg::StateSet* ss = camera->getOrCreateStateSet(); + ss->addUniform( _depthInColor ); + camera->addChild( mDeferredRealRoot.get() ); return camera; @@ -1252,14 +1265,19 @@ osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* in camera->setRenderOrder(osg::Camera::POST_RENDER, 50); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setViewport( new osg::Viewport ); - attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::LIGHTING_CAMERA, flightgear::RenderBufferInfo::DEPTH_BUFFER ); attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER, flightgear::LIGHTING_CAMERA, flightgear::RenderBufferInfo::LIGHTING_BUFFER ); + if (_useColorForDepth) { + attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::REAL_DEPTH_BUFFER ); + } else { + attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::DEPTH_BUFFER ); + } camera->setDrawBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT); camera->setClearColor( osg::Vec4( 0., 0., 0., 1. ) ); camera->setClearMask( GL_COLOR_BUFFER_BIT ); osg::StateSet* ss = camera->getOrCreateStateSet(); ss->setAttribute( new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false) ); + ss->addUniform( _depthInColor ); osg::Group* lightingGroup = new osg::Group; @@ -1440,7 +1458,7 @@ FGRenderer::buildDeferredPipeline(flightgear::CameraGroup* cgroup, unsigned flag osg::GraphicsContext* gc) { CameraInfo* info = new CameraInfo(flags); - buildDeferredBuffers( info, _shadowMapSize, !fgGetBool("/sim/rendering/no-16bit-buffer", false ) ); + buildDeferredBuffers(info, _shadowMapSize, _useColorForDepth); osg::Camera* geometryCamera = buildDeferredGeometryCamera( info, gc ); cgroup->getViewer()->addSlave(geometryCamera, false); @@ -1479,6 +1497,9 @@ FGRenderer::buildDeferredPipeline(flightgear::CameraGroup* cgroup, unsigned flag camera->setProjectionMatrixAsOrtho2D(-1,1,-1,1); camera->addChild(eg); + osg::StateSet* ss = camera->getOrCreateStateSet(); + ss->addUniform( _depthInColor ); + cgroup->getViewer()->addSlave(camera, false); installCullVisitor(camera); slaveIndex = cgroup->getViewer()->getNumSlaves() - 1; diff --git a/src/Viewer/renderer.hxx b/src/Viewer/renderer.hxx index fa089bc80..10ae668db 100644 --- a/src/Viewer/renderer.hxx +++ b/src/Viewer/renderer.hxx @@ -137,6 +137,7 @@ protected: int _shadowMapSize; size_t _numCascades; float _cascadeFar[4]; + bool _useColorForDepth; osg::Camera* buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); osg::Camera* buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); @@ -152,6 +153,7 @@ protected: osg::ref_ptr _fogDensity; osg::ref_ptr _shadowNumber; osg::ref_ptr _shadowDistances; + osg::ref_ptr _depthInColor; }; bool fgDumpSceneGraphToFile(const char* filename); -- 2.39.5