30 Commits

Author SHA1 Message Date
Anakin
54b87b5de7 fixed things i've broken by the merge conflict 2017-06-20 11:58:03 +02:00
Anakin
68387fe7a7 Merge branch 'developement_1' of git.rwth-aachen.de:carstenf/OpenGL into developement_1
# Conflicts:
#	QtMeshViewer/Header/MainWindow.h
#	QtMeshViewer/Source/MainWindow.cpp
2017-06-20 11:45:15 +02:00
Anakin
44732057b6 using signal slot to update the combobox entries 2017-06-20 11:41:10 +02:00
2d34492517 Implemented qtreeviewwidget instead of a list 2017-06-18 09:33:02 -05:00
3f2713bd16 Fixed logic issue with offset file to file name in listWidget. Edited feel of settings window a bit 2017-06-18 06:46:45 -05:00
c2f7118ed6 Implemented recursive scan for mesh files on selection of dir path. Setup name instead of full path in list. 2017-06-18 06:17:40 -05:00
c6d82f5f55 Updated Settings to cleanup logic plus add a note for hard coded paths. 2017-06-18 06:14:10 -05:00
Anakin
33fafb29a8 removed unused or useless stuff,
renamed some functions for better description,
repaired the SettingsManager usage,
ToDo:
Dropdown list is not updated, it needs a restart,
display names for the directories instead of the path,
2017-06-17 15:42:43 +02:00
6141263f45 Edited open() function to be more descriptive. Set to openFileActual 2017-06-17 05:18:21 -05:00
e59dd980bd Temp update to show unexpected segfault error 2017-06-16 03:16:30 -05:00
1e71ebed47 Set ability to fill listWidget in SettingsWindow with saved dir list from SettingsManager. 2017-06-15 23:28:53 -05:00
d908894265 Added add and remove functionality to settings listWidget 2017-06-15 22:31:11 -05:00
Maxim Stewart
bddc7ea852 Getting dir list to the drop down field 2017-05-31 03:10:34 -05:00
Maxim Stewart
0372a4ad8c Setting up removing and adding stuff to the settings window dirlistview 2017-05-31 03:09:32 -05:00
Maxim Stewart
e768ae9af8 Setup dirList access from settings through getter and setters 2017-05-30 21:38:51 -05:00
Maxim Stewart
b089fcdaf6 Added settings for getting drop down filled and set list to hide folders.
Need to make a dirList setter plus get settings window to keep dirList for editing.
2017-05-30 21:37:17 -05:00
Maxim Stewart
cdda1922fa Fixed accidental overload of function. 2017-05-30 07:49:54 -05:00
Maxim Stewart
031c620f52 Added filter to QFileSystemModel fmodel
Setup some comments regarding a setFilter part
Edited getAssetLibrary to pass arguments to setAsset -- Note will be used for dropdown interaction.
Set a temp path for testing purposes.
2017-05-30 07:42:14 -05:00
Maxim Stewart
7a41f2d9bf Added QFileSystemModel for the fileListView or aka treeView
Added QString filters to be used with QFileSystemModel
Added setAsset method as part of getAssetLibrary for reusability
2017-05-30 07:38:19 -05:00
Maxim Stewart
b2efa83e17 Added check for qkList in meshviewer.config
Added QString listOfDirs
Added gettter method to get listOfDirs
Edited MainWindow.ui to prepare for list of file plus dir drop down
2017-05-30 07:12:50 -05:00
Anakin
7e87b14fe1 made all path relative now 2017-04-30 15:05:21 +02:00
Anakin
da0b7e3c5f new release version,
Features:
- fixed overexposed specular bug,
- most settings are saved after each session
Bugs:
-nothing known
2017-02-08 14:32:48 +01:00
Anakin
fa75e17d58 most settings are saved and restored 2017-02-08 14:29:22 +01:00
Anakin
49585945c3 fixed too high specular,
updated preview.jpg
2017-02-06 16:53:27 +01:00
Anakin
67657061b6 new release version,
Features:
- normal map support,
- added specular support for cloth,
- "glow" support,
Bugs:
- normal mapping looks a bit drizzly depending on the angle of view
2017-02-06 14:59:46 +01:00
Anakin
06d403d546 support normal map now,
support "glow" now,
update preview.jpg
2017-02-06 14:53:05 +01:00
Anakin
541a975624 added preview imange,
passed data to shader,
need to process data in shader
2017-02-05 20:10:05 +01:00
Anakin
30f1a1e627 passing poylNormal, tangent, bitangent to shader 2017-02-05 16:57:12 +01:00
Anakin
cdf19911f6 calculate polygon normal, tangent, and bitangent,
next step, use them for calculation
2017-02-05 16:39:37 +01:00
Anakin
4c40d140a9 cloth now has specular 2017-02-05 15:25:59 +01:00
19 changed files with 1135 additions and 308 deletions

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>600</width> <width>800</width>
<height>400</height> <height>600</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
@@ -19,7 +19,9 @@
<property name="windowTitle"> <property name="windowTitle">
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralWidget"/> <widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout"/>
</widget>
<widget class="QToolBar" name="mainToolBar"> <widget class="QToolBar" name="mainToolBar">
<property name="allowedAreas"> <property name="allowedAreas">
<set>Qt::LeftToolBarArea|Qt::RightToolBarArea|Qt::TopToolBarArea</set> <set>Qt::LeftToolBarArea|Qt::RightToolBarArea|Qt::TopToolBarArea</set>
@@ -32,10 +34,68 @@
</attribute> </attribute>
</widget> </widget>
<widget class="QStatusBar" name="statusBar"/> <widget class="QStatusBar" name="statusBar"/>
<widget class="QDockWidget" name="dockWidget">
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="floating">
<bool>false</bool>
</property>
<property name="features">
<set>QDockWidget::DockWidgetFloatable</set>
</property>
<property name="allowedAreas">
<set>Qt::RightDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Asset library</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QComboBox" name="dirDropDownList">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="fileTreeWidget">
<property name="autoExpandDelay">
<number>0</number>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources/>
<include location="../Resources/Resources.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>584</width>
<height>358</height> <height>645</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -290,77 +290,15 @@
<string>Light</string> <string>Light</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="1"> <item row="2" column="0" colspan="4">
<widget class="QSpinBox" name="light_R_SB"> <widget class="QLabel" name="labelAmbCoeff">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_7">
<property name="text"> <property name="text">
<string>G:</string> <string>Ambientcoefficient:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="4"> <item row="1" column="5">
<widget class="QLabel" name="labelAttFac"> <widget class="QSlider" name="light_G_S">
<property name="text">
<string>Attenuationfactor:</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QSpinBox" name="light_G_SB">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QLabel" name="label_8">
<property name="text">
<string>B:</string>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QSpinBox" name="light_B_SB">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSlider" name="light_R_S">
<property name="maximum"> <property name="maximum">
<number>255</number> <number>255</number>
</property> </property>
@@ -372,55 +310,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="8">
<widget class="QSlider" name="light_B_S">
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>255</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>R:</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QRadioButton" name="radioDirectLight">
<property name="text">
<string>Directional light</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="4" colspan="2">
<widget class="QDoubleSpinBox" name="attFac">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>55</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="2" column="4" colspan="2"> <item row="2" column="4" colspan="2">
<widget class="QDoubleSpinBox" name="ambCoef"> <widget class="QDoubleSpinBox" name="ambCoef">
<property name="enabled"> <property name="enabled">
@@ -446,8 +335,44 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="5"> <item row="3" column="4" colspan="2">
<widget class="QSlider" name="light_G_S"> <widget class="QDoubleSpinBox" name="attFac">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>55</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>R:</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QRadioButton" name="radioDirectLight">
<property name="text">
<string>Directional light</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="QSlider" name="light_B_S">
<property name="maximum"> <property name="maximum">
<number>255</number> <number>255</number>
</property> </property>
@@ -459,17 +384,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0" colspan="4"> <item row="1" column="1">
<widget class="QLabel" name="labelAmbCoeff"> <widget class="QSpinBox" name="light_R_SB">
<property name="text"> <property name="maximumSize">
<string>Ambientcoefficient:</string> <size>
<width>30</width>
<height>16777215</height>
</size>
</property> </property>
</widget> <property name="buttonSymbols">
</item> <enum>QAbstractSpinBox::NoButtons</enum>
<item row="0" column="7" colspan="2"> </property>
<widget class="QCheckBox" name="checkHeadlight"> <property name="maximum">
<property name="text"> <number>255</number>
<string>Headlight</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -480,6 +407,79 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2">
<widget class="QSlider" name="light_R_S">
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>255</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_7">
<property name="text">
<string>G:</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QSpinBox" name="light_G_SB">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<widget class="QLabel" name="labelAttFac">
<property name="text">
<string>Attenuationfactor:</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QLabel" name="label_8">
<property name="text">
<string>B:</string>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QSpinBox" name="light_B_SB">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="0" column="7" colspan="2">
<widget class="QCheckBox" name="checkHeadlight">
<property name="text">
<string>Headlight</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@@ -489,7 +489,21 @@
<string>General</string> <string>General</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="3" colspan="3">
<widget class="QCheckBox" name="checkBackfaceCulling">
<property name="text">
<string>Backface Culling</string>
</property>
</widget>
</item>
<item row="1" column="3"> <item row="1" column="3">
<widget class="QLabel" name="labelZoomSpeed">
<property name="text">
<string>Zoom speed:</string>
</property>
</widget>
</item>
<item row="1" column="6">
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@@ -502,14 +516,7 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="1"> <item row="1" column="5">
<widget class="QLabel" name="labelZoomSpeed">
<property name="text">
<string>Zoom speed:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="spinZSpeed"> <widget class="QSpinBox" name="spinZSpeed">
<property name="suffix"> <property name="suffix">
<string>%</string> <string>%</string>
@@ -525,29 +532,41 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1" colspan="2"> <item row="2" column="3" colspan="4">
<widget class="QCheckBox" name="checkBackfaceCulling"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Backface Culling</string> <string>Directory Drop Down List:</string>
</property>
</widget>
</item>
<item row="4" column="3" colspan="4">
<widget class="QListWidget" name="dirListWidget"/>
</item>
<item row="3" column="3">
<widget class="QLabel" name="label_9">
<property name="text">
<string>*** &quot;BF1_ModTools&quot; Goes To &quot;C:/BF1_ModTools/Assets/Shipped Worlds/&quot;
&quot;BF2_ModTools&quot; Goes To &quot;C:/BF2_ModTools/assets/Sides/&quot;</string>
</property>
</widget>
</item>
<item row="5" column="5">
<widget class="QPushButton" name="removeItem">
<property name="text">
<string>--</string>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QPushButton" name="addItem">
<property name="text">
<string>+</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

