1
0
Fork 0

Add the ability to record depth in color buffer. This should solve depth buffer resolution problem for older NVidia cards.

This commit is contained in:
Frederic Bouvier 2012-05-01 08:27:13 +02:00
parent 38ca3dda60
commit 746b0d60cc
3 changed files with 85 additions and 61 deletions

View file

@ -50,49 +50,50 @@ namespace flightgear
class GraphicsWindow; class GraphicsWindow;
struct RenderBufferInfo { struct RenderBufferInfo {
enum Kind { enum Kind {
DEPTH_BUFFER, REAL_DEPTH_BUFFER, // Only used if depth buffer is a color texture
NORMAL_BUFFER, DEPTH_BUFFER,
DIFFUSE_BUFFER, NORMAL_BUFFER,
SPEC_EMIS_BUFFER, DIFFUSE_BUFFER,
LIGHTING_BUFFER, SPEC_EMIS_BUFFER,
LIGHTING_BUFFER,
SHADOW_BUFFER SHADOW_BUFFER
}; };
RenderBufferInfo(osg::Texture2D* t = 0, float s = 1.0 ) : texture(t), scaleFactor(s) {} RenderBufferInfo(osg::Texture2D* t = 0, float s = 1.0 ) : texture(t), scaleFactor(s) {}
osg::ref_ptr<osg::Texture2D> texture; osg::ref_ptr<osg::Texture2D> texture;
float scaleFactor; float scaleFactor;
}; };
typedef std::map<RenderBufferInfo::Kind,RenderBufferInfo> RenderBufferMap; typedef std::map<RenderBufferInfo::Kind,RenderBufferInfo> RenderBufferMap;
typedef std::map<osg::Camera::BufferComponent,size_t> AttachmentMap; typedef std::map<osg::Camera::BufferComponent,size_t> AttachmentMap;
struct RenderStageInfo { struct RenderStageInfo {
RenderStageInfo(osg::Camera* camera_ = 0, int si = -1, bool fs = false) RenderStageInfo(osg::Camera* camera_ = 0, int si = -1, bool fs = false)
: camera(camera_), slaveIndex(si), scaleFactor(1.0f), fullscreen(fs) : camera(camera_), slaveIndex(si), scaleFactor(1.0f), fullscreen(fs)
, resizable(true) , resizable(true)
{ {
} }
osg::ref_ptr<osg::Camera> camera; osg::ref_ptr<osg::Camera> camera;
AttachmentMap buffers; AttachmentMap buffers;
int slaveIndex; int slaveIndex;
float scaleFactor; float scaleFactor;
bool fullscreen; bool fullscreen;
bool resizable; bool resizable;
}; };
enum CameraKind { enum CameraKind {
MAIN_CAMERA, MAIN_CAMERA,
FAR_CAMERA, FAR_CAMERA,
GEOMETRY_CAMERA, GEOMETRY_CAMERA,
SHADOW_CAMERA, SHADOW_CAMERA,
BLOOM_CAMERA_1, BLOOM_CAMERA_1,
BLOOM_CAMERA_2, BLOOM_CAMERA_2,
AO_CAMERA_1, AO_CAMERA_1,
AO_CAMERA_2, AO_CAMERA_2,
AO_CAMERA_3, AO_CAMERA_3,
LIGHTING_CAMERA, LIGHTING_CAMERA,
DISPLAY_CAMERA DISPLAY_CAMERA
}; };
typedef std::map<CameraKind,RenderStageInfo> CameraMap; typedef std::map<CameraKind,RenderStageInfo> CameraMap;
@ -115,10 +116,10 @@ struct CameraInfo : public osg::Referenced
{ {
} }
/** Update and resize cameras /** Update and resize cameras
*/ */
void updateCameras(); void updateCameras();
void resized(double w, double h); void resized(double w, double h);
/** The name as given in the config file. /** The name as given in the config file.
*/ */
std::string name; std::string name;
@ -146,19 +147,19 @@ struct CameraInfo : public osg::Referenced
/** the camera objects /** the camera objects
*/ */
CameraMap cameras; 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, 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, 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; } void addCamera( CameraKind k, osg::Camera* c, float s ) { cameras[k].camera = c; cameras[k].scaleFactor = s; }
osg::Camera* getCamera(CameraKind k) const; osg::Camera* getCamera(CameraKind k) const;
int getMainSlaveIndex() const; int getMainSlaveIndex() const;
RenderStageInfo& getRenderStageInfo( CameraKind k ) { return cameras[k]; } RenderStageInfo& getRenderStageInfo( CameraKind k ) { return cameras[k]; }
/** the buffer objects /** the buffer objects
*/ */
RenderBufferMap buffers; RenderBufferMap buffers;
void addBuffer(RenderBufferInfo::Kind k, osg::Texture2D* tex, float scale = 1.0 ) { buffers[k] = RenderBufferInfo(tex,scale); } 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::Texture2D* getBuffer(RenderBufferInfo::Kind k) const;
osg::ref_ptr<osg::TexGen> shadowTexGen[4]; osg::ref_ptr<osg::TexGen> shadowTexGen[4];
@ -170,9 +171,9 @@ struct CameraInfo : public osg::Referenced
osg::ref_ptr<osg::Uniform> du; osg::ref_ptr<osg::Uniform> du;
osg::ref_ptr<osg::Uniform> dv; osg::ref_ptr<osg::Uniform> 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. /** The reference points in the parents projection space.
*/ */
osg::Vec2d parentReference[2]; osg::Vec2d parentReference[2];

View file

