summaryrefslogtreecommitdiffstats
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp371
1 files changed, 1 insertions, 370 deletions
diff --git a/main.cpp b/main.cpp
index 7d20fc1..e71e334 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,374 +1,7 @@
#include <QtGui>
#include <QtOpenGL>
-#include <QFuture>
-#include <QFutureWatcher>
-
-#include "model.h"
-
-class GraphicsScene : public QGraphicsScene
-{
- Q_OBJECT
-
-public:
- GraphicsScene();
-
- void drawBackground(QPainter *painter, const QRectF &rect);
-
-public slots:
- void setModel(Model *model);
- void enableAutoRotate(bool enabled);
- void enableWireframe(bool enabled);
- void enableNormals(bool enabled);
- void setLightPosition(int pos);
- void setModelColor(QRgb color);
- void setBackgroundColor(QRgb color);
-
-protected:
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- void wheelEvent(QGraphicsSceneWheelEvent * wheelEvent);
-
-private:
- void updateMatrix();
- void updateRotation(const QPointF &last, const QPointF &current);
-
- bool m_wireframeEnabled;
- bool m_normalsEnabled;
- bool m_autoRotate;
- bool m_rotating;
-
- Point3d m_axis;
- float m_angle;
- float m_lightPos;
- float m_distance;
-
- QRgb m_backgroundColor;
- QRgb m_modelColor;
-
- Model *m_model;
-
- float m_matrix[4][4];
-};
-
-class Controls : public QGroupBox
-{
- Q_OBJECT
-
-public:
- Controls(GraphicsScene *scene);
-
-private slots:
- void loadModel(const QString &model);
- void modelLoaded();
- void setModelColor(bool showDialog = true);
- void setBackgroundColor(bool showDialog = true);
-
-private:
- GraphicsScene *m_scene;
- QFutureWatcher<Model *> m_modelLoader;
- QComboBox *m_models;
-
- QRgb m_modelColor;
- QRgb m_backgroundColor;
-};
-
-Controls::Controls(GraphicsScene *scene)
- : m_scene(scene)
- , m_models(new QComboBox)
- , m_modelColor(qRgb(180, 100, 255))
- , m_backgroundColor(qRgb(0, 0, 0))
-{
- QVBoxLayout *layout = new QVBoxLayout(this);
-
- layout->addWidget(new QLabel("Model:"));
-
- QDir dir("models");
- dir.setNameFilters(QStringList() << "*.obj");
- m_models->addItems(dir.entryList());
- connect(m_models, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(loadModel(const QString &)));
- connect(&m_modelLoader, SIGNAL(finished()), this, SLOT(modelLoaded()));
-
- if (m_models->count() > 0)
- loadModel(m_models->currentText());
- layout->addWidget(m_models);
-
- QCheckBox *autoRotate = new QCheckBox("Auto-rotate");
- autoRotate->setChecked(true);
- connect(autoRotate, SIGNAL(toggled(bool)), m_scene, SLOT(enableAutoRotate(bool)));
- layout->addWidget(autoRotate);
-
- QCheckBox *wireframe = new QCheckBox("Render as wireframe");
- wireframe->setChecked(true);
- connect(wireframe, SIGNAL(toggled(bool)), m_scene, SLOT(enableWireframe(bool)));
- layout->addWidget(wireframe);
-
- QCheckBox *normals = new QCheckBox("Display normals vectors");
- wireframe->setChecked(false);
- connect(normals, SIGNAL(toggled(bool)), m_scene, SLOT(enableNormals(bool)));
- layout->addWidget(normals);
-
- layout->addWidget(new QLabel("Light position:"));
- QSlider *lightPosition = new QSlider(Qt::Horizontal);
- lightPosition->setRange(-100, 100);
- connect(lightPosition, SIGNAL(valueChanged(int)), m_scene, SLOT(setLightPosition(int)));
- layout->addWidget(lightPosition);
-
- m_scene->setLightPosition(lightPosition->value());
-
- QPushButton *colorButton = new QPushButton("Choose model color");
- connect(colorButton, SIGNAL(pressed()), this, SLOT(setModelColor()));
- layout->addWidget(colorButton);
- setModelColor(false);
-
- QPushButton *backgroundButton = new QPushButton("Choose background color");
- connect(backgroundButton, SIGNAL(pressed()), this, SLOT(setBackgroundColor()));
- layout->addWidget(backgroundButton);
- setBackgroundColor(false);
-}
-
-Model *loadModel(const QString &filename)
-{
- return new Model(QString("models/") + filename);
-}
-
-void Controls::loadModel(const QString &filename)
-{
- m_modelLoader.setFuture(QtConcurrent::run(::loadModel, filename));
- m_models->setEnabled(false);
- QApplication::setOverrideCursor(Qt::BusyCursor);
-}
-
-void Controls::modelLoaded()
-{
- m_scene->setModel(m_modelLoader.result());
- m_models->setEnabled(true);
- QApplication::restoreOverrideCursor();
-}
-
-void Controls::setModelColor(bool showDialog)
-{
- if (showDialog)
- m_modelColor = QColorDialog::getRgba(m_modelColor);
-
- m_scene->setModelColor(m_modelColor);
-}
-
-void Controls::setBackgroundColor(bool showDialog)
-{
- if (showDialog)
- m_backgroundColor = QColorDialog::getRgba(m_backgroundColor);
-
- m_scene->setBackgroundColor(m_backgroundColor);
-}
-
-GraphicsScene::GraphicsScene()
- : m_wireframeEnabled(true)
- , m_normalsEnabled(false)
- , m_autoRotate(true)
- , m_rotating(false)
- , m_axis(0.5, 1, 0.1)
- , m_angle(0.2)
- , m_distance(1.5)
- , m_model(0)
-{
- // set identity matrix
- for (int i = 0; i < 4; ++i)
- for (int j = 0; j < 4; ++j)
- m_matrix[i][j] = (i == j);
-
- Controls *controls = new Controls(this);
- controls->setWindowOpacity(0.8);
-
- QGraphicsProxyWidget *item = addWidget(controls);
- item->translate(10, 10);
- item->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
-
- setSceneRect(QRect(0, 0, 1024, 768));
-}
-
-void GraphicsScene::updateMatrix()
-{
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glRotatef(m_angle, m_axis.x, m_axis.y, m_axis.z);
- glMultMatrixf(&m_matrix[0][0]);
- glGetFloatv(GL_MODELVIEW_MATRIX, &m_matrix[0][0]);
- glPopMatrix();
-}
-
-void GraphicsScene::drawBackground(QPainter *painter, const QRectF &)
-{
- painter->save();
-
- glClearColor(qRed(m_backgroundColor)/255.0f, qGreen(m_backgroundColor)/255.0f, qBlue(m_backgroundColor)/255.0f, 1);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- bool useMultisample = static_cast<QGLWidget *>(painter->device())->format().sampleBuffers();
-
- if (m_model) {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- gluPerspective(70, painter->device()->width() / float(painter->device()->height()), 0.01, 1000);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- float pos[] = { m_lightPos, 5, 2, 0 };
- glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glColor4f(qRed(m_modelColor)/255.0f, qGreen(m_modelColor)/255.0f, qBlue(m_modelColor)/255.0f, 1.0f);
-
- if (m_autoRotate && !m_rotating)
- updateMatrix();
-
- glLoadIdentity();
- glTranslatef(0, 0, -m_distance);
- glMultMatrixf(&m_matrix[0][0]);
-
- if (useMultisample)
- glEnable(GL_MULTISAMPLE);
-
- m_model->render(m_wireframeEnabled, m_normalsEnabled);
-
- if (useMultisample)
- glDisable(GL_MULTISAMPLE);
-
- glPopMatrix();
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- }
-
- painter->restore();
-
- QTimer::singleShot(20, this, SLOT(update()));
-}
-
-void GraphicsScene::setModel(Model *model)
-{
- delete m_model;
- m_model = model;
- update();
-}
-
-void GraphicsScene::enableAutoRotate(bool enabled)
-{
- m_autoRotate = enabled;
- update();
-}
-
-void GraphicsScene::enableWireframe(bool enabled)
-{
- m_wireframeEnabled = enabled;
-}
-
-void GraphicsScene::enableNormals(bool enabled)
-{
- m_normalsEnabled = enabled;
-}
-
-void GraphicsScene::setLightPosition(int pos)
-{
- m_lightPos = pos * 0.05;
- update();
-}
-
-void GraphicsScene::setModelColor(QRgb color)
-{
- m_modelColor = color;
- update();
-}
-
-void GraphicsScene::setBackgroundColor(QRgb color)
-{
- m_backgroundColor = color;
- update();
-}
-
-static Point3d spherical(const QPointF &point, qreal w, qreal h)
-{
- qreal R = qMax(w, h);
-
- Point3d p;
- p.x = -(point.x() - w / 2);
- p.y = point.y() - h / 2;
- p.z = sqrt(R * R - p.x * p.x - p.y * p.y);
-
- p.x /= R;
- p.y /= R;
- p.z /= R;
- return p;
-}
-
-void GraphicsScene::updateRotation(const QPointF &last, const QPointF &current)
-{
- Point3d pos = spherical(current, width(), height());
- Point3d lastPos = spherical(last, width(), height());
-
- m_axis.x = lastPos.y * pos.z - lastPos.z * pos.y;
- m_axis.y = lastPos.z * pos.x - lastPos.x * pos.z;
- m_axis.z = lastPos.x * pos.y - lastPos.y * pos.x;
-
- qreal length = sqrt(m_axis.x * m_axis.x + m_axis.y * m_axis.y + m_axis.z * m_axis.z);
-
- if (length == 0) {
- m_angle = 0;
- } else {
- m_angle = -10 * asin(sqrt(length));
-
- m_axis.x /= length;
- m_axis.y /= length;
- m_axis.z /= length;
-
- updateMatrix();
- update();
- }
-}
-
-void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- QGraphicsScene::mouseMoveEvent(event);
- if (event->isAccepted() || !m_rotating)
- return;
-
- updateRotation(event->lastScenePos(), event->scenePos());
- event->accept();
-}
-
-void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- QGraphicsScene::mousePressEvent(event);
- if (event->isAccepted())
- return;
-
- event->accept();
- m_rotating = true;
-}
-
-void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
- QGraphicsScene::mouseReleaseEvent(event);
- if (event->isAccepted())
- return;
-
- event->accept();
- m_rotating = false;
-}
-
-
-void GraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *event)
-{
- QGraphicsScene::wheelEvent(event);
- if (event->isAccepted())
- return;
-
- m_distance *= qPow(1.2, -event->delta() / 120);
- event->accept();
- update();
-}
+#include "graphicsscene.h"
int main(int argc, char **argv)
{
@@ -388,5 +21,3 @@ int main(int argc, char **argv)
return app.exec();
}
-
-#include "main.moc"