summaryrefslogtreecommitdiffstats
path: root/mazescene.cpp
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-10-01 18:28:48 +0200
committerSamuel Rødal <sroedal@trolltech.com>2009-10-01 18:31:27 +0200
commit180996ae0031c3eb47079d5d9a11e32c81f91faa (patch)
tree48e4b04e37313bc2bdde48906af9b59272033314 /mazescene.cpp
parent6dc84d85ea7d16057e6d298ee439f926414e765b (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.cpp187
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;