text in FileInfoWindow can be marked and copied,

code cleaning
This commit is contained in:
Anakin 2017-01-28 16:54:36 +01:00
parent 121f5c47f1
commit 96b7d6f736
15 changed files with 446 additions and 436 deletions

View File

@ -47,6 +47,9 @@ Triangles: -</string>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>

View File

@ -1,6 +1,5 @@
#pragma once
#include <QWidget>
#include <QString>
#include "ui_FileInfoWindow.h"
class FileInfoWindow : public QWidget
@ -8,13 +7,21 @@ class FileInfoWindow : public QWidget
Q_OBJECT
public:
FileInfoWindow(QWidget *parent = Q_NULLPTR);
~FileInfoWindow();
FileInfoWindow(QWidget *parent = Q_NULLPTR)
: QWidget(parent)
, ui(new Ui::FileInfoWindow)
{
ui->setupUi(this);
setWindowFlags(Qt::Tool | Qt::NoDropShadowWindowHint);
ui->scrollArea->widget()->setStyleSheet("background-color: #ffffff");
};
~FileInfoWindow() { delete ui; };
private:
Ui::FileInfoWindow* ui;
public:
void setBasicText(QString text);
void setDetailText(QString text);
void setBasicText(QString text) { ui->basic->setText(text); };
void setDetailText(QString text) { ui->detail->setText(text); };
};

View File

@ -1,17 +1,13 @@
#pragma once
#include <QObject>
#include <QOpenGlTexture>
#include <fstream>
#include <QVector>
#include <QVector2D>
#include <QVector3D>
#include <QMatrix4x4>
#include <QQuaternion>
#include <QOpenGLFunctions>
#include <QOpenGlTexture>
#include <QObject>
#include <QOpenGLTexture>
#include <QRegExp>
#include <..\Header\MainWindow.h>
#include "MainWindow.h"
struct BoundingBox {
QQuaternion rotation;

View File

@ -1,11 +1,11 @@
#pragma once
#include "..\Header\FileInterface.h"
#include <QObject>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QVector>
#include "FileInterface.h"
struct DrawInformation {
unsigned int offset;
@ -22,20 +22,28 @@ public:
GeometryEngine(QObject *parent = Q_NULLPTR);
virtual ~GeometryEngine();
// attributes
private:
QOpenGLBuffer m_arrayBuf;
QOpenGLBuffer m_indexBuf;
QVector<Material>* m_materials = Q_NULLPTR;
QVector<DrawInformation> m_drawList;
BoundingBox m_boundings;
Material* m_defaultMaterial;
BoundingBox m_boundings;
QVector<DrawInformation> m_drawList;
// functions
private:
void clearData();
public slots:
void loadFile(QString filePath);
public:
void drawGeometry(QOpenGLShaderProgram *program, bool wireframe);
// slots
public slots:
void loadFile(QString filePath);
// signals
signals:
void requestResetView();
void sendMessage(QString message, int severity);

View File

@ -1,12 +1,11 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include <qwidget.h>
#include <QByteArray>
#include <QStringList>
#include <QLabel>
#include <QWidget>
#include "ui_MainWindow.h"
#include "..\Header\FileInfoWindow.h"
#include "FileInfoWindow.h"
#include <QByteArray>
#include <QLabel>
struct Material;
@ -18,27 +17,32 @@ public:
MainWindow(QWidget *parent = Q_NULLPTR);
~MainWindow();
// attributes
private:
Ui::MainWindowClass* ui;
int m_curSeverity;
void setupWidgets();
QByteArray m_fileInfo;
QLabel* m_output;
int m_curSeverity;
FileInfoWindow* m_infoWindow;
// functions
private:
void setupWidgets();
void openFile();
void aboutFile();
void aboutTool();
void takeScreenShot();
void aboutTool();
protected:
virtual void resizeEvent(QResizeEvent * e) Q_DECL_OVERRIDE;
// slots
public slots:
void printMessage(QString message, int severity);
void setFileInfo(QString name, QVector<Material>* materials, int vertices, int triangle);
// signals
signals:
void loadFile(QString);
};

View File

@ -1,14 +1,10 @@
#pragma once
#include "geometryengine.h"
#include "..\Header\SettingsWindow.h"
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QMatrix4x4>
#include <QQuaternion>
#include <QVector2D>
#include <QBasicTimer>
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>
#include "GeometryEngine.h"
#include "SettingsWindow.h"
class GeometryEngine;
@ -21,10 +17,26 @@ public:
explicit OglViewerWidget(QWidget *parent = 0);
~OglViewerWidget();
signals:
void loadFile(QString);
// attributes
private:
QOpenGLShaderProgram m_program;
GeometryEngine *m_dataEngine;
QVector4D m_backgroundColorOn = { 0.02f, 0.02f, 0.02f, 1.0f };
QVector4D m_backgroundColorOff = { 0.5f, 0.8f, 1.0f, 1.0f };
bool m_wireframe = false;
bool m_lightOn = false;
struct {
QVector4D position = { 1,1,1,0 };
QVector3D intensities = { 1.0,1.0,1.0 };
float attenuationFactor = 0.0f;
float ambientCoefficient = 0.005f;
} m_light;
SettingsWindow* m_settings;
struct {
bool left = false;
bool right = false;
@ -37,53 +49,37 @@ private:
bool z = true;
} m_rotDirections;
struct {
QVector4D position = { 1,1,1,0 };
QVector3D intensities = { 1.0,1.0,1.0 };
float attenuationFactor = 0.0f;
float ambientCoefficient = 0.005f;
} m_light;
SettingsWindow* m_settings;
QVector4D m_backgroundColorOn = {0.02f, 0.02f, 0.02f, 1.0f};
QVector4D m_backgroundColorOff = { 0.5f, 0.8f, 1.0f, 1.0f };
QOpenGLShaderProgram m_program;
GeometryEngine *m_dataEngine;
QMatrix4x4 m_projection;
QVector3D m_translation;
QQuaternion m_rotation;
bool m_wireframe = false;
bool m_lightOn = false;
double m_zSpeed = 1.0;
protected:
void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void wheelEvent(QWheelEvent *e) Q_DECL_OVERRIDE;
void dragEnterEvent(QDragEnterEvent *e) Q_DECL_OVERRIDE;
void dropEvent(QDropEvent * event) Q_DECL_OVERRIDE;
void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;
// functions
private:
void initShaders();
void setConnections();
void resetView();
void updateLightPosition();
protected:
void initializeGL() Q_DECL_OVERRIDE;
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
private:
void initShaders();
void setConnections();
void updateLightPosition();
void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void wheelEvent(QWheelEvent *e) Q_DECL_OVERRIDE;
private slots:
void resetView();
void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;
void dragEnterEvent(QDragEnterEvent *e) Q_DECL_OVERRIDE;
void dropEvent(QDropEvent * event) Q_DECL_OVERRIDE;
// slots
public slots:
void changeDirection(int direction);
void toggleAxis(int axis);
void toggleWireframe();
void toggleLight();
void showSettings();
@ -93,7 +89,9 @@ public slots:
void setAttFac(double value);
void setAmbCoef(double value);
// signals
signals:
void sendMessage(QString message, int severity);
void loadFile(QString);
};

