File gl_widget.hpp
File List > gui > gl_widget.hpp
Go to the documentation of this file
#pragma once
#include <QEvent>
#include <QFutureWatcher>
#include <QMatrix4x4>
#include <QOpenGLBuffer>
#include <QOpenGLFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLWidget>
#include <QtConcurrent>
#include "gui/camera.hpp"
#include "gui/layer.hpp"
#include "gui/layer_renderer.hpp"
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions {
Q_OBJECT
public:
GLWidget(QWidget* parent = nullptr);
~GLWidget();
void add_layer(std::unique_ptr<Layer> layer) {
if (m_layers.empty()) {
m_projection = layer->projection();
m_camera.world_offset() = layer->extent().center();
} else if (m_projection != layer->projection()) {
throw std::runtime_error(
"New layer must have same projection as existing layers. New layer has projection: " +
layer->projection() + ", existing layers have projection: " + m_projection + ".");
}
makeCurrent();
m_layers.emplace_back(std::move(layer));
m_renderers.emplace_back(LayerRenderer::create(m_layers.back(), m_camera.world_offset()));
connect(m_layers.back().get(), &Layer::data_updated, m_renderers.back().get(),
&LayerRenderer::data_update_required);
connect(m_renderers.back().get(), &LayerRenderer::repaint_required, this, [this] { update(); });
m_camera.zoom_to_fit(m_layers.back()->extent() - m_camera.world_offset());
}
std::vector<std::shared_ptr<Layer>> layers() const { return m_layers; }
protected:
QSize sizeHint() const override;
void initializeGL() override;
void paintGL() override;
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
private:
QPoint m_last_mouse_pos;
QOpenGLVertexArrayObject m_vao;
QOpenGLBuffer m_vbo;
int m_proj_matrix_loc = 0;
int m_point_radius_loc = 0;
Camera m_camera;
std::vector<std::shared_ptr<Layer>> m_layers;
std::vector<std::unique_ptr<LayerRenderer>> m_renderers;
std::string m_projection;
};