View File

@@ -18,6 +18,9 @@ struct VertexData
QVector3D position; QVector3D position;
QVector2D texCoord; QVector2D texCoord;
QVector3D vertexNormal; QVector3D vertexNormal;
QVector3D polygonNormal;
QVector3D tangent;
QVector3D bitangent;
}; };
struct Segment { struct Segment {
@@ -42,10 +45,10 @@ struct Material {
QString tx3d; QString tx3d;
QOpenGLTexture* texture0 = Q_NULLPTR; QOpenGLTexture* texture0 = Q_NULLPTR;
QOpenGLTexture* texture1 = Q_NULLPTR; QOpenGLTexture* texture1 = Q_NULLPTR;
QVector4D specularColor = { 1.0, 1.0, 1.0, 1.0 }; QVector4D specularColor = { 0.1f, 0.1f, 0.1f, 1.0 };
QVector4D diffuseColor = { 1.0, 0.0, 0.0, 1.0 }; QVector4D diffuseColor = { 1.0, 0.0, 0.0, 1.0 };
QVector4D ambientColor = { 1.0, 1.0, 1.0, 1.0 }; QVector4D ambientColor = { 1.0, 1.0, 1.0, 1.0 };
float shininess = 80; float shininess = 1;
bool flags[8] = { false }; bool flags[8] = { false };
bool transparent = false; bool transparent = false;
quint8 rendertype = 0; quint8 rendertype = 0;

View File

@@ -34,6 +34,7 @@ private:
// functions // functions
private: private:
void clearData(); void clearData();
void setupPipeline(QOpenGLShaderProgram * program);
public: public:
void drawGeometry(QOpenGLShaderProgram *program); void drawGeometry(QOpenGLShaderProgram *program);

View File

@@ -6,7 +6,6 @@
#include <QByteArray> #include <QByteArray>
#include <QLabel> #include <QLabel>
struct Material; struct Material;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
@@ -26,11 +25,14 @@ private:
int m_curSeverity; int m_curSeverity;
FileInfoWindow* m_infoWindow; FileInfoWindow* m_infoWindow;
QStringList m_filters;
// functions // functions
private: private:
void setupWidgets(); void setupWidgets();
void openFile(); void updateAssetTree(QString);
void openFileDialog();
void openFile(QString);
void takeScreenShot(); void takeScreenShot();
void aboutTool(); void aboutTool();
@@ -42,6 +44,12 @@ public slots:
void printMessage(QString message, int severity); void printMessage(QString message, int severity);
void setFileInfo(QString name, QVector<Material>* materials, int vertices, int triangle); void setFileInfo(QString name, QVector<Material>* materials, int vertices, int triangle);
// private slots
private slots:
void setupAssetLibrary();
void on_fileTreeWidget_doubleClicked();
void on_dirDropDownList_currentTextChanged(const QString &arg1);
// signals // signals
signals: signals:
void loadFile(QString); void loadFile(QString);

View File

@@ -23,19 +23,19 @@ private:
QOpenGLShaderProgram m_program; QOpenGLShaderProgram m_program;
GeometryEngine *m_dataEngine; GeometryEngine *m_dataEngine;
QVector4D m_backgroundColorOn = { 0.02f, 0.02f, 0.02f, 1.0f }; QVector4D m_backgroundColorOn;
QVector4D m_backgroundColorOff = { 0.5f, 0.8f, 1.0f, 1.0f }; QVector4D m_backgroundColorOff;
bool m_wireframe = false; bool m_wireframe;
bool m_lightOn = false; bool m_lightOn;
bool m_backfaceCulling = false; bool m_backfaceCulling;
struct { struct {
QVector4D position = { 1,1,1,0 }; QVector4D position;
QVector3D intensities = { 1.0,1.0,1.0 }; QVector3D intensities;
float attenuationFactor = 0.0f; float attenuationFactor;
float ambientCoefficient = 0.005f; float ambientCoefficient;
bool headlight = false; bool headlight;
} m_light; } m_light;
struct { struct {
@@ -51,6 +51,7 @@ private:
// functions // functions
private: private:
void setDefaultValues();
void initShaders(); void initShaders();
void resetView(); void resetView();
void updateLightPosition(); void updateLightPosition();
@@ -89,5 +90,10 @@ public slots:
void setHeadlight(bool value); void setHeadlight(bool value);
void setBackfaceCulling(bool value); void setBackfaceCulling(bool value);
// signals
signals:
void lightChanged(bool value);
}; };

View File

@@ -0,0 +1,79 @@
#pragma once
#include <QObject>
#include <QFile>
#include <QVector3D>
#include <QVector4D>
class SettingsManager : public QObject
{
Q_OBJECT
private:
SettingsManager(QObject *parent = Q_NULLPTR);
public:
SettingsManager(SettingsManager const&) = delete;
void operator=(SettingsManager const&) = delete;
~SettingsManager();
static SettingsManager* getInstance(QObject *parent = Q_NULLPTR);
// attributes
private:
QFile m_file;
QStringList m_listOfDirs;
QVector3D m_bgColorOn = { 5, 5, 5 };
QVector3D m_bgColorOff = { 128, 204, 255 };
QVector3D m_lightColor = { 255,255,255 };
bool m_bfCulling = false;
bool m_light = false;
bool m_headlight = false;
bool m_autoColor = true;
float m_attenuation = 0.0f;
float m_ambient = 0.005f;
int m_lightType = 1; // 1 = direct, 2 = point
// functions
private:
void readFromFile();
void writeToFile();
public:
QVector3D getBgColorOn() const;
QVector3D getBgColorOff() const;
bool isBfCulling() const;
bool isLight() const;
QStringList getListOfDirs();
int getLightType() const;
QVector3D getLightColor() const;
float getAttenuation() const;
float getAmbient() const;
bool isHeadlight() const;
bool isAutoColor() const;
// slots
public:
void setBgColorOn(QVector3D value);
void setBgColorOff(QVector3D value);
void setBfCulling(bool value);
void setLight(bool value);
void setLightType(int value);
void setLightColor(QVector3D value);
void setAttenuation(double value);
void setAmbient(double value);
void setHeadlight(bool value);
void setAutoColor(int value);
void updateDirectories(QString path);
// signals
signals:
void dirsChanged();
};

View File

@@ -9,7 +9,7 @@ class SettingsWindow : public QWidget
Q_OBJECT Q_OBJECT
public: public:
SettingsWindow(QVector3D bgOffColor, QVector3D bgOnColor, QVector3D lightColor, bool autoColor, double ambCoef, double attFac, int lightType, QWidget * parent = Q_NULLPTR); SettingsWindow(QWidget * parent = Q_NULLPTR);
~SettingsWindow(); ~SettingsWindow();
private: private:
@@ -24,6 +24,9 @@ private slots:
void backgroundColorOnChanged(); void backgroundColorOnChanged();
void lightColorChanged(); void lightColorChanged();
void on_addItem_clicked();
void on_removeItem_clicked();
signals: signals:
void updateBGColorOff(QVector3D value); void updateBGColorOff(QVector3D value);
void updateBGColorOn(QVector3D value); void updateBGColorOn(QVector3D value);
@@ -33,5 +36,7 @@ signals:
void sendHeadlight(bool value); void sendHeadlight(bool value);
void sendBackfaceCulling(bool value); void sendBackfaceCulling(bool value);
void sendZommSpeed(int percent); void sendZommSpeed(int percent);
void changeLightType(int value);
void pathChanged(QString path);
}; };

View File

@@ -4,16 +4,22 @@ precision mediump int;
precision mediump float; precision mediump float;
#endif #endif
uniform mat3 n_matrix; uniform mat3 normalMatrix;
uniform vec3 cameraPosition; uniform vec3 cameraPosition;
uniform sampler2D texture; uniform sampler2D tx0;
uniform float materialShininess; uniform sampler2D tx1;
uniform vec3 materialSpecularColor;
uniform bool b_transparent; uniform struct Material {
uniform bool b_specular; float shininess;
uniform bool b_light; vec3 specularColor;
bool isTransparent;
bool hasSpecularmap;
bool hasNormalmap;
bool isGlow;
} material;
uniform bool useLight;
uniform struct Light { uniform struct Light {
vec4 position; vec4 position;
@@ -25,67 +31,96 @@ uniform struct Light {
varying vec2 v_surfaceUV; varying vec2 v_surfaceUV;
varying vec3 v_surfacePosition; varying vec3 v_surfacePosition;
varying vec3 v_surfaceNormal; varying vec3 v_surfaceNormal;
varying vec3 v_polyNorm;
varying vec3 v_polyTan;
varying vec3 v_polyBiTan;
void main() void main()
{ {
if(b_light) if(useLight && !material.isGlow)
{ {
// some values // get the color and undo gamma correction
vec3 normalWorld = normalize(n_matrix * v_surfaceNormal); vec4 surfaceColor = vec4(texture2D(tx0, v_surfaceUV));
vec4 surfaceColor = vec4(texture2D(texture, v_surfaceUV));
surfaceColor.rgb = pow(surfaceColor.rgb, vec3(2.2)); surfaceColor.rgb = pow(surfaceColor.rgb, vec3(2.2));
vec3 surfaceToLight; // attenutation depending on the distance to the light
float attenuation;
// directional light
if(light.position.w == 0.0f)
{
surfaceToLight = normalize(light.position.xyz);
}
// point light
else
{
surfaceToLight = normalize(light.position.xyz - v_surfacePosition);
}
float distanceToLight = length(light.position.xyz - v_surfacePosition); float distanceToLight = length(light.position.xyz - v_surfacePosition);
attenuation = 1.0 / (1.0 + light.attenuationFactor * pow(distanceToLight, 2)); float attenuation = 1.0 / (1.0 + light.attenuationFactor * pow(distanceToLight, 2));
// normal vector
vec3 normal = normalize(normalMatrix * v_surfaceNormal);
// direction from surface to light depending on the light type
vec3 surfaceToLight;
if(light.position.w == 0.0) // directional light
surfaceToLight = normalize(light.position.xyz);
else // point light
surfaceToLight = normalize(light.position.xyz - v_surfacePosition);
// direction from surface to camera
vec3 surfaceToCamera = normalize(cameraPosition - v_surfacePosition); vec3 surfaceToCamera = normalize(cameraPosition - v_surfacePosition);
// ambient // adjust the values if material has normal map
if(material.hasNormalmap)
{
vec3 surfaceTangent = normalize(normalMatrix * v_polyTan);
vec3 surfaceBitangent = normalize(normalMatrix * -v_polyBiTan);
vec3 surfaceNormal = normalize(normalMatrix * v_surfaceNormal);
mat3 tbn = transpose(mat3(surfaceTangent, surfaceBitangent, surfaceNormal));
normal = texture2D(tx1, v_surfaceUV).rgb;
normal = normalize(normal * 2.0 -1.0);
surfaceToLight = normalize(tbn * surfaceToLight);
surfaceToCamera = normalize(tbn * surfaceToCamera);
}
/////////////////////////////////////////////////////////////////////////////////////
// ambient component
vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities; vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities;
// diffuse
float diffuseCoefficient = max(0.0, dot(normalWorld, surfaceToLight)); /////////////////////////////////////////////////////////////////////////////////////
// diffuse component
float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight));
vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities; vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities;
// specular
/////////////////////////////////////////////////////////////////////////////////////
// specular component
float specularCoefficient = 0.0; float specularCoefficient = 0.0;
if(diffuseCoefficient > 0.0) if(diffuseCoefficient > 0.0)
specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normalWorld))), materialShininess); specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), material.shininess);
vec3 specColor;
if(b_specular) float specularWeight = 1;
specColor = vec3(surfaceColor.a); if(material.hasSpecularmap)
else specularWeight = surfaceColor.a;
specColor = materialSpecularColor; vec3 specColor = specularWeight * 1/255 * material.specularColor;
vec3 specular = specularCoefficient * specColor * light.intensities; vec3 specular = specularCoefficient * specColor * light.intensities;
// linear color before gamma correction) /////////////////////////////////////////////////////////////////////////////////////
// linear color before gamma correction
vec3 linearColor = ambient + attenuation * (diffuse + specular); vec3 linearColor = ambient + attenuation * (diffuse + specular);
// final color after gama correction /////////////////////////////////////////////////////////////////////////////////////
// gama correction
vec3 gamma = vec3(1.0/2.2); vec3 gamma = vec3(1.0/2.2);
if(!b_transparent)
surfaceColor.a = 1.0f; if(!material.isTransparent)
surfaceColor.a = 1.0;
gl_FragColor = vec4(pow(linearColor, gamma), surfaceColor.a); gl_FragColor = vec4(pow(linearColor, gamma), surfaceColor.a);
} }
// don't use light
else else
{ {
vec4 surfaceColor = vec4(texture2D(texture, v_surfaceUV)); vec4 surfaceColor = vec4(texture2D(tx0, v_surfaceUV));
if(!b_transparent)
surfaceColor.a = 1.0f; if(!material.isTransparent)
surfaceColor.a = 1.0;
gl_FragColor = surfaceColor; gl_FragColor = surfaceColor;
} }

