Handle keyboard in QML

This commit is contained in:
2020-06-23 16:29:36 -06:00
parent af761ca337
commit 82ff240cfd
5 changed files with 80 additions and 33 deletions

View File

@@ -27,6 +27,7 @@ public:
m_renderer->t(mitem->t()); m_renderer->t(mitem->t());
m_renderer->hue(mitem->hue()); m_renderer->hue(mitem->hue());
m_renderer->count(mitem->count()); m_renderer->count(mitem->count());
m_renderer->lagging(mitem->lagging());
} }
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override { QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override {
@@ -87,52 +88,37 @@ void MagnumItem::setCount(qint8 count) {
update(); update();
} }
void MagnumItem::keyPressEvent(QKeyEvent *evt) { void MagnumItem::setLagging(qreal lagging) {
switch (evt->key()) { if (lagging == m_lagging) return;
case Qt::Key_L: m_lagging = lagging;
auto camera = m_renderer->camera(); emit laggingChanged();
if (camera) { update();
if (camera->lagging() > 0.0f) {
camera->setLagging(0.0f);
} else {
camera->setLagging(0.85f);
}
}
break;
}
evt->accept();
} }
void MagnumItem::mousePressEvent(QMouseEvent *evt) { void MagnumItem::mousePressEvent(QMouseEvent *evt) {
if (auto camera = m_renderer->camera()) { if (auto& camera = m_renderer->camera()) {
camera->initTransformation({evt->pos().x(), evt->pos().y()}); camera->initTransformation({evt->pos().x(), evt->pos().y()});
} }
evt->accept();
}
void MagnumItem::mouseReleaseEvent(QMouseEvent *evt) {
evt->accept();
} }
void MagnumItem::mouseMoveEvent(QMouseEvent *evt) { void MagnumItem::mouseMoveEvent(QMouseEvent *evt) {
if (!evt->buttons()) if (!evt->buttons())
return; return;
if (auto camera = m_renderer->camera()) { if (auto& camera = m_renderer->camera()) {
if (evt->modifiers() & Qt::ShiftModifier) { if (evt->modifiers() & Qt::ShiftModifier) {
camera->translate({evt->pos().x(), evt->pos().y()}); camera->translate({evt->pos().x(), evt->pos().y()});
} else { } else {
camera->rotate({evt->pos().x(), evt->pos().y()}); camera->rotate({evt->pos().x(), evt->pos().y()});
} }
} }
evt->accept();
} }
void MagnumItem::wheelEvent(QWheelEvent *evt) { void MagnumItem::wheelEvent(QWheelEvent *evt) {
if (auto camera = m_renderer->camera()) { if (auto& camera = m_renderer->camera()) {
const Float delta = evt->delta(); const Float delta = evt->delta();
if (Math::abs(delta) < 1.0e-2f) if (Math::abs(delta) < 1.0e-2f)
return; return;
camera->zoom(delta); camera->zoom(delta*.01f);
} }
} }

View File

@@ -16,7 +16,8 @@ class MagnumItem : public QQuickFramebufferObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged) Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
Q_PROPERTY(qreal hue READ hue WRITE setHue NOTIFY hueChanged) Q_PROPERTY(qreal hue READ hue WRITE setHue NOTIFY hueChanged)
Q_PROPERTY(qreal count READ count WRITE setCount NOTIFY countChanged) Q_PROPERTY(qint8 count READ count WRITE setCount NOTIFY countChanged)
Q_PROPERTY(qreal lagging READ lagging WRITE setLagging NOTIFY laggingChanged)
public: public:
MagnumItem(); MagnumItem();
Renderer *createRenderer() const override; Renderer *createRenderer() const override;
@@ -30,15 +31,17 @@ public:
inline qint8 count() const { return m_count; } inline qint8 count() const { return m_count; }
void setCount(qint8 count); void setCount(qint8 count);
inline qreal lagging() const { return m_lagging; }
void setLagging(qreal lagging);
signals: signals:
void tChanged(); void tChanged();
void hueChanged(); void hueChanged();
void countChanged(); void countChanged();
void laggingChanged();
protected: protected:
void keyPressEvent(QKeyEvent *evt) override;
void mousePressEvent(QMouseEvent *evt) override; void mousePressEvent(QMouseEvent *evt) override;
void mouseReleaseEvent(QMouseEvent *evt) override;
void mouseMoveEvent(QMouseEvent *evt) override; void mouseMoveEvent(QMouseEvent *evt) override;
void wheelEvent(QWheelEvent *evt) override; void wheelEvent(QWheelEvent *evt) override;
@@ -48,6 +51,7 @@ private:
qreal m_t; qreal m_t;
qreal m_hue; qreal m_hue;
qint8 m_count; qint8 m_count;
qreal m_lagging;
MagnumRenderer *m_renderer; MagnumRenderer *m_renderer;
}; };

View File

@@ -41,10 +41,26 @@ void MagnumRenderer::count(int count) {
m_subjectDrawable->count(count); m_subjectDrawable->count(count);
} }
Containers::Optional<ArcBallCamera> MagnumRenderer::camera() { Containers::Optional<ArcBallCamera>& MagnumRenderer::camera() {
return m_camera; return m_camera;
} }
float MagnumRenderer::lagging() {
if (m_camera)
return m_camera->lagging();
else
return 0.f;
}
void MagnumRenderer::lagging(float lagging) {
if (m_camera)
m_camera->setLagging(lagging);
}
/**
* @brief MagnumRenderer::lazyInitialize
*
*/
void MagnumRenderer::lazyInitialize() { void MagnumRenderer::lazyInitialize() {
if (m_init) return; if (m_init) return;
@@ -97,6 +113,10 @@ void MagnumRenderer::reset(Platform::GLContext *ctx,
m_ctx = ctx; m_ctx = ctx;
} }
/**
* @brief MagnumRenderer::prepGLState
*
*/
void MagnumRenderer::prepGLState() { void MagnumRenderer::prepGLState() {
GL::Renderer::setClearColor(COLOR_BG); GL::Renderer::setClearColor(COLOR_BG);
GL::Renderer::enable(GL::Renderer::Feature::DepthTest); GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
@@ -115,7 +135,6 @@ void MagnumRenderer::prepGLState() {
void MagnumRenderer::render() { void MagnumRenderer::render() {
m_ctx->resetState(GL::Context::State::ExitExternal); m_ctx->resetState(GL::Context::State::ExitExternal);
prepGLState(); prepGLState();
// ---
m_FBO.bind(); m_FBO.bind();
m_FBO.clear(GL::FramebufferClear::Color | m_FBO.clear(GL::FramebufferClear::Color |
@@ -128,7 +147,7 @@ void MagnumRenderer::render() {
* bool cameraChanged = m_camera->update(); * bool cameraChanged = m_camera->update();
* m_camera->draw(m_drawables); * m_camera->draw(m_drawables);
* if (cameraChanged) { * if (cameraChanged) {
* redraw(); * redraw(); // should call back to MagnumItem::update()
* } */ * } */
// --- // ---
@@ -145,16 +164,22 @@ void GridDrawable::draw(const Matrix4 &transformation,
void SubjectDrawable::draw(const Matrix4 &transformation, void SubjectDrawable::draw(const Matrix4 &transformation,
SceneGraph::Camera3D &camera) { SceneGraph::Camera3D &camera) {
// We only need to do this once in this draw call
m_shader m_shader
.setNormalMatrix(transformation.normalMatrix()) .setNormalMatrix(transformation.normalMatrix())
.setProjectionMatrix(camera.projectionMatrix()); .setProjectionMatrix(camera.projectionMatrix());
static const float width = 3.f; static const float width = 3.f;
float x = -float(m_count)/2.f * width + width/2.f; float x = -float(m_count)/2.f * width + width/2.f;
for (int i = 0; i < m_count; i++) { for (int i = 0; i < m_count; i++) {
// Change hue depending on position
const auto color = Color3::fromHsv({Rad(m_hue+float(i)*.2f), 1.f, 1.f}); const auto color = Color3::fromHsv({Rad(m_hue+float(i)*.2f), 1.f, 1.f});
m_shader m_shader
.setDiffuseColor(color) .setDiffuseColor(color)
.setAmbientColor(Color3::fromHsv({color.hue(), 1.0f, 0.3f})); .setAmbientColor(Color3::fromHsv({color.hue(), 1.0f, 0.3f}));
// Move in +x
m_shader m_shader
.setTransformationMatrix( .setTransformationMatrix(
transformation * transformation *

View File

@@ -45,6 +45,7 @@ public:
m_count(count) {} m_count(count) {}
void draw(const Matrix4 &transformation, SceneGraph::Camera3D &camera); void draw(const Matrix4 &transformation, SceneGraph::Camera3D &camera);
void count(int count); void count(int count);
void hue(float hue); void hue(float hue);
void t(float t); void t(float t);
@@ -62,6 +63,9 @@ public:
MagnumRenderer(); MagnumRenderer();
~MagnumRenderer(); ~MagnumRenderer();
/**
* @brief Called when Qt needs to resize/re-create FBO.
*/
void reset(Platform::GLContext *ctx, void reset(Platform::GLContext *ctx,
GL::Framebuffer fbo, GL::Framebuffer fbo,
Vector2i windowSize, Vector2i windowSize,
@@ -72,16 +76,25 @@ public:
void t(float t); void t(float t);
void hue(float hue); void hue(float hue);
void count(int count); void count(int count);
Containers::Optional<ArcBallCamera> camera();
Containers::Optional<ArcBallCamera>& camera();
void lagging(float lagging);
float lagging();
private: private:
/**
* @brief We need to delay initialization until we have valid OpenGL context.
*/
void lazyInitialize(); void lazyInitialize();
/**
* @brief Reset OpenGL state to our desired state.
*/
void prepGLState(); void prepGLState();
bool m_init; bool m_init;
int m_count; int m_count;
Platform::GLContext *m_ctx; Platform::GLContext *m_ctx{nullptr};
GL::Framebuffer m_FBO{NoCreate}; GL::Framebuffer m_FBO{NoCreate};
Scene3D m_scene; Scene3D m_scene;

View File

@@ -4,11 +4,22 @@ import QtQuick.Layouts 1.3
import Magnum 1.0 import Magnum 1.0
ApplicationWindow { ApplicationWindow {
id: app
visible: true visible: true
width: 640 width: 640
height: 480 height: 480
title: qsTr("My Application") title: qsTr("My Application")
Shortcut {
sequence: "q"
onActivated: app.close()
}
Shortcut {
sequence: "l"
onActivated: lagging.checked = !lagging.checked
}
RowLayout { RowLayout {
id: root id: root
anchors.fill: parent anchors.fill: parent
@@ -81,11 +92,19 @@ ApplicationWindow {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
CheckBox { CheckBox {
text: "Lagging" id: lagging
text: "Lagging (L)"
onCheckStateChanged: {
if (checked)
magnum.lagging = 0.85
else
magnum.lagging = 0
}
} }
} }
} }
Magnum { Magnum {
id: magnum
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true