Reworked GAL switching.

Now OpenGL can report its problems instead of shutting down the application.
This commit is contained in:
Maciej Suminski 2015-02-15 02:18:35 +01:00
parent b19010ff8b
commit b1ace1607b
7 changed files with 136 additions and 171 deletions

View File

@ -1,8 +1,9 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2013-2014 CERN * Copyright (C) 2013-2015 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -28,6 +29,7 @@
#include <wx/event.h> #include <wx/event.h>
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/filename.h> #include <wx/filename.h>
#include <confirm.h>
#include <class_draw_panel_gal.h> #include <class_draw_panel_gal.h>
#include <view/view.h> #include <view/view.h>
@ -116,30 +118,30 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
m_pendingRefresh = false; m_pendingRefresh = false;
m_lastRefresh = wxGetLocalTimeMillis(); m_lastRefresh = wxGetLocalTimeMillis();
if( !m_drawing ) if( m_drawing )
return;
m_drawing = true;
m_view->UpdateItems();
m_gal->BeginDrawing();
m_gal->ClearScreen( m_painter->GetSettings()->GetBackgroundColor() );
if( m_view->IsDirty() )
{ {
m_drawing = true; m_view->ClearTargets();
m_view->UpdateItems(); // Grid has to be redrawn only when the NONCACHED target is redrawn
m_gal->BeginDrawing(); if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
m_gal->ClearScreen( m_painter->GetSettings()->GetBackgroundColor() );
if( m_view->IsDirty() )
{
m_view->ClearTargets();
// Grid has to be redrawn only when the NONCACHED target is redrawn
if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
m_gal->DrawGrid(); m_gal->DrawGrid();
m_view->Redraw(); m_view->Redraw();
}
m_gal->DrawCursor( m_viewControls->GetCursorPosition() );
m_gal->EndDrawing();
m_drawing = false;
} }
m_gal->DrawCursor( m_viewControls->GetCursorPosition() );
m_gal->EndDrawing();
m_drawing = false;
} }
@ -233,7 +235,8 @@ void EDA_DRAW_PANEL_GAL::SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher )
void EDA_DRAW_PANEL_GAL::StartDrawing() void EDA_DRAW_PANEL_GAL::StartDrawing()
{ {
m_pendingRefresh = false; m_drawing = false;
m_pendingRefresh = true;
Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this ); Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this );
wxPaintEvent redrawEvent; wxPaintEvent redrawEvent;
@ -243,7 +246,8 @@ void EDA_DRAW_PANEL_GAL::StartDrawing()
void EDA_DRAW_PANEL_GAL::StopDrawing() void EDA_DRAW_PANEL_GAL::StopDrawing()
{ {
m_pendingRefresh = true; m_pendingRefresh = false;
m_drawing = true;
m_refreshTimer.Stop(); m_refreshTimer.Stop();
Disconnect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this ); Disconnect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this );
} }
@ -271,41 +275,54 @@ void EDA_DRAW_PANEL_GAL::SetTopLayer( LAYER_ID aLayer )
} }
void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) bool EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
{ {
// Do not do anything if the currently used GAL is correct // Do not do anything if the currently used GAL is correct
if( aGalType == m_backend && m_gal != NULL ) if( aGalType == m_backend && m_gal != NULL )
return; return true;
// Prevent refreshing canvas during backend switch // Prevent refreshing canvas during backend switch
StopDrawing(); StopDrawing();
delete m_gal; KIGFX::GAL* new_gal = NULL;
switch( aGalType ) try
{ {
case GAL_TYPE_OPENGL: switch( aGalType )
m_gal = new KIGFX::OPENGL_GAL( this, this, this ); {
break; case GAL_TYPE_OPENGL:
new_gal = new KIGFX::OPENGL_GAL( this, this, this );
break;
case GAL_TYPE_CAIRO: case GAL_TYPE_CAIRO:
m_gal = new KIGFX::CAIRO_GAL( this, this, this ); new_gal = new KIGFX::CAIRO_GAL( this, this, this );
break; break;
case GAL_TYPE_NONE: case GAL_TYPE_NONE:
return; return false;
}
delete m_gal;
m_gal = new_gal;
wxSize size = GetClientSize();
m_gal->ResizeScreen( size.GetX(), size.GetY() );
if( m_painter )
m_painter->SetGAL( m_gal );
if( m_view )
m_view->SetGAL( m_gal );
m_backend = aGalType;
}
catch (std::runtime_error& err)
{
DisplayError( m_parent, wxString( err.what() ) );
return false;
} }
wxSize size = GetClientSize(); return true;
m_gal->ResizeScreen( size.GetX(), size.GetY() );
if( m_painter )
m_painter->SetGAL( m_gal );
if( m_view )
m_view->SetGAL( m_gal );
m_backend = aGalType;
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2013 CERN * Copyright (C) 2013-2015 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -24,13 +24,14 @@
/** /**
* @file opengl_compositor.cpp * @file opengl_compositor.cpp
* @brief Class that handles multitarget rendering (ie. to different textures/surfaces) and * @brief Class that handles multitarget rendering (i.e. to different textures/surfaces) and
* later compositing into a single image (OpenGL flavour). * later compositing into a single image (OpenGL flavour).
*/ */
#include <gal/opengl/opengl_compositor.h> #include <gal/opengl/opengl_compositor.h>
#include <wx/msgdlg.h>
#include <confirm.h> #include <stdexcept>
#include <cassert>
using namespace KIGFX; using namespace KIGFX;
@ -89,7 +90,7 @@ void OPENGL_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
unsigned int OPENGL_COMPOSITOR::CreateBuffer() unsigned int OPENGL_COMPOSITOR::CreateBuffer()
{ {
wxASSERT( m_initialized ); assert( m_initialized );
unsigned int maxBuffers; unsigned int maxBuffers;
@ -98,10 +99,9 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
if( usedBuffers() >= maxBuffers ) if( usedBuffers() >= maxBuffers )
{ {
DisplayError( NULL, wxT( "Cannot create more framebuffers. OpenGL rendering " throw std::runtime_error("Cannot create more framebuffers. OpenGL rendering "
"backend requires at least 3 framebuffers. You may try to update/change " "backend requires at least 3 framebuffers. You may try to update/change "
"your graphic drivers." ) ); "your graphic drivers.");
return 0; // Unfortunately we have no more free buffers left
} }
// GL_COLOR_ATTACHMENTn are consecutive integers // GL_COLOR_ATTACHMENTn are consecutive integers
@ -133,38 +133,38 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer()
switch( status ) switch( status )
{ {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
DisplayError( NULL,wxT( "Cannot create the framebuffer." ) ); throw std::runtime_error( "Cannot create the framebuffer." );
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
DisplayError( NULL, wxT( "The framebuffer attachment points are incomplete." ) ); throw std::runtime_error( "The framebuffer attachment points are incomplete." );
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
DisplayError( NULL, wxT( "The framebuffer does not have at least " throw std::runtime_error( "The framebuffer does not have at least one "
"one image attached to it." ) ); "image attached to it." );
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
DisplayError( NULL, wxT( "The framebuffer read buffer is incomplete." ) ); throw std::runtime_error( "The framebuffer read buffer is incomplete." );
break; break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT: case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
DisplayError( NULL, wxT( "The combination of internal formats of the attached images " throw std::runtime_error( "The combination of internal formats of the attached "
"violates an implementation-dependent set of restrictions." ) ); "images violates an implementation-dependent set of restrictions." );
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
DisplayError( NULL, wxT( "GL_RENDERBUFFER_SAMPLES is not the same " throw std::runtime_error( "GL_RENDERBUFFER_SAMPLES is not the same for "
"for all attached renderbuffers" ) ); "all attached renderbuffers" );
break; break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT: case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
DisplayError( NULL, wxT( "Framebuffer incomplete layer targets errors." ) ); throw std::runtime_error( "Framebuffer incomplete layer targets errors." );
break; break;
default: default:
DisplayError( NULL, wxT( "Cannot create the framebuffer." ) ); throw std::runtime_error( "Cannot create the framebuffer." );
break; break;
} }
@ -211,7 +211,7 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
void OPENGL_COMPOSITOR::ClearBuffer() void OPENGL_COMPOSITOR::ClearBuffer()
{ {
wxASSERT( m_initialized ); assert( m_initialized );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
@ -220,8 +220,8 @@ void OPENGL_COMPOSITOR::ClearBuffer()
void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle ) void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
{ {
wxASSERT( m_initialized ); assert( m_initialized );
wxASSERT( aBufferHandle != 0 && aBufferHandle <= usedBuffers() ); assert( aBufferHandle != 0 && aBufferHandle <= usedBuffers() );
// Switch to the main framebuffer and blit the scene // Switch to the main framebuffer and blit the scene
glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING ); glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING );
@ -267,7 +267,7 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
void OPENGL_COMPOSITOR::clean() void OPENGL_COMPOSITOR::clean()
{ {
wxASSERT( m_initialized ); assert( m_initialized );
glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING ); glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING );
m_currentFbo = DIRECT_RENDERING; m_currentFbo = DIRECT_RENDERING;

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors. * Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
* Copyright (C) 2013 CERN * Copyright (C) 2013-2015 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* Graphics Abstraction Layer (GAL) for OpenGL * Graphics Abstraction Layer (GAL) for OpenGL
@ -31,7 +31,6 @@
#include <wx/log.h> #include <wx/log.h>
#include <macros.h> #include <macros.h>
#include <confirm.h>
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
#include <profile.h> #include <profile.h>
#endif /* __WXDEBUG__ */ #endif /* __WXDEBUG__ */
@ -51,6 +50,9 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
wxEvtHandler* aPaintListener, const wxString& aName ) : wxEvtHandler* aPaintListener, const wxString& aName ) :
wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize, wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
wxEXPAND, aName ), wxEXPAND, aName ),
parentWindow( aParent ),
mouseListener( aMouseListener ),
paintListener( aPaintListener ),
cachedManager( true ), cachedManager( true ),
nonCachedManager( false ), nonCachedManager( false ),
overlayManager( false ) overlayManager( false )
@ -59,14 +61,29 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
if( glContext == NULL ) if( glContext == NULL )
glContext = new wxGLContext( this ); glContext = new wxGLContext( this );
parentWindow = aParent; aParent->Show(); // wxWidgets require the window to be visible to set its GL context
mouseListener = aMouseListener;
paintListener = aPaintListener; // Initialize GLEW, FBOs & VBOs
SetCurrent( *glContext );
initGlew();
// Prepare shaders
if( !shader.LoadBuiltinShader( 0, SHADER_TYPE_VERTEX ) )
throw std::runtime_error( "Cannot compile vertex shader!" );
if( !shader.LoadBuiltinShader( 1, SHADER_TYPE_FRAGMENT ) )
throw std::runtime_error( "Cannot compile fragment shader!" );
if( !shader.Link() )
throw std::runtime_error( "Cannot link the shaders!" );
// Make VBOs use shaders
cachedManager.SetShader( shader );
nonCachedManager.SetShader( shader );
overlayManager.SetShader( shader );
// Initialize the flags // Initialize the flags
isGlewInitialized = false;
isFramebufferInitialized = false; isFramebufferInitialized = false;
isShaderInitialized = false;
isGrouping = false; isGrouping = false;
groupCounter = 0; groupCounter = 0;
@ -100,10 +117,7 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
InitTesselatorCallbacks( tesselator ); InitTesselatorCallbacks( tesselator );
if( tesselator == NULL ) if( tesselator == NULL )
{ throw std::runtime_error( "Could not create the tesselator" );
DisplayError( parentWindow, wxT( "Could not create the tesselator" ) );
exit( 1 );
}
gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE ); gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
@ -123,13 +137,8 @@ OPENGL_GAL::~OPENGL_GAL()
void OPENGL_GAL::BeginDrawing() void OPENGL_GAL::BeginDrawing()
{ {
SetCurrent( *glContext ); SetCurrent( *glContext );
clientDC = new wxClientDC( this ); clientDC = new wxClientDC( this );
// Initialize GLEW, FBOs & VBOs
if( !isGlewInitialized )
initGlew();
// Set up the view port // Set up the view port
glMatrixMode( GL_PROJECTION ); glMatrixMode( GL_PROJECTION );
glLoadIdentity(); glLoadIdentity();
@ -148,35 +157,6 @@ void OPENGL_GAL::BeginDrawing()
isFramebufferInitialized = true; isFramebufferInitialized = true;
} }
// Compile the shaders
if( !isShaderInitialized )
{
if( !shader.LoadBuiltinShader( 0, SHADER_TYPE_VERTEX ) )
{
DisplayError( parentWindow, wxT( "Cannot compile vertex shader!" ) );
exit( 1 );
}
if( !shader.LoadBuiltinShader( 1, SHADER_TYPE_FRAGMENT ) )
{
DisplayError( parentWindow, wxT( "Cannot compile fragment shader!" ) );
exit( 1 );
}
if( !shader.Link() )
{
DisplayError( parentWindow, wxT( "Cannot link the shaders!" ) );
exit( 1 );
}
// Make VBOs use shaders
cachedManager.SetShader( shader );
nonCachedManager.SetShader( shader );
overlayManager.SetShader( shader );
isShaderInitialized = true;
}
// Disable 2D Textures // Disable 2D Textures
glDisable( GL_TEXTURE_2D ); glDisable( GL_TEXTURE_2D );
@ -815,7 +795,7 @@ void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
if( lineLength <= 0.0 ) if( lineLength <= 0.0 )
return; return;
double scale = 0.5 * lineWidth / lineLength; double scale = 0.5 * lineWidth / lineLength;
// The perpendicular vector also needs transformations // The perpendicular vector also needs transformations
@ -941,8 +921,7 @@ void OPENGL_GAL::initGlew()
if( GLEW_OK != err ) if( GLEW_OK != err )
{ {
DisplayError( parentWindow, wxString::FromUTF8( (char*) glewGetErrorString( err ) ) ); throw std::runtime_error( (const char*) glewGetErrorString( err ) );
exit( 1 );
} }
else else
{ {
@ -952,30 +931,17 @@ void OPENGL_GAL::initGlew()
// Check the OpenGL version (minimum 2.1 is required) // Check the OpenGL version (minimum 2.1 is required)
if( GLEW_VERSION_2_1 ) if( GLEW_VERSION_2_1 )
{
wxLogInfo( wxT( "OpenGL 2.1 supported." ) ); wxLogInfo( wxT( "OpenGL 2.1 supported." ) );
}
else else
{ throw std::runtime_error( "OpenGL 2.1 or higher is required!" );
DisplayError( parentWindow, wxT( "OpenGL 2.1 or higher is required!" ) );
exit( 1 );
}
// Framebuffers have to be supported // Framebuffers have to be supported
if( !GLEW_EXT_framebuffer_object ) if( !GLEW_EXT_framebuffer_object )
{ throw std::runtime_error( "Framebuffer objects are not supported!" );
DisplayError( parentWindow, wxT( "Framebuffer objects are not supported!" ) );
exit( 1 );
}
// Vertex buffer has to be supported // Vertex buffer has to be supported
if( !GLEW_ARB_vertex_buffer_object ) if( !GLEW_ARB_vertex_buffer_object )
{ throw std::runtime_error( "Vertex buffer objects are not supported!" );
DisplayError( parentWindow, wxT( "Vertex buffer objects are not supported!" ) );
exit( 1 );
}
isGlewInitialized = true;
} }
@ -1058,12 +1024,8 @@ void CALLBACK EdgeCallback( GLboolean aEdgeFlag )
void CALLBACK ErrorCallback( GLenum aErrorCode ) void CALLBACK ErrorCallback( GLenum aErrorCode )
{ {
const GLubyte* eString = gluErrorString( aErrorCode ); //throw std::runtime_error( std::string( "Tessellation error: " ) +
//std::string( (const char*) gluErrorString( aErrorCode ) );
DisplayError( NULL, wxT( "Tessellation error: " ) +
wxString( (const char*)( eString ), wxConvUTF8 ) );
exit( 1 );
} }

