Fixes for OpenGL resources handling.

This commit is contained in:
Maciej Suminski 2016-06-07 14:42:42 +02:00
parent f4525875f1
commit 3fcae6b120
4 changed files with 69 additions and 53 deletions

View File

@ -61,10 +61,7 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize, wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
wxEXPAND, aName ), wxEXPAND, aName ),
mouseListener( aMouseListener ), mouseListener( aMouseListener ),
paintListener( aPaintListener ), paintListener( aPaintListener )
cachedManager( true ),
nonCachedManager( false ),
overlayManager( false )
{ {
if( glMainContext == NULL ) if( glMainContext == NULL )
{ {
@ -81,9 +78,14 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
runTest(); runTest();
// Make VBOs use shaders // Make VBOs use shaders
cachedManager.SetShader( *shader ); cachedManager = new VERTEX_MANAGER( true );
nonCachedManager.SetShader( *shader ); cachedManager->SetShader( *shader );
overlayManager.SetShader( *shader ); nonCachedManager = new VERTEX_MANAGER( false );
nonCachedManager->SetShader( *shader );
overlayManager = new VERTEX_MANAGER( false );
overlayManager->SetShader( *shader );
compositor = new OPENGL_COMPOSITOR;
// Initialize the flags // Initialize the flags
isFramebufferInitialized = false; isFramebufferInitialized = false;
@ -132,7 +134,7 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE ); gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
currentManager = &nonCachedManager; currentManager = nonCachedManager;
} }
@ -140,9 +142,14 @@ OPENGL_GAL::~OPENGL_GAL()
{ {
GL_CONTEXT_MANAGER::Get().LockCtx( glPrivContext ); GL_CONTEXT_MANAGER::Get().LockCtx( glPrivContext );
glFlush();
gluDeleteTess( tesselator ); gluDeleteTess( tesselator );
ClearCache(); ClearCache();
glFlush();
delete compositor;
delete cachedManager;
delete nonCachedManager;
delete overlayManager;
// Are destroying the last GAL instance? // Are destroying the last GAL instance?
if( glPrivContext == glMainContext ) if( glPrivContext == glMainContext )
@ -191,9 +198,9 @@ void OPENGL_GAL::BeginDrawing()
if( !isFramebufferInitialized ) if( !isFramebufferInitialized )
{ {
// Prepare rendering target buffers // Prepare rendering target buffers
compositor.Initialize(); compositor->Initialize();
mainBuffer = compositor.CreateBuffer(); mainBuffer = compositor->CreateBuffer();
overlayBuffer = compositor.CreateBuffer(); overlayBuffer = compositor->CreateBuffer();
isFramebufferInitialized = true; isFramebufferInitialized = true;
} }
@ -232,12 +239,12 @@ void OPENGL_GAL::BeginDrawing()
SetStrokeColor( strokeColor ); SetStrokeColor( strokeColor );
// Remove all previously stored items // Remove all previously stored items
nonCachedManager.Clear(); nonCachedManager->Clear();
overlayManager.Clear(); overlayManager->Clear();
cachedManager.BeginDrawing(); cachedManager->BeginDrawing();
nonCachedManager.BeginDrawing(); nonCachedManager->BeginDrawing();
overlayManager.BeginDrawing(); overlayManager->BeginDrawing();
if( !isBitmapFontInitialized ) if( !isBitmapFontInitialized )
{ {
@ -279,7 +286,7 @@ void OPENGL_GAL::BeginDrawing()
} }
// Unbind buffers - set compositor for direct drawing // Unbind buffers - set compositor for direct drawing
compositor.SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING ); compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
prof_end( &totalRealTime ); prof_end( &totalRealTime );
@ -297,20 +304,20 @@ void OPENGL_GAL::EndDrawing()
#endif /* __WXDEBUG__ */ #endif /* __WXDEBUG__ */
// Cached & non-cached containers are rendered to the same buffer // Cached & non-cached containers are rendered to the same buffer
compositor.SetBuffer( mainBuffer ); compositor->SetBuffer( mainBuffer );
nonCachedManager.EndDrawing(); nonCachedManager->EndDrawing();
cachedManager.EndDrawing(); cachedManager->EndDrawing();
// Overlay container is rendered to a different buffer // Overlay container is rendered to a different buffer
compositor.SetBuffer( overlayBuffer ); compositor->SetBuffer( overlayBuffer );
overlayManager.EndDrawing(); overlayManager->EndDrawing();
// Be sure that the framebuffer is not colorized (happens on specific GPU&drivers combinations) // Be sure that the framebuffer is not colorized (happens on specific GPU&drivers combinations)
glColor4d( 1.0, 1.0, 1.0, 1.0 ); glColor4d( 1.0, 1.0, 1.0, 1.0 );
// Draw the remaining contents, blit the rendering targets to the screen, swap the buffers // Draw the remaining contents, blit the rendering targets to the screen, swap the buffers
compositor.DrawBuffer( mainBuffer ); compositor->DrawBuffer( mainBuffer );
compositor.DrawBuffer( overlayBuffer ); compositor->DrawBuffer( overlayBuffer );
blitCursor(); blitCursor();
SwapBuffers(); SwapBuffers();
@ -326,13 +333,13 @@ void OPENGL_GAL::EndDrawing()
void OPENGL_GAL::BeginUpdate() void OPENGL_GAL::BeginUpdate()
{ {
GL_CONTEXT_MANAGER::Get().LockCtx( glPrivContext ); GL_CONTEXT_MANAGER::Get().LockCtx( glPrivContext );
cachedManager.Map(); cachedManager->Map();
} }
void OPENGL_GAL::EndUpdate() void OPENGL_GAL::EndUpdate()
{ {
cachedManager.Unmap(); cachedManager->Unmap();
GL_CONTEXT_MANAGER::Get().UnlockCtx( glPrivContext ); GL_CONTEXT_MANAGER::Get().UnlockCtx( glPrivContext );
} }
@ -843,7 +850,7 @@ void OPENGL_GAL::DrawGrid()
return; return;
SetTarget( TARGET_NONCACHED ); SetTarget( TARGET_NONCACHED );
compositor.SetBuffer( mainBuffer ); compositor->SetBuffer( mainBuffer );
// Draw the grid // Draw the grid
// For the drawing the start points, end points and increments have // For the drawing the start points, end points and increments have
@ -942,7 +949,7 @@ void OPENGL_GAL::ResizeScreen( int aWidth, int aHeight )
#endif #endif
// Resize framebuffers // Resize framebuffers
compositor.Resize( aWidth * scaleFactor, aHeight * scaleFactor ); compositor->Resize( aWidth * scaleFactor, aHeight * scaleFactor );
isFramebufferInitialized = false; isFramebufferInitialized = false;
wxGLCanvas::SetSize( aWidth, aHeight ); wxGLCanvas::SetSize( aWidth, aHeight );
@ -969,7 +976,7 @@ void OPENGL_GAL::Flush()
void OPENGL_GAL::ClearScreen( const COLOR4D& aColor ) void OPENGL_GAL::ClearScreen( const COLOR4D& aColor )
{ {
// Clear screen // Clear screen
compositor.SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING ); compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
glClearColor( aColor.r, aColor.g, aColor.b, aColor.a ); glClearColor( aColor.r, aColor.g, aColor.b, aColor.a );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
} }
@ -1027,7 +1034,7 @@ int OPENGL_GAL::BeginGroup()
{ {
isGrouping = true; isGrouping = true;
boost::shared_ptr<VERTEX_ITEM> newItem( new VERTEX_ITEM( cachedManager ) ); boost::shared_ptr<VERTEX_ITEM> newItem( new VERTEX_ITEM( *cachedManager ) );
int groupNumber = getNewGroupNumber(); int groupNumber = getNewGroupNumber();
groups.insert( std::make_pair( groupNumber, newItem ) ); groups.insert( std::make_pair( groupNumber, newItem ) );
@ -1037,26 +1044,26 @@ int OPENGL_GAL::BeginGroup()
void OPENGL_GAL::EndGroup() void OPENGL_GAL::EndGroup()
{ {
cachedManager.FinishItem(); cachedManager->FinishItem();
isGrouping = false; isGrouping = false;
} }
void OPENGL_GAL::DrawGroup( int aGroupNumber ) void OPENGL_GAL::DrawGroup( int aGroupNumber )
{ {
cachedManager.DrawItem( *groups[aGroupNumber] ); cachedManager->DrawItem( *groups[aGroupNumber] );
} }
void OPENGL_GAL::ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor ) void OPENGL_GAL::ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor )
{ {
cachedManager.ChangeItemColor( *groups[aGroupNumber], aNewColor ); cachedManager->ChangeItemColor( *groups[aGroupNumber], aNewColor );
} }
void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth ) void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth )
{ {
cachedManager.ChangeItemDepth( *groups[aGroupNumber], aDepth ); cachedManager->ChangeItemDepth( *groups[aGroupNumber], aDepth );
} }
@ -1070,7 +1077,7 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber )
void OPENGL_GAL::ClearCache() void OPENGL_GAL::ClearCache()
{ {
groups.clear(); groups.clear();
cachedManager.Clear(); cachedManager->Clear();
} }
@ -1092,15 +1099,15 @@ void OPENGL_GAL::SetTarget( RENDER_TARGET aTarget )
{ {
default: default:
case TARGET_CACHED: case TARGET_CACHED:
currentManager = &cachedManager; currentManager = cachedManager;
break; break;
case TARGET_NONCACHED: case TARGET_NONCACHED:
currentManager = &nonCachedManager; currentManager = nonCachedManager;
break; break;
case TARGET_OVERLAY: case TARGET_OVERLAY:
currentManager = &overlayManager; currentManager = overlayManager;
break; break;
} }
@ -1117,7 +1124,7 @@ RENDER_TARGET OPENGL_GAL::GetTarget() const
void OPENGL_GAL::ClearTarget( RENDER_TARGET aTarget ) void OPENGL_GAL::ClearTarget( RENDER_TARGET aTarget )
{ {
// Save the current state // Save the current state
unsigned int oldTarget = compositor.GetBuffer(); unsigned int oldTarget = compositor->GetBuffer();
switch( aTarget ) switch( aTarget )
{ {
@ -1125,18 +1132,18 @@ void OPENGL_GAL::ClearTarget( RENDER_TARGET aTarget )
default: default:
case TARGET_CACHED: case TARGET_CACHED:
case TARGET_NONCACHED: case TARGET_NONCACHED:
compositor.SetBuffer( mainBuffer ); compositor->SetBuffer( mainBuffer );
break; break;
case TARGET_OVERLAY: case TARGET_OVERLAY:
compositor.SetBuffer( overlayBuffer ); compositor->SetBuffer( overlayBuffer );
break; break;
} }
compositor.ClearBuffer(); compositor->ClearBuffer();
// Restore the previous state // Restore the previous state
compositor.SetBuffer( oldTarget ); compositor->SetBuffer( oldTarget );
} }
@ -1426,7 +1433,7 @@ void OPENGL_GAL::blitCursor()
if( !isCursorEnabled ) if( !isCursorEnabled )
return; return;
compositor.SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING ); compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
VECTOR2D cursorBegin = cursorPosition - cursorSize / ( 2 * worldScale ); VECTOR2D cursorBegin = cursorPosition - cursorSize / ( 2 * worldScale );
VECTOR2D cursorEnd = cursorPosition + cursorSize / ( 2 * worldScale ); VECTOR2D cursorEnd = cursorPosition + cursorSize / ( 2 * worldScale );

