summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--entity.cpp4
-rw-r--r--matrix4x4.cpp194
-rw-r--r--matrix4x4.h60
-rw-r--r--mazescene.cpp187
-rw-r--r--mazescene.h20
-rw-r--r--mediaplayer/mediaplayer.h11
-rw-r--r--model.cpp109
-rw-r--r--model.h28
-rw-r--r--modelitem.cpp109
-rw-r--r--modelitem.h18
-rw-r--r--point3d.h123
-rw-r--r--qt3d.pro11
-rw-r--r--standing.pngbin0 -> 5105 bytes
-rw-r--r--walking.pngbin0 -> 4693 bytes
14 files changed, 346 insertions, 528 deletions
diff --git a/entity.cpp b/entity.cpp
index 3196cdd..1c0bb00 100644
--- a/entity.cpp
+++ b/entity.cpp
@@ -122,9 +122,9 @@ bool Entity::move(MazeScene *scene)
angleToTarget -= 360;
if (angleToTarget < 0)
- m_angle -= qMin(-angleToTarget, 0.5);
+ m_angle -= qMin(-angleToTarget, qreal(0.5));
else
- m_angle += qMin(angleToTarget, 0.5);
+ m_angle += qMin(angleToTarget, qreal(0.5));
moved = true;
}
} else if (m_turnVelocity != 0) {
diff --git a/matrix4x4.cpp b/matrix4x4.cpp
deleted file mode 100644
index 5458f58..0000000
--- a/matrix4x4.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the Graphics Dojo project on Trolltech Labs.
-**
-** This file may be used under the terms of the GNU General Public
-** License version 2.0 or 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of
-** this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-****************************************************************************/
-
-#include "matrix4x4.h"
-
-#include "qmath.h"
-
-Matrix4x4::Matrix4x4()
-{
- float identity[] =
- {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1
- };
-
- setData(identity);
-}
-
-Matrix4x4::Matrix4x4(float *data)
-{
- setData(data);
-}
-
-Matrix4x4 Matrix4x4::orderSwapped() const
-{
- float data[16];
- for (int i = 0; i < 4; ++i)
- for (int j = 0; j < 4; ++j)
- data[4*i + j] = m[4*j + i];
- return Matrix4x4(data);
-}
-
-void Matrix4x4::setData(float *data)
-{
- for (int i = 0; i < 16; ++i)
- m[i] = data[i];
-}
-
-Matrix4x4 &Matrix4x4::operator*=(const Matrix4x4 &rhs)
-{
- const Matrix4x4 lhs = *this;
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- m[4*i + j] = 0;
- for (int k = 0; k < 4; ++k)
- m[4*i + j] += lhs.m[4*i + k] * rhs.m[4*k + j];
- }
- }
- return *this;
-}
-
-Matrix4x4 Matrix4x4::operator*(const Matrix4x4 &other) const
-{
- return Matrix4x4(*this) *= other;
-}
-
-Point3d Matrix4x4::operator*(const Point3d &p) const
-{
- qreal x = m[0] * p.x + m[4] * p.y + m[8] * p.z + m[12];
- qreal y = m[1] * p.x + m[5] * p.y + m[9] * p.z + m[13];
- qreal z = m[2] * p.x + m[6] * p.y + m[10] * p.z + m[14];
- qreal w = m[3] * p.x + m[7] * p.y + m[11] * p.z + m[15];
-
- return Point3d(x / w, y / w, z);
-}
-
-Matrix4x4 Matrix4x4::fromRotation(float angle, Qt::Axis axis)
-{
- QTransform rot;
- rot.rotate(angle);
- switch (axis) {
- case Qt::XAxis:
- {
- float data[] =
- {
- 1, 0, 0, 0,
- 0, rot.m11(), rot.m12(), 0,
- 0, rot.m21(), rot.m22(), 0,
- 0, 0, 0, 1
- };
- return Matrix4x4(data);
- }
- case Qt::YAxis:
- {
- float data[] =
- {
- rot.m11(), 0, rot.m12(), 0,
- 0, 1, 0, 0,
- rot.m21(), 0, rot.m22(), 0,
- 0, 0, 0, 1
- };
- return Matrix4x4(data);
- }
- case Qt::ZAxis:
- {
- float data[] =
- {
- rot.m11(), rot.m12(), 0, 0,
- rot.m21(), rot.m22(), 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1
- };
- return Matrix4x4(data);
- }
- default:
- return Matrix4x4();
- }
-}
-
-Matrix4x4 Matrix4x4::fromTranslation(float dx, float dy, float dz)
-{
- float data[] =
- {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- dx, dy, dz, 1
- };
- return Matrix4x4(data);
-}
-
-Matrix4x4 Matrix4x4::fromScale(float sx, float sy, float sz)
-{
- float data[] =
- {
- sx, 0, 0, 0,
- 0, sy, 0, 0,
- 0, 0, sz, 0,
- 0, 0, 0, 1
- };
- return Matrix4x4(data);
-}
-
-Matrix4x4 Matrix4x4::fromProjection(float fovAngle)
-{
- float fov = qCos(fovAngle / 2) / qSin(fovAngle / 2);
-
- float zNear = 0.001;
- float zFar = 1000;
-
- float m33 = (zNear + zFar) / (zNear - zFar);
- float m34 = (2 * zNear * zFar) / (zNear - zFar);
-
- float data[] =
- {
- fov, 0, 0, 0,
- 0, fov, 0, 0,
- 0, 0, m33, -1,
- 0, 0, m34, 0
- };
- return Matrix4x4(data);
-}
-
-QTransform Matrix4x4::toQTransform() const
-{
- return QTransform(m[0], m[1], m[3],
- m[4], m[5], m[7],
- m[12], m[13], m[15]);
-}
-
-Matrix4x4 Matrix4x4::fromQTransform(const QTransform &transform)
-{
- float data[] =
- {
- transform.m11(), transform.m12(), 0, transform.m13(),
- transform.m21(), transform.m22(), 0, transform.m23(),
- 0, 0, 1, 0,
- transform.m31(), transform.m32(), 0, transform.m33()
- };
-
- return Matrix4x4(data);
-}
diff --git a/matrix4x4.h b/matrix4x4.h
deleted file mode 100644
index 0a286c4..0000000
--- a/matrix4x4.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the Graphics Dojo project on Trolltech Labs.
-**
-** This file may be used under the terms of the GNU General Public
-** License version 2.0 or 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of
-** this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-****************************************************************************/
-
-#ifndef MATRIX4X4_H
-#define MATRIX4X4_H
-
-#include <qnamespace.h>
-#include <QTransform>
-
-#include "point3d.h"
-
-class Matrix4x4
-{
-public:
- Matrix4x4();
- Matrix4x4(float *data);
-
- Matrix4x4 &operator*=(const Matrix4x4 &other);
- Matrix4x4 operator*(const Matrix4x4 &other) const;
-
- Point3d operator*(const Point3d &point) const;
-
- static Matrix4x4 fromRotation(float angle, Qt::Axis axis);
- static Matrix4x4 fromTranslation(float dx, float dy, float dz);
- static Matrix4x4 fromScale(float sx, float sy, float sz);
- static Matrix4x4 fromProjection(float fov);
-
- QTransform toQTransform() const;
- static Matrix4x4 fromQTransform(const QTransform &transform);
-
- void setData(float *data);
- const float *data() const { return m; }
-
- Matrix4x4 orderSwapped() const;
-
-private:
- float m[16];
-};
-
-#endif
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;
diff --git a/mazescene.h b/mazescene.h
index 82b8697..b0621cf 100644
--- a/mazescene.h
+++ b/mazescene.h
@@ -34,17 +34,23 @@
#include <QTime>
#include <QTimeLine>
-#include "matrix4x4.h"
+#include <QMatrix4x4>
class MazeScene;
class MediaPlayer;
class Entity;
+class WalkingItem;
class View : public QGraphicsView
{
Q_OBJECT
public:
+ View();
void resizeEvent(QResizeEvent *event);
+ void setScene(MazeScene *scene);
+
+private:
+ MazeScene *m_scene;
};
class Camera
@@ -70,8 +76,8 @@ public:
void setFov(qreal fov);
void setTime(qreal time);
- const Matrix4x4 &viewProjectionMatrix() const;
- const Matrix4x4 &viewMatrix() const;
+ const QMatrix4x4 &viewProjectionMatrix() const;
+ const QMatrix4x4 &viewMatrix() const;
private:
void updateMatrix() const;
@@ -84,8 +90,8 @@ private:
QPointF m_pos;
mutable bool m_matrixDirty;
- mutable Matrix4x4 m_viewMatrix;
- mutable Matrix4x4 m_viewProjectionMatrix;
+ mutable QMatrix4x4 m_viewMatrix;
+ mutable QMatrix4x4 m_viewProjectionMatrix;
};
class Light
@@ -168,6 +174,8 @@ public:
Camera camera() const { return m_camera; }
+ void viewResized(QGraphicsView *view);
+
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
@@ -216,6 +224,8 @@ private:
int m_height;
MediaPlayer *m_player;
QPointF m_playerPos;
+
+ WalkingItem *m_walkingItem;
};
#endif
diff --git a/mediaplayer/mediaplayer.h b/mediaplayer/mediaplayer.h
index bb2f94b..99bf6e5 100644
--- a/mediaplayer/mediaplayer.h
+++ b/mediaplayer/mediaplayer.h
@@ -30,7 +30,16 @@
#include <QtGui/QShowEvent>
#include <QtGui/QIcon>
-#include <phonon>
+#include <Phonon/AudioOutput>
+#include <Phonon/BackendCapabilities>
+#include <Phonon/Effect>
+#include <Phonon/EffectParameter>
+#include <Phonon/EffectWidget>
+#include <Phonon/MediaObject>
+#include <Phonon/SeekSlider>
+#include <Phonon/VideoWidget>
+#include <Phonon/VolumeSlider>
+
QT_BEGIN_NAMESPACE
class QPushButton;
class QLabel;
diff --git a/model.cpp b/model.cpp
index d3492b0..6437de1 100644
--- a/model.cpp
+++ b/model.cpp
@@ -29,6 +29,9 @@
#include <QVarLengthArray>
#ifndef QT_NO_OPENGL
+#ifndef QT_OPENGL_ES_2
+#include <GL/glew.h>
+#endif
#include <QtOpenGL>
#endif
@@ -39,8 +42,8 @@ Model::Model(const QString &filePath)
if (!file.open(QIODevice::ReadOnly))
return;
- Point3d boundsMin( 1e9, 1e9, 1e9);
- Point3d boundsMax(-1e9,-1e9,-1e9);
+ QVector3D boundsMin( 1e9, 1e9, 1e9);
+ QVector3D boundsMax(-1e9,-1e9,-1e9);
QTextStream in(&file);
while (!in.atEnd()) {
@@ -52,11 +55,11 @@ Model::Model(const QString &filePath)
QString id;
ts >> id;
if (id == "v") {
- Point3d p;
+ QVector3D p;
for (int i = 0; i < 3; ++i) {
- ts >> p[i];
- boundsMin[i] = qMin(boundsMin[i], p[i]);
- boundsMax[i] = qMax(boundsMax[i], p[i]);
+ ts >> ((float *)&p)[i];
+ ((float *)&boundsMin)[i] = qMin(((float *)&boundsMin)[i], ((float *)&p)[i]);
+ ((float *)&boundsMax)[i] = qMax(((float *)&boundsMax)[i], ((float *)&p)[i]);
}
m_points << p;
} else if (id == "f" || id == "fo") {
@@ -87,8 +90,8 @@ Model::Model(const QString &filePath)
}
}
- const Point3d bounds = boundsMax - boundsMin;
- const qreal scale = 1 / qMax(bounds.x / 1, qMax(bounds.y, bounds.z / 1));
+ const QVector3D bounds = boundsMax - boundsMin;
+ const qreal scale = 1 / qMax(bounds.x() / 1, qMax(bounds.y(), bounds.z() / 1));
for (int i = 0; i < m_points.size(); ++i)
m_points[i] = (m_points[i] - (boundsMin + bounds * 0.5)) * scale;
@@ -96,21 +99,21 @@ Model::Model(const QString &filePath)
m_normals.resize(m_points.size());
for (int i = 0; i < m_pointIndices.size(); i += 3) {
- const Point3d a = m_points.at(m_pointIndices.at(i));
- const Point3d b = m_points.at(m_pointIndices.at(i+1));
- const Point3d c = m_points.at(m_pointIndices.at(i+2));
+ const QVector3D a = m_points.at(m_pointIndices.at(i));
+ const QVector3D b = m_points.at(m_pointIndices.at(i+1));
+ const QVector3D c = m_points.at(m_pointIndices.at(i+2));
- const Point3d normal = cross(b - a, c - a).normalize();
+ const QVector3D normal = QVector3D::crossProduct(b - a, c - a).normalized();
for (int j = 0; j < 3; ++j)
m_normals[m_pointIndices.at(i + j)] += normal;
}
for (int i = 0; i < m_normals.size(); ++i)
- m_normals[i] = m_normals[i].normalize();
+ m_normals[i] = m_normals[i].normalized();
}
-Point3d Model::size() const
+QVector3D Model::size() const
{
return m_size;
}
@@ -122,65 +125,67 @@ void Model::render(bool wireframe, bool normals) const
Q_UNUSED(normals);
#else
glEnable(GL_DEPTH_TEST);
- glEnableClientState(GL_VERTEX_ARRAY);
glDepthFunc(GL_GEQUAL);
glDepthMask(true);
- glDisable(GL_TEXTURE_1D);
- glDisable(GL_TEXTURE_2D);
- if (wireframe) {
- glVertexPointer(3, GL_FLOAT, 0, (float *)m_points.data());
- glDrawElements(GL_LINES, m_edgeIndices.size(), GL_UNSIGNED_INT, m_edgeIndices.data());
- } else {
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glEnable(GL_COLOR_MATERIAL);
- glShadeModel(GL_SMOOTH);
-
- glEnableClientState(GL_NORMAL_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, (float *)m_points.data());
- glNormalPointer(GL_FLOAT, 0, (float *)m_normals.data());
- glDrawElements(GL_TRIANGLES, m_pointIndices.size(), GL_UNSIGNED_INT, m_pointIndices.data());
-
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_LIGHT0);
- glDisable(GL_LIGHTING);
- }
+
+#ifdef QT_OPENGL_ES_2
+ GLenum elementType = GL_UNSIGNED_SHORT;
+#else
+ GLenum elementType = GL_UNSIGNED_INT;
+#endif
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (float *)m_points.data());
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (float *)m_normals.data());
+
+ if (wireframe)
+ glDrawElements(GL_LINES, m_edgeIndices.size(), elementType, m_edgeIndices.data());
+ else
+ glDrawElements(GL_TRIANGLES, m_pointIndices.size(), elementType, m_pointIndices.data());
if (normals) {
- QVector<Point3d> normals;
- for (int i = 0; i < m_normals.size(); ++i)
- normals << m_points.at(i) << (m_points.at(i) + m_normals.at(i) * 0.02f);
- glVertexPointer(3, GL_FLOAT, 0, (float *)normals.data());
- glDrawArrays(GL_LINES, 0, normals.size());
+ QVector<QVector3D> points;
+ QVector<QVector3D> normals;
+ for (int i = 0; i < m_normals.size(); ++i) {
+ points << m_points.at(i) << (m_points.at(i) + m_normals.at(i) * 0.02f);
+ normals << m_normals.at(i) << m_normals.at(i);
+ }
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (float *)points.data());
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (float *)normals.data());
+ glDrawArrays(GL_LINES, 0, points.size());
}
- glDisableClientState(GL_VERTEX_ARRAY);
+
+ glDisableVertexAttribArray(1);
+ glDisableVertexAttribArray(0);
glDisable(GL_DEPTH_TEST);
#endif
}
-void Model::render(QPainter *painter, const Matrix4x4 &matrix, bool normals) const
+void Model::render(QPainter *painter, const QMatrix4x4 &matrix, bool normals) const
{
m_mapped.resize(m_points.size());
for (int i = 0; i < m_points.size(); ++i)
- m_mapped[i] = matrix * m_points.at(i);
+ m_mapped[i] = matrix.map(m_points.at(i));
m_lines.clear();
for (int i = 0; i < m_edgeIndices.size(); i += 2) {
- const Point3d a = m_mapped.at(m_edgeIndices.at(i));
- const Point3d b = m_mapped.at(m_edgeIndices.at(i+1));
+ const QVector3D a = m_mapped.at(m_edgeIndices.at(i));
+ const QVector3D b = m_mapped.at(m_edgeIndices.at(i+1));
- if (a.z > 0 && b.z > 0)
- m_lines << QLineF(a.toQPoint(), b.toQPoint());
+ if (a.z() > 0 && b.z() > 0)
+ m_lines << QLineF(a.toPointF(), b.toPointF());
}
if (normals) {
for (int i = 0; i < m_normals.size(); ++i) {
- const Point3d a = m_mapped.at(i);
- const Point3d b = matrix * (m_points.at(i) + m_normals.at(i) * 0.02f);
+ const QVector3D a = m_mapped.at(i);
+ const QVector3D b = matrix.map(m_points.at(i) + m_normals.at(i) * 0.02f);
- if (a.z > 0 && b.z > 0)
- m_lines << QLineF(a.toQPoint(), b.toQPoint());
+ if (a.z() > 0 && b.z() > 0)
+ m_lines << QLineF(a.toPointF(), b.toPointF());
}
}
diff --git a/model.h b/model.h
index e79c9dd..5380b0d 100644
--- a/model.h
+++ b/model.h
@@ -30,8 +30,8 @@
#include <math.h>
-#include "point3d.h"
-#include "matrix4x4.h"
+#include <QMatrix4x4>
+#include <QVector3D>
class Model
{
@@ -40,25 +40,33 @@ public:
Model(const QString &filePath);
void render(bool wireframe = false, bool normals = false) const;
- void render(QPainter *painter, const Matrix4x4 &matrix, bool normals = false) const;
+ void render(QPainter *painter, const QMatrix4x4 &matrix, bool normals = false) const;
QString fileName() const { return m_fileName; }
int faces() const { return m_pointIndices.size() / 3; }
int edges() const { return m_edgeIndices.size() / 2; }
int points() const { return m_points.size(); }
- Point3d size() const;
+ QVector3D size() const;
private:
QString m_fileName;
- QVector<Point3d> m_points;
- QVector<Point3d> m_normals;
- QVector<int> m_edgeIndices;
- QVector<int> m_pointIndices;
- Point3d m_size;
+
+ QVector<QVector3D> m_points;
+ QVector<QVector3D> m_normals;
+
+#ifdef QT_OPENGL_ES_2
+ QVector<ushort> m_edgeIndices;
+ QVector<ushort> m_pointIndices;
+#else
+ QVector<uint> m_edgeIndices;
+ QVector<uint> m_pointIndices;
+#endif
+
+ QVector3D m_size;
mutable QVector<QLineF> m_lines;
- mutable QVector<Point3d> m_mapped;
+ mutable QVector<QVector3D> m_mapped;
};
#endif
diff --git a/modelitem.cpp b/modelitem.cpp
index ab5c537..9255ad9 100644
--- a/modelitem.cpp
+++ b/modelitem.cpp
@@ -29,6 +29,9 @@
#include "mazescene.h"
#ifndef QT_NO_OPENGL
+#ifndef QT_OPENGL_ES_2
+#include <GL/glew.h>
+#endif
#include <QtOpenGL>
#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D
@@ -40,7 +43,7 @@ void ModelItem::updateTransform(const Camera &camera)
ProjectedItem::updateTransform(camera);
setTransform(QTransform());
- m_matrix = Matrix4x4::fromTranslation(3, 0, 7) * camera.viewMatrix();
+ m_matrix = camera.viewMatrix() * QMatrix4x4().translate(3, 0, 7);
}
QRectF ModelItem::boundingRect() const
@@ -58,75 +61,106 @@ void ModelItem::updateItem()
ProjectedItem::update();
}
+const char *vertexProgram =
+ "attribute highp vec4 vertexCoordsArray;"
+ "attribute highp vec4 normalCoordsArray;"
+ "varying highp vec4 normal;"
+ "uniform highp mat4 pmvMatrix;"
+ "uniform highp mat4 modelMatrix;"
+ "void main(void)"
+ "{"
+ " normal = modelMatrix * vec4(normalCoordsArray.xyz, 0);"
+ " gl_Position = pmvMatrix * vertexCoordsArray;"
+ "}";
+
+const char *fragmentProgram =
+ "uniform lowp vec4 color;"
+ "varying highp vec4 normal;"
+ "void main() {"
+ " lowp vec3 toLight = normalize(vec3(-0.9, -1, 0.6));"
+ " gl_FragColor = color * (0.4 + 0.6 * max(dot(normalize(normal).xyz, toLight), 0.0));"
+ "}";
+
+QMatrix4x4 fromProjection(float fov);
+QMatrix4x4 fromRotation(float angle, Qt::Axis axis);
+
void ModelItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
if (!m_model)
return;
- Matrix4x4 projectionMatrix = Matrix4x4::fromProjection(70);
- projectionMatrix *= Matrix4x4::fromQTransform(painter->transform());
+ QMatrix4x4 projectionMatrix = QMatrix4x4(painter->transform()) * fromProjection(70);
- Matrix4x4 modelMatrix;
const int delta = m_time.elapsed() - m_lastTime;
m_rotation += m_angularMomentum * (delta / 1000.0);
m_lastTime += delta;
- Point3d size = m_model->size();
+ QVector3D size = m_model->size();
float extent = qSqrt(2.0);
- float scale = 1 / qMax(size.y, qMax(size.x / extent, size.z / extent));
- modelMatrix *= Matrix4x4::fromScale(scale, -scale, scale);
+ float scale = 1 / qMax(size.y(), qMax(size.x() / extent, size.z() / extent));
+ QMatrix4x4 modelMatrix = QMatrix4x4().scale(scale, -scale, scale);
- modelMatrix *= Matrix4x4::fromRotation(m_rotation.z, Qt::ZAxis);
- modelMatrix *= Matrix4x4::fromRotation(m_rotation.y, Qt::YAxis);
- modelMatrix *= Matrix4x4::fromRotation(m_rotation.x, Qt::XAxis);
+ modelMatrix = fromRotation(m_rotation.z(), Qt::ZAxis) * modelMatrix;
+ modelMatrix = fromRotation(m_rotation.y(), Qt::YAxis) * modelMatrix;
+ modelMatrix = fromRotation(m_rotation.x(), Qt::XAxis) * modelMatrix;
QTimer::singleShot(10, this, SLOT(updateItem()));
#ifndef QT_NO_OPENGL
- if (painter->paintEngine()->type() != QPaintEngine::OpenGL) {
+ if (painter->paintEngine()->type() != QPaintEngine::OpenGL
+ && painter->paintEngine()->type() != QPaintEngine::OpenGL2) {
#endif
m_wireframe->setEnabled(false);
m_wireframe->setChecked(false);
m_wireframeEnabled = false;
painter->setTransform(QTransform());
painter->setPen(m_modelColor);
- m_model->render(painter, modelMatrix * m_matrix * projectionMatrix, m_normalsEnabled);
+ m_model->render(painter, projectionMatrix * m_matrix * modelMatrix, m_normalsEnabled);
return;
#ifndef QT_NO_OPENGL
}
m_wireframe->setEnabled(true);
+ painter->beginNativePainting();
+
+#ifdef QT_OPENGL_ES_2
+ glClearDepthf(0);
+#else
glClearDepth(0);
+#endif
glClear(GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glOrtho(0, painter->device()->width(), painter->device()->height(), 0, -1, 1);
- glMultMatrixf(projectionMatrix.data());
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadMatrixf(m_matrix.data());
-
- const float ambient[] = { 0.1, 0.1, 0.1, 1 };
- const float pos[] = { 50, -500, 200 };
- glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
-
- glMultMatrixf(modelMatrix.data());
-
- glColor4f(m_modelColor.redF(), m_modelColor.greenF(), m_modelColor.blueF(), 1.0f);
+ if (!m_program) {
+#ifndef QT_OPENGL_ES_2
+ glewInit();
+#endif
+ m_program = new QGLShaderProgram;
+ m_program->addShader(QGLShader::FragmentShader, fragmentProgram);
+ m_program->addShader(QGLShader::VertexShader, vertexProgram);
+ m_program->bindAttributeLocation("vertexCoordsArray", 0);
+ m_program->bindAttributeLocation("normalCoordsArray", 1);
+ m_program->link();
+
+ if (!m_program->isLinked())
+ qDebug() << m_program->log();
+ }
- glEnable(GL_MULTISAMPLE);
+ qreal ortho[] = {
+ 2.0f / painter->device()->width(), 0, 0, -1,
+ 0, -2.0f / painter->device()->height(), 0, 1,
+ 0, 0, -1, 0,
+ 0, 0, 0, 1
+ };
+
+ m_program->enable();
+ m_program->setUniformValue("color", m_modelColor);
+ m_program->setUniformValue("pmvMatrix", QMatrix4x4(ortho) * projectionMatrix * m_matrix * modelMatrix);
+ m_program->setUniformValue("modelMatrix", modelMatrix);
m_model->render(m_wireframeEnabled, m_normalsEnabled);
- glDisable(GL_MULTISAMPLE);
+ m_program->disable();
- glPopMatrix();
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
+ painter->endNativePainting();
#endif
}
@@ -140,6 +174,9 @@ ModelItem::ModelItem()
, m_lastTime(0)
, m_distance(1.4f)
, m_angularMomentum(0, 40, 0)
+#ifndef QT_NO_OPENGL
+ , m_program(0)
+#endif
{
QPointF pos(3, 7);
setPosition(pos, pos);
diff --git a/modelitem.h b/modelitem.h
index 062d9fc..26477c1 100644
--- a/modelitem.h
+++ b/modelitem.h
@@ -24,7 +24,7 @@
#ifndef OPENGLSCENE_H
#define OPENGLSCENE_H
-#include "point3d.h"
+#include <QVector3D>
#include <QCheckBox>
#include <QWidget>
@@ -36,6 +36,10 @@
#include "mazescene.h"
+QT_BEGIN_NAMESPACE
+class QGLShaderProgram;
+QT_END_NAMESPACE
+
class Model;
class ModelItem : public QWidget, public ProjectedItem
@@ -75,9 +79,9 @@ private:
int m_mouseEventTime;
float m_distance;
- Point3d m_rotation;
- Point3d m_angularMomentum;
- Point3d m_accumulatedMomentum;
+ QVector3D m_rotation;
+ QVector3D m_angularMomentum;
+ QVector3D m_accumulatedMomentum;
QWidget *m_modelButton;
QCheckBox *m_wireframe;
@@ -85,7 +89,11 @@ private:
#ifndef QT_NO_CONCURRENT
QFutureWatcher<Model *> m_modelLoader;
#endif
- Matrix4x4 m_matrix;
+ QMatrix4x4 m_matrix;
+
+#ifndef QT_NO_OPENGL
+ mutable QGLShaderProgram *m_program;
+#endif
};
#endif
diff --git a/point3d.h b/point3d.h
deleted file mode 100644
index 4172c3a..0000000
--- a/point3d.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the Graphics Dojo project on Trolltech Labs.
-**
-** This file may be used under the terms of the GNU General Public
-** License version 2.0 or 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of
-** this file. Please review the following information to ensure GNU
-** General Public Licensing requirements will be met:
-** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-****************************************************************************/
-
-#ifndef POINT3D_H
-#define POINT3D_H
-
-#include "math.h"
-
-#include <qglobal.h>
-#include <qpoint.h>
-
-struct Point3d
-{
- float x, y, z;
-
- Point3d()
- : x(0)
- , y(0)
- , z(0)
- {
- }
-
- Point3d(float x_, float y_, float z_)
- : x(x_)
- , y(y_)
- , z(z_)
- {
- }
-
- Point3d operator+(const Point3d &p) const
- {
- return Point3d(*this) += p;
- }
-
- Point3d operator-(const Point3d &p) const
- {
- return Point3d(*this) -= p;
- }
-
- Point3d operator*(float f) const
- {
- return Point3d(*this) *= f;
- }
-
-
- Point3d &operator+=(const Point3d &p)
- {
- x += p.x;
- y += p.y;
- z += p.z;
- return *this;
- }
-
- Point3d &operator-=(const Point3d &p)
- {
- x -= p.x;
- y -= p.y;
- z -= p.z;
- return *this;
- }
-
- Point3d &operator*=(float f)
- {
- x *= f;
- y *= f;
- z *= f;
- return *this;
- }
-
- Point3d normalize() const
- {
- float r = 1. / sqrt(x * x + y * y + z * z);
- return Point3d(x * r, y * r, z * r);
- }
-
- float &operator[](unsigned int index) {
- Q_ASSERT(index < 3);
- return (&x)[index];
- }
-
- const float &operator[](unsigned int index) const {
- Q_ASSERT(index < 3);
- return (&x)[index];
- }
-
- QPointF toQPoint() const {
- return QPointF(x, y);
- }
-};
-
-inline float dot(const Point3d &a, const Point3d &b)
-{
- return a.x * b.x + a.y * b.y + a.z * b.z;
-}
-
-inline Point3d cross(const Point3d &a, const Point3d &b)
-{
- return Point3d(a.y * b.z - a.z * b.y,
- a.z * b.x - a.x * b.z,
- a.x * b.y - a.y * b.x);
-}
-
-#endif
diff --git a/qt3d.pro b/qt3d.pro
index fb017f0..1806bd5 100644
--- a/qt3d.pro
+++ b/qt3d.pro
@@ -11,7 +11,10 @@ QMAKE_CXXFLAGS += -g
QT += webkit script
-contains(QT_CONFIG, opengl):QT += opengl
+contains(QT_CONFIG, opengl):{
+QT += opengl
+unix:!contains(QT_CONFIG, opengles2): LIBS += -lGLEW
+}
contains(QT_CONFIG, phonon):{
DEPENDPATH += mediaplayer
@@ -33,9 +36,9 @@ DEPLOYMENT_PLUGIN += phonon_ds9 phonon_waveout
}
# Input
-HEADERS += entity.h mazescene.h matrix4x4.h scriptwidget.h
-SOURCES += main.cpp entity.cpp mazescene.cpp matrix4x4.cpp scriptwidget.cpp
+HEADERS += entity.h mazescene.h scriptwidget.h
+SOURCES += main.cpp entity.cpp mazescene.cpp scriptwidget.cpp
# From modelviewer
-HEADERS += modelitem.h point3d.h model.h
+HEADERS += modelitem.h model.h
SOURCES += model.cpp modelitem.cpp
diff --git a/standing.png b/standing.png
new file mode 100644
index 0000000..8e9eb12
--- /dev/null
+++ b/standing.png
Binary files differ
diff --git a/walking.png b/walking.png
new file mode 100644
index 0000000..fe54ece
--- /dev/null
+++ b/walking.png
Binary files differ