View File

@ -3,6 +3,7 @@
#include "ui_SettingsWindow.h"
#include <QVector3D>
class SettingsWindow : public QWidget
{
Q_OBJECT

View File

@ -3,7 +3,6 @@
#include <QImage>
#include <QColor>
#include <iostream>
QImage loadTga(QString filePath, bool &success)
{
@ -67,7 +66,7 @@ QImage loadTga(QString filePath, bool &success)
int valb = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8);
QColor value(valr, valg, valb);
img.setPixelColor(x, ui32Width - 1 - y, value);
img.setPixel(x, ui32Width - 1 - y, value.rgba());
}
}
}
@ -97,7 +96,7 @@ QImage loadTga(QString filePath, bool &success)
else
color.setRgb(qRgb(tempData[2], tempData[1], tempData[0]));
img.setPixelColor(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color);
img.setPixel(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color.rgba());
tmp_pixelIndex++;
}
}
@ -117,7 +116,7 @@ QImage loadTga(QString filePath, bool &success)
else
color.setRgb(qRgb(tempData[2], tempData[1], tempData[0]));
img.setPixelColor(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color);
img.setPixel(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color.rgba());
tmp_pixelIndex++;
}
}

View File

@ -1,3 +1,9 @@
QLabel#output {
color : white;
min-width: 400px;
min-height: 50px;
}
QToolButton {
image: url(:/images/toolbar/placeholder.png);
border-style: none;

View File

@ -1,29 +0,0 @@
#include "..\Header\FileInfoWindow.h"
#include <QIcon>
FileInfoWindow::FileInfoWindow(QWidget *parent)
: QWidget(parent)
, ui(new Ui::FileInfoWindow)
{
ui->setupUi(this);
setWindowFlags(Qt::Tool | Qt::NoDropShadowWindowHint);
ui->scrollArea->widget()->setStyleSheet("background-color: #ffffff");
}
FileInfoWindow::~FileInfoWindow()
{
delete ui;
}
void FileInfoWindow::setBasicText(QString text)
{
ui->basic->setText(text);
}
void FileInfoWindow::setDetailText(QString text)
{
ui->detail->setText(text);
}

View File

@ -2,20 +2,18 @@
#include "..\Header\MshFile.h"
#include "..\Header\OglViewerWidget.h"
#include "..\Header\MainWindow.h"
#include <cmath>
#include <QRegExp>
/////////////////////////////////////////////////////////////////////////
// public constructor/destructor
// constructor/destructor
GeometryEngine::GeometryEngine(QObject *parent)
: QObject(parent)
, m_indexBuf(QOpenGLBuffer::IndexBuffer)
, m_defaultMaterial(FileInterface::getDefaultMaterial())
{
initializeOpenGLFunctions();
m_defaultMaterial = FileInterface::getDefaultMaterial();
}
GeometryEngine::~GeometryEngine()
@ -27,7 +25,7 @@ GeometryEngine::~GeometryEngine()
/////////////////////////////////////////////////////////////////////////
// private functions
// functions
void GeometryEngine::clearData()
{
@ -52,88 +50,6 @@ void GeometryEngine::clearData()
m_drawList.clear();
}
/////////////////////////////////////////////////////////////////////////
// public slots
void GeometryEngine::loadFile(QString filePath)
{
// cleanup old stuff and recreate buffers
clearData();
m_arrayBuf.create();
m_indexBuf.create();
//reset view
emit requestResetView();
emit sendMessage("loading file..", 0);
try
{
QVector<Model*>* models;
QVector<VertexData> vertexData;
QVector<GLuint> indexData;
// open file and get the information
MshFile file(filePath, this);
models = file.getModels();
m_materials = file.getMaterials();
m_boundings = file.getBoundingBox();
// collect data
unsigned int indexOffset(0);
unsigned int vertexOffset(0);
for (auto& modelIterator : *models)
{
for (auto& segmentIterator : modelIterator->segmList)
{
// get draw information
DrawInformation new_info;
new_info.offset = indexOffset;
new_info.size = segmentIterator->indices.size();
new_info.textureIndex = segmentIterator->textureIndex;
new_info.modelMatrix = modelIterator->m4x4Translation;
new_info.modelMatrix.rotate(modelIterator->quadRotation);
// add offset to indices, no need to do it for the first one (maybe it's very big)
if (vertexOffset != 0)
for (auto& it : segmentIterator->indices)
it += vertexOffset;
// save data
vertexData += segmentIterator->vertices;
indexData += segmentIterator->indices;
if (segmentIterator->textureIndex < (unsigned) m_materials->size() && m_materials->at(segmentIterator->textureIndex).transparent)
m_drawList.push_back(new_info);
else
m_drawList.push_front(new_info);
// update offset
indexOffset += new_info.size;
vertexOffset += segmentIterator->vertices.size();
}
}
// Transfer vertex data to VBO 0
m_arrayBuf.bind();
m_arrayBuf.allocate(vertexData.data(), vertexData.size() * sizeof(VertexData));
// Transfer index data to VBO 1
m_indexBuf.bind();
m_indexBuf.allocate(indexData.data(), indexData.size() * sizeof(GLuint));
emit requestUpdate();
emit sendMessage("done..", 0);
emit sendFileInfo(filePath.right(filePath.size() - filePath.lastIndexOf(QRegExp("/|\\\\")) - 1), m_materials, vertexData.size(), indexData.size() / 3);
}
catch (std::invalid_argument e)
{
clearData();
emit sendMessage(QString(e.what()), 2);
}
}
void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program, bool wireframe)
{
if (!m_arrayBuf.isCreated() || !m_indexBuf.isCreated())
@ -225,3 +141,85 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program, bool wireframe)
}
}
/////////////////////////////////////////////////////////////////////////
// slots
void GeometryEngine::loadFile(QString filePath)
{
// cleanup old stuff and recreate buffers
clearData();
m_arrayBuf.create();
m_indexBuf.create();
//reset view
emit requestResetView();
emit sendMessage("loading file..", 0);
try
{
QVector<Model*>* models;
QVector<VertexData> vertexData;
QVector<GLuint> indexData;
// open file and get the information
MshFile file(filePath, this);
models = file.getModels();
m_materials = file.getMaterials();
m_boundings = file.getBoundingBox();
// collect data
unsigned int indexOffset(0);
unsigned int vertexOffset(0);
for (auto& modelIterator : *models)
{
for (auto& segmentIterator : modelIterator->segmList)
{
// get draw information
DrawInformation new_info;
new_info.offset = indexOffset;
new_info.size = segmentIterator->indices.size();
new_info.textureIndex = segmentIterator->textureIndex;
new_info.modelMatrix = modelIterator->m4x4Translation;
new_info.modelMatrix.rotate(modelIterator->quadRotation);
// add offset to indices, no need to do it for the first one (maybe it's very big)
if (vertexOffset != 0)
for (auto& it : segmentIterator->indices)
it += vertexOffset;
// save data
vertexData += segmentIterator->vertices;
indexData += segmentIterator->indices;
if (segmentIterator->textureIndex < (unsigned) m_materials->size() && m_materials->at(segmentIterator->textureIndex).transparent)
m_drawList.push_back(new_info);
else
m_drawList.push_front(new_info);
// update offset
indexOffset += new_info.size;
vertexOffset += segmentIterator->vertices.size();
}
}
// Transfer vertex data to VBO 0
m_arrayBuf.bind();
m_arrayBuf.allocate(vertexData.data(), vertexData.size() * sizeof(VertexData));
// Transfer index data to VBO 1
m_indexBuf.bind();
m_indexBuf.allocate(indexData.data(), indexData.size() * sizeof(GLuint));
emit requestUpdate();
emit sendMessage("done..", 0);
emit sendFileInfo(filePath.right(filePath.size() - filePath.lastIndexOf(QRegExp("/|\\\\")) - 1), m_materials, vertexData.size(), indexData.size() / 3);
}
catch (std::invalid_argument e)
{
clearData();
emit sendMessage(QString(e.what()), 2);
}
}

