Render generated model in graphics viewer

master
Jeremy Hu 2018-03-30 07:32:30 +08:00
parent f48d6bd5f5
commit 94cd279ef3
6 changed files with 89 additions and 16 deletions

View File

@ -3,11 +3,12 @@
#include <QMouseEvent> #include <QMouseEvent>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QCoreApplication> #include <QCoreApplication>
#include <QGuiApplication>
#include <math.h> #include <math.h>
// Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html // Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html
bool ModelWidget::m_transparent = false; bool ModelWidget::m_transparent = true;
ModelWidget::ModelWidget(QWidget *parent) ModelWidget::ModelWidget(QWidget *parent)
: QOpenGLWidget(parent), : QOpenGLWidget(parent),
@ -18,12 +19,15 @@ ModelWidget::ModelWidget(QWidget *parent)
m_renderTriangleVertexCount(0), m_renderTriangleVertexCount(0),
m_renderEdgeVertexCount(0), m_renderEdgeVertexCount(0),
m_mesh(NULL), m_mesh(NULL),
m_meshUpdated(false) m_meshUpdated(false),
m_moveStarted(false)
{ {
m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
// --transparent causes the clear color to be transparent. Therefore, on systems that // --transparent causes the clear color to be transparent. Therefore, on systems that
// support it, the widget will become transparent apart from the logo. // support it, the widget will become transparent apart from the logo.
if (m_transparent) { if (m_transparent) {
setAttribute(Qt::WA_AlwaysStackOnTop);
setAttribute(Qt::WA_TranslucentBackground);
QSurfaceFormat fmt = format(); QSurfaceFormat fmt = format();
fmt.setAlphaBufferSize(8); fmt.setAlphaBufferSize(8);
fmt.setSamples(4); fmt.setSamples(4);
@ -166,8 +170,12 @@ void ModelWidget::initializeGL()
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelWidget::cleanup); connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelWidget::cleanup);
initializeOpenGLFunctions(); initializeOpenGLFunctions();
QColor bgcolor = QWidget::palette().color(QWidget::backgroundRole()); if (m_transparent) {
glClearColor(bgcolor.redF(), bgcolor.greenF(), bgcolor.blueF(), m_transparent ? 0 : 1); glClearColor(0, 0, 0, 0);
} else {
QColor bgcolor = QWidget::palette().color(QWidget::backgroundRole());
glClearColor(bgcolor.redF(), bgcolor.greenF(), bgcolor.blueF(), 1);
}
m_program = new QOpenGLShaderProgram; m_program = new QOpenGLShaderProgram;
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
@ -285,6 +293,21 @@ void ModelWidget::resizeGL(int w, int h)
void ModelWidget::mousePressEvent(QMouseEvent *event) void ModelWidget::mousePressEvent(QMouseEvent *event)
{ {
m_lastPos = event->pos(); m_lastPos = event->pos();
setMouseTracking(true);
if (event->button() == Qt::LeftButton) {
if (!m_moveStarted) {
m_moveStartPos = mapToParent(event->pos());
m_moveStartGeometry = geometry();
m_moveStarted = true;
}
}
}
void ModelWidget::mouseReleaseEvent(QMouseEvent *event)
{
if (m_moveStarted) {
m_moveStarted = false;
}
} }
void ModelWidget::mouseMoveEvent(QMouseEvent *event) void ModelWidget::mouseMoveEvent(QMouseEvent *event)
@ -293,15 +316,37 @@ void ModelWidget::mouseMoveEvent(QMouseEvent *event)
int dy = event->y() - m_lastPos.y(); int dy = event->y() - m_lastPos.y();
if (event->buttons() & Qt::LeftButton) { if (event->buttons() & Qt::LeftButton) {
setXRotation(m_xRot - 8 * dy); if (m_moveStarted) {
setYRotation(m_yRot - 8 * dx); QRect rect = m_moveStartGeometry;
QPoint pos = mapToParent(event->pos());
rect.translate(pos.x() - m_moveStartPos.x(), pos.y() - m_moveStartPos.y());
setGeometry(rect);
}
} else if (event->buttons() & Qt::RightButton) { } else if (event->buttons() & Qt::RightButton) {
setXRotation(m_xRot - 8 * dy); setXRotation(m_xRot - 8 * dy);
setZRotation(m_zRot - 8 * dx); setYRotation(m_yRot - 8 * dx);
} }
m_lastPos = event->pos(); m_lastPos = event->pos();
} }
void ModelWidget::wheelEvent(QWheelEvent *event)
{
if (m_moveStarted)
return;
qreal delta = event->delta() / 10;
if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) {
if (delta > 0)
delta = 1;
else
delta = -1;
} else {
if (fabs(delta) < 1)
delta = delta < 0 ? -1.0 : 1.0;
}
QMargins margins(delta, delta, delta, delta);
setGeometry(geometry().marginsAdded(margins));
}
void ModelWidget::updateMesh(Mesh *mesh) void ModelWidget::updateMesh(Mesh *mesh)
{ {
QMutexLocker lock(&m_meshMutex); QMutexLocker lock(&m_meshMutex);

View File

@ -7,6 +7,7 @@
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QMutex> #include <QMutex>
#include <QRubberBand>
#include "mesh.h" #include "mesh.h"
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram) QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
@ -42,7 +43,8 @@ protected:
void resizeGL(int width, int height) override; void resizeGL(int width, int height) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
private: private:
bool m_core; bool m_core;
int m_xRot; int m_xRot;
@ -68,6 +70,9 @@ private:
Mesh *m_mesh; Mesh *m_mesh;
QMutex m_meshMutex; QMutex m_meshMutex;
bool m_meshUpdated; bool m_meshUpdated;
bool m_moveStarted;
QPoint m_moveStartPos;
QRect m_moveStartGeometry;
}; };
#endif #endif

