Handle keyboard in QML
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
@@ -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 *
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user