summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2008-06-23 11:34:41 +0200
committerSamuel Rødal <sroedal@trolltech.com>2008-06-23 11:34:41 +0200
commitd33e1a6025e80df963745592dbbc5eb53d6ce63f (patch)
tree5dfaa73a34bb551d1c225e70c147108ca705c463
parentf726310976201bf033ac2e39e2d6da7fbf018405 (diff)
Added background color and mouse rotation.
-rw-r--r--main.cpp195
1 files changed, 169 insertions, 26 deletions
diff --git a/main.cpp b/main.cpp
index fd70298..7d20fc1 100644
--- a/main.cpp
+++ b/main.cpp
@@ -21,19 +21,35 @@ public slots:
void enableWireframe(bool enabled);
void enableNormals(bool enabled);
void setLightPosition(int pos);
- void setColor(QRgb color);
+ 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_color;
+ QRgb m_backgroundColor;
+ QRgb m_modelColor;
Model *m_model;
+
+ float m_matrix[4][4];
};
class Controls : public QGroupBox
@@ -46,19 +62,23 @@ public:
private slots:
void loadModel(const QString &model);
void modelLoaded();
- void setColor(bool showDialog = true);
+ void setModelColor(bool showDialog = true);
+ void setBackgroundColor(bool showDialog = true);
private:
GraphicsScene *m_scene;
QFutureWatcher<Model *> m_modelLoader;
QComboBox *m_models;
- QRgb m_color;
+
+ QRgb m_modelColor;
+ QRgb m_backgroundColor;
};
Controls::Controls(GraphicsScene *scene)
: m_scene(scene)
, m_models(new QComboBox)
- , m_color(qRgb(180, 100, 255))
+ , m_modelColor(qRgb(180, 100, 255))
+ , m_backgroundColor(qRgb(0, 0, 0))
{
QVBoxLayout *layout = new QVBoxLayout(this);
@@ -91,16 +111,21 @@ Controls::Controls(GraphicsScene *scene)
layout->addWidget(new QLabel("Light position:"));
QSlider *lightPosition = new QSlider(Qt::Horizontal);
- lightPosition->setRange(-1000, 1000);
+ 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("Set model color");
- connect(colorButton, SIGNAL(pressed()), this, SLOT(setColor()));
+ QPushButton *colorButton = new QPushButton("Choose model color");
+ connect(colorButton, SIGNAL(pressed()), this, SLOT(setModelColor()));
layout->addWidget(colorButton);
- setColor(false);
+ 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)
@@ -122,33 +147,63 @@ void Controls::modelLoaded()
QApplication::restoreOverrideCursor();
}
-void Controls::setColor(bool showDialog)
+void Controls::setModelColor(bool showDialog)
{
if (showDialog)
- m_color = QColorDialog::getRgba(m_color);
+ m_modelColor = QColorDialog::getRgba(m_modelColor);
- m_scene->setColor(m_color);
+ 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_angle(0)
+ , 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);
- addWidget(controls)->translate(10, 10);
+ 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(1, 1, 1, 1);
+ 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();
@@ -162,19 +217,19 @@ void GraphicsScene::drawBackground(QPainter *painter, const QRectF &)
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
-
float pos[] = { m_lightPos, 5, 2, 0 };
glLightfv(GL_LIGHT0, GL_POSITION, pos);
- glColor4f(qRed(m_color)/255.0f, qGreen(m_color)/255.0f, qBlue(m_color)/255.0f, 1.0f);
+ glColor4f(qRed(m_modelColor)/255.0f, qGreen(m_modelColor)/255.0f, qBlue(m_modelColor)/255.0f, 1.0f);
- if (useMultisample)
- glEnable(GL_MULTISAMPLE);
+ if (m_autoRotate && !m_rotating)
+ updateMatrix();
- glTranslatef(0, 0, -1.5);
- glRotatef(m_angle, 0.5, 1, 0.1);
+ glLoadIdentity();
+ glTranslatef(0, 0, -m_distance);
+ glMultMatrixf(&m_matrix[0][0]);
- if (m_autoRotate)
- m_angle += 0.4;
+ if (useMultisample)
+ glEnable(GL_MULTISAMPLE);
m_model->render(m_wireframeEnabled, m_normalsEnabled);
@@ -217,13 +272,101 @@ void GraphicsScene::enableNormals(bool enabled)
void GraphicsScene::setLightPosition(int pos)
{
- m_lightPos = pos * 0.005;
+ m_lightPos = pos * 0.05;
+ update();
+}
+
+void GraphicsScene::setModelColor(QRgb color)
+{
+ m_modelColor = color;
+ update();
+}
+
+void GraphicsScene::setBackgroundColor(QRgb color)
+{
+ m_backgroundColor = color;
update();
}
-void GraphicsScene::setColor(QRgb color)
+static Point3d spherical(const QPointF &point, qreal w, qreal h)
{
- m_color = color;
+ 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();
}