View File

@ -24,9 +24,17 @@ SkeletonEditGraphicsView::SkeletonEditGraphicsView(QWidget *parent) :
m_lastHoverNodeItem(NULL), m_lastHoverNodeItem(NULL),
m_lastMousePos(0, 0), m_lastMousePos(0, 0),
m_isMovingNodeItem(false), m_isMovingNodeItem(false),
m_backgroundLoaded(false) m_backgroundLoaded(false),
m_modelWidget(NULL),
m_modelWidgetProxy(NULL)
{ {
setScene(new QGraphicsScene()); setScene(new QGraphicsScene());
m_modelWidget = new ModelWidget(this);
m_modelWidget->setMinimumSize(128, 128);
m_modelWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_modelWidget->move(100, 100);
m_modelWidgetProxy = scene()->addWidget(m_modelWidget);
m_backgroundItem = new QGraphicsPixmapItem(); m_backgroundItem = new QGraphicsPixmapItem();
m_backgroundItem->setOpacity(0.25); m_backgroundItem->setOpacity(0.25);
@ -41,6 +49,11 @@ SkeletonEditGraphicsView::SkeletonEditGraphicsView(QWidget *parent) :
scene()->addItem(m_pendingEdgeItem); scene()->addItem(m_pendingEdgeItem);
} }
ModelWidget *SkeletonEditGraphicsView::modelWidget()
{
return m_modelWidget;
}
void SkeletonEditGraphicsView::toggleAddNodeMode() void SkeletonEditGraphicsView::toggleAddNodeMode()
{ {
if (!m_backgroundLoaded) if (!m_backgroundLoaded)

View File

@ -5,9 +5,11 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include <QGraphicsProxyWidget>
#include "skeletoneditnodeitem.h" #include "skeletoneditnodeitem.h"
#include "skeletoneditedgeitem.h" #include "skeletoneditedgeitem.h"
#include "skeletonsnapshot.h" #include "skeletonsnapshot.h"
#include "modelwidget.h"
class SkeletonEditGraphicsView : public QGraphicsView class SkeletonEditGraphicsView : public QGraphicsView
{ {
@ -31,6 +33,7 @@ public:
QPixmap backgroundImage(); QPixmap backgroundImage();
void saveToSnapshot(SkeletonSnapshot *snapshot); void saveToSnapshot(SkeletonSnapshot *snapshot);
void loadFromSnapshot(SkeletonSnapshot *snapshot); void loadFromSnapshot(SkeletonSnapshot *snapshot);
ModelWidget *modelWidget();
protected: protected:
void mouseMoveEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event); void wheelEvent(QWheelEvent *event);
@ -51,6 +54,8 @@ private:
QPointF m_lastMousePos; QPointF m_lastMousePos;
bool m_isMovingNodeItem; bool m_isMovingNodeItem;
bool m_backgroundLoaded; bool m_backgroundLoaded;
ModelWidget *m_modelWidget;
QGraphicsProxyWidget *m_modelWidgetProxy;
private: private:
void toggleAddNodeMode(); void toggleAddNodeMode();
void applyAddNodeMode(); void applyAddNodeMode();

View File

@ -32,11 +32,13 @@ SkeletonWidget::SkeletonWidget(QWidget *parent) :
m_graphicsView->setContentsMargins(0, 0, 0, 0); m_graphicsView->setContentsMargins(0, 0, 0, 0);
m_graphicsView->setFrameStyle(QFrame::NoFrame); m_graphicsView->setFrameStyle(QFrame::NoFrame);
/*
m_modelWidget = new ModelWidget(this); m_modelWidget = new ModelWidget(this);
m_modelWidget->setMinimumSize(128, 128); m_modelWidget->setMinimumSize(128, 128);
m_modelWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); m_modelWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_modelWidget->setWindowFlags(Qt::Tool | Qt::Window); m_modelWidget->setWindowFlags(Qt::Tool | Qt::Window);
m_modelWidget->setWindowTitle("3D Model"); m_modelWidget->setWindowTitle("3D Model");
*/
QVBoxLayout *rightLayout = new QVBoxLayout; QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addSpacing(0); rightLayout->addSpacing(0);
@ -112,25 +114,28 @@ SkeletonEditGraphicsView *SkeletonWidget::graphicsView()
ModelWidget *SkeletonWidget::modelWidget() ModelWidget *SkeletonWidget::modelWidget()
{ {
return m_modelWidget; //return m_modelWidget;
return graphicsView()->modelWidget();
} }
void SkeletonWidget::showModelingWidgetAtCorner() void SkeletonWidget::showModelingWidgetAtCorner()
{ {
/*
if (!m_modelWidget->isVisible()) { if (!m_modelWidget->isVisible()) {
QPoint pos = QPoint(QApplication::desktop()->width(), QPoint pos = QPoint(QApplication::desktop()->width(),
QApplication::desktop()->height()); QApplication::desktop()->height());
m_modelWidget->move(pos.x() - m_modelWidget->width(), m_modelWidget->move(pos.x() - m_modelWidget->width(),
pos.y() - m_modelWidget->height()); pos.y() - m_modelWidget->height());
m_modelWidget->show(); m_modelWidget->show();
} }*/
} }
void SkeletonWidget::meshReady() void SkeletonWidget::meshReady()
{ {
Mesh *resultMesh = m_skeletonToMesh->takeResultMesh(); Mesh *resultMesh = m_skeletonToMesh->takeResultMesh();
showModelingWidgetAtCorner(); //showModelingWidgetAtCorner();
m_modelWidget->updateMesh(resultMesh); //m_modelWidget->updateMesh(resultMesh);
modelWidget()->updateMesh(resultMesh);
delete m_skeletonToMesh; delete m_skeletonToMesh;
m_skeletonToMesh = NULL; m_skeletonToMesh = NULL;
if (m_skeletonDirty) { if (m_skeletonDirty) {

View File

@ -15,14 +15,14 @@
// 0xf7, 0xd9, 0xc8 // 0xf7, 0xd9, 0xc8
QColor Theme::red = QColor(0xfc, 0x66, 0x21); QColor Theme::red = QColor(0xfc, 0x66, 0x21);
QColor Theme::green = QColor(0xaa, 0xeb, 0xc4); QColor Theme::green = QColor(0xf7, 0xd9, 0xc8);
QColor Theme::blue = QColor(0x2a, 0x5a, 0xac); QColor Theme::blue = QColor(0x2a, 0x5a, 0xac);
float Theme::normalAlpha = 128.0 / 255; float Theme::normalAlpha = 128.0 / 255;
float Theme::branchAlpha = 64.0 / 255; float Theme::branchAlpha = 64.0 / 255;
float Theme::checkedAlpha = 1.0; float Theme::checkedAlpha = 1.0;
float Theme::fillAlpha = 50.0 / 255; float Theme::fillAlpha = 50.0 / 255;
int Theme::skeletonNodeBorderSize = 1; int Theme::skeletonNodeBorderSize = 2;
int Theme::skeletonEdgeWidth = 1; int Theme::skeletonEdgeWidth = 2;
std::map<QString, QString> createSideColorNameMap() { std::map<QString, QString> createSideColorNameMap() {
std::map<QString, QString> map; std::map<QString, QString> map;