View File

@@ -4,26 +4,35 @@ precision mediump int;
precision mediump float; precision mediump float;
#endif #endif
uniform mat4 vp_matrix; uniform mat4 viewProjection;
uniform mat4 norm_matrix; uniform mat4 normalizeModel;
uniform mat4 m_matrix; uniform mat4 modelMatrix;
attribute vec4 a_position; attribute vec4 a_position;
attribute vec2 a_texcoord; attribute vec2 a_texcoord;
attribute vec3 a_normal; attribute vec3 a_normal;
attribute vec3 a_polyNorm;
attribute vec3 a_polyTan;
attribute vec3 a_polyBiTan;
varying vec2 v_surfaceUV; varying vec2 v_surfaceUV;
varying vec3 v_surfacePosition; varying vec3 v_surfacePosition;
varying vec3 v_surfaceNormal; varying vec3 v_surfaceNormal;
varying vec3 v_polyNorm;
varying vec3 v_polyTan;
varying vec3 v_polyBiTan;
void main() void main()
{ {
// Calculate vertex position in screen space // Calculate vertex position in screen space
gl_Position = vp_matrix * norm_matrix * m_matrix * a_position; gl_Position = viewProjection * normalizeModel * modelMatrix * a_position;
// Pass data to fragment shader // Pass data to fragment shader
// Value will be automatically interpolated to fragments inside polygon faces // Value will be automatically interpolated to fragments inside polygon faces
v_surfaceUV = a_texcoord; v_surfaceUV = a_texcoord;
v_surfacePosition = vec3(norm_matrix * m_matrix * a_position); v_surfacePosition = vec3(normalizeModel * modelMatrix * a_position);
v_surfaceNormal = a_normal; v_surfaceNormal = a_normal;
v_polyNorm = a_polyNorm;
v_polyTan = a_polyTan;
v_polyBiTan = a_polyBiTan;
} }

View File

