diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-10-01 18:28:48 +0200 |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-10-01 18:31:27 +0200 |
commit | 180996ae0031c3eb47079d5d9a11e32c81f91faa (patch) | |
tree | 48e4b04e37313bc2bdde48906af9b59272033314 /mazescene.cpp | |
parent | 6dc84d85ea7d16057e6d298ee439f926414e765b (diff) |
Port to Qt 4.6 etc...
Ported to use Qt 4.6's matrix and vector classes, as well as using
QGLShaderProgram to make the OpenGL rendering code work both on desktop
OpenGL and OpenGL ES 2.0 (the desktop version requires GLEW atm).
Also added auto-walk toggler to improve navigation on a touchscreen
device.
Diffstat (limited to 'mazescene.cpp')
-rw-r--r-- | mazescene.cpp | 187 |
1 files changed, 151 insertions, 36 deletions
diff --git a/mazescene.cpp b/mazescene.cpp index 891f9b7..c99aec4 100644 --- a/mazescene.cpp +++ b/mazescene.cpp @@ -40,6 +40,8 @@ #include "entity.h" #include "modelitem.h" +#include <QVector3D> + #ifdef USE_PHONON #include "mediaplayer/mediaplayer.h" #endif @@ -48,11 +50,27 @@ #include <QGLWidget> #endif +View::View() + : m_scene(0) +{ +} + +void View::setScene(MazeScene *scene) +{ + QGraphicsView::setScene(scene); + + m_scene = scene; + m_scene->viewResized(this); +} + void View::resizeEvent(QResizeEvent *) { resetMatrix(); qreal factor = width() / 4.0; scale(factor, factor); + + if (m_scene) + m_scene->viewResized(this); } Light::Light(const QPointF &pos, qreal intensity) @@ -71,6 +89,96 @@ qreal Light::intensityAt(const QPointF &pos) const + linearIntensity / d; } +QMatrix4x4 fromRotation(float angle, Qt::Axis axis) +{ + QMatrix4x4 m; + if (axis == Qt::XAxis) + m.rotate(angle, QVector3D(1, 0, 0)); + else if (axis == Qt::YAxis) + m.rotate(-angle, QVector3D(0, 1, 0)); + else if (axis == Qt::ZAxis) + m.rotate(angle, QVector3D(0, 0, 1)); + return m; +} + +QMatrix4x4 fromProjection(float fovAngle) +{ + float fov = qCos(fovAngle / 2) / qSin(fovAngle / 2); + + float zNear = 0.01; + float zFar = 1000; + + float m33 = (zNear + zFar) / (zNear - zFar); + float m34 = (2 * zNear * zFar) / (zNear - zFar); + + qreal data[] = + { + fov, 0, 0, 0, + 0, fov, 0, 0, + 0, 0, m33, m34, + 0, 0, -1, 0 + }; + return QMatrix4x4(data); +} + +class WalkingItem : public QGraphicsPixmapItem +{ +public: + WalkingItem(MazeScene *scene); + + void mousePressEvent(QGraphicsSceneMouseEvent *event); + + bool walking() const { return m_walking; } + +private: + void updatePixmap(); + + MazeScene *m_scene; + bool m_walking; + + QPixmap m_walkingPixmap; + QPixmap m_standingPixmap; +}; + +QPixmap colorize(const QPixmap &source, const QColor &color) +{ + QImage temp(source.size(), QImage::Format_ARGB32_Premultiplied); + + temp.fill(0x0); + QPainter p(&temp); + p.drawPixmap(0, 0, source); + p.setCompositionMode(QPainter::CompositionMode_SourceIn); + p.fillRect(temp.rect(), color); + p.end(); + + return QPixmap::fromImage(temp); +} + +WalkingItem::WalkingItem(MazeScene *scene) + : m_scene(scene) + , m_walking(false) + , m_walkingPixmap(colorize(QPixmap("walking.png"), QColor(Qt::green).darker())) + , m_standingPixmap(colorize(QPixmap("standing.png"), QColor(Qt::green).darker())) +{ + setShapeMode(BoundingRectShape); + updatePixmap(); +} + +void WalkingItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->accept(); + m_walking = !m_walking; + updatePixmap(); +} + +void WalkingItem::updatePixmap() +{ + if (m_walking) + setPixmap(m_standingPixmap); + else + setPixmap(m_walkingPixmap); +} + MazeScene::MazeScene(const QVector<Light> &lights, const char *map, int width, int height) : m_lights(lights) , m_walkingVelocity(0) @@ -138,6 +246,20 @@ MazeScene::MazeScene(const QVector<Light> &lights, const char *map, int width, i m_time.start(); updateTransforms(); updateRenderer(); + + m_walkingItem = new WalkingItem(this); + m_walkingItem->scale(0.008, 0.008); + m_walkingItem->setZValue(100000); + + addItem(m_walkingItem); +} + +void MazeScene::viewResized(QGraphicsView *view) +{ + QRectF bounds = m_walkingItem->sceneBoundingRect(); + QPointF bottomLeft = view->mapToScene(QPoint(5, view->height() - 5)); + + m_walkingItem->setPos(bottomLeft.x(), bottomLeft.y() - bounds.height()); } void MazeScene::addProjectedItem(ProjectedItem *item) @@ -230,13 +352,13 @@ void Camera::setTime(qreal time) } -const Matrix4x4 &Camera::viewMatrix() const +const QMatrix4x4 &Camera::viewMatrix() const { updateMatrix(); return m_viewMatrix; } -const Matrix4x4 &Camera::viewProjectionMatrix() const +const QMatrix4x4 &Camera::viewProjectionMatrix() const { updateMatrix(); return m_viewProjectionMatrix; @@ -249,13 +371,13 @@ void Camera::updateMatrix() const m_matrixDirty = false; - Matrix4x4 m; - m *= Matrix4x4::fromTranslation(-m_pos.x(), 0.04 * qSin(10 * m_time) + 0.1, -m_pos.y()); - m *= Matrix4x4::fromRotation(m_yaw + 180, Qt::YAxis); - m *= Matrix4x4::fromScale(-1, 1, 1); - m *= Matrix4x4::fromRotation(m_pitch, Qt::XAxis); + QMatrix4x4 m; + m = QMatrix4x4().translate(-m_pos.x(), 0.04 * qSin(10 * m_time) + 0.1, -m_pos.y()) * m; + m = fromRotation(m_yaw + 180, Qt::YAxis) * m; + m = QMatrix4x4().scale(-1, 1, 1) * m; + m = fromRotation(m_pitch, Qt::XAxis) * m; m_viewMatrix = m; - m *= Matrix4x4::fromProjection(m_fov); + m = fromProjection(m_fov) * m; m_viewProjectionMatrix = m; } @@ -274,23 +396,23 @@ void MazeScene::drawBackground(QPainter *painter, const QRectF &) const QRectF r(1, 1, m_width-2, m_height-2); - Matrix4x4 m = m_camera.viewProjectionMatrix(); + QMatrix4x4 m = m_camera.viewProjectionMatrix(); - Matrix4x4 floorMatrix = Matrix4x4::fromRotation(90, Qt::XAxis); - floorMatrix *= Matrix4x4::fromTranslation(0, 0.5, 0); - floorMatrix *= m; + QMatrix4x4 floorMatrix = fromRotation(90, Qt::XAxis); + floorMatrix = QMatrix4x4().translate(0, 0.5, 0) * floorMatrix; + floorMatrix = m * floorMatrix; painter->save(); - painter->setTransform(floorMatrix.toQTransform(), true); + painter->setTransform(floorMatrix.toTransform(0), true); painter->fillRect(r, floorBrush); painter->restore(); - Matrix4x4 ceilingMatrix = Matrix4x4::fromRotation(90, Qt::XAxis); - ceilingMatrix *= Matrix4x4::fromTranslation(0, -0.5, 0); - ceilingMatrix *= m; + QMatrix4x4 ceilingMatrix = fromRotation(90, Qt::XAxis); + ceilingMatrix = QMatrix4x4().translate(0, -0.5, 0) * ceilingMatrix; + ceilingMatrix = m * ceilingMatrix; painter->save(); - painter->setTransform(ceilingMatrix.toQTransform(), true); + painter->setTransform(ceilingMatrix.toTransform(0), true); painter->fillRect(r, ceilingBrush); painter->restore(); } @@ -326,16 +448,6 @@ void ProjectedItem::setLightingEnabled(bool enable) m_shadowItem->setVisible(enable); } -class ResizingView : public QGraphicsView -{ -protected: - void resizeEvent(QResizeEvent *event) { - if (scene()) - scene()->setSceneRect(QRect(QPoint(0, 0), event->size())); - QGraphicsView::resizeEvent(event); - } -}; - class ProxyWidget : public QGraphicsProxyWidget { public: @@ -443,7 +555,6 @@ WallItem::WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int typ QWebView *view = new QWebView; view->setUrl(QUrl(url)); - childWidget = view; } @@ -585,16 +696,16 @@ void ProjectedItem::updateTransform(const Camera &camera) return; } - Matrix4x4 m; - m *= Matrix4x4::fromRotation(-QLineF(m_b, m_a).angle(), Qt::YAxis); - m *= Matrix4x4::fromTranslation(center.x(), 0, center.y()); - m *= camera.viewProjectionMatrix(); + QMatrix4x4 m; + m = fromRotation(-QLineF(m_b, m_a).angle(), Qt::YAxis) * m; + m = QMatrix4x4().translate(center.x(), 0, center.y()) * m; + m = camera.viewProjectionMatrix() * m; qreal zm = QLineF(camera.pos(), center).length(); setVisible(true); setZValue(-zm); - setTransform(m.toQTransform()); + setTransform(m.toTransform(0)); } @@ -605,7 +716,7 @@ void MazeScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) return; } - if (event->buttons() & Qt::RightButton) { + if (event->buttons() & Qt::LeftButton) { QPointF delta(event->scenePos() - event->lastScenePos()); m_deltaYaw += delta.x() * 80; m_deltaPitch -= delta.y() * 80; @@ -780,13 +891,17 @@ void MazeScene::move() m_deltaPitch += m_pitchSpeed; } + qreal walkingVelocity = m_walkingVelocity; + if (m_walkingItem->walking()) + walkingVelocity = 0.005; + for (int i = 0; i < steps; ++i) { m_camera.setYaw(m_camera.yaw() + m_deltaYaw); m_camera.setPitch(m_camera.pitch() + m_deltaPitch); bool walking = false; - if (m_walkingVelocity != 0) { - QPointF walkingDelta = QLineF::fromPolar(m_walkingVelocity, m_camera.yaw() - 90).p2(); + if (walkingVelocity != 0) { + QPointF walkingDelta = QLineF::fromPolar(walkingVelocity, m_camera.yaw() - 90).p2(); QPointF pos = m_camera.pos(); if (tryMove(pos, walkingDelta)) { walking = true; |