View File

@ -28,10 +28,10 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <stdexcept>
#include <wx/log.h> #include <cstring>
#include <wx/gdicmn.h> #include <cassert>
#include <confirm.h>
#include <gal/opengl/shader.h> #include <gal/opengl/shader.h>
#include "shader_src.h" #include "shader_src.h"
@ -102,8 +102,7 @@ bool SHADER::Link()
glGetObjectParameterivARB( programNumber, GL_OBJECT_LINK_STATUS_ARB, glGetObjectParameterivARB( programNumber, GL_OBJECT_LINK_STATUS_ARB,
(GLint*) &isShaderLinked ); (GLint*) &isShaderLinked );
#ifdef __WXDEBUG__ #ifdef DEBUG
if( !isShaderLinked ) if( !isShaderLinked )
{ {
int maxLength; int maxLength;
@ -115,8 +114,7 @@ bool SHADER::Link()
std::cerr << linkInfoLog; std::cerr << linkInfoLog;
delete[] linkInfoLog; delete[] linkInfoLog;
} }
#endif /* DEBUG */
#endif /* __WXDEBUG__ */
return isShaderLinked; return isShaderLinked;
} }
@ -127,9 +125,7 @@ int SHADER::AddParameter( const std::string& aParameterName )
GLint location = glGetUniformLocation( programNumber, aParameterName.c_str() ); GLint location = glGetUniformLocation( programNumber, aParameterName.c_str() );
if( location != -1 ) if( location != -1 )
{
parameterLocation.push_back( location ); parameterLocation.push_back( location );
}
return location; return location;
} }
@ -167,7 +163,7 @@ void SHADER::programInfo( GLuint aProgram )
GLchar* glInfoLog = new GLchar[glInfoLogLength]; GLchar* glInfoLog = new GLchar[glInfoLogLength];
glGetProgramInfoLog( aProgram, glInfoLogLength, &writtenChars, glInfoLog ); glGetProgramInfoLog( aProgram, glInfoLogLength, &writtenChars, glInfoLog );
wxLogInfo( wxString::FromUTF8( (char*) glInfoLog ) ); std::cerr << glInfoLog << std::endl;
delete[] glInfoLog; delete[] glInfoLog;
} }
@ -188,7 +184,7 @@ void SHADER::shaderInfo( GLuint aShader )
GLchar* glInfoLog = new GLchar[glInfoLogLength]; GLchar* glInfoLog = new GLchar[glInfoLogLength];
glGetShaderInfoLog( aShader, glInfoLogLength, &writtenChars, glInfoLog ); glGetShaderInfoLog( aShader, glInfoLogLength, &writtenChars, glInfoLog );
wxLogInfo( wxString::FromUTF8( (char*) glInfoLog ) ); std::cerr << glInfoLog << std::endl;
delete[] glInfoLog; delete[] glInfoLog;
} }
@ -202,11 +198,7 @@ std::string SHADER::readSource( std::string aShaderSourceName )
std::string shaderSource; std::string shaderSource;
if( !inputFile ) if( !inputFile )
{ throw std::runtime_error( "Can't read the shader source: " + aShaderSourceName );
DisplayError( NULL, wxString::FromUTF8( "Can't read the shader source: " ) +
wxString( aShaderSourceName.c_str(), wxConvUTF8 ) );
exit( 1 );
}
std::string shaderSourceLine; std::string shaderSourceLine;
@ -223,10 +215,7 @@ std::string SHADER::readSource( std::string aShaderSourceName )
bool SHADER::addSource( const std::string& aShaderSource, SHADER_TYPE aShaderType ) bool SHADER::addSource( const std::string& aShaderSource, SHADER_TYPE aShaderType )
{ {
if( isShaderLinked ) assert( !isShaderLinked );
{
wxLogDebug( wxT( "Shader is already linked!" ) );
}
// Create the program // Create the program
if( !isProgramCreated ) if( !isProgramCreated )
@ -244,7 +233,7 @@ bool SHADER::addSource( const std::string& aShaderSource, SHADER_TYPE aShaderTyp
// Copy to char array // Copy to char array
char* source = new char[aShaderSource.size() + 1]; char* source = new char[aShaderSource.size() + 1];
strcpy( source, aShaderSource.c_str() ); strncpy( source, aShaderSource.c_str(), aShaderSource.size() + 1 );
const char** source_ = (const char**) ( &source ); const char** source_ = (const char**) ( &source );
// Attach the source // Attach the source
@ -261,11 +250,8 @@ bool SHADER::addSource( const std::string& aShaderSource, SHADER_TYPE aShaderTyp
if( status != GL_TRUE ) if( status != GL_TRUE )
{ {
DisplayError( NULL, wxT( "Shader compilation error" ) );
shaderInfo( shaderNumber ); shaderInfo( shaderNumber );
throw std::runtime_error( "Shader compilation error" );
return false;
} }
glAttachShader( programNumber, shaderNumber ); glAttachShader( programNumber, shaderNumber );

View File

@ -66,7 +66,7 @@ public:
* Switches method of rendering graphics. * Switches method of rendering graphics.
* @param aGalType is a type of rendering engine that you want to use. * @param aGalType is a type of rendering engine that you want to use.
*/ */
void SwitchBackend( GalType aGalType ); bool SwitchBackend( GalType aGalType );
/** /**
* Function GetBackend * Function GetBackend

View File

@ -277,9 +277,7 @@ private:
SHADER shader; ///< There is only one shader used for different objects SHADER shader; ///< There is only one shader used for different objects
// Internal flags // Internal flags
bool isGlewInitialized; ///< Is GLEW initialized?
bool isFramebufferInitialized; ///< Are the framebuffers initialized? bool isFramebufferInitialized; ///< Are the framebuffers initialized?
bool isShaderInitialized; ///< Was the shader initialized?
bool isGrouping; ///< Was a group started? bool isGrouping; ///< Was a group started?
// Polygon tesselation // Polygon tesselation

View File

@ -694,24 +694,26 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable )
void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent ) void PCB_EDIT_FRAME::SwitchCanvas( wxCommandEvent& aEvent )
{ {
int id = aEvent.GetId(); int id = aEvent.GetId();
bool use_gal = false;
switch( id ) switch( id )
{ {
case ID_MENU_CANVAS_DEFAULT: case ID_MENU_CANVAS_DEFAULT:
Compile_Ratsnest( NULL, true );
UseGalCanvas( false );
break; break;
case ID_MENU_CANVAS_CAIRO: case ID_MENU_CANVAS_CAIRO:
GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ); use_gal = GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO );
UseGalCanvas( true );
break; break;
case ID_MENU_CANVAS_OPENGL: case ID_MENU_CANVAS_OPENGL:
GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL ); use_gal = GetGalCanvas()->SwitchBackend( EDA_DRAW_PANEL_GAL::GAL_TYPE_OPENGL );
UseGalCanvas( true );
break; break;
} }
if( !use_gal )
Compile_Ratsnest( NULL, true );
UseGalCanvas( use_gal );
} }