aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/accelerate/myqtconcurrent.cpp29
-rw-r--r--src/illuminate/shadow.cpp4
-rw-r--r--src/main.cpp172
-rw-r--r--src/mainwindow.cpp147
-rw-r--r--src/mainwindow.h41
-rw-r--r--src/raytracer/raytracer.cpp62
-rw-r--r--src/raytracer/raytracer.h26
-rw-r--r--src/settings.cpp3
-rw-r--r--src/settings.h16
-rw-r--r--src/utils/aspectratiowidget/aspectratiowidget.hpp66
-rw-r--r--src/utils/sceneparser.cpp2
11 files changed, 470 insertions, 98 deletions
diff --git a/src/accelerate/myqtconcurrent.cpp b/src/accelerate/myqtconcurrent.cpp
index 1dff0e0..aeb160b 100644
--- a/src/accelerate/myqtconcurrent.cpp
+++ b/src/accelerate/myqtconcurrent.cpp
@@ -1,13 +1,13 @@
#include <QList>
#include <QtConcurrent>
-#include "raytracer/raytracer.h"
+#include "../raytracer/raytracer.h"
struct pixelRoutineArgs {
glm::vec4 pCamera;
glm::vec4 dCamera;
const RayTraceScene &scene;
- RayTracer rt;
+ RayTracer *rt;
};
static RGBA pixelRoutine(pixelRoutineArgs args);
@@ -28,12 +28,13 @@ void RayTracer::renderParallel(RGBA *imageData, const RayTraceScene &scene)
glm::vec4 pixelDirCamera{xCameraSpace, -yCameraSpace, -cameraDepth, 0.f}; //w=0 for dir
glm::vec4 eyeCamera{0.f, 0.f, 0.f, 1.f}; // w=1.f for point
- l.append({
- eyeCamera, // eye
- pixelDirCamera, // direction
- scene,
- *this
- });
+ pixelRoutineArgs args{
+ eyeCamera,
+ pixelDirCamera,
+ scene,
+ this
+ };
+ l.append(args);
}
}
@@ -44,7 +45,7 @@ void RayTracer::renderParallel(RGBA *imageData, const RayTraceScene &scene)
imageData[index++] = p;
}
- if (m_config.enableAntiAliasing)
+ if (m_enableAntiAliasing)
{
filterBlur(imageData, scene.width(), scene.height());
}
@@ -63,18 +64,18 @@ RGBA pixelRoutine(pixelRoutineArgs args)
glm::vec4 pWorld = inv * eyeCamera;
glm::vec4 dWorld = glm::normalize(inv * pixelDirCamera);
- if (rt.m_config.enableDepthOfField)
+ if (rt->m_enableDepthOfField)
{
// if we're doing depth of field, we need to shoot multiple rays, see camera.cpp
- return RayTracer::toRGBA(rt.secondaryRays(pWorld, dWorld, scene));
+ return RayTracer::toRGBA(rt->secondaryRays(pWorld, dWorld, scene));
}
- if (rt.m_config.enableSuperSample)
+ if (rt->m_enableSuperSample)
{
// if we're doing super sampling, we need to shoot multiple rays, see raytracer.cpp
- return rt.superSample(eyeCamera, pixelDirCamera, scene);
+ return rt->superSample(eyeCamera, pixelDirCamera, scene);
}
// shoot ray!
- RGBA pixel = RayTracer::toRGBA(rt.getPixelFromRay(pWorld, dWorld, scene, 0));
+ RGBA pixel = RayTracer::toRGBA(rt->getPixelFromRay(pWorld, dWorld, scene, 0));
return pixel;
}
diff --git a/src/illuminate/shadow.cpp b/src/illuminate/shadow.cpp
index 99e2b29..efb52a7 100644
--- a/src/illuminate/shadow.cpp
+++ b/src/illuminate/shadow.cpp
@@ -11,7 +11,7 @@ bool RayTracer::isShadowed(
directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
// acceleration causes "bad jaggies" so we disable it for now
- if (m_config.enableAcceleration)
+ if (m_enableAcceleration)
{
RenderShapeData shapeData;
auto pBias = intersectionWorld + .001f * directionFromIntersectionToLight;
@@ -55,4 +55,4 @@ bool RayTracer::isShadowed(
}
return false;
-} \ No newline at end of file
+}
diff --git a/src/main.cpp b/src/main.cpp
index 8cb00b8..29828d8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2,85 +2,111 @@
#include <QCommandLineParser>
#include <QImage>
#include <QtCore>
+#include <QApplication>
+#include <QScreen>
+#include <iostream>
+#include <QSettings>
+#include <QSurfaceFormat>
#include <iostream>
#include "utils/sceneparser.h"
#include "raytracer/raytracer.h"
#include "raytracer/raytracescene.h"
+#include "mainwindow.h"
+
int main(int argc, char *argv[])
{
- QCoreApplication a(argc, argv);
-
- QCommandLineParser parser;
- parser.addHelpOption();
- parser.addPositionalArgument("config", "Path of the config file.");
- parser.process(a);
-
- auto positionalArgs = parser.positionalArguments();
- if (positionalArgs.size() != 1) {
- std::cerr << "Not enough arguments. Please provide a path to a config file (.ini) as a command-line argument." << std::endl;
- a.exit(1);
- return 1;
- }
-
- QSettings settings( positionalArgs[0], QSettings::IniFormat );
- QString iScenePath = settings.value("IO/scene").toString();
- QString oImagePath = settings.value("IO/output").toString();
-
- RenderData metaData;
- bool success = SceneParser::parse(iScenePath.toStdString(), metaData);
-
- if (!success) {
- std::cerr << "Error loading scene: \"" << iScenePath.toStdString() << "\"" << std::endl;
- a.exit(1);
- return 1;
- }
-
- // Raytracing-relevant code starts here
-
- int width = settings.value("Canvas/width").toInt();
- int height = settings.value("Canvas/height").toInt();
-
- // Extracting data pointer from Qt's image API
- QImage image = QImage(width, height, QImage::Format_RGBX8888);
- image.fill(Qt::black);
- RGBA *data = reinterpret_cast<RGBA *>(image.bits());
-
- // Setting up the raytracer
- Config rtConfig{};
- rtConfig.enableShadow = settings.value("Feature/shadows").toBool();
- rtConfig.enableReflection = settings.value("Feature/reflect").toBool();
- rtConfig.enableRefraction = settings.value("Feature/refract").toBool();
- rtConfig.enableTextureMap = settings.value("Feature/texture").toBool();
- rtConfig.enableTextureFilter = settings.value("Feature/texture-filter").toBool();
- rtConfig.enableParallelism = settings.value("Feature/parallel").toBool();
- rtConfig.enableSuperSample = settings.value("Feature/super-sample").toBool();
- rtConfig.enableAntiAliasing = settings.value("Feature/post-process").toBool();
- rtConfig.enableAcceleration = settings.value("Feature/acceleration").toBool();
- rtConfig.enableDepthOfField = settings.value("Feature/depthoffield").toBool();
- rtConfig.maxRecursiveDepth = settings.value("Settings/maximum-recursive-depth").toInt();
- rtConfig.onlyRenderNormals = settings.value("Settings/only-render-normals").toBool();
-
- RayTracer raytracer{ rtConfig };
-
- RayTraceScene rtScene{ width, height, metaData };
-
- // Note that we're passing `data` as a pointer (to its first element)
- // Recall from Lab 1 that you can access its elements like this: `data[i]`
- raytracer.render(data, rtScene);
-
- // Saving the image
- success = image.save(oImagePath);
- if (!success) {
- success = image.save(oImagePath, "PNG");
- }
- if (success) {
- std::cout << "Saved rendered image to \"" << oImagePath.toStdString() << "\"" << std::endl;
- } else {
- std::cerr << "Error: failed to save image to \"" << oImagePath.toStdString() << "\"" << std::endl;
- }
-
- a.exit();
- return 0;
+ // QCoreApplication a(argc, argv);
+
+ // QCommandLineParser parser;
+ // parser.addHelpOption();
+ // parser.addPositionalArgument("config", "Path of the config file.");
+ // parser.process(a);
+
+ // auto positionalArgs = parser.positionalArguments();
+ // if (positionalArgs.size() != 1) {
+ // std::cerr << "Not enough arguments. Please provide a path to a config file (.ini) as a command-line argument." << std::endl;
+ // a.exit(1);
+ // return 1;
+ // }
+
+ // QSettings settings( positionalArgs[0], QSettings::IniFormat );
+ // QString iScenePath = settings.value("IO/scene").toString();
+ // QString oImagePath = settings.value("IO/output").toString();
+
+ // RenderData metaData;
+ // bool success = SceneParser::parse(iScenePath.toStdString(), metaData);
+
+ // if (!success) {
+ // std::cerr << "Error loading scene: \"" << iScenePath.toStdString() << "\"" << std::endl;
+ // a.exit(1);
+ // return 1;
+ // }
+
+ // // Raytracing-relevant code starts here
+
+ // int width = settings.value("Canvas/width").toInt();
+ // int height = settings.value("Canvas/height").toInt();
+
+ // // Extracting data pointer from Qt's image API
+ // QImage image = QImage(width, height, QImage::Format_RGBX8888);
+ // image.fill(Qt::black);
+ // RGBA *data = reinterpret_cast<RGBA *>(image.bits());
+
+ // // Setting up the raytracer
+ // Config rtConfig{};
+ // rtConfig.enableShadow = settings.value("Feature/shadows").toBool();
+ // rtConfig.enableReflection = settings.value("Feature/reflect").toBool();
+ // rtConfig.enableRefraction = settings.value("Feature/refract").toBool();
+ // rtConfig.enableTextureMap = settings.value("Feature/texture").toBool();
+ // rtConfig.enableTextureFilter = settings.value("Feature/texture-filter").toBool();
+ // rtConfig.enableParallelism = settings.value("Feature/parallel").toBool();
+ // rtConfig.enableSuperSample = settings.value("Feature/super-sample").toBool();
+ // rtConfig.enableAntiAliasing = settings.value("Feature/post-process").toBool();
+ // rtConfig.enableAcceleration = settings.value("Feature/acceleration").toBool();
+ // rtConfig.enableDepthOfField = settings.value("Feature/depthoffield").toBool();
+ // rtConfig.maxRecursiveDepth = settings.value("Settings/maximum-recursive-depth").toInt();
+ // rtConfig.onlyRenderNormals = settings.value("Settings/only-render-normals").toBool();
+
+ // RayTracer raytracer{ rtConfig };
+
+ // RayTraceScene rtScene{ width, height, metaData };
+
+ // // Note that we're passing `data` as a pointer (to its first element)
+ // // Recall from Lab 1 that you can access its elements like this: `data[i]`
+ // raytracer.render(data, rtScene);
+
+ // // Saving the image
+ // success = image.save(oImagePath);
+ // if (!success) {
+ // success = image.save(oImagePath, "PNG");
+ // }
+ // if (success) {
+ // std::cout << "Saved rendered image to \"" << oImagePath.toStdString() << "\"" << std::endl;
+ // } else {
+ // std::cerr << "Error: failed to save image to \"" << oImagePath.toStdString() << "\"" << std::endl;
+ // }
+
+ // a.exit();
+ // return 0;
+
+ QApplication a(argc, argv);
+
+ QCoreApplication::setApplicationName("The All Americans 4D Raytracer");
+ QCoreApplication::setOrganizationName("CS 1230/2230");
+ // QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+
+ QSurfaceFormat fmt;
+ fmt.setVersion(4, 1);
+ fmt.setProfile(QSurfaceFormat::CoreProfile);
+ QSurfaceFormat::setDefaultFormat(fmt);
+
+ MainWindow w;
+ w.initialize();
+ w.resize(800, 600);
+ w.show();
+ int return_val = a.exec();
+ w.finish();
+ return return_val;
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
new file mode 100644
index 0000000..e4c9675
--- /dev/null
+++ b/src/mainwindow.cpp
@@ -0,0 +1,147 @@
+#include "mainwindow.h"
+#include "settings.h"
+
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QFileDialog>
+#include <QSettings>
+#include <QLabel>
+#include <QGroupBox>
+#include <iostream>
+
+void MainWindow::initialize() {
+ // create RayTracer
+ rayTracer = new RayTracer(this);
+ imageLabel = new QLabel(this);
+ // aspectRatioWidget = new AspectRatioWidget(this);
+ // aspectRatioWidget->setAspectWidget(imageLabel, 3.f/4.f);
+ QHBoxLayout *hLayout = new QHBoxLayout; // horizontal alignment
+ QVBoxLayout *vLayout = new QVBoxLayout(); // vertical alignment
+ vLayout->setAlignment(Qt::AlignTop);
+ hLayout->addLayout(vLayout);
+ hLayout->addWidget(imageLabel, 1);
+ this->setLayout(hLayout);
+
+ QFont font;
+ font.setPointSize(12);
+ font.setBold(true);
+ QLabel *w_label = new QLabel(); // Width label
+ w_label->setText("W value:");
+
+ // Create file uploader for scene file
+ uploadFile = new QPushButton();
+ uploadFile->setText(QStringLiteral("Upload Scene File"));
+
+ saveImage = new QPushButton();
+ saveImage->setText(QStringLiteral("Save image"));
+
+ QGroupBox *wLayout = new QGroupBox(); // horizonal w slider alignment
+ QHBoxLayout *lw = new QHBoxLayout();
+
+ wSlider = new QSlider(Qt::Orientation::Horizontal); // W value slider
+ wSlider->setTickInterval(1);
+ wSlider->setMinimum(1);
+ wSlider->setMaximum(100);
+ wSlider->setValue(1);
+
+ wBox = new QDoubleSpinBox();
+ wBox->setMinimum(0.01f);
+ wBox->setMaximum(1.f);
+ wBox->setSingleStep(0.01f);
+ wBox->setValue(0.01f);
+
+ lw->addWidget(wSlider);
+ lw->addWidget(wBox);
+ wLayout->setLayout(lw);
+
+ vLayout->addWidget(uploadFile);
+ vLayout->addWidget(saveImage);
+ vLayout->addWidget(w_label);
+ vLayout->addWidget(wLayout);
+
+ connectUIElements();
+
+ onValChangeWBox(0.01f);
+}
+
+void MainWindow::finish() {
+// realtime->finish();
+// delete(realtime);
+}
+
+void MainWindow::connectUIElements() {
+ connectUploadFile();
+ connectSaveImage();
+ connectW();
+}
+
+void MainWindow::connectUploadFile() {
+ connect(uploadFile, &QPushButton::clicked, this, &MainWindow::onUploadFile);
+}
+
+void MainWindow::connectSaveImage() {
+ connect(saveImage, &QPushButton::clicked, this, &MainWindow::onSaveImage);
+}
+
+void MainWindow::connectW() {
+ connect(wSlider, &QSlider::valueChanged, this, &MainWindow::onValChangeWSlider);
+ connect(wBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ this, &MainWindow::onValChangeWBox);
+}
+
+void MainWindow::onUploadFile() {
+ // Get abs path of scene file
+ QString configFilePath = QFileDialog::getOpenFileName(this, tr("Upload File"),
+ QDir::currentPath()
+ .append(QDir::separator())
+ .append("scenefiles")
+ .append(QDir::separator())
+ .append("lights-camera")
+ .append(QDir::separator())
+ .append("required"), tr("Scene Files (*.json)"));
+ if (configFilePath.isNull()) {
+ std::cout << "Failed to load null scenefile." << std::endl;
+ return;
+ }
+
+ settings.sceneFilePath = configFilePath.toStdString();
+
+ std::cout << "Loaded scenefile: \"" << configFilePath.toStdString() << "\"." << std::endl;
+
+ rayTracer->sceneChanged(imageLabel);
+}
+
+void MainWindow::onSaveImage() {
+ if (settings.sceneFilePath.empty()) {
+ std::cout << "No scene file loaded." << std::endl;
+ return;
+ }
+ std::string sceneName = settings.sceneFilePath.substr(0, settings.sceneFilePath.find_last_of("."));
+ sceneName = sceneName.substr(sceneName.find_last_of("/")+1);
+ QString filePath = QFileDialog::getSaveFileName(this, tr("Save Image"),
+ QDir::currentPath()
+ .append(QDir::separator())
+ .append("student_outputs")
+ .append(QDir::separator())
+ .append("lights-camera")
+ .append(QDir::separator())
+ .append("required")
+ .append(QDir::separator())
+ .append(sceneName), tr("Image Files (*.png)"));
+ std::cout << "Saving image to: \"" << filePath.toStdString() << "\"." << std::endl;
+// realtime->saveViewportImage(filePath.toStdString());
+}
+
+void MainWindow::onValChangeWSlider(int newValue) {
+ //wSlider->setValue(newValue);
+ wBox->setValue(newValue/100.f);
+ settings.w = wBox->value();
+ rayTracer->settingsChanged(imageLabel);
+}
+
+void MainWindow::onValChangeWBox(double newValue) {
+ wSlider->setValue(int(newValue*100.f));
+ //wBox->setValue(newValue);
+ settings.w = wBox->value();
+ rayTracer->settingsChanged(imageLabel);
+}
diff --git a/src/mainwindow.h b/src/mainwindow.h
new file mode 100644
index 0000000..9cd5d1a
--- /dev/null
+++ b/src/mainwindow.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <QMainWindow>
+#include <QCheckBox>
+#include <QSlider>
+#include <QSpinBox>
+#include <QDoubleSpinBox>
+#include <QPushButton>
+#include <QLabel>
+// #include "realtime.h"
+#include "raytracer/raytracer.h"
+#include "utils/aspectratiowidget/aspectratiowidget.hpp"
+
+class MainWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ void initialize();
+ void finish();
+ QLabel *imageLabel;
+
+private:
+ void connectUIElements();
+ void connectUploadFile();
+ void connectSaveImage();
+ void connectW();
+
+ RayTracer *rayTracer;
+ AspectRatioWidget *aspectRatioWidget;
+ QPushButton *uploadFile;
+ QPushButton *saveImage;
+ QSlider *wSlider;
+ QDoubleSpinBox *wBox;
+
+private slots:
+ void onUploadFile();
+ void onSaveImage();
+ void onValChangeWSlider(int newValue);
+ void onValChangeWBox(double newValue);
+};
diff --git a/src/raytracer/raytracer.cpp b/src/raytracer/raytracer.cpp
index c3466cf..93f5225 100644
--- a/src/raytracer/raytracer.cpp
+++ b/src/raytracer/raytracer.cpp
@@ -3,16 +3,19 @@
#include <iostream>
#include "raytracer.h"
#include "raytracescene.h"
+#include "settings.h"
+#include "mainwindow.h"
//struct Ray {
// glm::vec3 p;
// glm::vec3 d;
//};
-RayTracer::RayTracer(const Config &config) : m_config(config) {}
+// RayTracer::RayTracer(const Config &config) : m_config(config) {}
+RayTracer::RayTracer(QWidget *parent) : QWidget(parent) {}
void RayTracer::render(RGBA *imageData, const RayTraceScene &scene) {
- if(m_config.enableParallelism)
+ if(m_enableParallelism)
{
renderParallel(imageData, scene);
return;
@@ -53,7 +56,7 @@ glm::vec4 RayTracer::getPixelFromRay(
const RayTraceScene &scene,
int depth)
{
- if (depth > m_config.maxRecursiveDepth)
+ if (depth > m_maxRecursiveDepth)
{
return glm::vec4(0.f);
}
@@ -63,7 +66,7 @@ glm::vec4 RayTracer::getPixelFromRay(
glm::vec4 closestIntersectionWorld;
RenderShapeData intersectedShape;
- if (m_config.enableAcceleration)
+ if (m_enableAcceleration)
{
float tWorld = traverseBVH(pWorld, dWorld, intersectedShape, scene.m_bvh);
if (tWorld == FINF)
@@ -147,4 +150,53 @@ glm::vec4 RayTracer::secondaryRays(glm::vec4 pWorld, glm::vec4 dWorld, RayTraceS
}
return illumination / (float) TIMES;
-} \ No newline at end of file
+}
+
+void RayTracer::sceneChanged(QLabel* imageLabel) {
+ // RenderData metaData;
+
+ bool success = SceneParser::parse(settings.sceneFilePath, m_metaData);
+
+ if (!success) {
+ std::cerr << "Error loading scene: \"" << settings.sceneFilePath << "\"" << std::endl;
+ return;
+ }
+
+ int width = 576;
+ int height = 432;
+
+ // render the scene
+ QImage image = QImage(width, height, QImage::Format_RGBX8888);
+ image.fill(Qt::black);
+ RGBA *data = reinterpret_cast<RGBA *>(image.bits());
+
+
+
+ // RayTracer raytracer{ rtConfig };
+
+ RayTraceScene rtScene{ width, height, m_metaData };
+ this->render(data, rtScene);
+
+ QImage flippedImage = image.mirrored(false, false);
+ // make the image larger
+ flippedImage = flippedImage.scaled(2*width, 2*height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ imageLabel->setPixmap(QPixmap::fromImage(flippedImage));
+}
+
+void RayTracer::settingsChanged(QLabel* imageLabel) {
+ int width = 576;
+ int height = 432;
+
+ QImage image = QImage(width, height, QImage::Format_RGBX8888);
+ image.fill(Qt::black);
+ RGBA *data = reinterpret_cast<RGBA *>(image.bits());
+
+ RayTraceScene rtScene{ width, height, m_metaData };
+ this->render(data, rtScene);
+
+ QImage flippedImage = image.mirrored(false, false);
+ flippedImage = flippedImage.scaled(2*width, 2*height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ imageLabel->setPixmap(QPixmap::fromImage(flippedImage));
+}
+
+
diff --git a/src/raytracer/raytracer.h b/src/raytracer/raytracer.h
index 6a16cdf..5fbe907 100644
--- a/src/raytracer/raytracer.h
+++ b/src/raytracer/raytracer.h
@@ -6,6 +6,8 @@
#include "raytracescene.h"
#include "accelerate/kdtree.h"
#include "accelerate/bvh.h"
+#include <QOpenGLWidget>
+#include <QLabel>
// A forward declaration for the RaytraceScene class
@@ -31,12 +33,12 @@ struct Config {
bool onlyRenderNormals = false;
};
-class RayTracer
+class RayTracer : public QWidget
{
public:
// constructor for the config
- explicit RayTracer(const Config &config);
- const Config &m_config;
+ RayTracer(QWidget *parent = nullptr);
+// const Config &m_config;
// Renders the scene synchronously.
// The ray-tracer will render the scene and fill imageData in-place.
@@ -136,5 +138,23 @@ public:
// depth of field
glm::vec4 secondaryRays(glm::vec4 pWorld, glm::vec4 dWorld, RayTraceScene &scene);
+
+ // Old m_config
+
+ bool m_enableShadow = true;
+ bool m_enableReflection = true;
+ bool m_enableRefraction = false;
+ bool m_enableTextureMap = false;
+ bool m_enableAcceleration = true;
+ bool m_enableParallelism = true;
+ int m_maxRecursiveDepth = 4;
+ bool m_enableAntiAliasing = false;
+ bool m_enableDepthOfField = false;
+ bool m_enableSuperSample = false;
+
+ void sceneChanged(QLabel* imageLabel);
+ void settingsChanged(QLabel* imageLabel);
+ RenderData m_metaData;
+
};
diff --git a/src/settings.cpp b/src/settings.cpp
new file mode 100644
index 0000000..3d3e980
--- /dev/null
+++ b/src/settings.cpp
@@ -0,0 +1,3 @@
+#include "settings.h"
+
+Settings settings;
diff --git a/src/settings.h b/src/settings.h
new file mode 100644
index 0000000..c8a454e
--- /dev/null
+++ b/src/settings.h
@@ -0,0 +1,16 @@
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <string>
+
+struct Settings {
+ std::string sceneFilePath;
+ float w = 1;
+
+};
+
+
+// The global Settings object, will be initialized by MainWindow
+extern Settings settings;
+
+#endif // SETTINGS_H
diff --git a/src/utils/aspectratiowidget/aspectratiowidget.hpp b/src/utils/aspectratiowidget/aspectratiowidget.hpp
new file mode 100644
index 0000000..9a5f81c
--- /dev/null
+++ b/src/utils/aspectratiowidget/aspectratiowidget.hpp
@@ -0,0 +1,66 @@
+#ifndef ASPECTRATIOWIDGET_HPP
+#define ASPECTRATIOWIDGET_HPP
+
+#include <QWidget>
+#include <QBoxLayout>
+
+class AspectRatioWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ AspectRatioWidget(QWidget *parent = 0) : QWidget(parent)
+ {
+ m_layout = new QHBoxLayout();
+ m_layout->setSpacing(0);
+ m_layout->setContentsMargins(0, 0, 0, 0);
+ setLayout(m_layout);
+ }
+
+ // the widget we want to keep the ratio
+ void setAspectWidget(QWidget* widget, const double ratio = 1.0) {
+ m_aspect_widget = widget;
+ m_layout->addWidget(widget);
+ m_ratio = ratio;
+ }
+ void setRatio(const double ratio) {
+ m_ratio = ratio;
+ applyAspectRatio();
+ }
+
+protected:
+ void resizeEvent(QResizeEvent *event) {
+ (void)event;
+ applyAspectRatio();
+ }
+
+public slots:
+ void applyAspectRatio() {
+ int w = this->width();
+ int h = this->height();
+ double aspect = static_cast<double>(h)/static_cast<double>(w);
+
+ if(aspect < m_ratio) // parent is too wide
+ {
+ int target_width = static_cast<int>(static_cast<double>(h)/m_ratio);
+ m_aspect_widget->setMaximumWidth(target_width);
+ m_aspect_widget->setMaximumHeight(h);
+
+ }
+ else // parent is too high
+ {
+ int target_heigth = static_cast<int>(static_cast<double>(w)*m_ratio);
+ m_aspect_widget->setMaximumHeight(target_heigth);
+ m_aspect_widget->setMaximumWidth(w);
+ }
+ }
+
+private:
+ QHBoxLayout* m_layout;
+
+ QWidget* m_aspect_widget;
+
+ double m_ratio;
+};
+
+#endif // ASPECTRATIOWINDOW_H
+
diff --git a/src/utils/sceneparser.cpp b/src/utils/sceneparser.cpp
index 74c605a..99c4f55 100644
--- a/src/utils/sceneparser.cpp
+++ b/src/utils/sceneparser.cpp
@@ -58,7 +58,7 @@ void initTree(SceneNode* currentNode, std::vector<RenderShapeData> *shapes, std:
for(auto primitive : currentNode->primitives) {
- primitive->material.textureData = loadTextureFromFile(QString::fromStdString(primitive->material.textureMap.filename));
+ // primitive->material.textureData = loadTextureFromFile(QString::fromStdString(primitive->material.textureMap.filename));
RenderShapeData rsd = {*primitive, currentCTM, glm::inverse(currentCTM)};
shapes->push_back(rsd);
}