View File

@ -54,13 +54,22 @@ SHADER::SHADER() :
SHADER::~SHADER() SHADER::~SHADER()
{ {
if( active )
Deactivate();
if( isProgramCreated ) if( isProgramCreated )
{ {
// Delete the shaders and the program // Delete the shaders and the program
for( std::deque<GLuint>::iterator it = shaderNumbers.begin(); it != shaderNumbers.end(); for( std::deque<GLuint>::iterator it = shaderNumbers.begin();
++it ) it != shaderNumbers.end(); ++it )
{ {
glDeleteShader( *it ); GLuint shader = *it;
if( glIsShader( shader ) )
{
glDetachShader( programNumber, shader );
glDeleteShader( shader );
}
} }
glDeleteProgram( programNumber ); glDeleteProgram( programNumber );

View File

@ -285,12 +285,12 @@ private:
GROUPS_MAP groups; ///< Stores informations about VBO objects (groups) GROUPS_MAP groups; ///< Stores informations about VBO objects (groups)
unsigned int groupCounter; ///< Counter used for generating keys for groups unsigned int groupCounter; ///< Counter used for generating keys for groups
VERTEX_MANAGER* currentManager; ///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs) VERTEX_MANAGER* currentManager; ///< Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs)
VERTEX_MANAGER cachedManager; ///< Container for storing cached VERTEX_ITEMs VERTEX_MANAGER* cachedManager; ///< Container for storing cached VERTEX_ITEMs
VERTEX_MANAGER nonCachedManager; ///< Container for storing non-cached VERTEX_ITEMs VERTEX_MANAGER* nonCachedManager; ///< Container for storing non-cached VERTEX_ITEMs
VERTEX_MANAGER overlayManager; ///< Container for storing overlaid VERTEX_ITEMs VERTEX_MANAGER* overlayManager; ///< Container for storing overlaid VERTEX_ITEMs
// Framebuffer & compositing // Framebuffer & compositing
OPENGL_COMPOSITOR compositor; ///< Handles multiple rendering targets OPENGL_COMPOSITOR* compositor; ///< Handles multiple rendering targets
unsigned int mainBuffer; ///< Main rendering target unsigned int mainBuffer; ///< Main rendering target
unsigned int overlayBuffer; ///< Auxiliary rendering target (for menus etc.) unsigned int overlayBuffer; ///< Auxiliary rendering target (for menus etc.)
RENDER_TARGET currentTarget; ///< Current rendering target RENDER_TARGET currentTarget; ///< Current rendering target

View File

@ -44,7 +44,7 @@ public:
friend class CACHED_CONTAINER; friend class CACHED_CONTAINER;
friend class VERTEX_MANAGER; friend class VERTEX_MANAGER;
VERTEX_ITEM( const VERTEX_MANAGER& aManager ); explicit VERTEX_ITEM( const VERTEX_MANAGER& aManager );
virtual ~VERTEX_ITEM(); virtual ~VERTEX_ITEM();
/** /**