@@ -5,7 +5,6 @@
#include "..\Header\OutputDevice.h" #include "..\Header\OutputDevice.h"
#include <QRegExp> #include <QRegExp>
#include "..\Header\Profiler.h"
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// constructor/destructor // constructor/destructor
@@ -52,26 +51,8 @@ void GeometryEngine::clearData()
m_drawList.clear(); m_drawList.clear();
} }
void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program) void GeometryEngine::setupPipeline(QOpenGLShaderProgram *program)
{ {
if (!m_arrayBuf.isCreated() || !m_indexBuf.isCreated())
return;
// Setup
// Tell OpenGL which VBOs to use
m_arrayBuf.bind();
m_indexBuf.bind();
// Allways normalize by this
QMatrix4x4 normMatrix;
float maxExtent = std::max(std::max(m_boundings.extents[0], m_boundings.extents[1]), m_boundings.extents[2]);
normMatrix.scale(1 / maxExtent);
normMatrix.translate(-m_boundings.center[0], -m_boundings.center[1], -m_boundings.center[2]);
program->setUniformValue("norm_matrix", normMatrix);
// Allways use texture unit 0
program->setUniformValue("texture", 0);
// Offset for position // Offset for position
quintptr offset = 0; quintptr offset = 0;
@@ -88,13 +69,63 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program)
program->enableAttributeArray(texcoordLocation); program->enableAttributeArray(texcoordLocation);
program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData)); program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(VertexData));
//Offset for normal //Offset for vertexNormal
offset += sizeof(QVector2D); offset += sizeof(QVector2D);
// Tell OpenGL programmable pipeline how to locate vertex normal data // Tell OpenGL programmable pipeline how to locate vertex normal data
int normLocation = program->attributeLocation("a_normal"); int vertNormLocation = program->attributeLocation("a_normal");
program->enableAttributeArray(normLocation); program->enableAttributeArray(vertNormLocation);
program->setAttributeBuffer(normLocation, GL_FLOAT, offset, 3, sizeof(VertexData)); program->setAttributeBuffer(vertNormLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
//Offset for polygonNormal
offset += sizeof(QVector3D);
// Tell OpenGL programmable pipeline how to locate polygon normal data
int polyNormLocation = program->attributeLocation("a_polyNorm");
program->enableAttributeArray(polyNormLocation);
program->setAttributeBuffer(polyNormLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
//Offset for polygonTangent
offset += sizeof(QVector3D);
// Tell OpenGL programmable pipeline how to locate polygon tangent data
int polyTanLocation = program->attributeLocation("a_polyTan");
program->enableAttributeArray(polyTanLocation);
program->setAttributeBuffer(polyTanLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
//Offset for polygonBitangent
offset += sizeof(QVector3D);
// Tell OpenGL programmable pipeline how to locate polygon bitangent data
int polyBiTanLocation = program->attributeLocation("a_polyBiTan");
program->enableAttributeArray(polyBiTanLocation);
program->setAttributeBuffer(polyBiTanLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
}
void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program)
{
if (!m_arrayBuf.isCreated() || !m_indexBuf.isCreated())
return;
// Setup
// Tell OpenGL which VBOs to use
m_arrayBuf.bind();
m_indexBuf.bind();
// Allways normalize by this
QMatrix4x4 normMatrix;
float maxExtent = std::max(std::max(m_boundings.extents[0], m_boundings.extents[1]), m_boundings.extents[2]);
normMatrix.scale(1 / maxExtent);
normMatrix.translate(-m_boundings.center[0], -m_boundings.center[1], -m_boundings.center[2]);
program->setUniformValue("normalizeModel", normMatrix);
// Allways use texture unit 0 and 1
program->setUniformValue("tx0", 0);
program->setUniformValue("tx1", 1);
//setup the pipeline
setupPipeline(program);
// Paint // Paint
@@ -102,36 +133,51 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program)
{ {
bool tmp_transparent(false); bool tmp_transparent(false);
bool tmp_specular(false); bool tmp_specular(false);
bool tmp_normalmap(false);
bool tmp_glow(false);
float shininess(0.0); float shininess(0.0);
QVector3D specularColor; QVector3D specularColor;
// bind the correct texture // bind the correct texture
if (it.textureIndex < (unsigned)m_materials->size() && m_materials->at(it.textureIndex).texture0 != Q_NULLPTR) if (it.textureIndex < (unsigned)m_materials->size() && m_materials->at(it.textureIndex).texture0 != Q_NULLPTR)
{ {
m_materials->at(it.textureIndex).texture0->bind(); m_materials->at(it.textureIndex).texture0->bind(0);
tmp_transparent = m_materials->at(it.textureIndex).transparent; tmp_transparent = m_materials->at(it.textureIndex).transparent;
tmp_specular = m_materials->at(it.textureIndex).flags[7]; tmp_specular = m_materials->at(it.textureIndex).flags[7];
shininess = m_materials->at(it.textureIndex).shininess; shininess = m_materials->at(it.textureIndex).shininess;
specularColor = m_materials->at(it.textureIndex).specularColor.toVector3D(); specularColor = m_materials->at(it.textureIndex).specularColor.toVector3D();
if (m_materials->at(it.textureIndex).rendertype == 27 || m_materials->at(it.textureIndex).rendertype == 28)
{
if (m_materials->at(it.textureIndex).texture1 != Q_NULLPTR)
{
tmp_normalmap = true;
m_materials->at(it.textureIndex).texture1->bind(1);
}
}
if (m_materials->at(it.textureIndex).flags[0] || m_materials->at(it.textureIndex).flags[1] || m_materials->at(it.textureIndex).rendertype == 1)
tmp_glow = true;
} }
else else
{ {
m_defaultMaterial->texture0->bind(); m_defaultMaterial->texture0->bind(0);
tmp_transparent = m_defaultMaterial->transparent; tmp_transparent = m_defaultMaterial->transparent;
} }
// Set model matrix // Set model matrix
program->setUniformValue("m_matrix", it.modelMatrix); program->setUniformValue("modelMatrix", it.modelMatrix);
// Set normal matrix // Set normal matrix
program->setUniformValue("n_matrix", (normMatrix * it.modelMatrix).normalMatrix()); program->setUniformValue("normalMatrix", (normMatrix * it.modelMatrix).normalMatrix());
// set some more values
program->setUniformValue("b_transparent", tmp_transparent);
program->setUniformValue("b_specular", tmp_specular);
// set some material attributes // set some material attributes
program->setUniformValue("materialShininess", shininess); program->setUniformValue("material.shininess", shininess);
program->setUniformValue("materialSpecularColor", specularColor); program->setUniformValue("material.specularColor", specularColor);
program->setUniformValue("material.isTransparent", tmp_transparent);
program->setUniformValue("material.hasSpecularmap", tmp_specular);
program->setUniformValue("material.hasNormalmap", tmp_normalmap);
program->setUniformValue("material.isGlow", tmp_glow);
// Draw cube geometry using indices from VBO 1 // Draw cube geometry using indices from VBO 1
glDrawElements(GL_TRIANGLES, it.size, GL_UNSIGNED_INT, (void*)(it.offset * sizeof(GLuint))); glDrawElements(GL_TRIANGLES, it.size, GL_UNSIGNED_INT, (void*)(it.offset * sizeof(GLuint)));
@@ -141,7 +187,6 @@ void GeometryEngine::drawGeometry(QOpenGLShaderProgram *program)
void GeometryEngine::loadFile(QString filePath) void GeometryEngine::loadFile(QString filePath)
{ {
TIC("Start");
// cleanup old stuff and recreate buffers // cleanup old stuff and recreate buffers
clearData(); clearData();
m_arrayBuf.create(); m_arrayBuf.create();
@@ -216,7 +261,5 @@ void GeometryEngine::loadFile(QString filePath)
clearData(); clearData();
OutputDevice::getInstance()->print(QString(e.what()), 2); OutputDevice::getInstance()->print(QString(e.what()), 2);
} }
TOC("End");
} }

View File

@@ -2,6 +2,7 @@
#include "..\Header\OglViewerWidget.h" #include "..\Header\OglViewerWidget.h"
#include "..\Header\FileInterface.h" #include "..\Header\FileInterface.h"
#include "..\Header\OutputDevice.h" #include "..\Header\OutputDevice.h"
#include "..\Header\SettingsManager.h"
#include <QSurfaceFormat> #include <QSurfaceFormat>
#include <QSignalMapper> #include <QSignalMapper>
#include <QToolButton> #include <QToolButton>
@@ -10,6 +11,9 @@
#include <QMessageBox> #include <QMessageBox>
#include <QPalette> #include <QPalette>
#include <QResizeEvent> #include <QResizeEvent>
#include <QDirIterator>
#include <QFileInfo>
#define WINDOW_NAME "Mesh Viewer" #define WINDOW_NAME "Mesh Viewer"
@@ -41,6 +45,9 @@ MainWindow::MainWindow(QWidget *parent)
// set default text to file info // set default text to file info
m_fileInfo = "Filename: -\nMaterials: -\nVertices: -\nTriangle: -<detail>No file is open"; m_fileInfo = "Filename: -\nMaterials: -\nVertices: -\nTriangle: -<detail>No file is open";
ui->dirDropDownList->addItem("BF1_ModTools", "C:/BF1_ModTools/Assets/Shipped Worlds/");
ui->dirDropDownList->addItem("BF2_ModTools", "C:/BF2_ModTools/assets/Sides/");
// add widgets to the window // add widgets to the window
setupWidgets(); setupWidgets();
@@ -49,6 +56,10 @@ MainWindow::MainWindow(QWidget *parent)
styleSheet.open(QIODevice::ReadOnly); styleSheet.open(QIODevice::ReadOnly);
this->setStyleSheet(styleSheet.readAll()); this->setStyleSheet(styleSheet.readAll());
// setup dropdown
setupAssetLibrary();
connect(SettingsManager::getInstance(), &SettingsManager::dirsChanged, this, &MainWindow::setupAssetLibrary);
printMessage("MeshViewer by Anakin", 0); printMessage("MeshViewer by Anakin", 0);
} }
@@ -59,10 +70,8 @@ MainWindow::~MainWindow()
delete m_infoWindow; delete m_infoWindow;
} }
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// functions // functions
void MainWindow::setupWidgets() void MainWindow::setupWidgets()
{ {
// Ogl Viewer // Ogl Viewer
@@ -71,11 +80,11 @@ void MainWindow::setupWidgets()
connect(this, &MainWindow::loadFile, viewer, &OglViewerWidget::loadFile); connect(this, &MainWindow::loadFile, viewer, &OglViewerWidget::loadFile);
// open file // open file
QToolButton *openFile = new QToolButton(this); QToolButton *openFileDialog = new QToolButton(this);
openFile->setObjectName("openFile"); openFileDialog->setObjectName("openFile");
openFile->setToolTip("open file"); openFileDialog->setToolTip("open file");
connect(openFile, &QToolButton::pressed, this, &MainWindow::openFile); connect(openFileDialog, &QToolButton::pressed, this, &MainWindow::openFileDialog);
ui->mainToolBar->addWidget(openFile); ui->mainToolBar->addWidget(openFileDialog);
// screenshot // screenshot
QToolButton *screenshot = new QToolButton(this); QToolButton *screenshot = new QToolButton(this);
@@ -158,12 +167,31 @@ void MainWindow::setupWidgets()
m_output->setAlignment(Qt::AlignTop); m_output->setAlignment(Qt::AlignTop);
m_output->setText(m_fileInfo.left(m_fileInfo.indexOf("<detail>"))); m_output->setText(m_fileInfo.left(m_fileInfo.indexOf("<detail>")));
m_output->raise(); m_output->raise();
} }
void MainWindow::openFile() void MainWindow::updateAssetTree(QString path)
{
ui->fileTreeWidget->clear();
QDirIterator itterator(path, QStringList() << "*.msh" << "*.MSH" << "*.mesh" << "*.MESH",
QDir::Files, QDirIterator::Subdirectories);
while (itterator.hasNext()) {
QTreeWidgetItem* sub = new QTreeWidgetItem(ui->fileTreeWidget);
sub->setData(0, Qt::DisplayRole, itterator.fileName());
sub->setData(1, Qt::DisplayRole, itterator.fileInfo().absoluteFilePath());
itterator.next();
}
}
void MainWindow::openFileDialog()
{ {
QString fileName = QFileDialog::getOpenFileName(this, "Open File", "", "Mesh (*.msh)"); QString fileName = QFileDialog::getOpenFileName(this, "Open File", "", "Mesh (*.msh)");
openFile(fileName);
}
void MainWindow::openFile(QString fileName)
{
if(!fileName.isEmpty()) if(!fileName.isEmpty())
emit loadFile(fileName); emit loadFile(fileName);
} }
@@ -205,6 +233,35 @@ void MainWindow::resizeEvent(QResizeEvent * e)
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// slots // slots
void MainWindow::setupAssetLibrary()
{
// get all directories and put them in the dropdown.
while (ui->dirDropDownList->count() != 0)
ui->dirDropDownList->removeItem(0);
QStringList tmp_list = SettingsManager::getInstance()->getListOfDirs();
for (QString &it : tmp_list)
ui->dirDropDownList->addItem(it, it);
// choose the current path and display it.
if (ui->dirDropDownList->currentData().isValid())
updateAssetTree(ui->dirDropDownList->currentData().toString());
}
void MainWindow::on_fileTreeWidget_doubleClicked()
{
QString clickedFile = ui->fileTreeWidget->currentItem()->text(1);
openFile(clickedFile);
}
void MainWindow::on_dirDropDownList_currentTextChanged(const QString &arg1)
{
QString selectedDir;
selectedDir = ui->dirDropDownList->itemData(ui->dirDropDownList->currentIndex()).toString();
printMessage(arg1 + " : " + selectedDir, 0);
updateAssetTree(selectedDir);
}
void MainWindow::printMessage(QString message, int severity) void MainWindow::printMessage(QString message, int severity)
{ {
if (!ui->statusBar->currentMessage().isEmpty() && severity < m_curSeverity) if (!ui->statusBar->currentMessage().isEmpty() && severity < m_curSeverity)

View File

@@ -1,6 +1,7 @@
#include "..\Header\MshFile.h" #include "..\Header\MshFile.h"
#include "..\Header\tga.h" #include "..\Header\tga.h"
#include "..\Header\OutputDevice.h" #include "..\Header\OutputDevice.h"
#include <QVector3D>
// helper function to save data from file to any variable type // helper function to save data from file to any variable type
@@ -571,18 +572,106 @@ void MshFile::analyseSegmChunks(Model * dataDestination, QList<ChunkHeader*>& ch
if (tmp_buffer.size() == 5) if (tmp_buffer.size() == 5)
{ {
for (size_t i = 0; i < 3; i++) // calculate poylgon normal, tangent and bitangent
new_segment->indices.push_back(tmp_buffer.takeFirst()); QVector3D vec1, vec2, norm, tan, bi;
QVector2D uv1, uv2;
float f;
vec1 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[1]].position;
vec2 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[2]].position;
uv1 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[1]].texCoord;
uv2 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[2]].texCoord;
f = 1.0f / (uv1.x() * uv2.y() - uv2.x() * uv1.y());
norm = QVector3D::crossProduct(vec1, vec2).normalized();
tan.setX(f * (uv2.y() * vec1.x() - uv1.y() * vec2.x()));
tan.setY(f * (uv2.y() * vec1.y() - uv1.y() * vec2.y()));
tan.setZ(f * (uv2.y() * vec1.z() - uv1.y() * vec2.z()));
tan.normalize();
bi.setX(f * (-uv2.x() * vec1.x() + uv1.x() * vec2.x()));
bi.setY(f * (-uv2.x() * vec1.y() + uv1.x() * vec2.y()));
bi.setZ(f * (-uv2.x() * vec1.z() + uv1.x() * vec2.z()));
bi.normalize();
for (int k = 0; k < 3; k++)
{
// polygon normal wasn't calculated before
if (new_segment->vertices[tmp_buffer[k]].polygonNormal == QVector3D(0, 0, 0))
{
new_segment->vertices[tmp_buffer[k]].polygonNormal = norm;
new_segment->vertices[tmp_buffer[k]].tangent = tan;
new_segment->vertices[tmp_buffer[k]].bitangent = bi;
new_segment->indices.push_back(tmp_buffer[k]);
}
// polygon normal already calculated so duplicate the vertex
else
{
new_segment->vertices.push_back(new_segment->vertices[tmp_buffer[k]]);
new_segment->vertices.back().polygonNormal = norm;
new_segment->vertices.back().tangent = tan;
new_segment->vertices.back().bitangent = bi;
new_segment->indices.push_back(new_segment->vertices.size() - 1);
}
}
tmp_buffer.remove(0, 3);
} }
else if (tmp_buffer.size() > 5) else if (tmp_buffer.size() > 5)
{ {
unsigned int tmp_multiPolySize = tmp_buffer.size() - 2; unsigned int tmp_multiPolySize = tmp_buffer.size() - 2;
// calculate poylgon normal, tangent and bitangent
QVector3D vec1, vec2, norm, tan, bi;
QVector2D uv1, uv2;
float f;
vec1 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[1]].position;
vec2 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[2]].position;
uv1 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[1]].texCoord;
uv2 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[2]].texCoord;
f = 1.0f / (uv1.x() * uv2.y() - uv2.x() * uv1.y());
norm = QVector3D::crossProduct(vec1, vec2).normalized();
tan.setX(f * (uv2.y() * vec1.x() - uv1.y() * vec2.x()));
tan.setY(f * (uv2.y() * vec1.y() - uv1.y() * vec2.y()));
tan.setZ(f * (uv2.y() * vec1.z() - uv1.y() * vec2.z()));
tan.normalize();
bi.setX(f * (-uv2.x() * vec1.x() + uv1.x() * vec2.x()));
bi.setY(f * (-uv2.x() * vec1.y() + uv1.x() * vec2.y()));
bi.setZ(f * (-uv2.x() * vec1.z() + uv1.x() * vec2.z()));
bi.normalize();
// for every triangle of the multi polygon.. // for every triangle of the multi polygon..
for (unsigned int tri = 0; tri < tmp_multiPolySize - 2; tri++) for (unsigned int tri = 0; tri < tmp_multiPolySize - 2; tri++)
{
// ..calculate the edge indices // ..calculate the edge indices
for (int triEdge = 0; triEdge < 3; triEdge++) for (int triEdge = 0; triEdge < 3; triEdge++)
new_segment->indices.push_back(tmp_buffer[(tri + triEdge - ((tri % 2) * (triEdge - 1) * 2))]); {
int curIndi = tmp_buffer[(tri + triEdge - ((tri % 2) * (triEdge - 1) * 2))];
// polygon normal wasn't calculated before
if (new_segment->vertices[curIndi].polygonNormal == QVector3D(0, 0, 0))
{
new_segment->vertices[curIndi].polygonNormal = norm;
new_segment->vertices[curIndi].tangent = tan;
new_segment->vertices[curIndi].bitangent = bi;
new_segment->indices.push_back(curIndi);
}
// polygon normal already calculated so duplicate the vertex
else
{
new_segment->vertices.push_back(new_segment->vertices[curIndi]);
new_segment->vertices.back().polygonNormal = norm;
new_segment->vertices.back().tangent = tan;
new_segment->vertices.back().bitangent = bi;
new_segment->indices.push_back(new_segment->vertices.size() - 1);
}
}
}
tmp_buffer.remove(0, tmp_multiPolySize); tmp_buffer.remove(0, tmp_multiPolySize);
} }
@@ -593,17 +682,106 @@ void MshFile::analyseSegmChunks(Model * dataDestination, QList<ChunkHeader*>& ch
// save the last polygon (no 2 high bit followed) // save the last polygon (no 2 high bit followed)
if (tmp_buffer.size() == 3) if (tmp_buffer.size() == 3)
{ {
for (size_t i = 0; i < 3; i++) // calculate poylgon normal, tangent and bitangent
new_segment->indices.push_back(tmp_buffer.takeFirst()); QVector3D vec1, vec2, norm, tan, bi;
QVector2D uv1, uv2;
float f;
vec1 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[1]].position;
vec2 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[2]].position;
uv1 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[1]].texCoord;
uv2 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[2]].texCoord;
f = 1.0f / (uv1.x() * uv2.y() - uv2.x() * uv1.y());
norm = QVector3D::crossProduct(vec1, vec2).normalized();
tan.setX(f * (uv2.y() * vec1.x() - uv1.y() * vec2.x()));
tan.setY(f * (uv2.y() * vec1.y() - uv1.y() * vec2.y()));
tan.setZ(f * (uv2.y() * vec1.z() - uv1.y() * vec2.z()));
tan.normalize();
bi.setX(f * (-uv2.x() * vec1.x() + uv1.x() * vec2.x()));
bi.setY(f * (-uv2.x() * vec1.y() + uv1.x() * vec2.y()));
bi.setZ(f * (-uv2.x() * vec1.z() + uv1.x() * vec2.z()));
bi.normalize();
for (int k = 0; k < 3; k++)
{
// polygon normal wasn't calculated before
if (new_segment->vertices[tmp_buffer[k]].polygonNormal == QVector3D(0, 0, 0))
{
new_segment->vertices[tmp_buffer[k]].polygonNormal = norm;
new_segment->vertices[tmp_buffer[k]].tangent = tan;
new_segment->vertices[tmp_buffer[k]].bitangent = bi;
new_segment->indices.push_back(tmp_buffer[k]);
}
// polygon normal already calculated so duplicate the vertex
else
{
new_segment->vertices.push_back(new_segment->vertices[tmp_buffer[k]]);
new_segment->vertices.back().polygonNormal = norm;
new_segment->vertices.back().tangent = tan;
new_segment->vertices.back().bitangent = bi;
new_segment->indices.push_back(new_segment->vertices.size() - 1);
}
}
tmp_buffer.remove(0, 3);
} }
else if (tmp_buffer.size() > 3) else if (tmp_buffer.size() > 3)
{ {
unsigned int tmp_multiPolySize = tmp_buffer.size(); unsigned int tmp_multiPolySize = tmp_buffer.size();
// calculate poylgon normal, tangent and bitangent
QVector3D vec1, vec2, norm, tan, bi;
QVector2D uv1, uv2;
float f;
vec1 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[1]].position;
vec2 = new_segment->vertices[tmp_buffer[0]].position - new_segment->vertices[tmp_buffer[2]].position;
uv1 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[1]].texCoord;
uv2 = new_segment->vertices[tmp_buffer[0]].texCoord - new_segment->vertices[tmp_buffer[2]].texCoord;
f = 1.0f / (uv1.x() * uv2.y() - uv2.x() * uv1.y());
norm = QVector3D::crossProduct(vec1, vec2).normalized();
tan.setX(f * (uv2.y() * vec1.x() - uv1.y() * vec2.x()));
tan.setY(f * (uv2.y() * vec1.y() - uv1.y() * vec2.y()));
tan.setZ(f * (uv2.y() * vec1.z() - uv1.y() * vec2.z()));
tan.normalize();
bi.setX(f * (-uv2.x() * vec1.x() + uv1.x() * vec2.x()));
bi.setY(f * (-uv2.x() * vec1.y() + uv1.x() * vec2.y()));
bi.setZ(f * (-uv2.x() * vec1.z() + uv1.x() * vec2.z()));
bi.normalize();
// for every triangle of the multi polygon.. // for every triangle of the multi polygon..
for (unsigned int tri = 0; tri < tmp_multiPolySize - 2; tri++) for (unsigned int tri = 0; tri < tmp_multiPolySize - 2; tri++)
{
// ..calculate the edge indices // ..calculate the edge indices
for (int triEdge = 0; triEdge < 3; triEdge++) for (int triEdge = 0; triEdge < 3; triEdge++)
new_segment->indices.push_back(tmp_buffer[(tri + triEdge - ((tri % 2) * (triEdge - 1) * 2))]); {
int curIndi = tmp_buffer[(tri + triEdge - ((tri % 2) * (triEdge - 1) * 2))];
// polygon normal wasn't calculated before
if (new_segment->vertices[curIndi].polygonNormal == QVector3D(0, 0, 0))
{
new_segment->vertices[curIndi].polygonNormal = norm;
new_segment->vertices[curIndi].tangent = tan;
new_segment->vertices[curIndi].bitangent = bi;
new_segment->indices.push_back(curIndi);
}
// polygon normal already calculated so duplicate the vertex
else
{
new_segment->vertices.push_back(new_segment->vertices[curIndi]);
new_segment->vertices.back().polygonNormal = norm;
new_segment->vertices.back().tangent = tan;
new_segment->vertices.back().bitangent = bi;
new_segment->indices.push_back(new_segment->vertices.size() - 1);
}
}
}
} }
} }
} }
@@ -662,12 +840,26 @@ void MshFile::analyseClthChunks(Model * dataDestination, QList<ChunkHeader*>& ch
m_file.read(F2V(tmp_size), sizeof(tmp_size)); m_file.read(F2V(tmp_size), sizeof(tmp_size));
// for every triangle.. // for every triangle..
for (unsigned int i = 0; i < tmp_size * 3; i++) for (unsigned int i = 0; i < tmp_size; i++)
{ {
quint32 tmp_value; quint32 tmp_value[3];
m_file.read(F2V(tmp_value), sizeof(quint32)); for (unsigned int j = 0; j < 3; j++)
{
m_file.read(F2V(tmp_value[j]), sizeof(quint32));
new_segment->indices.push_back((GLuint)tmp_value[j]);
}
new_segment->indices.push_back((GLuint)tmp_value); QVector3D vec1, vec2, norm;
vec1 = new_segment->vertices[new_segment->indices[i * 3]].position - new_segment->vertices[new_segment->indices[i * 3 + 1]].position;
vec2 = new_segment->vertices[new_segment->indices[i * 3]].position - new_segment->vertices[new_segment->indices[i * 3 + 2]].position;
norm = QVector3D::crossProduct(vec1, vec2);
for (int k = 0; k < 3; k++)
{
new_segment->vertices[new_segment->indices[i * 3 + k]].vertexNormal += norm;
new_segment->vertices[new_segment->indices[i * 3 + k]].vertexNormal.normalize();
}
} }
} }
} }
@@ -728,7 +920,7 @@ void MshFile::loadTexture(QOpenGLTexture *& destination, QString filepath, QStri
if (!loadSuccess) if (!loadSuccess)
{ {
OutputDevice::getInstance()->print("WARNING: texture not found or corrupted: " + filename, 1); OutputDevice::getInstance()->print("WARNING: texture not found or corrupted: " + filename, 1);
//TODO: cloth use the wrong diffuse color. should be null
img = QImage(1, 1, QImage::Format_RGB32); img = QImage(1, 1, QImage::Format_RGB32);
img.fill(QColor(m_materials->back().diffuseColor[0] * 255, m_materials->back().diffuseColor[1] * 255, m_materials->back().diffuseColor[2] * 255)); img.fill(QColor(m_materials->back().diffuseColor[0] * 255, m_materials->back().diffuseColor[1] * 255, m_materials->back().diffuseColor[2] * 255));
filename += " *"; filename += " *";

View File

@@ -3,6 +3,7 @@
#include "..\Header\FreeCamera.h" #include "..\Header\FreeCamera.h"
#include "..\Header\OrbitCamera.h" #include "..\Header\OrbitCamera.h"
#include "..\Header\MoveCamera.h" #include "..\Header\MoveCamera.h"
#include "..\Header\SettingsManager.h"
#include <QMouseEvent> #include <QMouseEvent>
#include <QDropEvent> #include <QDropEvent>
#include <QMimeData> #include <QMimeData>
@@ -24,7 +25,8 @@ OglViewerWidget::OglViewerWidget(QWidget *parent)
setAcceptDrops(true); setAcceptDrops(true);
// settings window // settings window
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); setDefaultValues();
m_settings = new SettingsWindow(this);
connect(m_settings, &SettingsWindow::updateBGColorOff, this, &OglViewerWidget::setBGColorOff); connect(m_settings, &SettingsWindow::updateBGColorOff, this, &OglViewerWidget::setBGColorOff);
connect(m_settings, &SettingsWindow::updateBGColorOn, this, &OglViewerWidget::setBGColorOn); connect(m_settings, &SettingsWindow::updateBGColorOn, this, &OglViewerWidget::setBGColorOn);
@@ -52,6 +54,30 @@ OglViewerWidget::~OglViewerWidget()
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// functions // functions
void OglViewerWidget::setDefaultValues()
{
SettingsManager* sm = SettingsManager::getInstance(this);
m_backgroundColorOn = QVector4D(sm->getBgColorOn() / 255, 1.0f);
m_backgroundColorOff = QVector4D(sm->getBgColorOff() / 255, 1.0f);
m_wireframe = false;
m_lightOn = sm->isLight();
m_backfaceCulling = sm->isBfCulling();
if (sm->getLightType() == 1) // directional
m_light.position = { 0.0,0.0,0.0,0.0 };
else // point
m_light.position = { 0.0,0.0,0.0,1.0 };
m_light.intensities = sm->getLightColor() / 255;
m_light.attenuationFactor = sm->getAttenuation();
m_light.ambientCoefficient = sm->getAmbient();
m_light.headlight = sm->isHeadlight();
connect(this, &OglViewerWidget::lightChanged, sm, &SettingsManager::setLight);
}
void OglViewerWidget::initShaders() void OglViewerWidget::initShaders()
{ {
// Compile vertex shader // Compile vertex shader
@@ -143,10 +169,10 @@ void OglViewerWidget::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set view-projection matrix // Set view-projection matrix
m_program.setUniformValue("vp_matrix", m_projection * m_camera->getMatrix()); m_program.setUniformValue("viewProjection", m_projection * m_camera->getMatrix());
// Set Light values // Set Light values
m_program.setUniformValue("b_light", m_lightOn); m_program.setUniformValue("useLight", m_lightOn);
m_program.setUniformValue("light.position", m_light.position); m_program.setUniformValue("light.position", m_light.position);
m_program.setUniformValue("light.intensities", m_light.intensities); m_program.setUniformValue("light.intensities", m_light.intensities);
m_program.setUniformValue("light.attenuationFactor", m_light.attenuationFactor); m_program.setUniformValue("light.attenuationFactor", m_light.attenuationFactor);
@@ -371,6 +397,8 @@ void OglViewerWidget::toggleLight()
m_backgroundColorOff[3] = 1.0; m_backgroundColorOff[3] = 1.0;
} }
emit lightChanged(m_lightOn);
update(); update();
} }

