From a0d05753ade53866a926718061add19aff1595e1 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 28 Dec 2020 00:09:27 +0100 Subject: [PATCH 1/2] No segfault on OpenGL initialization failure but nice error screen. --- .../tools/view_25d/lay_plugin/D25View.ui | 79 ++++++++++++++++++- .../tools/view_25d/lay_plugin/layD25View.cc | 10 +++ .../tools/view_25d/lay_plugin/layD25View.h | 1 + .../view_25d/lay_plugin/layD25ViewWidget.cc | 50 ++++++++++-- .../view_25d/lay_plugin/layD25ViewWidget.h | 10 +++ 5 files changed, 144 insertions(+), 6 deletions(-) diff --git a/src/plugins/tools/view_25d/lay_plugin/D25View.ui b/src/plugins/tools/view_25d/lay_plugin/D25View.ui index f09a1a654..5e509de09 100644 --- a/src/plugins/tools/view_25d/lay_plugin/D25View.ui +++ b/src/plugins/tools/view_25d/lay_plugin/D25View.ui @@ -243,7 +243,84 @@ - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 255 + 213 + 213 + + + + + + + + + 255 + 213 + 213 + + + + + + + + + 239 + 239 + 239 + + + + + + + + + + + diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc index fd8d57bac..508eb89c5 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc @@ -50,6 +50,9 @@ D25View::D25View (QWidget *parent) connect (mp_ui->fit_bottom, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ())); connect (mp_ui->zoom_slider, SIGNAL (valueChanged (int)), this, SLOT (scale_slider_changed (int))); connect (mp_ui->d25_view, SIGNAL (scale_factor_changed (double)), this, SLOT (scale_factor_changed (double))); + connect (mp_ui->d25_view, SIGNAL (init_failed ()), this, SLOT (init_failed ())); + + mp_ui->gl_stack->setCurrentIndex (0); } D25View::~D25View () @@ -65,6 +68,13 @@ static QString scale_factor_to_string (double f) return s; } +void +D25View::init_failed () +{ + mp_ui->error_text->setPlainText (tl::to_qstring (mp_ui->d25_view->error ())); + mp_ui->gl_stack->setCurrentIndex (1); +} + void D25View::scale_slider_changed (int value) { diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.h b/src/plugins/tools/view_25d/lay_plugin/layD25View.h index 6f776ed3c..0ac98ebe1 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.h +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.h @@ -58,6 +58,7 @@ private slots: void fit_button_clicked (); void scale_factor_changed (double f); void scale_slider_changed (int value); + void init_failed (); private: Ui::D25View *mp_ui; diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc index ff9fc8f2a..58faad65c 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc @@ -36,6 +36,9 @@ #include #include #include +#include +#include +#include #include "math.h" @@ -186,7 +189,7 @@ private: D25ViewWidget::D25ViewWidget (QWidget *parent) : QOpenGLWidget (parent), - m_shapes_program (0) + m_shapes_program (0), m_gridplane_program (0) { QSurfaceFormat format; format.setDepthBufferSize (24); @@ -694,6 +697,39 @@ static std::pair find_grid (double v) void D25ViewWidget::initializeGL () +{ + tl_assert (m_shapes_program == 0); + tl_assert (m_gridplane_program == 0); + + bool error = false; + + try { + do_initialize_gl (); + } catch (tl::Exception &ex) { + m_error = ex.msg (); + error = true; + } catch (std::exception &ex) { + m_error = ex.what (); + error = true; + } catch (...) { + m_error = "(unspecific error)"; + error = true; + } + + if (error) { + + delete m_shapes_program; + m_shapes_program = 0; + delete m_gridplane_program; + m_gridplane_program = 0; + + emit init_failed (); + + } +} + +void +D25ViewWidget::do_initialize_gl () { QOpenGLFunctions::initializeOpenGLFunctions(); @@ -824,8 +860,8 @@ D25ViewWidget::initializeGL () void D25ViewWidget::paintGL () { - const qreal retinaScale = devicePixelRatio (); - glViewport (0, 0, width () * retinaScale, height () * retinaScale); + const qreal retina_scale = devicePixelRatio (); + glViewport (0, 0, width () * retina_scale, height () * retina_scale); QColor c = mp_view->background_color (); float foreground_rgb = (c.green () > 128 ? 0.0f : 1.0f); @@ -835,6 +871,12 @@ D25ViewWidget::paintGL () glClearColor (float (c.red ()) / 255.0f, float (c.green ()) / 255.0f, float (c.blue ()) / 255.0f, 1.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + const int positions = 0; + + if (! m_shapes_program || ! m_gridplane_program) { + return; + } + QMatrix4x4 scene_trans, scene_trans_wo_y; // provide the displacement and scaling (in this order!) @@ -846,8 +888,6 @@ D25ViewWidget::paintGL () scene_trans_wo_y = scene_trans; scene_trans_wo_y.translate (QVector3D (0.0, -m_displacement.y (), 0.0)); - const int positions = 0; - m_shapes_program->bind (); // draw the actual layout diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h index e23b068a5..700e41079 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h @@ -104,8 +104,14 @@ public: refresh (); } + const std::string &error () const + { + return m_error; + } + signals: void scale_factor_changed (double f); + void init_failed (); protected: virtual void camera_changed (); @@ -119,6 +125,7 @@ private: std::auto_ptr mp_mode; QOpenGLShaderProgram *m_shapes_program, *m_gridplane_program; + std::string m_error; double m_scale_factor; QVector3D m_displacement; lay::LayoutView *mp_view; @@ -126,9 +133,11 @@ private: double m_zmin, m_zmax; std::list m_vertex_chunks; + std::list m_normals_chunks; struct LayerInfo { const chunks_type *vertex_chunk; + const chunks_type *normals_chunk; GLfloat color [4]; }; @@ -138,6 +147,7 @@ private: void paintGL (); void resizeGL (int w, int h); + void do_initialize_gl (); bool prepare_view(); void render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, unsigned int layer, double zstart, double zstop); void render_polygon (D25ViewWidget::chunks_type &chunks, const db::Polygon &poly, double dbu, double zstart, double zstop); From cd73987b30e2a441ddd5be51ff296849e188271c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 28 Dec 2020 21:13:07 +0100 Subject: [PATCH 2/2] More consistent behavior of the preset views (front, top ...) --- src/plugins/tools/view_25d/lay_plugin/layD25View.cc | 6 ++++-- src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc index 508eb89c5..ae7aec5da 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc @@ -31,7 +31,7 @@ namespace lay { -const double initial_elevation = 3.0; +const double initial_elevation = 15.0; D25View::D25View (QWidget *parent) : QDialog (parent) @@ -110,7 +110,7 @@ D25View::exec_dialog (lay::LayoutView *view) mp_ui->d25_view->reset (); mp_ui->d25_view->set_cam_azimuth (0.0); - mp_ui->d25_view->set_cam_elevation (initial_elevation); + mp_ui->d25_view->set_cam_elevation (-initial_elevation); mp_ui->d25_view->fit (); int ret = QDialog::exec (); @@ -140,8 +140,10 @@ D25View::fit_button_clicked () azimuth = -90.0; elevation = -initial_elevation; } else if (sender () == mp_ui->fit_top) { + azimuth = 0; elevation = -90; } else if (sender () == mp_ui->fit_bottom) { + azimuth = 0; elevation = 90; } diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc index 58faad65c..bd849ba7b 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc @@ -384,9 +384,8 @@ D25ViewWidget::fit () QVector3D new_center (0.0, 0.0, -dv / 2.0 + std::max (0.0, -d / (2.0 * tan (cam_fov () * M_PI / 180.0 / 2.0)) + cam_dist ())); QVector3D new_center_in_scene = cam_trans ().inverted ().map (new_center); - new_center_in_scene.setY (0.0); - m_displacement = (new_center_in_scene - dim * 0.5) / m_scale_factor - bll; + m_displacement.setY (0.0); refresh ();