aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/illuminate/illuminate.cpp272
-rw-r--r--src/mainwindow.cpp147
-rw-r--r--src/mainwindow.h13
-rw-r--r--src/raytracer/raytracer.cpp4
-rw-r--r--src/settings.h2
5 files changed, 126 insertions, 312 deletions
diff --git a/src/illuminate/illuminate.cpp b/src/illuminate/illuminate.cpp
index 39ecccb..641f06d 100644
--- a/src/illuminate/illuminate.cpp
+++ b/src/illuminate/illuminate.cpp
@@ -1,50 +1,7 @@
#include <iostream>
#include "raytracer/raytracer.h"
-glm::vec4 RayTracer::illuminationFromPointLight(
- const SceneLightData &light,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- glm::vec4 directionToCamera,
- const RenderShapeData &shape,
- const RayTraceScene &scene
- )
-{
- auto directionFromIntersectionToLight = light.pos - intersectionWorld;
- directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
-
- // check if this light is blocked by an object
- auto distanceToLight = glm::distance(light.pos, intersectionWorld);
- bool isShadow = RayTracer::isShadowed(
- light.pos,
- distanceToLight,
- glm::vec4(directionFromIntersectionToLight),
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then no light contribution
- return glm::vec4(0.f);
- }
-
- // calculate attenuation
- float c1 = light.function.x;
- float c2 = light.function.y;
- float c3 = light.function.z;
- float attenuation = std::min(1.f, 1.f / (c1 + distanceToLight * c2 + (distanceToLight * distanceToLight) * c3));
-
- return phong(
- light.color,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
-}
-
-glm::vec4 RayTracer::illuminationFromSpotLight(
+glm::vec4 RayTracer::illuminationFromDirectionalLight(
const SceneLightData &light,
glm::vec4 intersectionWorld,
glm::vec4 normalWorld,
@@ -53,108 +10,42 @@ glm::vec4 RayTracer::illuminationFromSpotLight(
const RayTraceScene &scene
)
{
- auto distance = glm::distance(light.pos, intersectionWorld);
+ // define direction and distance of directional light
+ auto directionFromIntersectionToLight = - light.dir;
+ directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
+ float distanceToLight = FINF; // directional light infinitely far away
- // calculate the angle from the shape to the spot light
- auto directionFromIntersectionToLight = glm::normalize(light.pos - intersectionWorld);
+ float kd = scene.getGlobalData().kd;
+ float ks = scene.getGlobalData().ks;
+ auto material = shape.primitive.material;
- // calculate intensity, based on angle. apply falloff if necessary
- auto lightDirection = glm::normalize(light.dir);
- // invert the direction of the intersection to light for dot product to work correctly
- auto cosTheta = glm::dot(-directionFromIntersectionToLight, lightDirection);
- auto theta = glm::acos(cosTheta);
+ glm::vec4 illumination(0, 0, 0, 1.f);
- // determine intensity, based on location on spot cone
- glm::vec4 intensity;
- float inner = light.angle - light.penumbra;
- if (theta <= inner)
- {
- intensity = light.color;
- }
- else if
- (
- theta > inner
- && theta <= light.angle
- )
- {
- // inside the penumbra, need to apply falloff
- float falloff = -2 * std::pow(theta - inner, 3) / std::pow(light.penumbra, 3) +
- 3 * std::pow(theta - inner, 2) / std::pow(light.penumbra, 2);
- intensity = light.color * (1 - falloff);
- }
- else // theta > light.angle
- {
- return glm::vec4(0.f);
+ // calculate diffuse term
+ auto dotDiffuse = glm::dot(normalWorld, directionFromIntersectionToLight);
+ if (dotDiffuse < 0) {
+ return illumination;
}
+ // add the diffuse
+ auto diffuse = (kd * material.cDiffuse);
+ illumination += light.color * dotDiffuse * diffuse;
- // if the light is within the cone, see if it's a shadow
- auto distanceToLight = glm::distance(light.pos, intersectionWorld);
- bool isShadow = RayTracer::isShadowed(
- light.pos,
- distanceToLight,
- glm::vec4(directionFromIntersectionToLight),
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then no light contribution
- return glm::vec4(0.f);
+ // if the obj has no specular, return
+ if (material.cSpecular == glm::vec4(0.f)) {
+ return illumination;
}
- // calculate attenuation
- float c1 = light.function.x;
- float c2 = light.function.y;
- float c3 = light.function.z;
- float attenuation = std::min(1.f, 1.f / (c1 + distance * c2 + (distance * distance) * c3));
+ // get the light reflection vector
+ auto reflectedDirOverNormal = glm::normalize(glm::reflect(directionFromIntersectionToLight, normalWorld));
- return phong(
- intensity,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
-}
-
-glm::vec4 RayTracer::illuminationFromDirectionalLight(
- const SceneLightData &light,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- glm::vec4 directionToCamera,
- const RenderShapeData &shape,
- const RayTraceScene &scene
-)
-{
- // define direction and distance of directional light
- auto directionFromIntersectionToLight = - light.dir;
- directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
- float distanceToLight = FINF; // directional light infinitely far away
-
- // check if an object blocks ours
- bool isShadow = RayTracer::isShadowed(
- light.pos,
- distanceToLight,
- directionFromIntersectionToLight,
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then no light contribution
- return glm::vec4(0.f);
+ // calculate specular term
+ auto dotSpecular = glm::dot(reflectedDirOverNormal, -directionToCamera);
+ if (dotSpecular > 0) {
+ auto toPow = std::pow(dotSpecular, material.shininess);
+ illumination += light.color * toPow * (ks * material.cSpecular);
}
- float attenuation = 1.f; // directional lights don't attenuate
- return phong(
- light.color,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
+ return illumination;
}
@@ -182,125 +73,24 @@ glm::vec4 RayTracer::illuminatePixel(
for (const SceneLightData &light : scene.getLights()) {
switch (light.type) {
case LightType::LIGHT_POINT:
- illumination +=
- illuminationFromPointLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
case LightType::LIGHT_DIRECTIONAL:
illumination +=
illuminationFromDirectionalLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
case LightType::LIGHT_SPOT:
- illumination +=
- illuminationFromSpotLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
case LightType::LIGHT_AREA:
- illumination +=
- illuminationFromAreaLight(light, intersectionWorld, normalWorld, directionToCamera, shape, scene);
continue;
default:
continue;
}
}
- auto incidentDir = -directionToCamera;
+ // auto incidentDir = -directionToCamera;
// recursive raytracing for the reflection and refraction (see reflect.cpp)
- illumination += refract(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
- illumination += reflect(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
+ // illumination += refract(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
+ // illumination += reflect(intersectionWorld, normalWorld, incidentDir, shape, scene, depth + 1);
return illumination;
-}
-
-// helper function to handle the diffuse and specular terms
-// also handles the texture within that diffuse term
-glm::vec4 RayTracer::phong(
- glm::vec4 lightColor,
- float attenuation,
- glm::vec4 directionFromIntersectionToLight,
- glm::vec4 directionToCamera,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- const RenderShapeData &shape,
- const RayTraceScene &scene)
-{
- float kd = scene.getGlobalData().kd;
- float ks = scene.getGlobalData().ks;
- auto material = shape.primitive.material;
-
- glm::vec4 illumination(0.f);
-
- // calculate diffuse term
- auto dotDiffuse = glm::dot(normalWorld, directionFromIntersectionToLight);
- if (dotDiffuse > 0) // ensure not facing away
- {
- auto diffuse = (kd * material.cDiffuse);
- // commenting out texture stuff bc 4d textures??????
-// if (material.textureMap.isUsed)
-// {
-// glm::vec4 pObject = shape.inverseCTM * glm::vec4(intersectionWorld, 1.f);
-// diffuse = interpolateTexture(pObject, shape, diffuse);
-// }
- illumination += (attenuation * lightColor) * dotDiffuse * diffuse;
- }
-
- // add specular term
- auto reflectedDirOverNormal =
- 2 * glm::dot(directionFromIntersectionToLight, normalWorld) * normalWorld -
- directionFromIntersectionToLight;
- auto dotSpecular = glm::dot(reflectedDirOverNormal, directionToCamera);
- auto toPow = std::pow(dotSpecular, material.shininess);
- if (dotSpecular > 0) {
- illumination += (attenuation * lightColor) * toPow * (ks * material.cSpecular);
- }
-
- return illumination;
-}
-
-// EXTRA CREDIT -> AREA LIGHT
-glm::vec4 RayTracer::illuminationFromAreaLight(
- const SceneLightData &light,
- glm::vec4 intersectionWorld,
- glm::vec4 normalWorld,
- glm::vec4 directionToCamera,
- const RenderShapeData &shape,
- const RayTraceScene &scene
-) {
- // select a random point within the light's height and width
- float width = light.width;
- float height = light.height;
- float x = ((float) rand() / (float) RAND_MAX) * width - width / 2.f;
- float y = ((float) rand() / (float) RAND_MAX) * height - height / 2.f;
- glm::vec4 lightPosition = light.pos + glm::vec4(x, y, 0.f, 0.f);
-
- auto directionFromIntersectionToLight = lightPosition - intersectionWorld;
- directionFromIntersectionToLight = glm::normalize(directionFromIntersectionToLight);
-
- // check if this light is blocked by an object
- auto distanceToLight = glm::distance(lightPosition, intersectionWorld);
- bool isShadow = RayTracer::isShadowed(
- lightPosition,
- distanceToLight,
- glm::vec4(directionFromIntersectionToLight),
- glm::vec4(intersectionWorld),
- scene);
- if (isShadow)
- {
- // if this is a shadow, then show a ray to a random point in the light
- return glm::vec4(0.f);
- }
-
- // calculate attenuation
- float c1 = light.function.x;
- float c2 = light.function.y;
- float c3 = light.function.z;
- float attenuation = std::min(1.f, 1.f / (c1 + distanceToLight * c2 + (distanceToLight * distanceToLight) * c3));
-
- return phong(
- light.color,
- attenuation,
- directionFromIntersectionToLight,
- directionToCamera,
- intersectionWorld,
- normalWorld,
- shape,
- scene);
-}
+} \ No newline at end of file
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index ef15b61..973d5a7 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -47,9 +47,13 @@ void MainWindow::initialize() {
w_label->setText("W value:");
w_label->setFont(font);
- QLabel *rotation_label = new QLabel(); // Rotation label
- rotation_label->setText("Time value:");
- rotation_label->setFont(font);
+ QLabel *curr_time_label = new QLabel(); // Current Time label
+ curr_time_label->setText("Curr Time: 0");
+ curr_time_label->setFont(font);
+
+ QLabel *max_time_label = new QLabel(); // Max Time label
+ max_time_label->setText("Max Time:");
+ max_time_label->setFont(font);
// Create file uploader for scene file
@@ -59,7 +63,11 @@ void MainWindow::initialize() {
saveImage = new QPushButton();
saveImage->setText(QStringLiteral("Save image"));
- QGroupBox *xyLayout = new QGroupBox(); // horizonal w slider alignment
+ // Select directory for bulk output
+ bulkRender = new QPushButton();
+ bulkRender->setText(QStringLiteral("Bulk Render"));
+
+ QGroupBox *xyLayout = new QGroupBox(); // horizontal w slider alignment
QHBoxLayout *lxy = new QHBoxLayout();
xySlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
@@ -79,7 +87,7 @@ void MainWindow::initialize() {
xyLayout->setLayout(lxy);
// XZ Slider
- QGroupBox *xzLayout = new QGroupBox(); // horizonal w slider alignment
+ QGroupBox *xzLayout = new QGroupBox(); // horizontal w slider alignment
QHBoxLayout *lxz = new QHBoxLayout();
xzSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
@@ -99,7 +107,7 @@ void MainWindow::initialize() {
xzLayout->setLayout(lxz);
// XW Slider
- QGroupBox *xwLayout = new QGroupBox(); // horizonal w slider alignment
+ QGroupBox *xwLayout = new QGroupBox(); // horizontal w slider alignment
QHBoxLayout *lxw = new QHBoxLayout();
xwSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
@@ -119,7 +127,7 @@ void MainWindow::initialize() {
xwLayout->setLayout(lxw);
// YZ Slider
- QGroupBox *yzLayout = new QGroupBox(); // horizonal w slider alignment
+ QGroupBox *yzLayout = new QGroupBox(); // horizontal w slider alignment
QHBoxLayout *lyz = new QHBoxLayout();
yzSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
@@ -139,7 +147,7 @@ void MainWindow::initialize() {
yzLayout->setLayout(lyz);
// YW Slider
- QGroupBox *ywLayout = new QGroupBox(); // horizonal w slider alignment
+ QGroupBox *ywLayout = new QGroupBox(); // horizontal w slider alignment
QHBoxLayout *lyw = new QHBoxLayout();
ywSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
@@ -159,7 +167,7 @@ void MainWindow::initialize() {
ywLayout->setLayout(lyw);
// ZW Slider
- QGroupBox *zwLayout = new QGroupBox(); // horizonal w slider alignment
+ QGroupBox *zwLayout = new QGroupBox(); // horizontal w slider alignment
QHBoxLayout *lzw = new QHBoxLayout();
zwSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
@@ -178,37 +186,37 @@ void MainWindow::initialize() {
lzw->addWidget(zwBox);
zwLayout->setLayout(lzw);
- // Rotation Slider
- QGroupBox *rotationLayout = new QGroupBox(); // horizonal w slider alignment
- QHBoxLayout *lrotation = new QHBoxLayout();
+ // Max Time Slider
+ QGroupBox *maxTimeGroupBox = new QGroupBox(); // horizontal
+ QHBoxLayout *maxTimeLayout = new QHBoxLayout();
- rotationSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
- rotationSlider->setTickInterval(1);
- rotationSlider->setMinimum(0);
- rotationSlider->setMaximum(18000);
- rotationSlider->setValue(1);
+ maxTimeSlider = new QSlider(Qt::Orientation::Horizontal);
+ maxTimeSlider->setTickInterval(1);
+ maxTimeSlider->setMinimum(0);
+ maxTimeSlider->setMaximum(18000);
+ maxTimeSlider->setValue(1);
- rotationBox = new QDoubleSpinBox();
- rotationBox->setMinimum(0.0f);
- rotationBox->setMaximum(600.f);
- rotationBox->setSingleStep(1.f);
- rotationBox->setValue(settings.rotation);
+ maxTimeSpinBox = new QSpinBox();
+ maxTimeSpinBox->setMinimum(0);
+ maxTimeSpinBox->setMaximum(600);
+ maxTimeSpinBox->setSingleStep(1);
+ maxTimeSpinBox->setValue(settings.rotation);
- lrotation->addWidget(rotationSlider);
- lrotation->addWidget(rotationBox);
- rotationLayout->setLayout(lrotation);
+ maxTimeLayout->addWidget(maxTimeSlider);
+ maxTimeLayout->addWidget(maxTimeSpinBox);
+ maxTimeGroupBox->setLayout(maxTimeLayout);
- // checkbox
- rotateNegative = new QCheckBox();
- rotateNegative->setText(QStringLiteral("Reverse Rotation"));
- rotateNegative->setChecked(false);
+ // // checkbox
+ // rotateNegative = new QCheckBox();
+ // rotateNegative->setText(QStringLiteral("Reverse Rotation"));
+ // rotateNegative->setChecked(false);
// w Slider
- QGroupBox *wLayout = new QGroupBox(); // horizonal w slider alignment
+ QGroupBox *wLayout = new QGroupBox(); // horizontal w slider alignment
QHBoxLayout *lw = new QHBoxLayout();
wSlider = new QSlider(Qt::Orientation::Horizontal); // XY value slider
- wSlider->setTickInterval(0.01);
+ wSlider->setTickInterval(1);
wSlider->setMinimum(-10000);
wSlider->setMaximum(10000);
wSlider->setValue(0);
@@ -240,11 +248,12 @@ void MainWindow::initialize() {
vLayout->addWidget(zwLayout);
vLayout->addWidget(w_label);
vLayout->addWidget(wLayout);
- vLayout->addWidget(rotation_label);
- vLayout->addWidget(rotationLayout);
-
- vLayout->addWidget(rotateNegative);
+ vLayout->addWidget(curr_time_label);
+ vLayout->addWidget(max_time_label);
+ vLayout->addWidget(maxTimeGroupBox);
+ vLayout->addWidget(bulkRender);
+ // vLayout->addWidget(rotateNegative);
connectUIElements();
@@ -259,13 +268,14 @@ void MainWindow::finish() {
void MainWindow::connectUIElements() {
connectUploadFile();
connectSaveImage();
+ connectBulkRender();
connectxy();
connectxz();
connectxw();
connectyz();
connectyw();
connectzw();
- connectRotationSlider();
+ connectMaxTimeSlider();
connectNegativeRotation();
connect(rayTracer, &RayTracer::xyRotationChanged, this, &MainWindow::updateXySlider);
connect(rayTracer, &RayTracer::xzRotationChanged, this, &MainWindow::updateXzSlider);
@@ -286,6 +296,10 @@ void MainWindow::connectSaveImage() {
connect(saveImage, &QPushButton::clicked, this, &MainWindow::onSaveImage);
}
+void MainWindow::connectBulkRender() {
+ connect(bulkRender, &QPushButton::clicked, this, &MainWindow::onBulkRender);
+}
+
void MainWindow::connectxy() {
connect(xySlider, &QSlider::valueChanged, this, &MainWindow::onValChangexySlider);
connect(xyBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
@@ -322,10 +336,10 @@ void MainWindow::connectzw() {
this, &MainWindow::onValChangezwBox);
}
-void MainWindow::connectRotationSlider() {
- connect(rotationSlider, &QSlider::valueChanged, this, &MainWindow::onValChangeRotationSlider);
- connect(rotationBox, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
- this, &MainWindow::onValChangeRotationBox);
+void MainWindow::connectMaxTimeSlider() {
+ connect(maxTimeSlider, &QSlider::valueChanged, this, &MainWindow::onValChangeMaxTimeSlider);
+ connect(maxTimeSpinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &MainWindow::onValChangeMaxTimeBox);
}
void MainWindow::connectNegativeRotation() {
@@ -361,24 +375,31 @@ void MainWindow::onUploadFile() {
}
void MainWindow::onSaveImage() {
- if (settings.sceneFilePath.empty()) {
- std::cout << "No scene file loaded." << std::endl;
- return;
- }
+ // 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());
+ rayTracer->saveViewportImage(filePath.toStdString());
+}
+
+void MainWindow::onBulkRender() {
+ // 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 folderPath = QFileDialog::getExistingDirectory(this, tr("Select Directory for Bulk Render"),
+ QDir::currentPath());
+ std::cout << "Setting bulk output path to: \"" << folderPath.toStdString() << "\"." << std::endl;
+ settings.bulkOutputFolderPath = folderPath.toStdString();
}
void MainWindow::onValChangexySlider(int newValue) {
@@ -465,18 +486,18 @@ void MainWindow::onValChangezwBox(double newValue) {
// rayTracer->settingsChanged(imageLabel);
}
-void MainWindow::onValChangeRotationSlider(int newValue) {
+void MainWindow::onValChangeMaxTimeSlider(int newValue) {
//wSlider->setValue(newValue);
- rotationBox->setValue(newValue/100.f);
- settings.rotation = rotationBox->value();
- // rayTracer->settingsChanged(imageLabel);
+ maxTimeSpinBox->setValue(newValue/100.f);
+ settings.maxTime = maxTimeSpinBox->value();
+ rayTracer->settingsChanged(imageLabel);
}
-void MainWindow::onValChangeRotationBox(double newValue) {
- rotationSlider->setValue(int(newValue*100.f));
+void MainWindow::onValChangeMaxTimeBox(double newValue) {
+ maxTimeSlider->setValue(int(newValue*100.f));
//wBox->setValue(newValue);
- settings.rotation = rotationBox->value();
- // rayTracer->settingsChanged(imageLabel);
+ settings.rotation = maxTimeSpinBox->value();
+ rayTracer->settingsChanged(imageLabel);
}
void MainWindow::onValChangeWSlider(int newValue) {
@@ -537,11 +558,11 @@ void MainWindow::updateZwSlider(double value) {
}
void MainWindow::updateRotationSlider(float value) {
- rotationSlider->setValue(int(value*100.f));
- rotationBox->setValue(value);
- // rayTracer->settingsChanged(imageLabel);
+ maxTimeSlider->setValue(int(value*100.f));
+ maxTimeSpinBox->setValue(value);
+ rayTracer->settingsChanged(imageLabel);
}
void MainWindow::updateCameraPosition() {
rayTracer->wSliderChanged(imageLabel);
-} \ No newline at end of file
+}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 34656e2..06f27be 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -23,13 +23,14 @@ private:
void connectUIElements();
void connectUploadFile();
void connectSaveImage();
+ void connectBulkRender();
void connectxy();
void connectxz();
void connectxw();
void connectyz();
void connectyw();
void connectzw();
- void connectRotationSlider();
+ void connectMaxTimeSlider();
void connectNegativeRotation();
void connectW();
@@ -37,6 +38,7 @@ private:
AspectRatioWidget *aspectRatioWidget;
QPushButton *uploadFile;
QPushButton *saveImage;
+ QPushButton *bulkRender;
QSlider *xySlider;
QDoubleSpinBox *xyBox;
QSlider *xzSlider;
@@ -49,8 +51,8 @@ private:
QDoubleSpinBox *ywBox;
QSlider *zwSlider;
QDoubleSpinBox *zwBox;
- QSlider *rotationSlider;
- QDoubleSpinBox *rotationBox;
+ QSlider *maxTimeSlider;
+ QSpinBox *maxTimeSpinBox;
QCheckBox *rotateNegative;
QSlider *wSlider;
QDoubleSpinBox *wBox;
@@ -59,6 +61,7 @@ private:
private slots:
void onUploadFile();
void onSaveImage();
+ void onBulkRender();
void onValChangexySlider(int newValue);
void onValChangexyBox(double newValue);
void onValChangexzSlider(int newValue);
@@ -71,8 +74,8 @@ private slots:
void onValChangeywBox(double newValue);
void onValChangezwSlider(int newValue);
void onValChangezwBox(double newValue);
- void onValChangeRotationSlider(int newValue);
- void onValChangeRotationBox(double newValue);
+ void onValChangeMaxTimeSlider(int newValue);
+ void onValChangeMaxTimeBox(double newValue);
void onRotateNegative();
void updateXySlider(double newValue);
void updateXzSlider(double newValue);
diff --git a/src/raytracer/raytracer.cpp b/src/raytracer/raytracer.cpp
index 4d1e14a..d6fa14f 100644
--- a/src/raytracer/raytracer.cpp
+++ b/src/raytracer/raytracer.cpp
@@ -69,9 +69,9 @@ void RayTracer::render(RGBA *imageData, const RayTraceScene &scene) {
}
}
- if (settings.bulkOutputFilePath.size() > 0) { // means we are doing bulk rendering
+ if (settings.bulkOutputFolderPath.size() > 0) { // means we are doing bulk rendering
// save the image to the bulk directory
- std::string filePath = settings.bulkOutputFilePath + QDir::separator().toLatin1() + std::to_string(settings.currentTime) + ".png";
+ std::string filePath = settings.bulkOutputFolderPath + QDir::separator().toLatin1() + std::to_string(settings.currentTime) + ".png";
saveViewportImage(filePath);
if (settings.currentTime < settings.maxTime) { // still more to render
// render the next frame
diff --git a/src/settings.h b/src/settings.h
index 0865e44..32c6484 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -17,7 +17,7 @@ struct Settings {
float w = 0.f;
int currentTime = 0;
int maxTime = 0;
- std::string bulkOutputFilePath;
+ std::string bulkOutputFolderPath;
};