View File

@ -1,32 +1,37 @@
#include "..\Header\MainWindow.h"
#include "..\Header\OglViewerWidget.h"
#include <QSurfaceFormat>
#include <QMessageBox>
#include <QFileDialog>
#include <QPalette>
#include <QAction>
#include <QSignalMapper>
#include <QFile>
#include <QSizePolicy>
#include <QFont>
#include <QResizeEvent>
#include <QToolButton>
#include "..\Header\FileInterface.h"
#include <QSurfaceFormat>
#include <QSignalMapper>
#include <QToolButton>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QPalette>
#include <QResizeEvent>
#define WINDOW_NAME "Mesh Viewer"
/////////////////////////////////////////////////////////////////////////
// constructor/destructor
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindowClass)
, m_curSeverity(0)
, m_output(new QLabel(this))
, m_curSeverity(0)
, m_infoWindow(new FileInfoWindow(this))
{
// setup window
ui->setupUi(this);
setWindowTitle(WINDOW_NAME);
setWindowIcon(QIcon(":/images/icon.ico"));
printMessage("MeshViewer by Anakin", 0);
// setup opengl things
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setMajorVersion(2);
@ -34,12 +39,13 @@ MainWindow::MainWindow(QWidget *parent)
format.setProfile(QSurfaceFormat::NoProfile);
QSurfaceFormat::setDefaultFormat(format);
// set default text to file info
m_fileInfo = "Filename: -\nMaterials: -\nVertices: -\nTriangle: -<detail>No file is open";
// add widgets to the window
setupWidgets();
printMessage("MeshViewer by Anakin", 0);
m_fileInfo += "Filename: -\nMaterials: -\nVertices: -\nTriangle: -<detail>No file is open";
// load stylesheet
QFile styleSheet(":/files/StyleSheet.txt");
styleSheet.open(QIODevice::ReadOnly);
this->setStyleSheet(styleSheet.readAll());
@ -52,35 +58,37 @@ MainWindow::~MainWindow()
delete m_infoWindow;
}
void MainWindow::openFile()
{
QString fileName = QFileDialog::getOpenFileName(this, "Open File", "", "Mesh (*.msh)");
if(!fileName.isEmpty())
emit loadFile(fileName);
}
/////////////////////////////////////////////////////////////////////////
// functions
void MainWindow::setupWidgets()
{
// Ogl Viewer
OglViewerWidget* viewer = new OglViewerWidget(this);
setCentralWidget(viewer);
connect(viewer, &OglViewerWidget::sendMessage, this, &MainWindow::printMessage);
// open file
QToolButton *openFile = new QToolButton(this);
openFile->setObjectName("openFile");
openFile->setToolTip("open file");
connect(openFile, &QToolButton::pressed, this, &MainWindow::openFile);
ui->mainToolBar->addWidget(openFile);
// screenshot
QToolButton *screenshot = new QToolButton(this);
screenshot->setObjectName("screenshot");
screenshot->setToolTip("take screenshot");
connect(screenshot, &QToolButton::pressed, this, &MainWindow::takeScreenShot);
ui->mainToolBar->addWidget(screenshot);
//////////////////////////////////////////////////
ui->mainToolBar->addSeparator();
QSignalMapper* signalMapper = new QSignalMapper(this);
// X
QToolButton *x = new QToolButton(this);
x->setObjectName("x");
x->setToolTip("x-direction");
@ -88,6 +96,7 @@ void MainWindow::setupWidgets()
x->setChecked(true);
ui->mainToolBar->addWidget(x);
// Y
QToolButton *y = new QToolButton(this);
y->setObjectName("y");
y->setToolTip("y-direction");
@ -95,6 +104,7 @@ void MainWindow::setupWidgets()
y->setChecked(true);
ui->mainToolBar->addWidget(y);
// Z
QToolButton *z = new QToolButton(this);
z->setObjectName("z");
z->setToolTip("z-direction");
@ -110,10 +120,12 @@ void MainWindow::setupWidgets()
signalMapper->setMapping(y, 2);
signalMapper->setMapping(z, 3);
connect(signalMapper, SIGNAL(mapped(int)), viewer, SLOT(changeDirection(int)));
connect(signalMapper, SIGNAL(mapped(int)), viewer, SLOT(toggleAxis(int)));
//////////////////////////////////////////////////
ui->mainToolBar->addSeparator();
// wireframe
QToolButton *wireframe = new QToolButton(this);
wireframe->setObjectName("wireframe");
wireframe->setToolTip("wireframe");
@ -122,6 +134,7 @@ void MainWindow::setupWidgets()
connect(wireframe, &QToolButton::pressed, viewer, &OglViewerWidget::toggleWireframe);
ui->mainToolBar->addWidget(wireframe);
// light
QToolButton *light = new QToolButton(this);
light->setObjectName("light");
light->setToolTip("toggle light");
@ -130,48 +143,52 @@ void MainWindow::setupWidgets()
connect(light, &QToolButton::pressed, viewer, &OglViewerWidget::toggleLight);
ui->mainToolBar->addWidget(light);
// settings
QToolButton *settings = new QToolButton(this);
settings->setObjectName("settings");
settings->setToolTip("settings");
connect(settings, &QToolButton::pressed, viewer, &OglViewerWidget::showSettings);
ui->mainToolBar->addWidget(settings);
//////////////////////////////////////////////////
ui->mainToolBar->addSeparator();
// fileinfo
QToolButton *fileInfo = new QToolButton(this);
fileInfo->setObjectName("fileInfo");
fileInfo->setToolTip("file info");
connect(fileInfo, &QToolButton::pressed, this, &MainWindow::aboutFile);
connect(fileInfo, &QToolButton::pressed, m_infoWindow, &FileInfoWindow::show);
ui->mainToolBar->addWidget(fileInfo);
// help
QToolButton *help = new QToolButton(this);
help->setObjectName("help");
help->setToolTip("help");
connect(help, &QToolButton::pressed, this, &MainWindow::aboutTool);
ui->mainToolBar->addWidget(help);
// output on screen
m_output->setObjectName("output");
m_output->setStyleSheet("QLabel#output{color : white; min-width: 400px; min-height: 50px;}");
m_output->setAlignment(Qt::AlignTop);
m_output->setText("Name: -\nMaterials: -\nVertice: -\nTriangle: -");
m_output->setText(m_fileInfo.left(m_fileInfo.indexOf("<detail>")));
m_output->raise();
}
void MainWindow::aboutFile()
void MainWindow::openFile()
{
/*QMessageBox* dialog = new QMessageBox(QMessageBox::NoIcon,
WINDOW_NAME,
QString(m_fileInfo.left(m_fileInfo.indexOf("<detail>"))),
QMessageBox::StandardButton::Close,
this,
Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
QString fileName = QFileDialog::getOpenFileName(this, "Open File", "", "Mesh (*.msh)");
if(!fileName.isEmpty())
emit loadFile(fileName);
}
dialog->setStyleSheet("QLabel{min-width: 200px;}");
dialog->setDetailedText(QString(m_fileInfo.right(m_fileInfo.size() - m_fileInfo.indexOf("<detail>") - 8)));
dialog->exec();
delete dialog;*/
m_infoWindow->show();
void MainWindow::takeScreenShot()
{
QString destination = QFileDialog::getSaveFileName(this, "Save as...", "", "PNG (*.png);; BMP (*.bmp);;TIFF (*.tiff, *.tif);;JPEG (*.jpg *jpeg)");
OglViewerWidget* viewer = dynamic_cast<OglViewerWidget*>(centralWidget());
if (!destination.isEmpty() && viewer != NULL)
viewer->grab().save(destination);
}
void MainWindow::aboutTool()
@ -193,22 +210,48 @@ void MainWindow::aboutTool()
delete dialog;
}
void MainWindow::takeScreenShot()
{
QString destination = QFileDialog::getSaveFileName(this, "Save as...", "", "PNG (*.png);; BMP (*.bmp);;TIFF (*.tiff, *.tif);;JPEG (*.jpg *jpeg)");
OglViewerWidget* viewer = dynamic_cast<OglViewerWidget*>(centralWidget());
if (!destination.isEmpty() && viewer != NULL)
viewer->grab().save(destination);
}
void MainWindow::resizeEvent(QResizeEvent * e)
{
m_output->move(40, e->size().height() - 80);
}
/////////////////////////////////////////////////////////////////////////
// slots
void MainWindow::printMessage(QString message, int severity)
{
if (!ui->statusBar->currentMessage().isEmpty() && severity < m_curSeverity)
return;
m_curSeverity = severity;
int time(0);
QPalette palette;
switch (severity)
{
case 1:
time = 3000;
palette.setColor(QPalette::WindowText, Qt::darkYellow);
break;
case 2:
time = 3000;
palette.setColor(QPalette::WindowText, Qt::red);
break;
case 0:
default:
time = 2000;
palette.setColor(QPalette::WindowText, Qt::black);
break;
}
ui->statusBar->setPalette(palette);
ui->statusBar->showMessage(message, time);
}
void MainWindow::setFileInfo(QString name, QVector<Material>* materials, int vertices, int triangle)
{
// save basic file information
m_fileInfo = QByteArray("Filename: ");
m_fileInfo += name;
m_fileInfo += "\nMaterials: ";
@ -219,6 +262,7 @@ void MainWindow::setFileInfo(QString name, QVector<Material>* materials, int ver
m_fileInfo += QByteArray::number(triangle);
m_fileInfo += "<detail>";
// add detailed information
for (auto& it : *materials)
{
m_fileInfo += it.name;
@ -307,39 +351,11 @@ void MainWindow::setFileInfo(QString name, QVector<Material>* materials, int ver
m_fileInfo += "-----------------------------------------------------------------\n";
}
// print basic information on screen
m_output->setText(m_fileInfo.left(m_fileInfo.indexOf("<detail>")));
// print basic and detailed information on info window
m_infoWindow->setBasicText(QString(m_fileInfo.left(m_fileInfo.indexOf("<detail>"))));
m_infoWindow->setDetailText(QString(m_fileInfo.right(m_fileInfo.size() - m_fileInfo.indexOf("<detail>") - 8)));
}
void MainWindow::printMessage(QString message, int severity)
{
if (!ui->statusBar->currentMessage().isEmpty() && severity < m_curSeverity)
return;
m_curSeverity = severity;
int time(0);
QPalette palette;
switch (severity)
{
case 1:
time = 3000;
palette.setColor(QPalette::WindowText, Qt::darkYellow);
break;
case 2:
time = 3000;
palette.setColor(QPalette::WindowText, Qt::red);
break;
case 0:
default:
time = 2000;
palette.setColor(QPalette::WindowText, Qt::black);
break;
}
ui->statusBar->setPalette(palette);
ui->statusBar->showMessage(message, time);
}

View File

@ -1,23 +1,20 @@
#include "..\Header\OglViewerWidget.h"
#include "..\Header\MainWindow.h"
#include <QMouseEvent>
#include <QDropEvent>
#include <QMimeData>
#include <math.h>
#include <iostream>
#define DEFAULT_Z_DISTANCE -4.0
/////////////////////////////////////////////////////////////////////////
// public constructor/destructor
// constructor/destructor
OglViewerWidget::OglViewerWidget(QWidget *parent)
: QOpenGLWidget(parent)
, m_dataEngine(0)
{
setFocus();
m_translation.setZ(DEFAULT_Z_DISTANCE);
setAcceptDrops(true);
m_settings = new SettingsWindow(m_backgroundColorOff.toVector3D() * 255, m_backgroundColorOn.toVector3D() * 255, m_light.intensities * 255, true, m_light.ambientCoefficient, m_light.attenuationFactor, 1, this);
@ -42,7 +39,135 @@ OglViewerWidget::~OglViewerWidget()
/////////////////////////////////////////////////////////////////////////
// protected functions
// functions
void OglViewerWidget::initShaders()
{
// Compile vertex shader
if (!m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl"))
close();
// Compile fragment shader
if (!m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl"))
close();
// Link shader pipeline
if (!m_program.link())
close();
// Bind shader pipeline for use
if (!m_program.bind())
close();
}
void OglViewerWidget::setConnections()
{
connect(m_dataEngine, &GeometryEngine::requestResetView, this, &OglViewerWidget::resetView);
connect(parentWidget(), SIGNAL(loadFile(QString)), m_dataEngine, SLOT(loadFile(QString)));
connect(this, SIGNAL(loadFile(QString)), m_dataEngine, SLOT(loadFile(QString)));
connect(m_dataEngine, SIGNAL(sendMessage(QString, int)), parentWidget(), SLOT(printMessage(QString, int)));
connect(m_dataEngine, SIGNAL(requestUpdate()), this, SLOT(update()));
connect(m_dataEngine, SIGNAL(sendFileInfo(QString, QVector<Material>*, int, int)), parentWidget(), SLOT(setFileInfo(QString, QVector<Material>*, int, int)));
}
void OglViewerWidget::resetView()
{
m_rotation = QQuaternion();
m_translation = { 0.0, 0.0, DEFAULT_Z_DISTANCE };
m_zSpeed = 1;
update();
}
void OglViewerWidget::updateLightPosition()
{
QMatrix4x4 rotateBack;
rotateBack.rotate(m_rotation.inverted());
QVector3D cameraPosition = rotateBack * (-m_translation);
m_light.position.setX(cameraPosition.x());
m_light.position.setY(cameraPosition.y());
m_light.position.setZ(cameraPosition.z());
}
// OpenGL ///////////////////////////////////////////////////////////////
void OglViewerWidget::initializeGL()
{
initializeOpenGLFunctions();
initShaders();
// Enable depth buffer
glEnable(GL_DEPTH_TEST);
//TODO: make this optional
// Enable back face culling
//glEnable(GL_CULL_FACE);
// Enable transparency
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
m_dataEngine = new GeometryEngine(this);
setConnections();
}
void OglViewerWidget::resizeGL(int w, int h)
{
// Calculate aspect ratio
qreal aspect = qreal(w) / qreal(h ? h : 1);
// Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
const qreal zNear = 0.1, zFar = 100.0, fov = 45.0;
// Reset projection
m_projection.setToIdentity();
// Set perspective projection
m_projection.perspective(fov, aspect, zNear, zFar);
}
void OglViewerWidget::paintGL()
{
// set background color, last value is dirtybit
if (m_lightOn && m_backgroundColorOn[3] == 1.0)
{
glClearColor(m_backgroundColorOn[0], m_backgroundColorOn[1], m_backgroundColorOn[2], 0.0000f);
m_backgroundColorOn[3] = 0.0;
}
else if (!m_lightOn && m_backgroundColorOff[3] == 1.0)
{
glClearColor(m_backgroundColorOff[0], m_backgroundColorOff[1], m_backgroundColorOff[2], 0.0000f);
m_backgroundColorOff[3] = 0.0;
}
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate view transformation
QMatrix4x4 view;
view.translate(m_translation);
view.rotate(m_rotation);
// Set view-projection matrix
m_program.setUniformValue("vp_matrix", m_projection * view);
// Set Light values
m_program.setUniformValue("b_light", m_lightOn);
m_program.setUniformValue("light.position", m_light.position);
m_program.setUniformValue("light.intensities", m_light.intensities);
m_program.setUniformValue("light.attenuationFactor", m_light.attenuationFactor);
m_program.setUniformValue("light.ambientCoefficient", m_light.ambientCoefficient);
// Set camera position
QMatrix4x4 rotateBack;
rotateBack.rotate(m_rotation.inverted());
m_program.setUniformValue("cameraPosition", rotateBack * (-m_translation));
// Draw cube geometry
m_dataEngine->drawGeometry(&m_program, m_wireframe);
}
// Inputs ///////////////////////////////////////////////////////////////
void OglViewerWidget::mousePressEvent(QMouseEvent *e)
{
@ -74,11 +199,13 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
// update the new position
m_mouse.position = QVector2D(e->localPos());
// calculate the rotation axis and rotate
// calculate the rotations depending on the active axis
// XYZ
if (m_rotDirections.x && m_rotDirections.y && m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(diff.y(), diff.x(), 0.0).normalized(), diff.length() * 0.5) * m_rotation;
}
// XY
else if (m_rotDirections.x && m_rotDirections.y && !m_rotDirections.z)
{
@ -96,18 +223,22 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
m_rotation = QQuaternion::fromEulerAngles(pitch, yaw, roll);
}
// X
else if (m_rotDirections.x && !m_rotDirections.y && !m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(0.0, 1.0, 0.0).normalized(), diff.x() * 0.5) * m_rotation;
}
// Y
else if (!m_rotDirections.x && m_rotDirections.y && !m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0).normalized(), diff.y() * 0.5) * m_rotation;
}
// Z
else if (!m_rotDirections.x && !m_rotDirections.y && m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(0.0, 0.0, 1.0).normalized(), diff.x() * 0.5) * m_rotation;
}
// XZ
else if (m_rotDirections.x && !m_rotDirections.y && m_rotDirections.z)
{
float pitch, yaw, roll;
@ -117,6 +248,7 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
m_rotation = QQuaternion::fromEulerAngles(pitch, yaw, roll);
}
// YZ
else if (!m_rotDirections.x && m_rotDirections.y && m_rotDirections.z)
{
float pitch, yaw, roll;
@ -132,7 +264,6 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
m_rotation = QQuaternion::fromEulerAngles(pitch, yaw, roll);
}
// request an update
update();
}
@ -158,20 +289,6 @@ void OglViewerWidget::wheelEvent(QWheelEvent *e)
update();
}
void OglViewerWidget::dragEnterEvent(QDragEnterEvent *e)
{
if (e->mimeData()->hasUrls())
if(e->mimeData()->urls().size() == 1)
if(e->mimeData()->urls().first().toLocalFile().endsWith(".msh"))
e->acceptProposedAction();
}
void OglViewerWidget::dropEvent(QDropEvent * e)
{
emit loadFile(e->mimeData()->urls().first().toLocalFile());
}
void OglViewerWidget::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Space)
@ -200,147 +317,27 @@ void OglViewerWidget::keyPressEvent(QKeyEvent *e)
}
}
void OglViewerWidget::initializeGL()
void OglViewerWidget::dragEnterEvent(QDragEnterEvent *e)
{
initializeOpenGLFunctions();
//glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f);
initShaders();
// Enable depth buffer
glEnable(GL_DEPTH_TEST);
// Enable back face culling
//glEnable(GL_CULL_FACE);
// Enable transparency
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
m_dataEngine = new GeometryEngine(this);
setConnections();
}
void OglViewerWidget::resizeGL(int w, int h)
{
// Calculate aspect ratio
qreal aspect = qreal(w) / qreal(h ? h : 1);
// Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
const qreal zNear = 0.1, zFar = 100.0, fov = 45.0;
// Reset projection
m_projection.setToIdentity();
// Set perspective projection
m_projection.perspective(fov, aspect, zNear, zFar);
}
void OglViewerWidget::paintGL()
{
if (m_lightOn && m_backgroundColorOn[3] == 1.0)
{
glClearColor(m_backgroundColorOn[0], m_backgroundColorOn[1], m_backgroundColorOn[2], 0.0000f);
m_backgroundColorOn[3] = 0.0;
}
else if(!m_lightOn && m_backgroundColorOff[3] == 1.0)
{
glClearColor(m_backgroundColorOff[0], m_backgroundColorOff[1], m_backgroundColorOff[2], 0.0000f);
m_backgroundColorOff[3] = 0.0;
}
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate model view transformation
QMatrix4x4 view;
view.translate(m_translation);
view.rotate(m_rotation);
// Set view-projection matrix
m_program.setUniformValue("vp_matrix", m_projection * view);
// Set Light values
m_program.setUniformValue("b_light", m_lightOn);
m_program.setUniformValue("light.position", m_light.position);
m_program.setUniformValue("light.intensities", m_light.intensities);
m_program.setUniformValue("light.attenuationFactor", m_light.attenuationFactor);
m_program.setUniformValue("light.ambientCoefficient", m_light.ambientCoefficient);
// Set camera position
QMatrix4x4 rotateBack;
rotateBack.rotate(m_rotation.inverted());
m_program.setUniformValue("cameraPosition", rotateBack * (-m_translation));
// Draw cube geometry
m_dataEngine->drawGeometry(&m_program, m_wireframe);
}
/////////////////////////////////////////////////////////////////////////
// private functions
void OglViewerWidget::initShaders()
{
// Compile vertex shader
if (!m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/vshader.glsl"))
close();
// Compile fragment shader
if (!m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fshader.glsl"))
close();
// Link shader pipeline
if (!m_program.link())
close();
// Bind shader pipeline for use
if (!m_program.bind())
close();
}
void OglViewerWidget::setConnections()
{
connect(m_dataEngine, &GeometryEngine::requestResetView, this, &OglViewerWidget::resetView);
connect(parentWidget(), SIGNAL(loadFile(QString)), m_dataEngine, SLOT(loadFile(QString)));
connect(this, SIGNAL(loadFile(QString)), m_dataEngine, SLOT(loadFile(QString)));
connect(m_dataEngine, SIGNAL(sendMessage(QString, int)), parentWidget(), SLOT(printMessage(QString, int)));
connect(m_dataEngine, SIGNAL(requestUpdate()), this, SLOT(update()));
connect(m_dataEngine, SIGNAL(sendFileInfo(QString, QVector<Material>*, int, int)), parentWidget(), SLOT(setFileInfo(QString, QVector<Material>*, int, int)));
if (e->mimeData()->hasUrls())
if(e->mimeData()->urls().size() == 1)
if(e->mimeData()->urls().first().toLocalFile().endsWith(".msh"))
e->acceptProposedAction();
}
void OglViewerWidget::updateLightPosition()
void OglViewerWidget::dropEvent(QDropEvent * e)
{
QMatrix4x4 rotateBack;
rotateBack.rotate(m_rotation.inverted());
QVector3D cameraPosition = rotateBack * (-m_translation);
m_light.position.setX(cameraPosition.x());
m_light.position.setY(cameraPosition.y());
m_light.position.setZ(cameraPosition.z());
}
/////////////////////////////////////////////////////////////////////////
// private slots
void OglViewerWidget::resetView()
{
m_rotation = QQuaternion();
m_translation = { 0.0, 0.0, DEFAULT_Z_DISTANCE };
m_zSpeed = 1;
update();
emit loadFile(e->mimeData()->urls().first().toLocalFile());
}
/////////////////////////////////////////////////////////////////////////
// public slots
void OglViewerWidget::changeDirection(int direction)
void OglViewerWidget::toggleAxis(int axis)
{
switch (direction)
switch (axis)
{
case 1:
m_rotDirections.x = !m_rotDirections.x;
@ -356,13 +353,13 @@ void OglViewerWidget::changeDirection(int direction)
void OglViewerWidget::toggleWireframe()
{
m_wireframe = 1 - m_wireframe;
m_wireframe = !m_wireframe;
update();
}
void OglViewerWidget::toggleLight()
{
m_lightOn = 1 - m_lightOn;
m_lightOn = !m_lightOn;
if (m_lightOn)
{
@ -373,6 +370,7 @@ void OglViewerWidget::toggleLight()
{
m_backgroundColorOff[3] = 1.0;
}
update();
}

View File

@ -1,5 +1,8 @@
#include "..\Header\SettingsWindow.h"
#include <QString>
/////////////////////////////////////////////////////////////////////////
// constructor/destructor
SettingsWindow::SettingsWindow(QVector3D bgOffColor, QVector3D bgOnColor, QVector3D lightColor, bool autoColor, double ambCoef, double attFac, int lightType, QWidget * parent)
: QWidget(parent)
@ -38,6 +41,10 @@ SettingsWindow::~SettingsWindow()
delete ui;
}
/////////////////////////////////////////////////////////////////////////
// functions
void SettingsWindow::setupConnections()
{
// light off
@ -87,8 +94,8 @@ void SettingsWindow::setupConnections()
}
////////////////////////////////////////////////////////////////////////////////
// connection slots
/////////////////////////////////////////////////////////////////////////
// slots
void SettingsWindow::autoColorToggled()
{

View File

@ -1,8 +1,6 @@
#include "Header\MainWindow.h"
#include <QtWidgets/QApplication>
// TODO: add glow/emissive
int main(int argc, char *argv[])
{
QApplication a(argc, argv);