@ -416,7 +416,8 @@ FGRenderer::FGRenderer() :
_fogColor( new osg::Uniform( "fg_FogColor", osg::Vec4f(1.0, 1.0, 1.0, 1.0) ) ), _fogColor( new osg::Uniform( "fg_FogColor", osg::Vec4f(1.0, 1.0, 1.0, 1.0) ) ),
_fogDensity( new osg::Uniform( "fg_FogDensity", 0.0001f ) ), _fogDensity( new osg::Uniform( "fg_FogDensity", 0.0001f ) ),
_shadowNumber( new osg::Uniform( "fg_ShadowNumber", (int)4 ) ), _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 #ifdef FG_JPEG_SERVER
jpgRenderFrame = updateRenderer; jpgRenderFrame = updateRenderer;
@ -519,6 +520,8 @@ FGRenderer::init( void )
updateCascadeFar(1, _cascadeFar[1]); updateCascadeFar(1, _cascadeFar[1]);
updateCascadeFar(2, _cascadeFar[2]); updateCascadeFar(2, _cascadeFar[2]);
updateCascadeFar(3, _cascadeFar[3]); updateCascadeFar(3, _cascadeFar[3]);
_useColorForDepth = fgGetBool( "/sim/rendering/use-color-for-depth", false );
_depthInColor->set( _useColorForDepth );
_scenery_loaded = fgGetNode("/sim/sceneryloaded", true); _scenery_loaded = fgGetNode("/sim/sceneryloaded", true);
_scenery_override = fgGetNode("/sim/sceneryloaded-override", true); _scenery_override = fgGetNode("/sim/sceneryloaded-override", true);
@ -770,14 +773,16 @@ osg::Texture2D* buildDeferredBuffer(GLint internalFormat, GLenum sourceFormat, G
return tex; 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 (useColorForDepth) {
if (false) 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::NORMAL_BUFFER, buildDeferredBuffer( 0x822C /*GL_RG16*/, 0x8227 /*GL_RG*/, GL_UNSIGNED_SHORT, 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::NORMAL_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::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::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) ); 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->setClearDepth( 1.0 );
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
camera->setViewport( new osg::Viewport ); 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_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_BUFFER1, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::DIFFUSE_BUFFER );
attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER2, flightgear::GEOMETRY_CAMERA, flightgear::RenderBufferInfo::SPEC_EMIS_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->setDrawBuffer(GL_FRONT);
camera->setReadBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT);
osg::StateSet* ss = camera->getOrCreateStateSet();
ss->addUniform( _depthInColor );
camera->addChild( mDeferredRealRoot.get() ); camera->addChild( mDeferredRealRoot.get() );
return camera; return camera;
@ -1252,14 +1265,19 @@ osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* in
camera->setRenderOrder(osg::Camera::POST_RENDER, 50); camera->setRenderOrder(osg::Camera::POST_RENDER, 50);
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
camera->setViewport( new osg::Viewport ); 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 ); 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->setDrawBuffer(GL_FRONT);
camera->setReadBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT);
camera->setClearColor( osg::Vec4( 0., 0., 0., 1. ) ); camera->setClearColor( osg::Vec4( 0., 0., 0., 1. ) );
camera->setClearMask( GL_COLOR_BUFFER_BIT ); camera->setClearMask( GL_COLOR_BUFFER_BIT );
osg::StateSet* ss = camera->getOrCreateStateSet(); osg::StateSet* ss = camera->getOrCreateStateSet();
ss->setAttribute( new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false) ); ss->setAttribute( new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false) );
ss->addUniform( _depthInColor );
osg::Group* lightingGroup = new osg::Group; osg::Group* lightingGroup = new osg::Group;
@ -1440,7 +1458,7 @@ FGRenderer::buildDeferredPipeline(flightgear::CameraGroup* cgroup, unsigned flag
osg::GraphicsContext* gc) osg::GraphicsContext* gc)
{ {
CameraInfo* info = new CameraInfo(flags); 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 ); osg::Camera* geometryCamera = buildDeferredGeometryCamera( info, gc );
cgroup->getViewer()->addSlave(geometryCamera, false); cgroup->getViewer()->addSlave(geometryCamera, false);
@ -1479,6 +1497,9 @@ FGRenderer::buildDeferredPipeline(flightgear::CameraGroup* cgroup, unsigned flag
camera->setProjectionMatrixAsOrtho2D(-1,1,-1,1); camera->setProjectionMatrixAsOrtho2D(-1,1,-1,1);
camera->addChild(eg); camera->addChild(eg);
osg::StateSet* ss = camera->getOrCreateStateSet();
ss->addUniform( _depthInColor );
cgroup->getViewer()->addSlave(camera, false); cgroup->getViewer()->addSlave(camera, false);
installCullVisitor(camera); installCullVisitor(camera);
slaveIndex = cgroup->getViewer()->getNumSlaves() - 1; slaveIndex = cgroup->getViewer()->getNumSlaves() - 1;

View file

@ -137,6 +137,7 @@ protected:
int _shadowMapSize; int _shadowMapSize;
size_t _numCascades; size_t _numCascades;
float _cascadeFar[4]; float _cascadeFar[4];
bool _useColorForDepth;
osg::Camera* buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); osg::Camera* buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
osg::Camera* buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); osg::Camera* buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc );
@ -152,6 +153,7 @@ protected:
osg::ref_ptr<osg::Uniform> _fogDensity; osg::ref_ptr<osg::Uniform> _fogDensity;
osg::ref_ptr<osg::Uniform> _shadowNumber; osg::ref_ptr<osg::Uniform> _shadowNumber;
osg::ref_ptr<osg::Uniform> _shadowDistances; osg::ref_ptr<osg::Uniform> _shadowDistances;
osg::ref_ptr<osg::Uniform> _depthInColor;
}; };
bool fgDumpSceneGraphToFile(const char* filename); bool fgDumpSceneGraphToFile(const char* filename);