Skip to content
Snippets Groups Projects
Commit c961eea2 authored by Felix de las Pozas's avatar Felix de las Pozas
Browse files

Merge branch 'particle-lab' into 'master'

Improve ParticleLab support.

See merge request nsviz/visimpl!87
parents 746c19b9 548356c4
No related branches found
No related tags found
No related merge requests found
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
cmake_minimum_required( VERSION 3.1 FATAL_ERROR ) cmake_minimum_required( VERSION 3.1 FATAL_ERROR )
# visimpl project and version # visimpl project and version
project( visimpl VERSION 1.8.2 ) project( visimpl VERSION 1.8.3 )
set( visimpl_VERSION_ABI 6 ) set( visimpl_VERSION_ABI 6 )
SET( VISIMPL_LICENSE "GPL") SET( VISIMPL_LICENSE "GPL")
......
...@@ -24,6 +24,8 @@ namespace visimpl ...@@ -24,6 +24,8 @@ namespace visimpl
, _currentRenderer( nullptr ) , _currentRenderer( nullptr )
, _defaultRenderer( nullptr ) , _defaultRenderer( nullptr )
, _solidRenderer( nullptr ) , _solidRenderer( nullptr )
, _solidMode( false )
, _accumulativeMode( false )
, _decay( 0.0f ) , _decay( 0.0f )
{ {
} }
...@@ -62,15 +64,48 @@ namespace visimpl ...@@ -62,15 +64,48 @@ namespace visimpl
visimpl::PARTICLE_SOLID_FRAGMENT_SHADER ); visimpl::PARTICLE_SOLID_FRAGMENT_SHADER );
_solidProgram.compileAndLink( ); _solidProgram.compileAndLink( );
_defaultRenderer = std::make_shared< plab::CoverageRenderer >( _defaultAccProgram.loadFromText(
visimpl::PARTICLE_VERTEX_SHADER ,
visimpl::PARTICLE_ACC_DEFAULT_FRAGMENT_SHADER );
_defaultAccProgram.compileAndLink( );
_solidAccProgram.loadFromText(
visimpl::PARTICLE_VERTEX_SHADER ,
visimpl::PARTICLE_ACC_SOLID_FRAGMENT_SHADER );
_solidAccProgram.compileAndLink( );
_defaultRenderer = std::make_shared< plab::SimpleRenderer >(
_defaultProgram.program( )); _defaultProgram.program( ));
_solidRenderer = std::make_shared< plab::CoverageRenderer >( _solidRenderer = std::make_shared< plab::SimpleRenderer >(
_solidProgram.program( )); _solidProgram.program( ));
_currentRenderer = _defaultRenderer; _defaultAccRenderer = std::make_shared< plab::SimpleRenderer >(
_defaultAccProgram.program( ));
_solidAccRenderer = std::make_shared< plab::SimpleRenderer >(
_solidAccProgram.program( ));
_selectionCluster->setModel( _selectionModel ); _selectionCluster->setModel( _selectionModel );
_selectionCluster->setRenderer( _currentRenderer );
refreshRenderer( );
}
void DomainManager::refreshRenderer( )
{
if ( _accumulativeMode )
{
_currentRenderer = _solidMode ? _solidAccRenderer : _defaultAccRenderer;
}
else
{
_currentRenderer = _solidMode ? _solidRenderer : _defaultRenderer;
}
if ( _selectionCluster != nullptr )
_selectionCluster->setRenderer( _currentRenderer );
for ( const auto& item: _groupClusters )
item.second->setRenderer( _currentRenderer );
for ( const auto& item: _attributeClusters )
item.second->setRenderer( _currentRenderer );
} }
#ifdef SIMIL_USE_BRION #ifdef SIMIL_USE_BRION
...@@ -291,8 +326,7 @@ namespace visimpl ...@@ -291,8 +326,7 @@ namespace visimpl
_currentRenderer , _currentRenderer ,
_selectionModel->isClippingEnabled( )); _selectionModel->isClippingEnabled( ));
group->getModel( )->setAccumulativeMode( group->getModel( )->setAccumulativeMode( _accumulativeMode );
_selectionModel->isAccumulativeMode( ));
std::vector< uint32_t > ids; std::vector< uint32_t > ids;
std::vector< NeuronParticle > particles; std::vector< NeuronParticle > particles;
...@@ -326,8 +360,7 @@ namespace visimpl ...@@ -326,8 +360,7 @@ namespace visimpl
_currentRenderer , _currentRenderer ,
_selectionModel->isClippingEnabled( )); _selectionModel->isClippingEnabled( ));
group->getModel( )->setAccumulativeMode( group->getModel( )->setAccumulativeMode( _accumulativeMode );
_selectionModel->isAccumulativeMode( ));
std::vector< NeuronParticle > particles; std::vector< NeuronParticle > particles;
for ( const auto& gid: _selectionGids ) for ( const auto& gid: _selectionGids )
...@@ -345,7 +378,7 @@ namespace visimpl ...@@ -345,7 +378,7 @@ namespace visimpl
void DomainManager::removeGroup( const std::string& name ) void DomainManager::removeGroup( const std::string& name )
{ {
if(1 != _groupClusters.erase( name )) if ( 1 != _groupClusters.erase( name ))
{ {
std::cerr << "DomainManager: Error removing group '" << name std::cerr << "DomainManager: Error removing group '" << name
<< "' - " << __FILE__ << ":" << __LINE__ << std::endl; << "' - " << __FILE__ << ":" << __LINE__ << std::endl;
...@@ -373,8 +406,7 @@ namespace visimpl ...@@ -373,8 +406,7 @@ namespace visimpl
_selectionModel->getRightPlane( ) , _selectionModel->getRightPlane( ) ,
_currentRenderer , _currentRenderer ,
_selectionModel->isClippingEnabled( )); _selectionModel->isClippingEnabled( ));
group->getModel( )->setAccumulativeMode( group->getModel( )->setAccumulativeMode( _accumulativeMode );
_selectionModel->isAccumulativeMode( ));
const auto currentIndex = i % colors.size( ); const auto currentIndex = i % colors.size( );
const auto color = colors[ currentIndex ].toRgb( ); const auto color = colors[ currentIndex ].toRgb( );
...@@ -402,14 +434,21 @@ namespace visimpl ...@@ -402,14 +434,21 @@ namespace visimpl
} }
bool DomainManager::isAccumulativeModeEnabled( )
{
return _accumulativeMode;
}
void DomainManager::enableAccumulativeMode( bool enabled ) void DomainManager::enableAccumulativeMode( bool enabled )
{ {
_accumulativeMode = enabled;
if ( _selectionModel != nullptr ) if ( _selectionModel != nullptr )
{ {
_selectionModel->setAccumulativeMode( enabled ); _selectionModel->setAccumulativeMode( enabled );
} }
for ( const auto& item: _groupClusters ) for ( const auto& item: _groupClusters )
item.second->getModel( )->setAccumulativeMode( enabled ); item.second->getModel( )->setAccumulativeMode( enabled );
refreshRenderer( );
} }
void DomainManager::enableClipping( bool enabled ) void DomainManager::enableClipping( bool enabled )
...@@ -456,22 +495,14 @@ namespace visimpl ...@@ -456,22 +495,14 @@ namespace visimpl
void DomainManager::applyDefaultShader( ) void DomainManager::applyDefaultShader( )
{ {
_currentRenderer = _defaultRenderer; _solidMode = false;
_selectionCluster->setRenderer( _currentRenderer ); refreshRenderer( );
for ( const auto& item: _groupClusters )
item.second->setRenderer( _currentRenderer );
for ( const auto& item: _attributeClusters )
item.second->setRenderer( _currentRenderer );
} }
void DomainManager::applySolidShader( ) void DomainManager::applySolidShader( )
{ {
_currentRenderer = _solidRenderer; _solidMode = true;
_selectionCluster->setRenderer( _currentRenderer ); refreshRenderer( );
for ( const auto& item: _groupClusters )
item.second->setRenderer( _currentRenderer );
for ( const auto& item: _attributeClusters )
item.second->setRenderer( _currentRenderer );
} }
void DomainManager::processInput( void DomainManager::processInput(
...@@ -551,7 +582,7 @@ namespace visimpl ...@@ -551,7 +582,7 @@ namespace visimpl
{ {
particle->timestamp = -std::numeric_limits< float >::infinity( ); particle->timestamp = -std::numeric_limits< float >::infinity( );
} }
auto gid = item.second->getGids().at( i ); auto gid = item.second->getGids( ).at( i );
auto value = input.find( gid ); auto value = input.find( gid );
if ( value != input.cend( )) if ( value != input.cend( ))
{ {
...@@ -580,7 +611,7 @@ namespace visimpl ...@@ -580,7 +611,7 @@ namespace visimpl
{ {
particle->timestamp = -std::numeric_limits< float >::infinity( ); particle->timestamp = -std::numeric_limits< float >::infinity( );
} }
auto gid = item.second->getGids().at( i ); auto gid = item.second->getGids( ).at( i );
auto value = input.find( gid ); auto value = input.find( gid );
if ( value != input.cend( )) if ( value != input.cend( ))
{ {
......
...@@ -47,10 +47,16 @@ namespace visimpl ...@@ -47,10 +47,16 @@ namespace visimpl
// Renders // Renders
reto::ShaderProgram _defaultProgram; reto::ShaderProgram _defaultProgram;
reto::ShaderProgram _solidProgram; reto::ShaderProgram _solidProgram;
reto::ShaderProgram _defaultAccProgram;
reto::ShaderProgram _solidAccProgram;
std::shared_ptr< plab::CoverageRenderer > _currentRenderer; std::shared_ptr< plab::SimpleRenderer > _currentRenderer;
std::shared_ptr< plab::CoverageRenderer > _defaultRenderer; std::shared_ptr< plab::SimpleRenderer > _defaultRenderer;
std::shared_ptr< plab::CoverageRenderer > _solidRenderer; std::shared_ptr< plab::SimpleRenderer > _solidRenderer;
std::shared_ptr< plab::SimpleRenderer > _defaultAccRenderer;
std::shared_ptr< plab::SimpleRenderer > _solidAccRenderer;
bool _solidMode , _accumulativeMode;
// Others // Others
tBoundingBox _boundingBox; tBoundingBox _boundingBox;
...@@ -65,6 +71,8 @@ namespace visimpl ...@@ -65,6 +71,8 @@ namespace visimpl
const std::shared_ptr< reto::ClippingPlane >& rightPlane , const std::shared_ptr< reto::ClippingPlane >& rightPlane ,
const std::shared_ptr< plab::ICamera >& camera ); const std::shared_ptr< plab::ICamera >& camera );
void refreshRenderer( );
#ifdef SIMIL_USE_BRION #ifdef SIMIL_USE_BRION
void initAttributeData( const TGIDSet& gids , void initAttributeData( const TGIDSet& gids ,
...@@ -97,7 +105,7 @@ namespace visimpl ...@@ -97,7 +105,7 @@ namespace visimpl
void setTime( float time ); void setTime( float time );
void addTime( float time, float endTime ); void addTime( float time , float endTime );
const tBoundingBox& getBoundingBox( ) const; const tBoundingBox& getBoundingBox( ) const;
...@@ -125,6 +133,8 @@ namespace visimpl ...@@ -125,6 +133,8 @@ namespace visimpl
void applySolidShader( ); void applySolidShader( );
bool isAccumulativeModeEnabled( );
void enableAccumulativeMode( bool enabled ); void enableAccumulativeMode( bool enabled );
void enableClipping( bool enabled ); void enableClipping( bool enabled );
......
...@@ -61,8 +61,6 @@ ...@@ -61,8 +61,6 @@
constexpr float ZOOM_FACTOR = 1.3f; constexpr float ZOOM_FACTOR = 1.3f;
constexpr float TRANSLATION_FACTOR = 0.001f; constexpr float TRANSLATION_FACTOR = 0.001f;
constexpr float ROTATION_FACTOR = 0.01f; constexpr float ROTATION_FACTOR = 0.01f;
constexpr int FRAMEBUFFER_SCALE_FACTOR = 2;
constexpr int SAMPLES = 4;
constexpr float DEFAULT_DELTA_TIME = 0.5f; constexpr float DEFAULT_DELTA_TIME = 0.5f;
const QString INITIAL_CAMERA_POSITION = "0,0,0;1;1,0,0,0,1,0,0,0,1"; const QString INITIAL_CAMERA_POSITION = "0,0,0;1;1,0,0,0,1,0,0,0,1";
...@@ -81,44 +79,18 @@ namespace visimpl ...@@ -81,44 +79,18 @@ namespace visimpl
constexpr float invRGBInt = 1.0f / 255; constexpr float invRGBInt = 1.0f / 255;
const static std::string vertexShaderCode = R"(#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
TexCoords = aTexCoords;
}
)";
const static std::string screenFragment = R"(#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
void main()
{
FragColor = vec4(texture(screenTexture, TexCoords).rgb, 1);
}
)";
OpenGLWidget::OpenGLWidget( QWidget* parent_ , OpenGLWidget::OpenGLWidget( QWidget* parent_ ,
Qt::WindowFlags windowsFlags_ , Qt::WindowFlags windowsFlags_ ,
const std::string& const std::string&
#ifdef VISIMPL_USE_ZEROEQ #ifdef VISIMPL_USE_ZEROEQ
zeqUri zeqUri
#endif #endif
) )
: QOpenGLWidget( parent_ , windowsFlags_ ) : QOpenGLWidget( parent_ , windowsFlags_ )
#ifdef VISIMPL_USE_ZEROEQ #ifdef VISIMPL_USE_ZEROEQ
, _zeqUri( zeqUri ) , _zeqUri( zeqUri )
#endif #endif
, _gl( )
, _fpsLabel( nullptr ) , _fpsLabel( nullptr )
, _labelCurrentTime( nullptr ) , _labelCurrentTime( nullptr )
, _showFps( false ) , _showFps( false )
...@@ -189,12 +161,10 @@ void main() ...@@ -189,12 +161,10 @@ void main()
, _deltaEvents( 0.125f ) , _deltaEvents( 0.125f )
, _domainManager( ) , _domainManager( )
, _screenPlaneShader( nullptr ) , _screenPlaneShader( nullptr )
, _msaaFrameBuffer( 0 ) , _quadVAO( 0 )
, _msaaTextureColor( 0 ) , _weightFrameBuffer( 0 )
, _msaaRBODepth( 0 ) , _accumulationTexture( 0 )
, _midFrameBuffer( 0 ) , _revealTexture( 0 )
, _midTextureColor( 0 )
, _midRBODepth( 0 )
{ {
_lastCameraPosition = glm::vec3( 0 , 0 , 0 ); _lastCameraPosition = glm::vec3( 0 , 0 , 0 );
...@@ -277,7 +247,7 @@ void main() ...@@ -277,7 +247,7 @@ void main()
} }
} }
#else #else
_camera = std::make_shared< Camera >( ); _camera = std::make_shared< Camera >( );
#endif #endif
Q_ASSERT( _camera ); Q_ASSERT( _camera );
...@@ -292,7 +262,7 @@ void main() ...@@ -292,7 +262,7 @@ void main()
void OpenGLWidget::initializeGL( void ) void OpenGLWidget::initializeGL( void )
{ {
initializeOpenGLFunctions( ); _gl.initializeOpenGLFunctions( );
auto* logger = new QOpenGLDebugLogger( this ); auto* logger = new QOpenGLDebugLogger( this );
logger->initialize( ); logger->initialize( );
...@@ -316,8 +286,6 @@ void main() ...@@ -316,8 +286,6 @@ void main()
glPolygonMode( GL_FRONT_AND_BACK , GL_FILL ); glPolygonMode( GL_FRONT_AND_BACK , GL_FILL );
glEnable( GL_CULL_FACE ); glEnable( GL_CULL_FACE );
glLineWidth( 1.5 );
_then = std::chrono::system_clock::now( ); _then = std::chrono::system_clock::now( );
_lastFrame = std::chrono::system_clock::now( ); _lastFrame = std::chrono::system_clock::now( );
...@@ -331,13 +299,14 @@ void main() ...@@ -331,13 +299,14 @@ void main()
const GLubyte* shadingVer = glGetString( GL_SHADING_LANGUAGE_VERSION ); const GLubyte* shadingVer = glGetString( GL_SHADING_LANGUAGE_VERSION );
_screenPlaneShader = new reto::ShaderProgram( ); _screenPlaneShader = new reto::ShaderProgram( );
_screenPlaneShader->loadVertexShaderFromText( vertexShaderCode ); _screenPlaneShader->loadVertexShaderFromText( SHADER_SCREEN_VERTEX );
_screenPlaneShader->loadFragmentShaderFromText( screenFragment ); _screenPlaneShader->loadFragmentShaderFromText( SHADER_SCREEN_FRAGMENT );
_screenPlaneShader->create( ); _screenPlaneShader->create( );
_screenPlaneShader->link( ); _screenPlaneShader->link( );
_screenPlaneShader->autocatching( true ); _screenPlaneShader->autocatching( true );
_screenPlaneShader->use( ); _screenPlaneShader->use( );
_screenPlaneShader->sendUniformi( "screenTexture" , 0 ); _screenPlaneShader->sendUniformi( "accumulation" , 0 );
_screenPlaneShader->sendUniformi( "reveal" , 1 );
std::cout << "OpenGL Hardware: " << vendor << " (" << renderer << ")" std::cout << "OpenGL Hardware: " << vendor << " (" << renderer << ")"
...@@ -348,84 +317,66 @@ void main() ...@@ -348,84 +317,66 @@ void main()
void OpenGLWidget::_initRenderToTexture( void ) void OpenGLWidget::_initRenderToTexture( void )
{ {
_screenPlaneShader = new reto::ShaderProgram( );
_screenPlaneShader->loadVertexShaderFromText( vertexShaderCode );
_screenPlaneShader->loadFragmentShaderFromText( screenFragment );
_screenPlaneShader->create( );
_screenPlaneShader->link( );
_screenPlaneShader->autocatching( true );
_screenPlaneShader->use( );
_screenPlaneShader->sendUniformi( "screenTexture" , 0 );
// Generate the MSAA framebuffer
glGenFramebuffers( 1 , &_msaaFrameBuffer ); // Generate the OIR framebuffer
glBindFramebuffer( GL_FRAMEBUFFER , _msaaFrameBuffer );
glGenTextures( 1 , &_msaaTextureColor ); _gl.glGenFramebuffers( 1 , &_weightFrameBuffer );
glBindTexture( GL_TEXTURE_2D_MULTISAMPLE , _msaaTextureColor ); _gl.glBindFramebuffer( GL_FRAMEBUFFER , _weightFrameBuffer );
glTexImage2DMultisample(
GL_TEXTURE_2D_MULTISAMPLE , SAMPLES , GL_RGB ,
width( ) * FRAMEBUFFER_SCALE_FACTOR ,
height( ) * FRAMEBUFFER_SCALE_FACTOR ,
GL_TRUE
);
glBindTexture( GL_TEXTURE_2D_MULTISAMPLE , 0 ); glGenTextures( 1 , &_accumulationTexture );
glBindTexture( GL_TEXTURE_2D , _accumulationTexture );
glFramebufferTexture2D( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , glTexImage2D( GL_TEXTURE_2D , 0 , GL_RGBA32F , width( ) , height( ) , 0 ,
GL_TEXTURE_2D_MULTISAMPLE , _msaaTextureColor , 0 ); GL_RGBA , GL_FLOAT , nullptr );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
glGenTextures( 1 , &_revealTexture );
glBindTexture( GL_TEXTURE_2D , _revealTexture );
glTexImage2D( GL_TEXTURE_2D , 0 , GL_R8 , width( ) , height( ) , 0 ,
GL_RED , GL_FLOAT , nullptr );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
glGenRenderbuffers( 1 , &_msaaRBODepth ); _gl.glFramebufferTexture2D( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 ,
glBindRenderbuffer( GL_RENDERBUFFER , _msaaRBODepth ); GL_TEXTURE_2D , _accumulationTexture , 0 );
glRenderbufferStorageMultisample( _gl.glFramebufferTexture2D( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT1 ,
GL_RENDERBUFFER , SAMPLES , GL_DEPTH_COMPONENT32 , GL_TEXTURE_2D , _revealTexture , 0 );
width( ) * FRAMEBUFFER_SCALE_FACTOR ,
height( ) * FRAMEBUFFER_SCALE_FACTOR );
glBindRenderbuffer( GL_RENDERBUFFER , 0 );
glFramebufferRenderbuffer( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT , const GLenum transparentDrawBuffers[] = { GL_COLOR_ATTACHMENT0 ,
GL_RENDERBUFFER , _msaaRBODepth ); GL_COLOR_ATTACHMENT1 };
_gl.glDrawBuffers( 2 , transparentDrawBuffers );
if ( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE ) if ( _gl.glCheckFramebufferStatus( GL_FRAMEBUFFER ) !=
GL_FRAMEBUFFER_COMPLETE )
std::cerr << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" std::cerr << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!"
<< std::endl; << std::endl;
// Generate the mid framebuffer. _gl.glBindFramebuffer( GL_FRAMEBUFFER , defaultFramebufferObject( ));
glGenFramebuffers( 1 , &_midFrameBuffer ); float quadVertices[] = {
glBindFramebuffer( GL_FRAMEBUFFER , _midFrameBuffer ); // positions
-1.0f , -1.0f , 0.0f ,
1.0f , -1.0f , 0.0f ,
1.0f , 1.0f , 0.0f ,
glGenTextures( 1 , &_midTextureColor ); 1.0f , 1.0f , 0.0f ,
glBindTexture( GL_TEXTURE_2D , _midTextureColor ); -1.0f , 1.0f , 0.0f ,
glTexImage2D( GL_TEXTURE_2D , 0 , GL_RGB , -1.0f , -1.0f , 0.0f
width( ) * FRAMEBUFFER_SCALE_FACTOR , };
height( ) * FRAMEBUFFER_SCALE_FACTOR ,
0 ,
GL_RGB , GL_UNSIGNED_BYTE , nullptr );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
glBindTexture( GL_TEXTURE_2D , 0 );
glFramebufferTexture2D( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 ,
GL_TEXTURE_2D , _midTextureColor , 0 );
glGenRenderbuffers( 1 , &_midRBODepth );
glBindRenderbuffer( GL_RENDERBUFFER , _midRBODepth );
glRenderbufferStorage( GL_RENDERBUFFER , GL_DEPTH_COMPONENT32 ,
width( ) * FRAMEBUFFER_SCALE_FACTOR ,
height( ) * FRAMEBUFFER_SCALE_FACTOR );
glBindRenderbuffer( GL_RENDERBUFFER , 0 );
glFramebufferRenderbuffer( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT ,
GL_RENDERBUFFER , _midRBODepth );
if ( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
std::cerr << "ERROR::FRAMEBUFFER:: Mid Framebuffer is not complete!"
<< std::endl;
glBindFramebuffer( GL_FRAMEBUFFER , defaultFramebufferObject( )); // quad VAO
unsigned int quadVBO;
_gl.glGenVertexArrays( 1 , &_quadVAO );
_gl.glGenBuffers( 1 , &quadVBO );
_gl.glBindVertexArray( _quadVAO );
_gl.glBindBuffer( GL_ARRAY_BUFFER , quadVBO );
_gl.glBufferData( GL_ARRAY_BUFFER , sizeof( quadVertices ) , quadVertices ,
GL_STATIC_DRAW );
_gl.glEnableVertexAttribArray( 0 );
_gl.glVertexAttribPointer( 0 , 3 , GL_FLOAT , GL_FALSE ,
3 * sizeof( float ) ,
( void* ) 0 );
_gl.glBindVertexArray( 0 );
} }
void OpenGLWidget::_configureSimulationFrame( void ) void OpenGLWidget::_configureSimulationFrame( void )
...@@ -738,39 +689,60 @@ void main() ...@@ -738,39 +689,60 @@ void main()
} // if player && player->isPlaying } // if player && player->isPlaying
glBindFramebuffer( GL_FRAMEBUFFER , _msaaFrameBuffer );
glViewport( 0 , 0 , width( ) * FRAMEBUFFER_SCALE_FACTOR ,
height( ) * FRAMEBUFFER_SCALE_FACTOR );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable( GL_DEPTH_TEST );
_paintPlanes( );
_paintParticles( );
glViewport( 0 , 0 , width( ) , height( )); glViewport( 0 , 0 , width( ) , height( ));
// Perform MSAA if ( _domainManager.isAccumulativeModeEnabled( ))
glBindFramebuffer( GL_READ_FRAMEBUFFER , _msaaFrameBuffer ); {
glBindFramebuffer( GL_DRAW_FRAMEBUFFER , _midFrameBuffer ); _gl.glBindFramebuffer( GL_FRAMEBUFFER , defaultFramebufferObject( ));
int w = width( ) * FRAMEBUFFER_SCALE_FACTOR; _gl.glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
int h = height( ) * FRAMEBUFFER_SCALE_FACTOR; _gl.glDisable( GL_DEPTH_TEST );
glBlitFramebuffer( _gl.glDepthMask( GL_FALSE );
0 , 0 , _gl.glEnable( GL_BLEND );
w , h , _gl.glBlendFunc( GL_SRC_ALPHA , GL_ONE_MINUS_CONSTANT_ALPHA );
0 , 0 , _gl.glBlendEquation( GL_FUNC_ADD );
w , h , _paintPlanes( );
GL_COLOR_BUFFER_BIT , GL_NEAREST ); _paintParticles( );
}
// Perform super-sampling else
glBindFramebuffer( GL_READ_FRAMEBUFFER , _midFrameBuffer ); {
glBindFramebuffer( GL_DRAW_FRAMEBUFFER , defaultFramebufferObject( )); _gl.glBindFramebuffer( GL_FRAMEBUFFER , _weightFrameBuffer );
glBlitFramebuffer( _gl.glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
0 , 0 , _gl.glEnable( GL_DEPTH_TEST );
w , h ,
0 , 0 ,
width( ) , height( ) , _gl.glDepthMask( GL_FALSE );
GL_COLOR_BUFFER_BIT , GL_LINEAR ); _gl.glEnable( GL_BLEND );
_gl.glBlendFunci( 0 , GL_ONE , GL_ONE );
_gl.glBlendFunci( 1 , GL_ZERO , GL_ONE_MINUS_SRC_COLOR );
_gl.glBlendEquation( GL_FUNC_ADD );
glm::vec4 zeroFillerVec( 0.0f );
glm::vec4 oneFillerVec( 1.0f );
_gl.glClearBufferfv( GL_COLOR , 0 , &zeroFillerVec[ 0 ] );
_gl.glClearBufferfv( GL_COLOR , 1 , &oneFillerVec[ 0 ] );
_paintPlanes( );
_paintParticles( );
// Perform blend
_gl.glDepthFunc( GL_ALWAYS );
_gl.glEnable( GL_BLEND );
_gl.glBlendFunc( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA );
_gl.glBindFramebuffer( GL_FRAMEBUFFER , defaultFramebufferObject( ));
_gl.glClear(
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
_screenPlaneShader->use( );
_gl.glActiveTexture( GL_TEXTURE0 );
_gl.glBindTexture( GL_TEXTURE_2D , _accumulationTexture );
_gl.glActiveTexture( GL_TEXTURE1 );
_gl.glBindTexture( GL_TEXTURE_2D , _revealTexture );
_gl.glBindVertexArray( _quadVAO );
_gl.glDrawArrays( GL_TRIANGLES , 0 , 6 );
}
} }
if ( _player && _elapsedTimeSliderAcc > _sliderUpdatePeriodMicroseconds ) if ( _player && _elapsedTimeSliderAcc > _sliderUpdatePeriodMicroseconds )
...@@ -1055,7 +1027,7 @@ void main() ...@@ -1055,7 +1027,7 @@ void main()
{ {
if ( _player && ( _player->isPlaying( ) || _firstFrame )) if ( _player && ( _player->isPlaying( ) || _firstFrame ))
{ {
_domainManager.addTime( renderDelta, _player->endTime() ); _domainManager.addTime( renderDelta , _player->endTime( ));
_firstFrame = false; _firstFrame = false;
} }
} }
...@@ -1111,35 +1083,21 @@ void main() ...@@ -1111,35 +1083,21 @@ void main()
// _pickRenderer->setWindowSize( w , h ); // _pickRenderer->setWindowSize( w , h );
//} //}
if ( _msaaTextureColor != 0 ) if ( _accumulationTexture != 0 )
{ {
int rw = width( ) * FRAMEBUFFER_SCALE_FACTOR;
int rh = height( ) * FRAMEBUFFER_SCALE_FACTOR;
// Resize MSAA buffers // Resize MSAA buffers
glBindTexture( GL_TEXTURE_2D_MULTISAMPLE , _msaaTextureColor ); _gl.glBindTexture( GL_TEXTURE_2D , _accumulationTexture );
glTexImage2DMultisample( _gl.glTexImage2D( GL_TEXTURE_2D , 0 , GL_RGBA32F , width( ) , height( ) ,
GL_TEXTURE_2D_MULTISAMPLE , SAMPLES , GL_RGB , 0 ,
rw , rh , GL_TRUE ); GL_RGBA , GL_FLOAT , nullptr );
glBindRenderbuffer( GL_RENDERBUFFER , _msaaRBODepth ); _gl.glBindTexture( GL_TEXTURE_2D , _revealTexture );
glRenderbufferStorageMultisample( _gl.glTexImage2D( GL_TEXTURE_2D , 0 , GL_R8 , width( ) , height( ) , 0 ,
GL_RENDERBUFFER , SAMPLES , GL_DEPTH_COMPONENT32 , GL_RED , GL_FLOAT , nullptr );
rw , rh );
_gl.glBindTexture( GL_TEXTURE_2D_MULTISAMPLE , 0 );
// And mid-buffers too! _gl.glBindTexture( GL_TEXTURE_2D , 0 );
//_gl.glBindRenderbuffer( GL_RENDERBUFFER , defaultFramebufferObject( ));
glBindTexture( GL_TEXTURE_2D , _midTextureColor );
glTexImage2D( GL_TEXTURE_2D , 0 , GL_RGB ,
rw , rh , 0 ,
GL_RGB , GL_UNSIGNED_BYTE , nullptr );
glBindRenderbuffer( GL_RENDERBUFFER , _midRBODepth );
glRenderbufferStorage( GL_RENDERBUFFER , GL_DEPTH_COMPONENT32 ,
rw , rh );
glBindTexture( GL_TEXTURE_2D_MULTISAMPLE , 0 );
glBindTexture( GL_TEXTURE_2D , 0 );
glBindRenderbuffer( GL_RENDERBUFFER , 0 );
} }
} }
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include <plab/plab.h> #include <plab/plab.h>
#include <sstream> #include <sstream>
#include <QOpenGLFunctions_4_0_Core>
#include "types.h" #include "types.h"
#include "render/Plane.h" #include "render/Plane.h"
...@@ -157,8 +158,7 @@ namespace visimpl ...@@ -157,8 +158,7 @@ namespace visimpl
AB_REPEAT AB_REPEAT
} TPlaybackMode; } TPlaybackMode;
class OpenGLWidget class OpenGLWidget : public QOpenGLWidget
: public QOpenGLWidget , public QOpenGLFunctions_3_3_Core
{ {
Q_OBJECT; Q_OBJECT;
...@@ -443,6 +443,8 @@ namespace visimpl ...@@ -443,6 +443,8 @@ namespace visimpl
#endif #endif
QOpenGLFunctions_4_0_Core _gl;
QLabel* _fpsLabel; QLabel* _fpsLabel;
QLabel* _labelCurrentTime; QLabel* _labelCurrentTime;
bool _showFps; bool _showFps;
...@@ -481,8 +483,8 @@ namespace visimpl ...@@ -481,8 +483,8 @@ namespace visimpl
reto::ShaderProgram* _shaderClippingPlanes; reto::ShaderProgram* _shaderClippingPlanes;
simil::SpikesPlayer* _player; simil::SpikesPlayer* _player;
std::shared_ptr<reto::ClippingPlane> _clippingPlaneLeft; std::shared_ptr< reto::ClippingPlane > _clippingPlaneLeft;
std::shared_ptr<reto::ClippingPlane> _clippingPlaneRight; std::shared_ptr< reto::ClippingPlane > _clippingPlaneRight;
evec3 _planesCenter; evec3 _planesCenter;
evec3 _planeNormalLeft; evec3 _planeNormalLeft;
evec3 _planeNormalRight; evec3 _planeNormalRight;
...@@ -570,13 +572,10 @@ namespace visimpl ...@@ -570,13 +572,10 @@ namespace visimpl
// Render to texture // Render to texture
reto::ShaderProgram* _screenPlaneShader; reto::ShaderProgram* _screenPlaneShader;
unsigned int _msaaFrameBuffer; unsigned int _quadVAO;
unsigned int _msaaTextureColor; unsigned int _weightFrameBuffer;
unsigned int _msaaRBODepth; unsigned int _accumulationTexture;
unsigned int _revealTexture;
unsigned int _midFrameBuffer;
unsigned int _midTextureColor;
unsigned int _midRBODepth;
}; };
} // namespace visimpl } // namespace visimpl
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
namespace visimpl namespace visimpl
{ {
const static std::string PARTICLE_VERTEX_SHADER = R"(#version 400 const static std::string PARTICLE_VERTEX_SHADER = R"(#version 330
//#extension GL_ARB_separate_shader_objects: enable //#extension GL_ARB_separate_shader_objects: enable
uniform mat4 viewProjectionMatrix; uniform mat4 viewProjectionMatrix;
...@@ -117,26 +117,56 @@ void main() ...@@ -117,26 +117,56 @@ void main()
)"; )";
const static std::string PARTICLE_DEFAULT_FRAGMENT_SHADER = R"( const static std::string PARTICLE_DEFAULT_FRAGMENT_SHADER = R"(#version 330
#version 400 in vec4 color;
in vec4 color;
in vec2 uvCoord; in vec2 uvCoord;
out vec4 outputColor;
layout (location = 0) out vec4 accumulation;
layout (location = 1) out float reveal;
void main() void main()
{ {
vec2 p = -1.0 + 2.0 * uvCoord; vec2 p = -1.0 + 2.0 * uvCoord;
float l = sqrt(dot(p,p)); float l = sqrt(dot(p, p));
l = 1.0 - clamp(l, 0.0, 1.0); l = 1.0 - clamp(l, 0.0, 1.0);
l *= color.a; l *= color.a;
outputColor = vec4(color.rgb, l);
vec4 c = vec4(color.rgb, l);
float weight = clamp(pow(min(1.0, c.a * 10.0) + 0.01, 3.0) * 1e8
* pow(1.0 - gl_FragCoord.z * 0.9, 3.0), 1e-2, 3e3);
accumulation = vec4 (c.rgb * c.a, c.a) * weight;
reveal = c.a;
} }
)"; )";
const static std::string PARTICLE_SOLID_FRAGMENT_SHADER = R"(#version 400 const static std::string PARTICLE_ACC_DEFAULT_FRAGMENT_SHADER = R"(#version 330
in vec4 color; in vec4 color;
in vec2 uvCoord; in vec2 uvCoord;
out vec4 outputColor;
out vec4 fragColor;
void main()
{
vec2 p = -1.0 + 2.0 * uvCoord;
float l = sqrt(dot(p, p));
l = 1.0 - clamp(l, 0.0, 1.0);
l *= color.a;
fragColor = vec4(color.rgb, l);
}
)";
const static std::string PARTICLE_SOLID_FRAGMENT_SHADER = R"(#version 330
in vec4 color;
in vec2 uvCoord;
layout (location = 0) out vec4 accumulation;
layout (location = 1) out float reveal;
void main() void main()
{ {
vec2 p = -1.0 + 2.0 * uvCoord; vec2 p = -1.0 + 2.0 * uvCoord;
...@@ -146,10 +176,37 @@ void main() ...@@ -146,10 +176,37 @@ void main()
if( l > 0.8 ) if( l > 0.8 )
discard; discard;
outputColor = vec4(color.rgb, 1.0f); vec4 c = vec4(color.rgb, 1.0f);
float weight = clamp(pow(min(1.0, c.a * 10.0) + 0.01, 3.0) * 1e8
* pow(1.0 - gl_FragCoord.z * 0.9, 3.0), 1e-2, 3e3);
accumulation = vec4 (c.rgb * c.a, c.a) * weight;
reveal = c.a;
})"; })";
const static std::string PICK_VERTEX_SHADER = R"(#version 400 const static std::string PARTICLE_ACC_SOLID_FRAGMENT_SHADER = R"(#version 330
in vec4 color;
in vec2 uvCoord;
out vec4 fragColor;
void main()
{
vec2 p = -1.0 + 2.0 * uvCoord;
float l = sqrt(dot(p,p));
l = clamp(l, 0.0, 1.0);
if( l > 0.8 )
discard;
fragColor = vec4(color.rgb, 1.0f);
}
)";
const static std::string PICK_VERTEX_SHADER = R"(#version 330
#extension GL_ARB_separate_shader_objects: enable #extension GL_ARB_separate_shader_objects: enable
uniform mat4 modelViewProjM; uniform mat4 modelViewProjM;
...@@ -189,7 +246,7 @@ void main() ...@@ -189,7 +246,7 @@ void main()
id = gl_InstanceID; id = gl_InstanceID;
})"; })";
const static std::string PICK_FRAGMENT_SHADER = R"(#version 400 const static std::string PICK_FRAGMENT_SHADER = R"(#version 330
uniform float radiusThreshold; uniform float radiusThreshold;
...@@ -222,8 +279,7 @@ void main( ) ...@@ -222,8 +279,7 @@ void main( )
outputColor = vec4(cc, 1.0); outputColor = vec4(cc, 1.0);
})"; })";
const static std::string SHADER_PLANE_VERTEX = R"( const static std::string SHADER_PLANE_VERTEX = R"(#version 330
#version 400
in vec3 inPos; in vec3 inPos;
...@@ -243,8 +299,7 @@ void main( ) ...@@ -243,8 +299,7 @@ void main( )
)"; )";
const static std::string SHADER_PLANE_FRAGMENT = R"( const static std::string SHADER_PLANE_FRAGMENT = R"(#version 330
#version 400
in vec4 outColor; in vec4 outColor;
out vec4 outputColor; out vec4 outputColor;
...@@ -256,6 +311,71 @@ void main( ) ...@@ -256,6 +311,71 @@ void main( )
} }
)";
const static std::string SHADER_SCREEN_VERTEX = R"(#version 330
// shader inputs
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0f);
}
)";
const static std::string SHADER_SCREEN_FRAGMENT = R"(#version 330
// shader outputs
layout (location = 0) out vec4 frag;
// color accumulation buffer
uniform sampler2D accumulation;
// revealage threshold buffer
uniform sampler2D reveal;
// epsilon number
const float EPSILON = 0.00001f;
// caluclate floating point numbers equality accurately
bool isApproximatelyEqual(float a, float b)
{
return abs(a - b) <= (abs(a) < abs(b) ? abs(b) : abs(a)) * EPSILON;
}
// get the max value between three values
float max3(vec3 v)
{
return max(max(v.x, v.y), v.z);
}
void main()
{
// fragment coordination
ivec2 coords = ivec2(gl_FragCoord.xy);
// fragment revealage
float revealage = texelFetch(reveal, coords, 0).r;
// save the blending and color texture fetch cost if there is not a transparent fragment
if (isApproximatelyEqual(revealage, 1.0f))
discard;
// fragment color
vec4 accumulation = texelFetch(accumulation, coords, 0);
// suppress overflow
if (isinf(max3(abs(accumulation.rgb))))
accumulation.rgb = vec3(accumulation.a);
// prevent floating point precision bug
vec3 average_color = accumulation.rgb / max(accumulation.a, EPSILON);
// blend pixels
frag = vec4(average_color, 1.0f - revealage);
}
)"; )";
} }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment