#include <QApplication>
#include <QWidget>
#include <QVector3D>
#include <QMatrix4x4>
#include <QPainter>
#include <QResizeEvent>
#include <QPaintEvent>
{
Q_OBJECT
public:
explicit Widget
(QWidget* parent
= NULL);
virtual ~Widget();
protected:
void DrawLine(QPainter& painter, const QMatrix4x4& transform, QVector3D vector1, QVector3D vector2);
void PaintCube(QPainter& painter, const QMatrix4x4& transform);
void PaintAxes(QPainter& painter, const QMatrix4x4& transform);
void UpdateViewTransform();
void UpdateProjectionTransform(const QSize& newSize);
void UpdateModelTransform();
void UpdateTranslateTransform(const QSize& newSize);
QMatrix4x4 TranslateTransform;
QMatrix4x4 ProjectionTransform;
QMatrix4x4 ViewTransform;
QMatrix4x4 ModelTransform;
};
#define WITH_PERSPECTIVE_PROJECTION
namespace
{
QVector3D TOP_LEFT_FRONT( -100.0, 100.0, 100.0 );
QVector3D TOP_RIGHT_FRONT( 100.0, 100.0, 100.0 );
QVector3D BOTTOM_RIGHT_FRONT( 100.0, -100.0, 100.0 );
QVector3D BOTTOM_LEFT_FRONT( -100.0, -100.0, 100.0 );
QVector3D TOP_LEFT_BACK( -100.0, 100.0, -100.0 );
QVector3D TOP_RIGHT_BACK( 100.0, 100.0, -100.0 );
QVector3D BOTTOM_RIGHT_BACK( 100.0, -100.0, -100.0 );
QVector3D BOTTOM_LEFT_BACK( -100.0, -100.0, -100.0 );
QVector3D X_AXIS( 200, 0, 0 );
QVector3D Y_AXIS( 0, 200, 0 );
QVector3D Z_AXIS( 0, 0, 200 );
}
{
UpdateViewTransform();
UpdateModelTransform();
}
Widget::~Widget()
{
}
{
UpdateTranslateTransform(event->size());
UpdateProjectionTransform(event->size());
}
void Widget::UpdateTranslateTransform(const QSize& newSize)
{
TranslateTransform.setToIdentity();
TranslateTransform.translate(newSize.width() / 2 , newSize.height() / 2);
}
void Widget::UpdateViewTransform()
{
// I question the camera distance compared to the perspective settings
ViewTransform.lookAt(QVector3D(0, 0, 300), QVector3D(), QVector3D(0, 1, 0));
}
void Widget::UpdateProjectionTransform(const QSize& newSize)
{
// I question the fov angle, near plane, and far plane settings compared to the camera position
ProjectionTransform.perspective(120.0, newSize.width() / newSize.height(), 1, 300.0);
}
void Widget::UpdateModelTransform()
{
ModelTransform.setToIdentity(); // no need to move the object around yet.
}
{
Q_UNUSED(event);
QMatrix4x4 transform;
transform *= TranslateTransform;
#ifdef WITH_PERSPECTIVE_PROJECTION
transform *= ProjectionTransform;
#endif
transform *= ViewTransform.inverted();
transform *= ModelTransform;
PaintCube(painter, transform);
PaintAxes(painter, transform);
}
void Widget::PaintCube(QPainter& painter, const QMatrix4x4& transform)
{
painter.setPen(Qt::black);
DrawLine(painter, transform, TOP_LEFT_FRONT, TOP_RIGHT_FRONT);
DrawLine(painter, transform, TOP_RIGHT_FRONT, BOTTOM_RIGHT_FRONT);
DrawLine(painter, transform, BOTTOM_RIGHT_FRONT, BOTTOM_LEFT_FRONT);
DrawLine(painter, transform, BOTTOM_LEFT_FRONT, TOP_LEFT_FRONT);
DrawLine(painter, transform, TOP_LEFT_BACK, TOP_RIGHT_BACK);
DrawLine(painter, transform, TOP_RIGHT_BACK, BOTTOM_RIGHT_BACK);
DrawLine(painter, transform, BOTTOM_RIGHT_BACK, BOTTOM_LEFT_BACK);
DrawLine(painter, transform, BOTTOM_LEFT_BACK, TOP_LEFT_BACK);
DrawLine(painter, transform, TOP_LEFT_FRONT, TOP_LEFT_BACK);
DrawLine(painter, transform, TOP_RIGHT_FRONT, TOP_RIGHT_BACK);
DrawLine(painter, transform, BOTTOM_RIGHT_FRONT, BOTTOM_RIGHT_BACK);
DrawLine(painter, transform, BOTTOM_LEFT_FRONT, BOTTOM_LEFT_BACK);
}
void Widget::PaintAxes(QPainter& painter, const QMatrix4x4& transform)
{
painter.setPen(Qt::red);
DrawLine(painter, transform, QVector3D(), X_AXIS);
painter.setPen(Qt::green);
DrawLine(painter, transform, QVector3D(), Y_AXIS);
painter.setPen(Qt::blue);
DrawLine(painter, transform, QVector3D(), Z_AXIS);
}
void Widget::DrawLine(QPainter& painter, const QMatrix4x4& transform, QVector3D vector1, QVector3D vector2)
{
vector1 = transform.map(vector1);
vector2 = transform.map(vector2);
painter.drawLine(vector1.toPointF(), vector2.toPointF());
}
int main(int argc, char *argv[])
{
Widget w;
w.resize(800, 600);
w.show();
return a.exec();
}
#include "main.moc"
#include <QApplication>
#include <QWidget>
#include <QVector3D>
#include <QMatrix4x4>
#include <QPainter>
#include <QResizeEvent>
#include <QPaintEvent>
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget* parent = NULL);
virtual ~Widget();
protected:
void paintEvent(QPaintEvent* event);
void resizeEvent(QResizeEvent* event);
void DrawLine(QPainter& painter, const QMatrix4x4& transform, QVector3D vector1, QVector3D vector2);
void PaintCube(QPainter& painter, const QMatrix4x4& transform);
void PaintAxes(QPainter& painter, const QMatrix4x4& transform);
void UpdateViewTransform();
void UpdateProjectionTransform(const QSize& newSize);
void UpdateModelTransform();
void UpdateTranslateTransform(const QSize& newSize);
QMatrix4x4 TranslateTransform;
QMatrix4x4 ProjectionTransform;
QMatrix4x4 ViewTransform;
QMatrix4x4 ModelTransform;
};
#define WITH_PERSPECTIVE_PROJECTION
namespace
{
QVector3D TOP_LEFT_FRONT( -100.0, 100.0, 100.0 );
QVector3D TOP_RIGHT_FRONT( 100.0, 100.0, 100.0 );
QVector3D BOTTOM_RIGHT_FRONT( 100.0, -100.0, 100.0 );
QVector3D BOTTOM_LEFT_FRONT( -100.0, -100.0, 100.0 );
QVector3D TOP_LEFT_BACK( -100.0, 100.0, -100.0 );
QVector3D TOP_RIGHT_BACK( 100.0, 100.0, -100.0 );
QVector3D BOTTOM_RIGHT_BACK( 100.0, -100.0, -100.0 );
QVector3D BOTTOM_LEFT_BACK( -100.0, -100.0, -100.0 );
QVector3D X_AXIS( 200, 0, 0 );
QVector3D Y_AXIS( 0, 200, 0 );
QVector3D Z_AXIS( 0, 0, 200 );
}
Widget::Widget(QWidget* parent)
: QWidget(parent)
{
UpdateViewTransform();
UpdateModelTransform();
}
Widget::~Widget()
{
}
void Widget::resizeEvent(QResizeEvent* event)
{
UpdateTranslateTransform(event->size());
UpdateProjectionTransform(event->size());
QWidget::resizeEvent(event);
}
void Widget::UpdateTranslateTransform(const QSize& newSize)
{
TranslateTransform.setToIdentity();
TranslateTransform.translate(newSize.width() / 2 , newSize.height() / 2);
}
void Widget::UpdateViewTransform()
{
// I question the camera distance compared to the perspective settings
ViewTransform.lookAt(QVector3D(0, 0, 300), QVector3D(), QVector3D(0, 1, 0));
}
void Widget::UpdateProjectionTransform(const QSize& newSize)
{
// I question the fov angle, near plane, and far plane settings compared to the camera position
ProjectionTransform.perspective(120.0, newSize.width() / newSize.height(), 1, 300.0);
}
void Widget::UpdateModelTransform()
{
ModelTransform.setToIdentity(); // no need to move the object around yet.
}
void Widget::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
QMatrix4x4 transform;
transform *= TranslateTransform;
#ifdef WITH_PERSPECTIVE_PROJECTION
transform *= ProjectionTransform;
#endif
transform *= ViewTransform.inverted();
transform *= ModelTransform;
PaintCube(painter, transform);
PaintAxes(painter, transform);
}
void Widget::PaintCube(QPainter& painter, const QMatrix4x4& transform)
{
painter.setPen(Qt::black);
DrawLine(painter, transform, TOP_LEFT_FRONT, TOP_RIGHT_FRONT);
DrawLine(painter, transform, TOP_RIGHT_FRONT, BOTTOM_RIGHT_FRONT);
DrawLine(painter, transform, BOTTOM_RIGHT_FRONT, BOTTOM_LEFT_FRONT);
DrawLine(painter, transform, BOTTOM_LEFT_FRONT, TOP_LEFT_FRONT);
DrawLine(painter, transform, TOP_LEFT_BACK, TOP_RIGHT_BACK);
DrawLine(painter, transform, TOP_RIGHT_BACK, BOTTOM_RIGHT_BACK);
DrawLine(painter, transform, BOTTOM_RIGHT_BACK, BOTTOM_LEFT_BACK);
DrawLine(painter, transform, BOTTOM_LEFT_BACK, TOP_LEFT_BACK);
DrawLine(painter, transform, TOP_LEFT_FRONT, TOP_LEFT_BACK);
DrawLine(painter, transform, TOP_RIGHT_FRONT, TOP_RIGHT_BACK);
DrawLine(painter, transform, BOTTOM_RIGHT_FRONT, BOTTOM_RIGHT_BACK);
DrawLine(painter, transform, BOTTOM_LEFT_FRONT, BOTTOM_LEFT_BACK);
}
void Widget::PaintAxes(QPainter& painter, const QMatrix4x4& transform)
{
painter.setPen(Qt::red);
DrawLine(painter, transform, QVector3D(), X_AXIS);
painter.setPen(Qt::green);
DrawLine(painter, transform, QVector3D(), Y_AXIS);
painter.setPen(Qt::blue);
DrawLine(painter, transform, QVector3D(), Z_AXIS);
}
void Widget::DrawLine(QPainter& painter, const QMatrix4x4& transform, QVector3D vector1, QVector3D vector2)
{
vector1 = transform.map(vector1);
vector2 = transform.map(vector2);
painter.drawLine(vector1.toPointF(), vector2.toPointF());
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.resize(800, 600);
w.show();
return a.exec();
}
#include "main.moc"
To copy to clipboard, switch view to plain text mode
Bookmarks