View File

@@ -0,0 +1,243 @@
#include "..\Header\SettingsManager.h"
#include "qdebug.h"
/////////////////////////////////////////////////////////////////////////
// constructor/destructor
SettingsManager::SettingsManager(QObject *parent)
: QObject(parent)
{
m_file.setFileName("meshviewer.config");
readFromFile();
}
SettingsManager::~SettingsManager()
{
writeToFile();
}
SettingsManager* SettingsManager::getInstance(QObject *parent)
{
static SettingsManager* instance = new SettingsManager(parent);
return instance;
}
/////////////////////////////////////////////////////////////////////////
// functions
void SettingsManager::readFromFile()
{
if (m_file.open(QIODevice::ReadOnly))
{
QByteArray stream = m_file.readAll();
QList<QByteArray> lines = stream.split('\n');
for (auto& it : lines)
{
if (it.startsWith("<bgOn>"))
{
QList<QByteArray> values = it.right(it.size() - it.indexOf('>') - 1).split(';');
for (int i = 0; i < 3; i++)
m_bgColorOn[i] = values[i].toFloat();
}
else if (it.startsWith("<bgOff>"))
{
QList<QByteArray> values = it.right(it.size() - it.indexOf('>') - 1).split(';');
for (int i = 0; i < 3; i++)
m_bgColorOff[i] = values[i].toFloat();
}
else if (it.startsWith("<liCo>"))
{
QList<QByteArray> values = it.right(it.size() - it.indexOf('>') - 1).split(';');
for (int i = 0; i < 3; i++)
m_lightColor[i] = values[i].toFloat();
}
else if (it.startsWith("<bfCul>"))
{
m_bfCulling = it.right(it.size() - it.indexOf('>') - 1).toInt();
}
else if (it.startsWith("<liOn>"))
{
m_light = it.right(it.size() - it.indexOf('>') - 1).toInt();
}
else if (it.startsWith("<heLi>"))
{
m_headlight = it.right(it.size() - it.indexOf('>') - 1).toInt();
}
else if (it.startsWith("<auCo>"))
{
m_autoColor = it.right(it.size() - it.indexOf('>') - 1).toInt();
}
else if (it.startsWith("<liTy>"))
{
m_lightType = it.right(it.size() - it.indexOf('>') - 1).toInt();
}
else if (it.startsWith("<atFa>"))
{
m_attenuation = it.right(it.size() - it.indexOf('>') - 1).toFloat();
}
else if (it.startsWith("<amCo>"))
{
m_ambient = it.right(it.size() - it.indexOf('>') - 1).toFloat();
}
else if (it.startsWith("<qkList>"))
{
m_listOfDirs = QString(it.right(it.size() - it.indexOf('>') - 1)).split(";");
}
}
m_file.close();
}
}
void SettingsManager::writeToFile()
{
m_file.open(QIODevice::WriteOnly);
m_file.write(QString("<bgOn>%1;%2;%3\n").arg(m_bgColorOn.x()).arg(m_bgColorOn.y()).arg(m_bgColorOn.z()).toUtf8());
m_file.write(QString("<bgOff>%1;%2;%3\n").arg(m_bgColorOff.x()).arg(m_bgColorOff.y()).arg(m_bgColorOff.z()).toUtf8());
m_file.write(QString("<liCo>%1;%2;%3\n").arg(m_lightColor.x()).arg(m_lightColor.y()).arg(m_lightColor.z()).toUtf8());
m_file.write(QString("<bfCul>%1\n").arg(m_bfCulling).toUtf8());
m_file.write(QString("<liOn>%1\n").arg(m_light).toUtf8());
m_file.write(QString("<heLi>%1\n").arg(m_headlight).toUtf8());
m_file.write(QString("<auCo>%1\n").arg(m_autoColor).toUtf8());
m_file.write(QString("<liTy>%1\n").arg(m_lightType).toUtf8());
m_file.write(QString("<atFa>%1\n").arg(m_attenuation).toUtf8());
m_file.write(QString("<amCo>%1\n").arg(m_ambient).toUtf8());
if(!m_listOfDirs.isEmpty())
m_file.write(QString("<qkList>%1\n").arg(m_listOfDirs.join(";")).toUtf8());
m_file.close();
}
// getter ///////////////////////////////////////////////////////////////
QStringList SettingsManager::getListOfDirs()
{
return m_listOfDirs;
}
QVector3D SettingsManager::getBgColorOn() const
{
return m_bgColorOn;
}
QVector3D SettingsManager::getBgColorOff() const
{
return m_bgColorOff;
}
bool SettingsManager::isBfCulling() const
{
return m_bfCulling;
}
bool SettingsManager::isLight() const
{
return m_light;
}
int SettingsManager::getLightType() const
{
return m_lightType;
}
QVector3D SettingsManager::getLightColor() const
{
return m_lightColor;
}
float SettingsManager::getAttenuation() const
{
return m_attenuation;
}
float SettingsManager::getAmbient() const
{
return m_ambient;
}
bool SettingsManager::isHeadlight() const
{
return m_headlight;
}
bool SettingsManager::isAutoColor() const
{
return m_autoColor;
}
/////////////////////////////////////////////////////////////////////////
// slots
void SettingsManager::setBgColorOn(QVector3D value)
{
m_bgColorOn = value;
}
void SettingsManager::setBgColorOff(QVector3D value)
{
m_bgColorOff = value;
}
void SettingsManager::setBfCulling(bool value)
{
m_bfCulling = value;
}
void SettingsManager::setLight(bool value)
{
m_light = value;
}
void SettingsManager::setLightType(int value)
{
m_lightType = value;
}
void SettingsManager::setLightColor(QVector3D value)
{
m_lightColor = value;
}
void SettingsManager::setAttenuation(double value)
{
m_attenuation = value;
}
void SettingsManager::setAmbient(double value)
{
m_ambient = value;
}
void SettingsManager::setHeadlight(bool value)
{
m_headlight = value;
}
void SettingsManager::setAutoColor(int value)
{
if (value == 0)
m_autoColor = false;
else
m_autoColor = true;
}
void SettingsManager::updateDirectories(QString path)
{
if (m_listOfDirs.contains(path))
m_listOfDirs.removeAll(path);
else
m_listOfDirs.append(path);
emit dirsChanged();
}

View File

@@ -1,10 +1,12 @@
#include "..\Header\SettingsWindow.h" #include "..\Header\SettingsWindow.h"
#include "..\Header\SettingsManager.h"
#include <QFileDialog>
#include <QListWidgetItem>
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// constructor/destructor // constructor/destructor
SettingsWindow::SettingsWindow(QVector3D bgOffColor, QVector3D bgOnColor, QVector3D lightColor, bool autoColor, double ambCoef, double attFac, int lightType, QWidget * parent) SettingsWindow::SettingsWindow(QWidget * parent)
: QWidget(parent) : QWidget(parent)
, ui(new Ui::SettingsWindow) , ui(new Ui::SettingsWindow)
{ {
@@ -15,25 +17,47 @@ SettingsWindow::SettingsWindow(QVector3D bgOffColor, QVector3D bgOnColor, QVecto
setupConnections(); setupConnections();
// set default values // set default values
ui->lightOff_R_SB->setValue((int)bgOffColor[0]); SettingsManager* sm = SettingsManager::getInstance(this);
ui->lightOff_G_SB->setValue((int)bgOffColor[1]);
ui->lightOff_B_SB->setValue((int)bgOffColor[2]);
ui->lightOn_R_SB->setValue((int)bgOnColor[0]); // set dirList for passing to Main and then fill settings manager dir list window
ui->lightOn_G_SB->setValue((int)bgOnColor[1]); QStringList tmp_directories = sm->getListOfDirs();
ui->lightOn_B_SB->setValue((int)bgOnColor[2]); for (auto &it : tmp_directories)
ui->dirListWidget->insertItem(0, it);
ui->light_R_SB->setValue((int)lightColor[0]); ui->lightOff_R_SB->setValue((int)(sm->getBgColorOff()[0]));
ui->light_G_SB->setValue((int)lightColor[1]); ui->lightOff_G_SB->setValue((int)(sm->getBgColorOff()[1]));
ui->light_B_SB->setValue((int)lightColor[2]); ui->lightOff_B_SB->setValue((int)(sm->getBgColorOff()[2]));
ui->ambCoef->setValue(ambCoef); ui->lightOn_R_SB->setValue((int)(sm->getBgColorOn()[0]));
ui->attFac->setValue(attFac); ui->lightOn_G_SB->setValue((int)(sm->getBgColorOn()[1]));
ui->lightOn_B_SB->setValue((int)(sm->getBgColorOn()[2]));
ui->checkAutoColor->setChecked(autoColor); ui->light_R_SB->setValue((int)(sm->getLightColor()[0]));
if (lightType == 1) ui->light_G_SB->setValue((int)(sm->getLightColor()[1]));
ui->light_B_SB->setValue((int)(sm->getLightColor()[2]));
ui->ambCoef->setValue(sm->getAmbient());
ui->attFac->setValue(sm->getAttenuation());
ui->checkBackfaceCulling->setChecked(sm->isBfCulling());
ui->checkAutoColor->setChecked(sm->isAutoColor());
ui->checkHeadlight->setChecked(sm->isHeadlight());
if (sm->getLightType() == 1)
ui->radioDirectLight->setChecked(true); ui->radioDirectLight->setChecked(true);
else
ui->radioPointLight->setChecked(true);
connect(this, &SettingsWindow::updateBGColorOff, sm, &SettingsManager::setBgColorOff);
connect(this, &SettingsWindow::updateBGColorOn, sm, &SettingsManager::setBgColorOn);
connect(this, &SettingsWindow::updateLightColor, sm, &SettingsManager::setLightColor);
connect(this, &SettingsWindow::updateAttFac, sm, &SettingsManager::setAttenuation);
connect(this, &SettingsWindow::updateAmbCoef, sm, &SettingsManager::setAmbient);
connect(this, &SettingsWindow::sendHeadlight, sm, &SettingsManager::setHeadlight);
connect(this, &SettingsWindow::sendBackfaceCulling, sm, &SettingsManager::setBfCulling);
connect(ui->checkAutoColor, &QCheckBox::stateChanged, sm, &SettingsManager::setAutoColor);
connect(this, &SettingsWindow::changeLightType, sm, &SettingsManager::setLightType);
connect(this, &SettingsWindow::pathChanged, sm, &SettingsManager::updateDirectories);
} }
SettingsWindow::~SettingsWindow() SettingsWindow::~SettingsWindow()
@@ -133,10 +157,12 @@ void SettingsWindow::radioToggled()
{ {
ui->attFac->setValue(0.0); ui->attFac->setValue(0.0);
ui->attFac->setEnabled(false); ui->attFac->setEnabled(false);
emit changeLightType(1);
} }
else else
{ {
ui->attFac->setEnabled(true); ui->attFac->setEnabled(true);
emit changeLightType(2);
} }
} }
@@ -161,3 +187,22 @@ void SettingsWindow::lightColorChanged()
ui->lightOn_B_S->setValue((int)(ui->light_B_S->value() / 50)); ui->lightOn_B_S->setValue((int)(ui->light_B_S->value() / 50));
} }
} }
void SettingsWindow::on_addItem_clicked()
{
QString dirName = QFileDialog::getExistingDirectory(this, tr("Open Directory"), "/home",
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
if (!SettingsManager::getInstance()->getListOfDirs().contains(dirName))
{
ui->dirListWidget->insertItem(0, dirName);
emit pathChanged(dirName);
}
}
void SettingsWindow::on_removeItem_clicked()
{
QListWidgetItem* tmp = ui->dirListWidget->takeItem(ui->dirListWidget->currentRow());
emit pathChanged(tmp->text());
delete tmp;
}

View File

@@ -12,10 +12,4 @@ So far it is just me. If you wanna help me, let me know :D
Feel free to use my code the way you like. But remember i used some public libraries. Make sure you read their Feel free to use my code the way you like. But remember i used some public libraries. Make sure you read their
licence, too. licence, too.
### To Do
- normal map,
- list all msh in a directory
- glow/emissive
- optional display bones, shadow, collision
- change pose
- animation

Binary file not shown.

BIN
preview.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB