diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.cpp b/3d-viewer/3d_canvas/eda_3d_canvas.cpp index df03d641d3..c0d305d02d 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.cpp +++ b/3d-viewer/3d_canvas/eda_3d_canvas.cpp @@ -28,6 +28,7 @@ */ #include // Must be included first +#include #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)" ), diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.h b/3d-viewer/3d_canvas/eda_3d_canvas.h index 495f9e816b..843c9cda10 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.h +++ b/3d-viewer/3d_canvas/eda_3d_canvas.h @@ -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 ); diff --git a/3d-viewer/3d_viewer/3d_menubar.cpp b/3d-viewer/3d_viewer/3d_menubar.cpp index a998819a06..b5957d2226 100644 --- a/3d-viewer/3d_viewer/3d_menubar.cpp +++ b/3d-viewer/3d_viewer/3d_menubar.cpp @@ -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, diff --git a/3d-viewer/3d_viewer/3d_toolbar.cpp b/3d-viewer/3d_viewer/3d_toolbar.cpp index 67fcec1bd0..28380ca8eb 100644 --- a/3d-viewer/3d_viewer/3d_toolbar.cpp +++ b/3d-viewer/3d_viewer/3d_toolbar.cpp @@ -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(); diff --git a/3d-viewer/3d_viewer/eda_3d_viewer.cpp b/3d-viewer/3d_viewer/eda_3d_viewer.cpp index 5fa3454c24..922a42cee3 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer.cpp +++ b/3d-viewer/3d_viewer/eda_3d_viewer.cpp @@ -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 ); } diff --git a/3d-viewer/3d_viewer/eda_3d_viewer.h b/3d-viewer/3d_viewer/eda_3d_viewer.h index a7f1e778a5..b742aa2bf8 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer.h +++ b/3d-viewer/3d_viewer/eda_3d_viewer.h @@ -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 diff --git a/3d-viewer/3d_viewer_id.h b/3d-viewer/3d_viewer_id.h index abc41c2e21..7b193359d7 100644 --- a/3d-viewer/3d_viewer_id.h +++ b/3d-viewer/3d_viewer_id.h @@ -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,