3D Viewer: disable ray tracing for OpenGL less than 2.1.

Add code to parse OpenGL version string and determine if ray tracing is
supported.

Rationalize ray tracing menu and toolbar to have the same behavior so
a single command ID can be used for setting states.

Fixes lp:1797500

https://bugs.launchpad.net/kicad/+bug/1797500
This commit is contained in:
Wayne Stambaugh 2019-01-19 08:02:10 -05:00
parent 9cac0a38cc
commit 75f18cfe62
7 changed files with 110 additions and 92 deletions

View File

@ -28,6 +28,7 @@
*/
#include <GL/glew.h> // Must be included first
#include <wx/tokenzr.h>
#include "../common_ogl/openGL_includes.h"
#include "../common_ogl/ogl_utils.h"
@ -172,7 +173,7 @@ void EDA_3D_CANVAS::releaseOpenGL()
delete m_3d_render_ogl_legacy;
m_3d_render_ogl_legacy = NULL;
// This is just a copy of a pointer, can safelly be set to NULL
// This is just a copy of a pointer, can safely be set to NULL
m_3d_render = NULL;
GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );
@ -216,10 +217,48 @@ bool EDA_3D_CANVAS::initializeOpenGL()
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
}
const GLubyte* version = glGetString( GL_VERSION );
wxString version = FROM_UTF8( (char *) glGetString( GL_VERSION ) );
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::%s OpenGL version string %s.",
__WXFUNCTION__, FROM_UTF8( (char*) version ) );
__WXFUNCTION__, version );
// Extract OpenGL version from string. This method is used because prior to OpenGL 2,
// getting the OpenGL major and minor version as integers didn't exist.
wxString tmp;
wxStringTokenizer tokenizer( version );
m_opengl_supports_raytracing = true;
if( tokenizer.HasMoreTokens() )
{
long major = 0;
long minor = 0;
tmp = tokenizer.GetNextToken();
tokenizer.SetString( tmp, wxString( "." ) );
if( tokenizer.HasMoreTokens() )
tokenizer.GetNextToken().ToLong( &major );
if( tokenizer.HasMoreTokens() )
tokenizer.GetNextToken().ToLong( &minor );
if( major < 2 || ( (major == 2 ) && (minor < 1) ) )
{
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::%s OpenGL ray tracing not supported.",
__WXFUNCTION__ );
if( GetParent() )
{
wxCommandEvent evt( wxEVT_MENU, ID_DISABLE_RAY_TRACING );
GetParent()->ProcessWindowEvent( evt );
}
m_opengl_supports_raytracing = false;
}
}
m_is_opengl_initialized = true;
@ -293,7 +332,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
// ensure this parent is still alive. When it is closed before the viewer
// frame, a paint event can be generated after the parent is closed,
// therefore with invalid board.
// This is dependant of the platform.
// This is dependent of the platform.
// Especially on OSX, but also on Windows, it frequently happens
if( !GetParent()->GetParent()->IsShown() )
return; // The parent board editor frame is no more alive
@ -338,7 +377,15 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
}
}
// Check if a raytacing was requented and need to switch to raytracing mode
// Don't attend to ray trace if OpenGL doesn't support it.
if( !m_opengl_supports_raytracing )
{
m_3d_render = m_3d_render_ogl_legacy;
m_render_raytracing_was_requested = false;
m_settings.RenderEngineSet( RENDER_ENGINE_OPENGL_LEGACY );
}
// Check if a raytacing was requested and need to switch to raytracing mode
if( m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY )
{
const bool was_camera_changed = m_settings.CameraGet().ParametersChanged();
@ -407,7 +454,7 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent &event )
{
if( m_mouse_was_moved || m_camera_is_moving )
{
// Calculation time in miliseconds
// Calculation time in milliseconds
const double calculation_time = (double)( GetRunningMicroSecs() - strtime) / 1e3;
activityReporter.Report( wxString::Format( _( "Render time %.0f ms ( %.1f fps)" ),

View File

@ -124,7 +124,11 @@ class EDA_3D_CANVAS : public HIDPI_GL_CANVAS
void OnKeyEvent( wxKeyEvent& event );
private:
bool SupportsRayTracing() const { return m_opengl_supports_raytracing; }
bool IsOpenGLInitialized() const { return m_is_opengl_initialized; }
private:
void OnPaint( wxPaintEvent &event );

View File

@ -142,23 +142,9 @@ void EDA_3D_VIEWER::CreateMenuBar()
_( "Display Options" ),
KiBitmap( read_setup_xpm ) );
wxMenu * renderEngineList = new wxMenu;
AddMenuItem( prefsMenu, renderEngineList, ID_MENU3D_ENGINE,
_( "Render Engine" ), KiBitmap( render_mode_xpm ) );
renderEngineList->AppendRadioItem( ID_MENU3D_ENGINE_OPENGL_LEGACY,
_( "OpenGL" ),
wxEmptyString );
renderEngineList->AppendRadioItem( ID_MENU3D_ENGINE_RAYTRACING,
_( "Raytracing" ),
wxEmptyString );
renderEngineList->Check( ID_MENU3D_ENGINE_OPENGL_LEGACY,
m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY );
renderEngineList->Check( ID_MENU3D_ENGINE_RAYTRACING,
m_settings.RenderEngineGet() == RENDER_ENGINE_RAYTRACING );
prefsMenu->AppendCheckItem( ID_RENDER_CURRENT_VIEW, _( "Raytracing" ) );
prefsMenu->Check( ID_RENDER_CURRENT_VIEW,
m_settings.RenderEngineGet() != RENDER_ENGINE_OPENGL_LEGACY );
wxMenu * renderOptionsMenu = new wxMenu;
AddMenuItem( prefsMenu, renderOptionsMenu, ID_MENU3D_FL,

View File

@ -67,9 +67,8 @@ void EDA_3D_VIEWER::ReCreateMainToolbar()
_( "Set display options, and some layers visibility" ) );
m_mainToolBar->AddSeparator();
m_mainToolBar->AddTool( ID_RENDER_CURRENT_VIEW, wxEmptyString,
KiBitmap( render_mode_xpm ),
_( "Render current view using Raytracing" ) );
m_mainToolBar->AddTool( ID_RENDER_CURRENT_VIEW, wxEmptyString, KiBitmap( render_mode_xpm ),
_( "Render current view using Raytracing" ), wxITEM_CHECK );
m_mainToolBar->AddSeparator();

View File

@ -120,27 +120,21 @@ BEGIN_EVENT_TABLE( EDA_3D_VIEWER, EDA_BASE_FRAME )
EVT_ACTIVATE( EDA_3D_VIEWER::OnActivate )
EVT_SET_FOCUS( EDA_3D_VIEWER::OnSetFocus )
EVT_TOOL_RANGE( ID_ZOOM_IN, ID_ZOOM_REDRAW,
EDA_3D_VIEWER::ProcessZoom )
EVT_TOOL_RANGE( ID_ZOOM_IN, ID_ZOOM_REDRAW, EDA_3D_VIEWER::ProcessZoom )
EVT_TOOL_RANGE( ID_START_COMMAND_3D, ID_MENU_COMMAND_END,
EDA_3D_VIEWER::Process_Special_Functions )
EVT_TOOL( ID_TOOL_SET_VISIBLE_ITEMS, EDA_3D_VIEWER::Install3DViewOptionDialog )
EVT_MENU( wxID_EXIT,
EDA_3D_VIEWER::Exit3DFrame )
EVT_MENU( wxID_EXIT, EDA_3D_VIEWER::Exit3DFrame )
EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER::OnRenderEngineSelection )
EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER::OnDisableRayTracing )
EVT_MENU_RANGE( ID_MENU3D_GRID, ID_MENU3D_GRID_END,
EDA_3D_VIEWER::On3DGridSelection )
EVT_MENU_RANGE( ID_MENU3D_ENGINE_OPENGL_LEGACY, ID_MENU3D_ENGINE_RAYTRACING,
EDA_3D_VIEWER::OnRenderEngineSelection )
EVT_MENU_RANGE( ID_MENU3D_GRID, ID_MENU3D_GRID_END, EDA_3D_VIEWER::On3DGridSelection )
EVT_CLOSE( EDA_3D_VIEWER::OnCloseWindow )
EVT_UPDATE_UI_RANGE( ID_MENU3D_ENGINE_OPENGL_LEGACY, ID_MENU3D_ENGINE_RAYTRACING,
EDA_3D_VIEWER::OnUpdateUIEngine )
EVT_UPDATE_UI_RANGE( ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL,
ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE,
EDA_3D_VIEWER::OnUpdateUIMaterial )
@ -150,6 +144,8 @@ BEGIN_EVENT_TABLE( EDA_3D_VIEWER, EDA_BASE_FRAME )
EVT_UPDATE_UI_RANGE( ID_MENU3D_FL_RAYTRACING_RENDER_SHADOWS,
ID_MENU3D_FL_RAYTRACING_PROCEDURAL_TEXTURES,
EDA_3D_VIEWER::OnUpdateUIRayTracing )
EVT_UPDATE_UI( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER::OnUpdateUIEngine )
EVT_UPDATE_UI( ID_MENU3D_AXIS_ONOFF, EDA_3D_VIEWER::OnUpdateUIAxis )
END_EVENT_TABLE()
@ -164,6 +160,7 @@ EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent,
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::EDA_3D_VIEWER %s", aTitle );
m_canvas = NULL;
m_disable_ray_tracing = false;
// Give it an icon
wxIcon icon;
@ -183,9 +180,6 @@ EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent,
wxStatusBar *status_bar = CreateStatusBar( arrayDim( status_dims ) );
SetStatusWidths( arrayDim( status_dims ), status_dims );
CreateMenuBar();
ReCreateMainToolbar();
m_canvas = new EDA_3D_CANVAS( this,
COGL_ATT_LIST::GetAttributesList( true ),
aParent->GetBoard(),
@ -195,6 +189,9 @@ EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent,
if( m_canvas )
m_canvas->SetStatusBar( status_bar );
CreateMenuBar();
ReCreateMainToolbar();
m_auimgr.SetManagedWindow( this );
m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Top().Layer( 6 ) );
@ -202,9 +199,6 @@ EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent,
m_auimgr.Update();
m_mainToolBar->EnableTool( ID_RENDER_CURRENT_VIEW,
(m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY) );
m_mainToolBar->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( EDA_3D_VIEWER::OnKeyEvent ),
NULL, this );
@ -287,10 +281,6 @@ void EDA_3D_VIEWER::Process_Special_Functions( wxCommandEvent &event )
switch( id )
{
case ID_RENDER_CURRENT_VIEW:
m_canvas->RenderRaytracingRequest();
break;
case ID_RELOAD3D_BOARD:
NewDisplay( true );
break;
@ -588,31 +578,16 @@ void EDA_3D_VIEWER::On3DGridSelection( wxCommandEvent &event )
void EDA_3D_VIEWER::OnRenderEngineSelection( wxCommandEvent &event )
{
int id = event.GetId();
wxASSERT( id < ID_MENU3D_ENGINE_END );
wxASSERT( id > ID_MENU3D_ENGINE );
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::OnRenderEngineSelection id %d", id );
const RENDER_ENGINE old_engine = m_settings.RenderEngineGet();
switch( id )
{
case ID_MENU3D_ENGINE_OPENGL_LEGACY:
if( old_engine != RENDER_ENGINE_OPENGL_LEGACY )
m_settings.RenderEngineSet( RENDER_ENGINE_OPENGL_LEGACY );
break;
if( old_engine == RENDER_ENGINE_OPENGL_LEGACY )
m_settings.RenderEngineSet( RENDER_ENGINE_RAYTRACING );
else
m_settings.RenderEngineSet( RENDER_ENGINE_OPENGL_LEGACY );
case ID_MENU3D_ENGINE_RAYTRACING:
if( old_engine != RENDER_ENGINE_RAYTRACING )
m_settings.RenderEngineSet( RENDER_ENGINE_RAYTRACING );
break;
default:
wxFAIL_MSG( "Invalid event in EDA_3D_VIEWER::OnRenderEngineSelection()" );
return;
}
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::OnRenderEngineSelection type %s ",
( m_settings.RenderEngineGet() == RENDER_ENGINE_RAYTRACING ) ?
"Ray Trace" : "OpenGL Legacy" );
if( old_engine != m_settings.RenderEngineGet() )
{
@ -657,6 +632,15 @@ void EDA_3D_VIEWER::ProcessZoom( wxCommandEvent &event )
}
void EDA_3D_VIEWER::OnDisableRayTracing( wxCommandEvent& aEvent )
{
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::%s disabling ray tracing.", __WXFUNCTION__ );
m_disable_ray_tracing = true;
m_settings.RenderEngineSet( RENDER_ENGINE_OPENGL_LEGACY );
}
void EDA_3D_VIEWER::OnActivate( wxActivateEvent &event )
{
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::OnActivate" );
@ -800,6 +784,8 @@ void EDA_3D_VIEWER::LoadSettings( wxConfigBase *aCfg )
m_settings.GridSet( (GRID3D_TYPE)tmpi );
aCfg->Read( keyRenderEngine, &tmpi, (int)RENDER_ENGINE_OPENGL_LEGACY );
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::LoadSettings render setting %s",
( (RENDER_ENGINE)tmpi == RENDER_ENGINE_RAYTRACING ) ? "Ray Trace" : "OpenGL" );
m_settings.RenderEngineSet( (RENDER_ENGINE)tmpi );
aCfg->Read( keyRenderMaterial, &tmpi, (int)MATERIAL_MODE_NORMAL );
@ -844,12 +830,16 @@ void EDA_3D_VIEWER::SaveSettings( wxConfigBase *aCfg )
aCfg->Write( keyShowRealisticMode, m_settings.GetFlag( FL_USE_REALISTIC_MODE ) );
aCfg->Write( keyRenderEngine, (int)m_settings.RenderEngineGet() );
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::SaveSettings render setting %s",
( m_settings.RenderEngineGet() == RENDER_ENGINE_RAYTRACING ) ? "Ray Trace" : "OpenGL" );
aCfg->Write( keyRenderMaterial, (int)m_settings.MaterialModeGet() );
// OpenGL options
aCfg->Write( keyRenderOGL_ShowCopperTck,m_settings.GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS ) );
aCfg->Write( keyRenderOGL_ShowModelBBox,m_settings.GetFlag( FL_RENDER_OPENGL_SHOW_MODEL_BBOX ) );
aCfg->Write( keyRenderOGL_ShowCopperTck,
m_settings.GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS ) );
aCfg->Write( keyRenderOGL_ShowModelBBox,
m_settings.GetFlag( FL_RENDER_OPENGL_SHOW_MODEL_BBOX ) );
// Raytracing options
aCfg->Write( keyRenderRAY_Shadows, m_settings.GetFlag( FL_RENDER_RAYTRACING_SHADOWS ) );
@ -1133,21 +1123,13 @@ bool EDA_3D_VIEWER::Set3DSolderPasteColorFromUser()
void EDA_3D_VIEWER::OnUpdateUIEngine( wxUpdateUIEvent& aEvent )
{
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::OnUpdateUIEngine() id %d", aEvent.GetId() );
wxLogTrace( m_logTrace, "EDA_3D_VIEWER::OnUpdateUIEngine %s %s",
( !m_disable_ray_tracing ) ? "enable" : "disable",
( m_settings.RenderEngineGet() == RENDER_ENGINE_RAYTRACING ) ?
"Ray Trace" : "OpenGL Legacy" );
switch( aEvent.GetId() )
{
case ID_MENU3D_ENGINE_OPENGL_LEGACY:
aEvent.Check( m_settings.RenderEngineGet() == RENDER_ENGINE_OPENGL_LEGACY );
break;
case ID_MENU3D_ENGINE_RAYTRACING:
aEvent.Check( m_settings.RenderEngineGet() == RENDER_ENGINE_RAYTRACING );
break;
default:
wxFAIL_MSG( "Invalid event in EDA_3D_VIEWER::OnUpdateUIEngine()" );
}
aEvent.Enable( !m_disable_ray_tracing );
aEvent.Check( m_settings.RenderEngineGet() != RENDER_ENGINE_OPENGL_LEGACY );
}

View File

@ -160,6 +160,7 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
void On3DGridSelection( wxCommandEvent &event );
void OnRenderEngineSelection( wxCommandEvent &event );
void OnDisableRayTracing( wxCommandEvent& aEvent );
void OnUpdateUIEngine( wxUpdateUIEvent& aEvent );
void OnUpdateUIMaterial( wxUpdateUIEvent& aEvent );
@ -223,6 +224,8 @@ class EDA_3D_VIEWER : public KIWAY_PLAYER
*/
CINFO3D_VISU m_settings;
bool m_disable_ray_tracing;
/**
* Trace mask used to enable or disable the trace output of this class.
* The debug output can be turned on by setting the WXTRACE environment variable to

View File

@ -78,8 +78,6 @@ enum id_3dview_frm
ID_MENU3D_FL_RAYTRACING_ANTI_ALIASING,
ID_MENU3D_FL_RAYTRACING_PROCEDURAL_TEXTURES,
ID_RENDER_CURRENT_VIEW,
ID_MENU_SCREENCOPY_PNG,
ID_MENU_SCREENCOPY_JPEG,
ID_MENU_SCREENCOPY_TOCLIBBOARD,
@ -91,6 +89,8 @@ enum id_3dview_frm
ID_MENU_COMMAND_END,
ID_RENDER_CURRENT_VIEW,
ID_TOOL_SET_VISIBLE_ITEMS,
ID_MENU3D_GRID,
@ -101,10 +101,7 @@ enum id_3dview_frm
ID_MENU3D_GRID_1_MM,
ID_MENU3D_GRID_END,
ID_MENU3D_ENGINE,
ID_MENU3D_ENGINE_OPENGL_LEGACY,
ID_MENU3D_ENGINE_RAYTRACING,
ID_MENU3D_ENGINE_END,
ID_DISABLE_RAY_TRACING,
ID_POPUP_3D_VIEW_START,
ID_POPUP_ZOOMIN,