From 7aa08821c566c85530e1ec4c3b490785d47d030a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82upczy=C5=84ski?= Date: Wed, 17 Jan 2024 19:37:11 +0100 Subject: [PATCH 1/7] Minor changes --- application.cpp | 9 +++++++++ camera.cpp | 5 +---- camera.hpp | 8 ++++++-- cuda.cu | 40 +++++++++++++++++++++++++++++----------- cuda.cuh | 2 ++ imgui.ini | 4 ++-- renderer.cpp | 4 +++- scene.hpp | 37 +++++++++++++++++++++---------------- 8 files changed, 73 insertions(+), 36 deletions(-) diff --git a/application.cpp b/application.cpp index 5730013..90aa500 100644 --- a/application.cpp +++ b/application.cpp @@ -171,7 +171,16 @@ void Application::imGuiFrame(int fps) ImGui::DragFloat3("Light", glm::value_ptr(renderer->scene.lightPositions[0]), 0.01f, -2.5f, 10.0f); + ImGui::SliderFloat("Diffuse", &renderer->scene.kDiffuse, 0.0, 1.0); + ImGui::SliderFloat("Specular", &renderer->scene.kSpecular, 0.0, 1.0); + ImGui::SliderFloat("Shininess", &renderer->scene.kShininess, 0.0, 20.0); + ImGui::SliderFloat("Ambient", &renderer->scene.kAmbient, 0.0, 1.0); + + ImGui::ColorPicker3("Sky color", glm::value_ptr(renderer->scene.skyColor)); + ImGui::ColorPicker3("Ambient color", glm::value_ptr(renderer->scene.ambientColor)); + ImGui::End(); + } void Application::textureResizeStorage(int width, int height) diff --git a/camera.cpp b/camera.cpp index 1c6fb83..053f30e 100644 --- a/camera.cpp +++ b/camera.cpp @@ -18,10 +18,7 @@ Camera::Camera(int width, int height, float fov, float nearPlane, float farPlane this->bottom = bottom; this->top = top;*/ - position = glm::vec3(0.0f, 0.0f, 6.0f); - - speed = 3.0f; - rotationSpeed = 0.005f; + position = glm::vec3(0.0f, 0.0f, 30.0f); forwardDirection = glm::vec3(0.0f, 0.0f, -1.0f); rightDirection = glm::normalize(glm::cross(forwardDirection, worldUpDirection)); diff --git a/camera.hpp b/camera.hpp index 31ec207..02b6e8d 100644 --- a/camera.hpp +++ b/camera.hpp @@ -7,7 +7,7 @@ class Camera { public: - Camera(int width, int height, float fov = glm::radians(70.0), + Camera(int width, int height, float fov = glm::radians(50.0), float nearPlane = 0.01, float farPlane = 100); //float left = -1.0f, float right = 1.0f, float bottom = -1.0f, float top = 1.0f); @@ -23,8 +23,12 @@ class Camera void calculateRayDirections(); + glm::mat4& getInverseProjMatrix() { return inverseProjMatrix; } + glm::mat4& getInverseViewMatrix() { return inverseViewMatrix; } + private: - float speed, rotationSpeed; + const float speed = 15.0f; + const float rotationSpeed = 0.005f; glm::vec3 forwardDirection, rightDirection, upDirection; const glm::vec3 worldUpDirection = glm::vec3(0.0f, 1.0f, 0.0f); diff --git a/cuda.cu b/cuda.cu index 35215a8..ed85317 100644 --- a/cuda.cu +++ b/cuda.cu @@ -79,7 +79,7 @@ __device__ HitPayload traceRayFromPixel(const Ray& ray, Scene scene) } for (int k = 0; k < scene.lightCount; k++) - { + { glm::vec3 origin = ray.origin - scene.cudaLightPositions[k]; glm::vec3 direction = ray.direction; @@ -100,7 +100,7 @@ __device__ HitPayload traceRayFromPixel(const Ray& ray, Scene scene) hitSphereIndex = -2; hitLightIndex = k; } - + } if (hitSphereIndex == -1) @@ -189,10 +189,12 @@ __device__ glm::vec4 rayGen(int i, int j, glm::vec3 origin, return glm::vec4(scene.cudaLightColors[idx], 1.0f); glm::vec4 color = glm::vec4(scene.kAmbient * scene.ambientColor * scene.cudaSphereAlbedos[idx], 1.0f); - + // cast rays from hitpoint to light sources for (int lightIdx = 0; lightIdx < scene.lightCount; lightIdx++) { + // todo: make choice for shadows or no shadows + /* Ray rayToLight; // cast ray a bit away from the sphere so that the ray doesn't hit it @@ -205,15 +207,31 @@ __device__ glm::vec4 rayGen(int i, int j, glm::vec3 origin, // no sphere hit on path to light if (payloadToLight.hitDistance < 0) - { - //printf("chuj mi w dupe\n"); + */ color += phong(payload, lightIdx, scene, cameraPos); - } } - + return glm::clamp(color, 0.0f, 1.0f); } +__device__ glm::vec3 getRayDirection(int i, int j, cudaArguments args) +{ + glm::vec2 coord{ + (float)j / args.width, + (float)i / args.height + }; + + coord = coord * 2.0f - 1.0f; + + //glm::vec4 origin = inverseProjMatrix * glm::vec4(coord.x, coord.y, -2.0f, 1.0f); + //glm::vec3 rayOrigin = glm::vec3(inverseViewMatrix * origin);//glm::vec4(glm::normalize(glm::vec3(origin) / origin.w), 1)); + + glm::vec4 target = args.inverseProjMatrix * glm::vec4(coord.x, coord.y, 1.0f, 1.0f); + glm::vec3 rayDirection = glm::vec3(args.inverseViewMatrix * glm::vec4(glm::normalize(glm::vec3(target) / target.w), 0)); + + return rayDirection; +} + __global__ void rayTrace(cudaArguments args) { int x = threadIdx.x + blockIdx.x * blockDim.x; @@ -225,9 +243,9 @@ __global__ void rayTrace(cudaArguments args) int k = x + y * args.width; //GLuint res = toRGBA(glm::vec4(0.0f, 0.0f, (float)x / args.width, 1.0f)); - - GLuint res = toRGBA(rayGen(y, x, - args.rayOrigin, args.rayDirections[k], args.scene, args.cameraPos)); - + + GLuint res = toRGBA(rayGen(y, x, + args.rayOrigin, getRayDirection(y, x, args), args.scene, args.cameraPos)); + args.cudaImage[k] = res; } \ No newline at end of file diff --git a/cuda.cuh b/cuda.cuh index a2b135e..b53df87 100644 --- a/cuda.cuh +++ b/cuda.cuh @@ -15,6 +15,8 @@ struct cudaArguments { const glm::vec3 rayOrigin; const glm::vec3* rayDirections; const glm::vec3 cameraPos; + const glm::mat4 inverseProjMatrix; + const glm::mat4 inverseViewMatrix; }; __host__ void callKernels(dim3 blocks_per_grid, dim3 max_threads, diff --git a/imgui.ini b/imgui.ini index 9b2fbdf..dade137 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,6 +3,6 @@ Pos=60,-9 Size=400,400 [Window][Menu] -Pos=781,339 -Size=173,154 +Pos=23,19 +Size=306,682 diff --git a/renderer.cpp b/renderer.cpp index 2a05052..0a74353 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -110,7 +110,9 @@ void Renderer::renderGPU() cudaImage, width, height, scene, camera->getRayOrigin(), cudaRayDirections, - camera->getRayOrigin() + camera->getRayOrigin(), + camera->getInverseProjMatrix(), + camera->getInverseViewMatrix() }; callKernels(blocks, threads, args); diff --git a/scene.hpp b/scene.hpp index f4d4a52..bfb13c5 100644 --- a/scene.hpp +++ b/scene.hpp @@ -25,6 +25,9 @@ struct Light struct Scene { + // todo: sliders for each light, sliders for material parameters + // todo: selectable sphere colors? :D + //std::vector spheres; //std::vector lights; @@ -46,27 +49,29 @@ struct Scene glm::vec3* cudaLightPositions; glm::vec3* cudaLightColors; - const int sphereCount = 15; + const int sphereCount = 300; const int lightCount = 10; - const glm::vec3 ambientColor{ + glm::vec3 ambientColor{ 1.0f, 1.0f, 1.0f }; - const glm::vec3 skyColor{ + glm::vec3 skyColor{ 0.0f, 0.0f, 0.0f }; - const float kDiffuse = 0.9f; - const float kSpecular = 0.4f; - const float kAmbient = 0.2f; - const float kShininess = 40; + float kDiffuse = 0.9f; + float kSpecular = 0.4f; + float kAmbient = 0.2f; + float kShininess = 40; + + const float worldBorder = -20; void create() { static std::vector colorPalette; static std::vector lightColorPalette; { - colorPalette.push_back(glm::vec3(0.5, 0.5, 0.5)); - /*colorPalette.push_back(glm::vec3(155.0f / 255.0f, 34.0f / 255.0f, 38.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(0.5, 0.5, 0.5)); + colorPalette.push_back(glm::vec3(155.0f / 255.0f, 34.0f / 255.0f, 38.0f / 255.0f)); colorPalette.push_back(glm::vec3(0.0f / 255.0f, 18.0f / 255.0f, 25.0f / 255.0f)); colorPalette.push_back(glm::vec3(0.0f / 255.0f, 95.0f / 255.0f, 115.0f / 255.0f)); colorPalette.push_back(glm::vec3(10.0f / 255.0f, 147.0f / 255.0f, 150.0f / 255.0f)); @@ -75,7 +80,7 @@ struct Scene colorPalette.push_back(glm::vec3(238.0f / 255.0f, 155.0f / 255.0f, 0.0f / 255.0f)); colorPalette.push_back(glm::vec3(202.0f / 255.0f, 103.0f / 255.0f, 2.0f / 255.0f)); colorPalette.push_back(glm::vec3(187.0f / 255.0f, 62.0f / 255.0f, 3.0f / 255.0f)); - colorPalette.push_back(glm::vec3(174.0f / 255.0f, 32.0f / 255.0f, 18.0f / 255.0f));*/ + colorPalette.push_back(glm::vec3(174.0f / 255.0f, 32.0f / 255.0f, 18.0f / 255.0f)); lightColorPalette.push_back(glm::vec3(1.0f, 1.0f, 1.0f)); lightColorPalette.push_back(glm::vec3(1.0f, 0.0f, 0.0f)); @@ -100,9 +105,9 @@ struct Scene for (int i = 0; i < sphereCount; i++) { spherePositions[i] = glm::vec3( - (float)rand() / RAND_MAX * 10.0f - 5.0f, - (float)rand() / RAND_MAX * 10.0f - 5.0f, - (float)rand() / RAND_MAX * 10.0f - 5.0f); + ((float)rand() / RAND_MAX) * worldBorder * 2 - worldBorder, + ((float)rand() / RAND_MAX) * worldBorder * 2 - worldBorder, + ((float)rand() / RAND_MAX) * worldBorder * 2 - worldBorder); sphereRadii[i] = 0.2f * (i % 5 + 1); sphereAlbedos[i] = colorPalette[i % colorPalette.size()]; } @@ -110,9 +115,9 @@ struct Scene for (int i = 0; i < lightCount; i++) { lightPositions[i] = glm::vec3( - 5.0f * (float)rand() / RAND_MAX - 2.5f, - 5.0f * (float)rand() / RAND_MAX - 2.5f, - 5.0f * (float)rand() / RAND_MAX - 2.5f); + ((float)rand() / RAND_MAX) * worldBorder * 5 + worldBorder, + ((float)rand() / RAND_MAX) * worldBorder * 5 + worldBorder, + ((float)rand() / RAND_MAX) * worldBorder * 5 + worldBorder); lightColors[i] = lightColorPalette[i % lightColorPalette.size()]; } From 1a0baeaa0d693478d3320458445591ea0b36d615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82upczy=C5=84ski?= Date: Thu, 18 Jan 2024 00:28:10 +0100 Subject: [PATCH 2/7] Many minor changes - cached ray directions on CPU, calculated parallelly - user-changable parameters - camera is rotatable again - little code cleanup - some todos resolved --- application.cpp | 70 +++++++++----------------- application.hpp | 2 +- application_imgui.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++ camera.cpp | 94 +++++++++++++++++----------------- camera.hpp | 9 +++- cuda.cu | 48 ++++++++++-------- cuda.cuh | 1 + imgui.ini | 30 ++++++++++- main.cpp | 1 - pro2.vcxproj | 2 +- renderer.cpp | 55 ++++++++------------ renderer.hpp | 9 ++-- scene.cpp | 12 ----- scene.hpp | 78 ++++++++++++++++------------- window.cpp | 48 +++++++++--------- 15 files changed, 339 insertions(+), 234 deletions(-) create mode 100644 application_imgui.cpp delete mode 100644 scene.cpp diff --git a/application.cpp b/application.cpp index 90aa500..6e2b7c7 100644 --- a/application.cpp +++ b/application.cpp @@ -1,12 +1,10 @@ #include "application.hpp" -#include - Application::Application() { window = new Window(this); shader = new Shader("vertex.glsl", "fragment.glsl"); - renderer = new Renderer(WIDTH, HEIGHT, this); + renderer = new Renderer(WIDTH, HEIGHT); deltaTime = 0; } @@ -31,10 +29,7 @@ void Application::run() double previousTime = glfwGetTime(); double previousFpsTime = previousTime; - if (freeCamera) - glfwSetInputMode(window->wndptr, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - else - glfwSetInputMode(window->wndptr, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + freeCamera = false; static bool firstFrame = true; @@ -134,10 +129,14 @@ void Application::createTexture() void Application::updateAndRenderScene() { renderer->update(deltaTime); + if (solutionMode == CPU) renderer->renderCPU(); else - renderer->renderGPU(); + { + renderer->scene.updateCuda(); + renderer->renderGPU(solutionMode == GPUshadows); + } glTextureSubImage2D(texture, 0, 0, 0, renderer->width, renderer->height, GL_RGBA, @@ -145,44 +144,6 @@ void Application::updateAndRenderScene() glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } -void Application::imGuiFrame(int fps) -{ - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - if (!ImGui::Begin("Menu", NULL, 0)) - { - ImGui::End(); - return; - } - - ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.45f); - - static const char* items[] = { "CPU", "GPU" }; - static int selectedItem = 1; - - if (ImGui::Combo("Solution", &selectedItem, items, IM_ARRAYSIZE(items))) - { - solutionMode = (solutionModes)selectedItem; - } - - ImGui::Text("%d fps", fps); - - ImGui::DragFloat3("Light", glm::value_ptr(renderer->scene.lightPositions[0]), 0.01f, -2.5f, 10.0f); - - ImGui::SliderFloat("Diffuse", &renderer->scene.kDiffuse, 0.0, 1.0); - ImGui::SliderFloat("Specular", &renderer->scene.kSpecular, 0.0, 1.0); - ImGui::SliderFloat("Shininess", &renderer->scene.kShininess, 0.0, 20.0); - ImGui::SliderFloat("Ambient", &renderer->scene.kAmbient, 0.0, 1.0); - - ImGui::ColorPicker3("Sky color", glm::value_ptr(renderer->scene.skyColor)); - ImGui::ColorPicker3("Ambient color", glm::value_ptr(renderer->scene.ambientColor)); - - ImGui::End(); - -} - void Application::textureResizeStorage(int width, int height) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, @@ -191,6 +152,23 @@ void Application::textureResizeStorage(int width, int height) void Application::processKeyboard(int key) { + if (key == GLFW_KEY_F) + { + freeCamera = !freeCamera; + if (freeCamera) + glfwSetInputMode(window->wndptr, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + else + glfwSetInputMode(window->wndptr, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + + return; + } + + if (freeCamera && (key == GLFW_KEY_Q || + key == GLFW_KEY_E || + key == GLFW_KEY_1 || + key == GLFW_KEY_3)) + return; + renderer->processKeyboard(key, deltaTime); } diff --git a/application.hpp b/application.hpp index 5ff02a2..92928e5 100644 --- a/application.hpp +++ b/application.hpp @@ -21,7 +21,7 @@ class Application void processKeyboard(int key); void processMouse(glm::vec2 offset); - enum solutionModes {CPU, GPU}; + enum solutionModes {CPU, GPU, GPUshadows}; solutionModes solutionMode = GPU; private: Window* window; diff --git a/application_imgui.cpp b/application_imgui.cpp new file mode 100644 index 0000000..d673423 --- /dev/null +++ b/application_imgui.cpp @@ -0,0 +1,114 @@ +#include "application.hpp" + +#include + +void Application::imGuiFrame(int fps) +{ + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + //ImGui::ShowDemoWindow(); + if (!ImGui::Begin("Menu", NULL, 0)) + { + ImGui::End(); + return; + } + + ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.45f); + + static const char* items[] = { "CPU", "GPU", "GPU shadows" }; + static int selectedItem = 1; + + if (ImGui::Combo("Solution", &selectedItem, items, IM_ARRAYSIZE(items))) + { + solutionMode = (solutionModes)selectedItem; + } + + ImGui::Text("%d fps", fps); + + if (ImGui::CollapsingHeader("Information")) + { + ImGui::Text("Number of spheres: %d", renderer->scene.sphereCount); + ImGui::Text("Number of light sources: %d", renderer->scene.lightCount); + } + + if (ImGui::CollapsingHeader("Camera controls")) + { + ImGui::SeparatorText("Position"); + ImGui::BulletText("W - forward"); + ImGui::BulletText("S - backward"); + ImGui::BulletText("A - left"); + ImGui::BulletText("R - right"); + ImGui::BulletText("Space - up"); + ImGui::BulletText("LShift - down"); + + ImGui::SeparatorText("Angles"); + ImGui::BulletText("Q - look left"); + ImGui::BulletText("E - look right"); + ImGui::BulletText("1 - look up"); + ImGui::BulletText("3 - look down"); + + ImGui::SeparatorText("Misc"); + ImGui::BulletText("F - toggle mouse/keyboard"); + } + + // todo maybe other function + if (ImGui::CollapsingHeader("Lights")) + { + ImGui::SliderFloat("Linear attenuation", &renderer->scene.linearAtt, 0.014f, 0.7f); + ImGui::SliderFloat("Quadratic attenuation", &renderer->scene.quadraticAtt, 0.0f, 0.5f); + + ImGuiWindowFlags window_flags = ImGuiWindowFlags_None; + + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); + ImGui::BeginChild("ChildR", ImVec2(0, 100), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY, window_flags); + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + if (ImGui::BeginTable("split", 1, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings)) + { + for (int i = 0; i < renderer->scene.lightCount; ++i) + { + ImGui::TableNextColumn(); + + ImGui::SeparatorText(("Light " + std::to_string(i)).c_str()); + { + float border = renderer->scene.worldBorder; + ImGui::PushID(i); + ImGui::DragFloat3("Position", glm::value_ptr(renderer->scene.lightPositions[i]), 0.1f, -border - 5, border + 5); + ImGui::ColorEdit3("Color", glm::value_ptr(renderer->scene.lightColors[i])); + + bool& on = renderer->scene.lightBools[i]; + ImGui::Checkbox(on ? "Turn off" : "Turn on", &on); + } + } + + ImGui::EndTable(); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + } + + if (ImGui::CollapsingHeader("Sphere material")) + { + ImGui::SliderFloat("Diffuse", &renderer->scene.kDiffuse, 0.0f, 1.0f); + ImGui::SliderFloat("Specular", &renderer->scene.kSpecular, 0.0f, 1.0f); + ImGui::SliderFloat("Shininess", &renderer->scene.kShininess, 1.0f, 100.0f); + ImGui::SliderFloat("Ambient", &renderer->scene.kAmbient, 0.0f, 1.0f); + } + + if (ImGui::CollapsingHeader("Environment")) + { + ImGui::ColorEdit3("Sky color", glm::value_ptr(renderer->scene.skyColor)); + ImGui::ColorEdit3("Ambient color", glm::value_ptr(renderer->scene.ambientColor)); + } + + ImGui::End(); + +} \ No newline at end of file diff --git a/camera.cpp b/camera.cpp index 053f30e..2285fc3 100644 --- a/camera.cpp +++ b/camera.cpp @@ -1,10 +1,18 @@ #include "camera.hpp" +#include +#include + #include #include #include -Camera::Camera(int width, int height, float fov, float nearPlane, float farPlane) +Camera::Camera(int width, int height, + std::vector& viewportHorizontalIter, + std::vector& viewportVerticalIter, + float fov, float nearPlane, float farPlane) + : viewportHorizontalIter{ viewportHorizontalIter }, + viewportVerticalIter{ viewportVerticalIter } { viewportWidth = width; viewportHeight = height; @@ -13,11 +21,6 @@ Camera::Camera(int width, int height, float fov, float nearPlane, float farPlane this->nearPlane = nearPlane; this->farPlane = farPlane; - /*this->left = left; - this->right = right; - this->bottom = bottom; - this->top = top;*/ - position = glm::vec3(0.0f, 0.0f, 30.0f); forwardDirection = glm::vec3(0.0f, 0.0f, -1.0f); @@ -43,15 +46,13 @@ void Camera::onResize(int width, int height) delete[] rayDirections; rayDirections = new glm::vec3[width * height]; - //float aspectRatio = (float)width / (float)height; - //bottom = -aspectRatio; - //top = aspectRatio; - calculateProjMatrix(); } -void Camera::onUpdate(int key, float deltaTime) +void Camera::onKeyboardUpdate(int key, float deltaTime) { + float rotationSpeed = speed / 3; + switch (key) { case GLFW_KEY_D: @@ -72,9 +73,22 @@ void Camera::onUpdate(int key, float deltaTime) case GLFW_KEY_W: position += forwardDirection * speed * deltaTime; break; + case GLFW_KEY_Q: + onMouseUpdate(glm::vec2(-rotationSpeed, 0), deltaTime); + break; + case GLFW_KEY_E: + onMouseUpdate(glm::vec2(rotationSpeed, 0), deltaTime); + break; + case GLFW_KEY_1: + onMouseUpdate(glm::vec2(0, rotationSpeed), deltaTime); + break; + case GLFW_KEY_3: + onMouseUpdate(glm::vec2(0, -rotationSpeed), deltaTime); + break; } calculateViewMatrix(); + calculateRayDirections(); } void Camera::onMouseUpdate(glm::vec2 offset, float deltaTime) @@ -88,6 +102,9 @@ void Camera::onMouseUpdate(glm::vec2 offset, float deltaTime) forwardDirection = glm::normalize(glm::rotate(q, forwardDirection)); rightDirection = glm::normalize(glm::cross(forwardDirection, worldUpDirection)); upDirection = glm::normalize(glm::cross(rightDirection, forwardDirection)); + + calculateViewMatrix(); + calculateRayDirections(); } std::vector& Camera::getOrthographicRayOrigins() @@ -102,57 +119,36 @@ glm::vec3* Camera::getRayDirections() void Camera::calculateRayDirections() { - //rayOrigins.resize(viewportWidth * viewportHeight); - //rayDirections.resize(viewportWidth * viewportHeight); - calculateViewMatrix(); - for (int i = 0; i < viewportHeight; ++i) - { - for (int j = 0; j < viewportWidth; ++j) + std::for_each(std::execution::par, viewportVerticalIter.begin(), viewportVerticalIter.end(), + [this](uint32_t i) { - glm::vec2 coord{ - (float)j / viewportWidth, - (float)i / viewportHeight - }; - - coord = coord * 2.0f - 1.0f; - - //glm::vec4 origin = inverseProjMatrix * glm::vec4(coord.x, coord.y, -2.0f, 1.0f); - //glm::vec3 rayOrigin = glm::vec3(inverseViewMatrix * origin);//glm::vec4(glm::normalize(glm::vec3(origin) / origin.w), 1)); - - glm::vec4 target = inverseProjMatrix * glm::vec4(coord.x, coord.y, 1.0f, 1.0f); - glm::vec3 rayDirection = glm::vec3(inverseViewMatrix * glm::vec4(glm::normalize(glm::vec3(target) / target.w), 0)); - //rayDirection = glm::normalize(rayDirection); - - /*rayOrigins[i * viewportWidth + j] = rayOrigin;*/ - rayDirections[i * viewportWidth + j] = rayDirection; - } - } + std::for_each(std::execution::par, viewportHorizontalIter.begin(), viewportHorizontalIter.end(), + [this, i](uint32_t j) + { + glm::vec2 coord{ + (float)j / viewportWidth, + (float)i / viewportHeight + }; + + coord = coord * 2.0f - 1.0f; + + glm::vec4 target = inverseProjMatrix * glm::vec4(coord.x, coord.y, 1.0f, 1.0f); + glm::vec3 rayDirection = glm::vec3(inverseViewMatrix * glm::vec4(glm::normalize(glm::vec3(target) / target.w), 0)); + rayDirections[i * viewportWidth + j] = rayDirection; + }); + }); } void Camera::calculateProjMatrix() { - /*projMatrix = glm::ortho(left, right, bottom, top);*/ projMatrix = glm::perspective(fov, (float)viewportWidth / (float)viewportHeight, nearPlane, farPlane); inverseProjMatrix = glm::inverse(projMatrix); } void Camera::calculateViewMatrix() { - /*viewMatrix = glm::mat4( - glm::vec4(rightDirection, 0.0f), - glm::vec4(upDirection, 0.0f), - glm::vec4(forwardDirection, 0.0f), - glm::vec4(position, 1.0) - );*/ viewMatrix = glm::lookAt(position, position + forwardDirection, worldUpDirection); inverseViewMatrix = glm::inverse(viewMatrix); - - /*inverseViewMatrix = glm::mat4( - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - position.x, position.y, position.z, 1.0f - );*/ } diff --git a/camera.hpp b/camera.hpp index 02b6e8d..0fade52 100644 --- a/camera.hpp +++ b/camera.hpp @@ -7,7 +7,9 @@ class Camera { public: - Camera(int width, int height, float fov = glm::radians(50.0), + Camera(int width, int height, + std::vector&, std::vector&, + float fov = glm::radians(50.0), float nearPlane = 0.01, float farPlane = 100); //float left = -1.0f, float right = 1.0f, float bottom = -1.0f, float top = 1.0f); @@ -16,7 +18,7 @@ class Camera glm::vec3* getRayDirections(); void onResize(int width, int height); - void onUpdate(int key, float deltaTime); + void onKeyboardUpdate(int key, float deltaTime); void onMouseUpdate(glm::vec2 offset, float deltaTime); glm::vec3 position; @@ -33,6 +35,9 @@ class Camera glm::vec3 forwardDirection, rightDirection, upDirection; const glm::vec3 worldUpDirection = glm::vec3(0.0f, 1.0f, 0.0f); + std::vector& viewportHorizontalIter; + std::vector& viewportVerticalIter; + float fov, nearPlane, farPlane; //float left, right, bottom, top; diff --git a/cuda.cu b/cuda.cu index ed85317..61b2869 100644 --- a/cuda.cu +++ b/cuda.cu @@ -148,7 +148,7 @@ __device__ HitPayload traceRayFromHitpoint(Ray& ray, float diff, Scene scene) return closestHit(ray, hitSphereIndex, hitDistance, scene); } -__device__ glm::vec4 phong(HitPayload payload, int lightIndex, Scene scene, glm::vec3 cameraPos) +__device__ glm::vec4 phong(HitPayload payload, int lightIndex, Scene scene, glm::vec3 cameraPos, float d) { glm::vec3 lightDir = glm::normalize(scene.cudaLightPositions[lightIndex] - payload.hitPoint); glm::vec3 lightColor = scene.cudaLightColors[lightIndex]; @@ -161,16 +161,18 @@ __device__ glm::vec4 phong(HitPayload payload, int lightIndex, Scene scene, glm: scene.kDiffuse * cosNL * lightColor + scene.kSpecular * glm::pow(cosVR, scene.kShininess) * lightColor; - color *= scene.cudaSphereAlbedos[payload.objectIndex]; + // todo: factors in a different struct + float attenuation = 1.0;// / (1.0f + scene.linearAtt * d + scene.quadraticAtt * (d * d)); + + color *= attenuation * scene.cudaSphereAlbedos[payload.objectIndex]; - //return glm::vec4(1, 0, 0, 1); return glm::vec4(color, 1.0f); } // todo: scene in shared memory? __device__ glm::vec4 rayGen(int i, int j, glm::vec3 origin, - glm::vec3 direction, Scene scene, glm::vec3 cameraPos) + glm::vec3 direction, Scene scene, bool shadows) { Ray ray; @@ -193,22 +195,28 @@ __device__ glm::vec4 rayGen(int i, int j, glm::vec3 origin, // cast rays from hitpoint to light sources for (int lightIdx = 0; lightIdx < scene.lightCount; lightIdx++) { - // todo: make choice for shadows or no shadows - /* - Ray rayToLight; + if (!scene.cudaLightBools[lightIdx]) + continue; - // cast ray a bit away from the sphere so that the ray doesn't hit it - rayToLight.origin = payload.hitPoint + payload.normal * 1e-4f; - // todo: avoid double calculating length float distanceToLight = glm::length(scene.cudaLightPositions[lightIdx] - payload.hitPoint); - rayToLight.direction = glm::normalize(scene.cudaLightPositions[lightIdx] - payload.hitPoint); - HitPayload payloadToLight = traceRayFromHitpoint(rayToLight, distanceToLight, scene); + if (shadows) + { + Ray rayToLight; + + // cast ray a bit away from the sphere so that the ray doesn't hit it + rayToLight.origin = payload.hitPoint + payload.normal * 1e-3f; + rayToLight.direction = glm::normalize(scene.cudaLightPositions[lightIdx] - payload.hitPoint); + + HitPayload payloadToLight = traceRayFromHitpoint(rayToLight, distanceToLight, scene); + + // no sphere hit on path to light + if (payloadToLight.hitDistance < 0) + color += phong(payload, lightIdx, scene, origin, distanceToLight); + } + else + color += phong(payload, lightIdx, scene, origin, distanceToLight); - // no sphere hit on path to light - if (payloadToLight.hitDistance < 0) - */ - color += phong(payload, lightIdx, scene, cameraPos); } return glm::clamp(color, 0.0f, 1.0f); @@ -223,9 +231,6 @@ __device__ glm::vec3 getRayDirection(int i, int j, cudaArguments args) coord = coord * 2.0f - 1.0f; - //glm::vec4 origin = inverseProjMatrix * glm::vec4(coord.x, coord.y, -2.0f, 1.0f); - //glm::vec3 rayOrigin = glm::vec3(inverseViewMatrix * origin);//glm::vec4(glm::normalize(glm::vec3(origin) / origin.w), 1)); - glm::vec4 target = args.inverseProjMatrix * glm::vec4(coord.x, coord.y, 1.0f, 1.0f); glm::vec3 rayDirection = glm::vec3(args.inverseViewMatrix * glm::vec4(glm::normalize(glm::vec3(target) / target.w), 0)); @@ -242,10 +247,9 @@ __global__ void rayTrace(cudaArguments args) int k = x + y * args.width; - //GLuint res = toRGBA(glm::vec4(0.0f, 0.0f, (float)x / args.width, 1.0f)); - GLuint res = toRGBA(rayGen(y, x, - args.rayOrigin, getRayDirection(y, x, args), args.scene, args.cameraPos)); + args.rayOrigin, getRayDirection(y, x, args), + args.scene, args.shadows)); args.cudaImage[k] = res; } \ No newline at end of file diff --git a/cuda.cuh b/cuda.cuh index b53df87..6a0a113 100644 --- a/cuda.cuh +++ b/cuda.cuh @@ -17,6 +17,7 @@ struct cudaArguments { const glm::vec3 cameraPos; const glm::mat4 inverseProjMatrix; const glm::mat4 inverseViewMatrix; + bool shadows; }; __host__ void callKernels(dim3 blocks_per_grid, dim3 max_threads, diff --git a/imgui.ini b/imgui.ini index dade137..90aa533 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,6 +3,32 @@ Pos=60,-9 Size=400,400 [Window][Menu] -Pos=23,19 -Size=306,682 +Pos=4,20 +Size=276,658 + +[Window][Dear ImGui Demo] +Pos=341,94 +Size=550,680 + +[Window][Dear ImGui Demo/ResizableChild_D5443E47] +IsChild=1 +Size=499,136 + +[Window][Dear ImGui Demo/Red_1D4E05CE] +IsChild=1 +Size=200,100 + +[Window][Menu/ChildR_46923D70] +IsChild=1 +Size=260,419 + +[Table][0xC9935533,3] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 +Column 2 Weight=1.0000 + +[Table][0xE0773582,3] +Column 0 Weight=1.0000 +Column 1 Weight=1.0000 +Column 2 Weight=1.0000 diff --git a/main.cpp b/main.cpp index c063667..66a4991 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,6 @@ __host__ void callKernels(dim3 blocks_per_grid, dim3 max_threads, cudaArguments args) { - // todo: check if callable from renderer because my god rayTrace << > > (args); gpuErrchk(cudaPeekAtLastError()); gpuErrchk(cudaDeviceSynchronize()); diff --git a/pro2.vcxproj b/pro2.vcxproj index ab9ff35..c3fd59e 100644 --- a/pro2.vcxproj +++ b/pro2.vcxproj @@ -115,6 +115,7 @@ + @@ -126,7 +127,6 @@ - diff --git a/renderer.cpp b/renderer.cpp index 0a74353..71c8a85 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -4,9 +4,8 @@ #include #include -Renderer::Renderer(int width, int height, Application* parent) +Renderer::Renderer(int width, int height) { - app = parent; imageData = nullptr; scene.create(); @@ -14,7 +13,7 @@ Renderer::Renderer(int width, int height, Application* parent) gpuErrchk(cudaMalloc(&cudaImage, width * height * sizeof(unsigned int))); gpuErrchk(cudaMalloc(&cudaRayDirections, width * height * sizeof(glm::vec3))); - camera = new Camera(width, height); + camera = new Camera(width, height, viewportHorizontalIter, viewportVerticalIter); resize(width, height); } @@ -46,6 +45,13 @@ void Renderer::resize(int width, int height) gpuErrchk(cudaMalloc(&cudaImage, width * height * sizeof(unsigned int))); gpuErrchk(cudaMalloc(&cudaRayDirections, width * height * sizeof(glm::vec3))); + viewportHorizontalIter.resize(width); + viewportVerticalIter.resize(height); + for (uint32_t i = 0; i < width; i++) + viewportHorizontalIter[i] = i; + for (uint32_t i = 0; i < height; i++) + viewportVerticalIter[i] = i; + camera->onResize(width, height); } @@ -54,7 +60,6 @@ void Renderer::update(float deltaTime) static float time = glfwGetTime(); scene.lightPositions[0] = glm::vec3( - //(glfwGetTime() - time), 0.0f, 0.0f 2.5f * glm::sin(glfwGetTime()), 2.5f * glm::cos(glfwGetTime()), 1.5f * glm::sin(glfwGetTime()) @@ -63,33 +68,18 @@ void Renderer::update(float deltaTime) void Renderer::renderCPU() { - // todo: cache the ray directions - camera->calculateRayDirections(); - - // todo: don't resize each time - std::vector horizontalIter; - std::vector verticalIter; - - horizontalIter.resize(width); - verticalIter.resize(height); - for (uint32_t i = 0; i < width; i++) - horizontalIter[i] = i; - for (uint32_t i = 0; i < height; i++) - verticalIter[i] = i; - - std::for_each(std::execution::par, verticalIter.begin(), verticalIter.end(), - [this, horizontalIter](uint32_t i) + std::for_each(std::execution::par, viewportVerticalIter.begin(), viewportVerticalIter.end(), + [this](uint32_t i) { - std::for_each(std::execution::par, horizontalIter.begin(), horizontalIter.end(), + std::for_each(std::execution::par, viewportHorizontalIter.begin(), viewportHorizontalIter.end(), [this, i](uint32_t j) { imageData[i * width + j] = toRGBA(rayGen(i, j)); }); }); - } -void Renderer::renderGPU() +void Renderer::renderGPU(bool shadows) { int pixelsCount = width * height; int size = pixelsCount * sizeof(unsigned int); @@ -101,18 +91,14 @@ void Renderer::renderGPU() dim3 blocks(width / tx + 1, height / ty + 1); dim3 threads(tx, ty); - // todo: temp - cuda probably should calculate ray directions - gpuErrchk(cudaMemcpy(cudaRayDirections, - camera->getRayDirections(), - vecSize, cudaMemcpyHostToDevice)); - cudaArguments args{ cudaImage, width, height, scene, camera->getRayOrigin(), cudaRayDirections, camera->getRayOrigin(), camera->getInverseProjMatrix(), - camera->getInverseViewMatrix() + camera->getInverseViewMatrix(), + shadows }; callKernels(blocks, threads, args); @@ -128,8 +114,7 @@ GLuint* Renderer::getImage() glm::vec4 Renderer::rayGen(int i, int j) { Ray ray; - - ray.origin = camera->getRayOrigin(); //camera->getOrthographicRayOrigins()[i * width + j]; + ray.origin = camera->getRayOrigin(); ray.direction = camera->getRayDirections()[i * width + j]; HitPayload payload = traceRayFromPixel(ray); @@ -148,11 +133,13 @@ glm::vec4 Renderer::rayGen(int i, int j) // cast rays from hitpoint to light sources for (int lightIdx = 0; lightIdx < scene.lightCount; lightIdx++) { + if (!scene.lightBools[lightIdx]) + continue; + Ray rayToLight; // cast ray a bit away from the sphere so that the ray doesn't hit it rayToLight.origin = payload.hitPoint + payload.normal * 1e-4f; - // todo: double calculated length float distanceToLight = glm::length(scene.lightPositions[lightIdx] - payload.hitPoint); rayToLight.direction = glm::normalize(scene.lightPositions[lightIdx] - payload.hitPoint); @@ -224,7 +211,7 @@ HitPayload Renderer::traceRayFromPixel(const Ray& ray) float a = glm::dot(direction, direction); float b = 2.0f * glm::dot(origin, direction); float c = glm::dot(origin, origin) - - 0.1f * 0.1f; + - scene.lightRadius * scene.lightRadius; float delta = b * b - 4.0f * a * c; if (delta < 0) @@ -317,7 +304,7 @@ HitPayload Renderer::closestHit(const Ray& ray, int sphereIndex, float hitDistan void Renderer::processKeyboard(int key, float deltaTime) { - camera->onUpdate(key, deltaTime); + camera->onKeyboardUpdate(key, deltaTime); } void Renderer::processMouse(glm::vec2 offset, float deltaTime) diff --git a/renderer.hpp b/renderer.hpp index fae2d93..53143f3 100644 --- a/renderer.hpp +++ b/renderer.hpp @@ -9,7 +9,7 @@ struct Scene; class Renderer { public: - Renderer(int width, int height, Application *parent); + Renderer(int width, int height); ~Renderer(); void resize(int width, int height); @@ -19,17 +19,18 @@ class Renderer // todo: this should be another class's responsibility void update(float deltaTime); void renderCPU(); - void renderGPU(); + void renderGPU(bool shadows); GLuint* getImage(); int width, height; Scene scene; private: - Application* app; Camera* camera; - unsigned int* imageData; + std::vector viewportHorizontalIter; + std::vector viewportVerticalIter; + unsigned int* imageData; unsigned int* cudaImage; glm::vec3* cudaRayDirections; diff --git a/scene.cpp b/scene.cpp deleted file mode 100644 index 8fafebe..0000000 --- a/scene.cpp +++ /dev/null @@ -1,12 +0,0 @@ -//#include "scene.hpp" - -// todo: why not constructor? -//void Scene::create() -//{ -// -//} -// -//// it can't be a destructor, because it would be undefined in device code -//void Scene::free() { -// -//} \ No newline at end of file diff --git a/scene.hpp b/scene.hpp index bfb13c5..afcaa75 100644 --- a/scene.hpp +++ b/scene.hpp @@ -4,35 +4,16 @@ #include #include +#include +#include #ifndef GPU_ERRCHK #define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } #endif -struct Sphere +class Scene { - glm::vec3 center; - float radius; - glm::vec3 albedo; -}; - -struct Light -{ - glm::vec3 position; - //const float radius = 0.2f; - glm::vec3 color; -}; - -struct Scene -{ - // todo: sliders for each light, sliders for material parameters - // todo: selectable sphere colors? :D - - //std::vector spheres; - //std::vector lights; - - // todo: those pointers are const - +public: glm::vec3* spherePositions; glm::vec3* sphereAlbedos; float* sphereRadii; @@ -40,6 +21,7 @@ struct Scene glm::vec3* lightPositions; glm::vec3* lightColors; const float lightRadius = 0.2f; + bool* lightBools; // todo: idk, dry, maybe do sth like SceneGPU and SceneCPU? glm::vec3* cudaSpherePositions; @@ -48,22 +30,26 @@ struct Scene glm::vec3* cudaLightPositions; glm::vec3* cudaLightColors; + bool* cudaLightBools; - const int sphereCount = 300; + const int sphereCount = 1000; const int lightCount = 10; glm::vec3 ambientColor{ 1.0f, 1.0f, 1.0f }; glm::vec3 skyColor{ - 0.0f, 0.0f, 0.0f }; + 0.25f, 0.25f, 0.25f }; float kDiffuse = 0.9f; float kSpecular = 0.4f; float kAmbient = 0.2f; float kShininess = 40; - const float worldBorder = -20; + float linearAtt = 0.0f; + float quadraticAtt = 0.032f; + + const float worldBorder = 30; void create() { @@ -82,6 +68,12 @@ struct Scene colorPalette.push_back(glm::vec3(187.0f / 255.0f, 62.0f / 255.0f, 3.0f / 255.0f)); colorPalette.push_back(glm::vec3(174.0f / 255.0f, 32.0f / 255.0f, 18.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(128.0f / 255.0f, 93.0f / 255.0f, 147.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(244.0f / 255.0f, 159.0f / 255.0f, 188.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(255.0f / 255.0f, 211.0f / 255.0f, 186.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(158.0f / 255.0f, 189.0f / 255.0f, 110.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(22.0f / 255.0f, 152.0f / 255.0f, 115.0f / 255.0f)); + lightColorPalette.push_back(glm::vec3(1.0f, 1.0f, 1.0f)); lightColorPalette.push_back(glm::vec3(1.0f, 0.0f, 0.0f)); lightColorPalette.push_back(glm::vec3(0.0f, 1.0f, 0.0f)); @@ -100,43 +92,48 @@ struct Scene lightPositions = new glm::vec3[lightCount]; lightColors = new glm::vec3[lightCount]; + lightBools = new bool[lightCount]; - //srand(time(NULL)); + srand(time(NULL)); for (int i = 0; i < sphereCount; i++) { - spherePositions[i] = glm::vec3( - ((float)rand() / RAND_MAX) * worldBorder * 2 - worldBorder, - ((float)rand() / RAND_MAX) * worldBorder * 2 - worldBorder, - ((float)rand() / RAND_MAX) * worldBorder * 2 - worldBorder); + // generate uniformly distributed points in a ball + glm::vec3 direction = glm::normalize(glm::gaussRand(glm::vec3(0.0f), glm::vec3(1.0f))); + float radius = glm::pow(glm::linearRand(0.0f, 1.0f), 1.0f / 3.0f) * worldBorder; + spherePositions[i] = radius * direction; sphereRadii[i] = 0.2f * (i % 5 + 1); sphereAlbedos[i] = colorPalette[i % colorPalette.size()]; } for (int i = 0; i < lightCount; i++) { - lightPositions[i] = glm::vec3( - ((float)rand() / RAND_MAX) * worldBorder * 5 + worldBorder, - ((float)rand() / RAND_MAX) * worldBorder * 5 + worldBorder, - ((float)rand() / RAND_MAX) * worldBorder * 5 + worldBorder); + glm::vec3 direction = glm::normalize(glm::gaussRand(glm::vec3(0.0f), glm::vec3(1.0f))); + float radius = glm::pow(glm::linearRand(0.0f, 1.0f), 1.0f / 3.0f) * worldBorder; + lightPositions[i] = radius * direction; lightColors[i] = lightColorPalette[i % lightColorPalette.size()]; + lightBools[i] = false; } size_t sphereVec3ArrSize = sphereCount * sizeof(glm::vec3); size_t sphereFloatArrSize = sphereCount * sizeof(float); size_t lightVec3ArrSize = lightCount * sizeof(glm::vec3); + size_t lightBoolArrSize = lightCount * sizeof(bool); gpuErrchk(cudaMalloc(&cudaSpherePositions, sphereVec3ArrSize)); gpuErrchk(cudaMalloc(&cudaSphereAlbedos, sphereVec3ArrSize)); gpuErrchk(cudaMalloc(&cudaSphereRadii, sphereFloatArrSize)); gpuErrchk(cudaMalloc(&cudaLightPositions, lightVec3ArrSize)); gpuErrchk(cudaMalloc(&cudaLightColors, lightVec3ArrSize)); + gpuErrchk(cudaMalloc(&cudaLightBools, lightBoolArrSize)); gpuErrchk(cudaMemcpy(cudaSpherePositions, spherePositions, sphereVec3ArrSize, cudaMemcpyHostToDevice)); gpuErrchk(cudaMemcpy(cudaSphereAlbedos, sphereAlbedos, sphereVec3ArrSize, cudaMemcpyHostToDevice)); gpuErrchk(cudaMemcpy(cudaSphereRadii, sphereRadii, sphereFloatArrSize, cudaMemcpyHostToDevice)); gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightVec3ArrSize, cudaMemcpyHostToDevice)); gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightBoolArrSize, cudaMemcpyHostToDevice)); } + void free() { delete[] spherePositions; @@ -144,13 +141,24 @@ struct Scene delete[] sphereAlbedos; delete[] lightPositions; delete[] lightColors; + delete[] lightBools; gpuErrchk(cudaFree(cudaSpherePositions)); gpuErrchk(cudaFree(cudaSphereAlbedos)); gpuErrchk(cudaFree(cudaSphereRadii)); gpuErrchk(cudaFree(cudaLightPositions)); gpuErrchk(cudaFree(cudaLightColors)); + gpuErrchk(cudaFree(cudaLightBools)); } + void updateCuda() + { + size_t lightVec3ArrSize = lightCount * sizeof(glm::vec3); + size_t lightBoolArrSize = lightCount * sizeof(bool); + + gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightBoolArrSize, cudaMemcpyHostToDevice)); + } }; \ No newline at end of file diff --git a/window.cpp b/window.cpp index 13d3406..664488f 100644 --- a/window.cpp +++ b/window.cpp @@ -7,8 +7,8 @@ Window::Window(Application *parent) width = Application::WIDTH; height = Application::HEIGHT; - lastX = width / 2; - lastY = height / 2; + lastX = (float)width / 2; + lastY = (float)height / 2; glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); @@ -44,11 +44,6 @@ Window::Window(Application *parent) ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - ImGui_ImplGlfw_InitForOpenGL(wndptr, true); - ImGui_ImplOpenGL3_Init(); - - //glEnable(GL_MULTISAMPLE); - glfwSetWindowUserPointer(wndptr, this); glfwSetFramebufferSizeCallback(wndptr, [](GLFWwindow* window, int width, int height) @@ -62,28 +57,31 @@ Window::Window(Application *parent) glViewport(0, 0, width, height); }); - //glfwSetCursorPosCallback(wndptr, - // [](GLFWwindow* window, double xposIn, double yposIn) - // { - // Window& wnd = *(Window*)glfwGetWindowUserPointer(window); + glfwSetCursorPosCallback(wndptr, + [](GLFWwindow* window, double xposIn, double yposIn) + { + Window& wnd = *(Window*)glfwGetWindowUserPointer(window); + + float xpos = static_cast(xposIn); + float ypos = static_cast(yposIn); - // float xpos = static_cast(xposIn); - // float ypos = static_cast(yposIn); + if (wnd.firstMouse) + { + wnd.lastX = xpos; + wnd.lastY = ypos; + wnd.firstMouse = false; + } - // if (wnd.firstMouse) - // { - // wnd.lastX = xpos; - // wnd.lastY = ypos; - // wnd.firstMouse = false; - // } + float xoffset = xpos - wnd.lastX; + float yoffset = wnd.lastY - ypos; // reversed since y-coordinates go from bottom to top + wnd.lastX = xpos; + wnd.lastY = ypos; - // float xoffset = xpos - wnd.lastX; - // float yoffset = wnd.lastY - ypos; // reversed since y-coordinates go from bottom to top - // wnd.lastX = xpos; - // wnd.lastY = ypos; + wnd.app->processMouse(glm::vec2(xoffset, yoffset)); + }); - // wnd.app->processMouse(glm::vec2(xoffset, yoffset)); - // }); + ImGui_ImplGlfw_InitForOpenGL(wndptr, true); + ImGui_ImplOpenGL3_Init(); } From 582b7d686a945a48b38b499bdd0da898b8fb6494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82upczy=C5=84ski?= Date: Thu, 18 Jan 2024 12:46:54 +0100 Subject: [PATCH 3/7] Minor refactoring changes again --- application.cpp | 38 ++++++- application.hpp | 2 +- application_imgui.cpp | 114 -------------------- camera.cpp | 12 +-- camera.hpp | 5 +- cuda.cu | 20 ++-- cuda.cuh | 8 +- framework.hpp | 15 +-- imgui.ini | 8 +- main.cpp | 3 +- pro2.vcxproj | 3 +- pro2.vcxproj.filters | 3 - renderer.cpp | 48 +++++---- renderer.hpp | 15 ++- scene.cpp | 234 ++++++++++++++++++++++++++++++++++++++++++ scene.hpp | 163 ++++++----------------------- utils.hpp | 4 - window.hpp | 2 +- 18 files changed, 361 insertions(+), 336 deletions(-) delete mode 100644 application_imgui.cpp create mode 100644 scene.cpp delete mode 100644 utils.hpp diff --git a/application.cpp b/application.cpp index 6e2b7c7..159998b 100644 --- a/application.cpp +++ b/application.cpp @@ -1,4 +1,7 @@ #include "application.hpp" +#include "window.hpp" +#include "shader.hpp" +#include "renderer.hpp" Application::Application() { @@ -62,9 +65,40 @@ void Application::run() glfwSwapBuffers(window->wndptr); glfwPollEvents(); + } +} + +void Application::imGuiFrame(int fps) +{ + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); - //while (true); + if (!ImGui::Begin("Menu", NULL, 0)) + { + ImGui::End(); + return; } + + ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.45f); + + static const char* items[] = { "CPU no shadows", + "GPU no shadows", + "GPU shadows" }; + static int selectedItem = 1; + + if (ImGui::Combo("Solution", &selectedItem, items, IM_ARRAYSIZE(items))) + { + solutionMode = (solutionModes)selectedItem; + renderer->notifyCamera(); + } + + ImGui::Text("%d fps", fps); + + renderer->scene.drawImGui(); + + ImGui::End(); + } void Application::resize(int width, int height) @@ -128,7 +162,7 @@ void Application::createTexture() void Application::updateAndRenderScene() { - renderer->update(deltaTime); + renderer->scene.updateScene(deltaTime); if (solutionMode == CPU) renderer->renderCPU(); diff --git a/application.hpp b/application.hpp index 92928e5..2870607 100644 --- a/application.hpp +++ b/application.hpp @@ -12,7 +12,7 @@ class Application Application(); ~Application(); - constexpr static int WIDTH = 800; + constexpr static int WIDTH = 1200; constexpr static int HEIGHT = 800; void run(); diff --git a/application_imgui.cpp b/application_imgui.cpp deleted file mode 100644 index d673423..0000000 --- a/application_imgui.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "application.hpp" - -#include - -void Application::imGuiFrame(int fps) -{ - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - //ImGui::ShowDemoWindow(); - if (!ImGui::Begin("Menu", NULL, 0)) - { - ImGui::End(); - return; - } - - ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.45f); - - static const char* items[] = { "CPU", "GPU", "GPU shadows" }; - static int selectedItem = 1; - - if (ImGui::Combo("Solution", &selectedItem, items, IM_ARRAYSIZE(items))) - { - solutionMode = (solutionModes)selectedItem; - } - - ImGui::Text("%d fps", fps); - - if (ImGui::CollapsingHeader("Information")) - { - ImGui::Text("Number of spheres: %d", renderer->scene.sphereCount); - ImGui::Text("Number of light sources: %d", renderer->scene.lightCount); - } - - if (ImGui::CollapsingHeader("Camera controls")) - { - ImGui::SeparatorText("Position"); - ImGui::BulletText("W - forward"); - ImGui::BulletText("S - backward"); - ImGui::BulletText("A - left"); - ImGui::BulletText("R - right"); - ImGui::BulletText("Space - up"); - ImGui::BulletText("LShift - down"); - - ImGui::SeparatorText("Angles"); - ImGui::BulletText("Q - look left"); - ImGui::BulletText("E - look right"); - ImGui::BulletText("1 - look up"); - ImGui::BulletText("3 - look down"); - - ImGui::SeparatorText("Misc"); - ImGui::BulletText("F - toggle mouse/keyboard"); - } - - // todo maybe other function - if (ImGui::CollapsingHeader("Lights")) - { - ImGui::SliderFloat("Linear attenuation", &renderer->scene.linearAtt, 0.014f, 0.7f); - ImGui::SliderFloat("Quadratic attenuation", &renderer->scene.quadraticAtt, 0.0f, 0.5f); - - ImGuiWindowFlags window_flags = ImGuiWindowFlags_None; - - ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); - ImGui::BeginChild("ChildR", ImVec2(0, 100), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY, window_flags); - if (ImGui::BeginMenuBar()) - { - if (ImGui::BeginMenu("Menu")) - { - ImGui::EndMenu(); - } - ImGui::EndMenuBar(); - } - if (ImGui::BeginTable("split", 1, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings)) - { - for (int i = 0; i < renderer->scene.lightCount; ++i) - { - ImGui::TableNextColumn(); - - ImGui::SeparatorText(("Light " + std::to_string(i)).c_str()); - { - float border = renderer->scene.worldBorder; - ImGui::PushID(i); - ImGui::DragFloat3("Position", glm::value_ptr(renderer->scene.lightPositions[i]), 0.1f, -border - 5, border + 5); - ImGui::ColorEdit3("Color", glm::value_ptr(renderer->scene.lightColors[i])); - - bool& on = renderer->scene.lightBools[i]; - ImGui::Checkbox(on ? "Turn off" : "Turn on", &on); - } - } - - ImGui::EndTable(); - } - ImGui::EndChild(); - ImGui::PopStyleVar(); - } - - if (ImGui::CollapsingHeader("Sphere material")) - { - ImGui::SliderFloat("Diffuse", &renderer->scene.kDiffuse, 0.0f, 1.0f); - ImGui::SliderFloat("Specular", &renderer->scene.kSpecular, 0.0f, 1.0f); - ImGui::SliderFloat("Shininess", &renderer->scene.kShininess, 1.0f, 100.0f); - ImGui::SliderFloat("Ambient", &renderer->scene.kAmbient, 0.0f, 1.0f); - } - - if (ImGui::CollapsingHeader("Environment")) - { - ImGui::ColorEdit3("Sky color", glm::value_ptr(renderer->scene.skyColor)); - ImGui::ColorEdit3("Ambient color", glm::value_ptr(renderer->scene.ambientColor)); - } - - ImGui::End(); - -} \ No newline at end of file diff --git a/camera.cpp b/camera.cpp index 2285fc3..a0df023 100644 --- a/camera.cpp +++ b/camera.cpp @@ -10,6 +10,7 @@ Camera::Camera(int width, int height, std::vector& viewportHorizontalIter, std::vector& viewportVerticalIter, + glm::vec3 position, float fov, float nearPlane, float farPlane) : viewportHorizontalIter{ viewportHorizontalIter }, viewportVerticalIter{ viewportVerticalIter } @@ -20,8 +21,7 @@ Camera::Camera(int width, int height, this->fov = fov; this->nearPlane = nearPlane; this->farPlane = farPlane; - - position = glm::vec3(0.0f, 0.0f, 30.0f); + this->position = position; forwardDirection = glm::vec3(0.0f, 0.0f, -1.0f); rightDirection = glm::normalize(glm::cross(forwardDirection, worldUpDirection)); @@ -29,9 +29,6 @@ Camera::Camera(int width, int height, rayDirections = new glm::vec3[width * height]; - calculateProjMatrix(); - calculateViewMatrix(); - calculateRayDirections(); } @@ -46,7 +43,7 @@ void Camera::onResize(int width, int height) delete[] rayDirections; rayDirections = new glm::vec3[width * height]; - calculateProjMatrix(); + calculateRayDirections(); } void Camera::onKeyboardUpdate(int key, float deltaTime) @@ -87,7 +84,6 @@ void Camera::onKeyboardUpdate(int key, float deltaTime) break; } - calculateViewMatrix(); calculateRayDirections(); } @@ -103,7 +99,6 @@ void Camera::onMouseUpdate(glm::vec2 offset, float deltaTime) rightDirection = glm::normalize(glm::cross(forwardDirection, worldUpDirection)); upDirection = glm::normalize(glm::cross(rightDirection, forwardDirection)); - calculateViewMatrix(); calculateRayDirections(); } @@ -119,6 +114,7 @@ glm::vec3* Camera::getRayDirections() void Camera::calculateRayDirections() { + calculateProjMatrix(); calculateViewMatrix(); std::for_each(std::execution::par, viewportVerticalIter.begin(), viewportVerticalIter.end(), diff --git a/camera.hpp b/camera.hpp index 0fade52..dafbe48 100644 --- a/camera.hpp +++ b/camera.hpp @@ -9,9 +9,10 @@ class Camera public: Camera(int width, int height, std::vector&, std::vector&, + glm::vec3 position = glm::vec3(-10.0f, 0.0f, 60.0f), float fov = glm::radians(50.0), - float nearPlane = 0.01, float farPlane = 100); - //float left = -1.0f, float right = 1.0f, float bottom = -1.0f, float top = 1.0f); + float nearPlane = 0.01, + float farPlane = 100); std::vector& getOrthographicRayOrigins(); glm::vec3& getRayOrigin() { return position; } diff --git a/cuda.cu b/cuda.cu index 61b2869..407ae48 100644 --- a/cuda.cu +++ b/cuda.cu @@ -46,7 +46,6 @@ __device__ HitPayload closestHit(const Ray& ray, int sphereIndex, float hitDista return payload; } -// todo: merge rayTrace functions __device__ HitPayload traceRayFromPixel(const Ray& ray, Scene scene) { int hitSphereIndex = -1; @@ -80,6 +79,9 @@ __device__ HitPayload traceRayFromPixel(const Ray& ray, Scene scene) for (int k = 0; k < scene.lightCount; k++) { + if (!scene.cudaLightBools[k]) + continue; + glm::vec3 origin = ray.origin - scene.cudaLightPositions[k]; glm::vec3 direction = ray.direction; @@ -158,19 +160,15 @@ __device__ glm::vec4 phong(HitPayload payload, int lightIndex, Scene scene, glm: float cosVR = glm::max(0.0f, glm::dot(reflectionVector, eyeVector)); glm::vec3 color = - scene.kDiffuse * cosNL * lightColor + - scene.kSpecular * glm::pow(cosVR, scene.kShininess) * lightColor; - - // todo: factors in a different struct - float attenuation = 1.0;// / (1.0f + scene.linearAtt * d + scene.quadraticAtt * (d * d)); - + scene.params.kDiffuse * cosNL * lightColor + + scene.params.kSpecular * glm::pow(cosVR, scene.params.kShininess) * lightColor; + + float attenuation = 1.0f / (1.0f + d * (scene.params.linearAtt + scene.params.quadraticAtt * d)); color *= attenuation * scene.cudaSphereAlbedos[payload.objectIndex]; - return glm::vec4(color, 1.0f); } -// todo: scene in shared memory? __device__ glm::vec4 rayGen(int i, int j, glm::vec3 origin, glm::vec3 direction, Scene scene, bool shadows) { @@ -184,13 +182,13 @@ __device__ glm::vec4 rayGen(int i, int j, glm::vec3 origin, // no sphere detected if (payload.hitDistance < 0) - return glm::vec4(scene.skyColor, 1.0f); + return glm::vec4(scene.params.skyColor, 1.0f); // light source hit if (payload.hitDistance == 0) return glm::vec4(scene.cudaLightColors[idx], 1.0f); - glm::vec4 color = glm::vec4(scene.kAmbient * scene.ambientColor * scene.cudaSphereAlbedos[idx], 1.0f); + glm::vec4 color = glm::vec4(scene.params.kAmbient * scene.params.ambientColor * scene.cudaSphereAlbedos[idx], 1.0f); // cast rays from hitpoint to light sources for (int lightIdx = 0; lightIdx < scene.lightCount; lightIdx++) diff --git a/cuda.cuh b/cuda.cuh index 6a0a113..dbf603b 100644 --- a/cuda.cuh +++ b/cuda.cuh @@ -1,17 +1,14 @@ -#ifndef _CUDA_CUH -#define _CUDA_CUH +#pragma once #include "framework.hpp" #include "scene.hpp" #include -//struct Scene; - struct cudaArguments { unsigned int* cudaImage; const int width; const int height; - const struct Scene scene; + const class Scene scene; const glm::vec3 rayOrigin; const glm::vec3* rayDirections; const glm::vec3 cameraPos; @@ -25,4 +22,3 @@ __host__ void callKernels(dim3 blocks_per_grid, dim3 max_threads, __global__ void rayTrace(cudaArguments args); -#endif \ No newline at end of file diff --git a/framework.hpp b/framework.hpp index 264de4f..812f95a 100644 --- a/framework.hpp +++ b/framework.hpp @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -20,6 +19,7 @@ #include "ImGUI/imgui_impl_opengl3.h" #ifndef GPU_ERRCHK +#define GPU_ERRCHK #define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } #endif @@ -32,16 +32,5 @@ inline void gpuAssert(cudaError_t code, const char* file, int line, bool abort = } } -#include "utils.hpp" #include "ray.hpp" -#include "scene.hpp" - - -#include "cuda.cuh" -#include "camera.hpp" -#include "shader.hpp" -#include "renderer.hpp" -#include "window.hpp" -#include "application.hpp" - - +#include "scene.hpp" \ No newline at end of file diff --git a/imgui.ini b/imgui.ini index 90aa533..3fc9af7 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,11 +3,11 @@ Pos=60,-9 Size=400,400 [Window][Menu] -Pos=4,20 -Size=276,658 +Pos=-7,17 +Size=276,693 [Window][Dear ImGui Demo] -Pos=341,94 +Pos=329,142 Size=550,680 [Window][Dear ImGui Demo/ResizableChild_D5443E47] @@ -20,7 +20,7 @@ Size=200,100 [Window][Menu/ChildR_46923D70] IsChild=1 -Size=260,419 +Size=260,243 [Table][0xC9935533,3] Column 0 Weight=1.0000 diff --git a/main.cpp b/main.cpp index 66a4991..d32972f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ #include "framework.hpp" -//#include "cuda.cuh" +#include "application.hpp" +#include "cuda.cuh" __host__ void callKernels(dim3 blocks_per_grid, dim3 max_threads, cudaArguments args) { diff --git a/pro2.vcxproj b/pro2.vcxproj index c3fd59e..149a652 100644 --- a/pro2.vcxproj +++ b/pro2.vcxproj @@ -110,12 +110,10 @@ - - @@ -127,6 +125,7 @@ + diff --git a/pro2.vcxproj.filters b/pro2.vcxproj.filters index 1d9c41e..9089edb 100644 --- a/pro2.vcxproj.filters +++ b/pro2.vcxproj.filters @@ -63,9 +63,6 @@ Headers - - Headers - Headers diff --git a/renderer.cpp b/renderer.cpp index 71c8a85..8a1b65c 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -1,4 +1,5 @@ #include "renderer.hpp" +#include "cuda.cuh" #include #include @@ -55,15 +56,9 @@ void Renderer::resize(int width, int height) camera->onResize(width, height); } -void Renderer::update(float deltaTime) +void Renderer::notifyCamera() { - static float time = glfwGetTime(); - - scene.lightPositions[0] = glm::vec3( - 2.5f * glm::sin(glfwGetTime()), - 2.5f * glm::cos(glfwGetTime()), - 1.5f * glm::sin(glfwGetTime()) - ); + camera->calculateRayDirections(); } void Renderer::renderCPU() @@ -122,38 +117,40 @@ glm::vec4 Renderer::rayGen(int i, int j) // no sphere detected if (payload.hitDistance < 0) - return glm::vec4(scene.skyColor, 1.0f); + return glm::vec4(scene.params.skyColor, 1.0f); // light source hit if (payload.hitDistance == 0) return glm::vec4(scene.lightColors[idx], 1.0f); - glm::vec4 color = glm::vec4(scene.kAmbient * scene.ambientColor * scene.sphereAlbedos[idx], 1.0f); + glm::vec4 color = glm::vec4(scene.params.kAmbient + * scene.params.ambientColor + * scene.sphereAlbedos[idx], 1.0f); // cast rays from hitpoint to light sources for (int lightIdx = 0; lightIdx < scene.lightCount; lightIdx++) { - if (!scene.lightBools[lightIdx]) - continue; + float distanceToLight = glm::length(scene.lightPositions[lightIdx] - payload.hitPoint); + //if (!scene.lightBools[lightIdx]) + // continue; - Ray rayToLight; + //Ray rayToLight; - // cast ray a bit away from the sphere so that the ray doesn't hit it - rayToLight.origin = payload.hitPoint + payload.normal * 1e-4f; - float distanceToLight = glm::length(scene.lightPositions[lightIdx] - payload.hitPoint); - rayToLight.direction = glm::normalize(scene.lightPositions[lightIdx] - payload.hitPoint); + //// cast ray a bit away from the sphere so that the ray doesn't hit it + //rayToLight.origin = payload.hitPoint + payload.normal * 1e-4f; + //rayToLight.direction = glm::normalize(scene.lightPositions[lightIdx] - payload.hitPoint); - HitPayload payloadToLight = traceRayFromHitpoint(rayToLight, distanceToLight); + //HitPayload payloadToLight = traceRayFromHitpoint(rayToLight, distanceToLight); - // no sphere hit on path to light - if (payloadToLight.hitDistance < 0) - color += phong(payload, lightIdx); + //// no sphere hit on path to light + //if (payloadToLight.hitDistance < 0) + color += phong(payload, lightIdx, distanceToLight); } return glm::clamp(color, 0.0f, 1.0f); } -glm::vec4 Renderer::phong(HitPayload payload, int lightIndex) +glm::vec4 Renderer::phong(HitPayload payload, int lightIndex, float d) { glm::vec3 lightDir = glm::normalize(scene.lightPositions[lightIndex] - payload.hitPoint); glm::vec3 lightColor = scene.lightColors[lightIndex]; @@ -163,10 +160,11 @@ glm::vec4 Renderer::phong(HitPayload payload, int lightIndex) float cosVR = glm::max(0.0f, glm::dot(reflectionVector, eyeVector)); glm::vec3 color = - scene.kDiffuse * cosNL * lightColor + - scene.kSpecular * glm::pow(cosVR, scene.kShininess) * lightColor; + scene.params.kDiffuse * cosNL * lightColor + + scene.params.kSpecular * glm::pow(cosVR, scene.params.kShininess) * lightColor; - color *= scene.sphereAlbedos[payload.objectIndex]; + float attenuation = 1.0f / (1.0f + d * (scene.params.linearAtt + scene.params.quadraticAtt * d)); + color *= attenuation * scene.sphereAlbedos[payload.objectIndex]; return glm::vec4(color, 1.0f); } diff --git a/renderer.hpp b/renderer.hpp index 53143f3..9fcd323 100644 --- a/renderer.hpp +++ b/renderer.hpp @@ -1,10 +1,7 @@ #pragma once -#include "framework.hpp" - -class Application; -class Camera; -struct Scene; +#include "application.hpp" +#include "camera.hpp" class Renderer { @@ -16,8 +13,7 @@ class Renderer void processKeyboard(int key, float dTime); void processMouse(glm::vec2 offset, float dTime); - // todo: this should be another class's responsibility - void update(float deltaTime); + void notifyCamera(); void renderCPU(); void renderGPU(bool shadows); GLuint* getImage(); @@ -35,14 +31,15 @@ class Renderer glm::vec3* cudaRayDirections; glm::vec4 rayGen(int i, int j); - // cast a ray and get hit information + + // casts a ray and gets hit information HitPayload traceRayFromPixel(const Ray& ray); HitPayload traceRayFromHitpoint(const Ray& ray, float diff); HitPayload lightHit(const Ray& ray, int lightIndex); HitPayload closestHit(const Ray& ray, int sphereIndex, float hitDistance); HitPayload miss(const Ray& ray); + glm::vec4 phong(HitPayload payload, int lightIndex, float d); - glm::vec4 phong(HitPayload payload, int lightIndex); unsigned int toRGBA(glm::vec4&); }; \ No newline at end of file diff --git a/scene.cpp b/scene.cpp new file mode 100644 index 0000000..2fa7db9 --- /dev/null +++ b/scene.cpp @@ -0,0 +1,234 @@ +#include "scene.hpp" + + +void Scene::create() +{ + static std::vector colorPalette; + static std::vector lightColorPalette; + { + //colorPalette.push_back(glm::vec3(1,1,1)); + colorPalette.push_back(glm::vec3(155.0f / 255.0f, 34.0f / 255.0f, 38.0f / 255.0f)); + colorPalette.push_back(glm::vec3(0.0f / 255.0f, 18.0f / 255.0f, 25.0f / 255.0f)); + colorPalette.push_back(glm::vec3(0.0f / 255.0f, 95.0f / 255.0f, 115.0f / 255.0f)); + colorPalette.push_back(glm::vec3(10.0f / 255.0f, 147.0f / 255.0f, 150.0f / 255.0f)); + colorPalette.push_back(glm::vec3(148.0f / 255.0f, 210.0f / 255.0f, 189.0f / 255.0f)); + colorPalette.push_back(glm::vec3(233.0f / 255.0f, 216.0f / 255.0f, 166.0f / 255.0f)); + colorPalette.push_back(glm::vec3(238.0f / 255.0f, 155.0f / 255.0f, 0.0f / 255.0f)); + colorPalette.push_back(glm::vec3(202.0f / 255.0f, 103.0f / 255.0f, 2.0f / 255.0f)); + colorPalette.push_back(glm::vec3(187.0f / 255.0f, 62.0f / 255.0f, 3.0f / 255.0f)); + colorPalette.push_back(glm::vec3(174.0f / 255.0f, 32.0f / 255.0f, 18.0f / 255.0f)); + + //colorPalette.push_back(glm::vec3(128.0f / 255.0f, 93.0f / 255.0f, 147.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(244.0f / 255.0f, 159.0f / 255.0f, 188.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(255.0f / 255.0f, 211.0f / 255.0f, 186.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(158.0f / 255.0f, 189.0f / 255.0f, 110.0f / 255.0f)); + //colorPalette.push_back(glm::vec3(22.0f / 255.0f, 152.0f / 255.0f, 115.0f / 255.0f)); + + lightColorPalette.push_back(glm::vec3(1.0f, 1.0f, 1.0f)); + lightColorPalette.push_back(glm::vec3(1.0f, 0.0f, 0.0f)); + lightColorPalette.push_back(glm::vec3(0.0f, 1.0f, 0.0f)); + lightColorPalette.push_back(glm::vec3(0.0f, 0.0f, 1.0f)); + lightColorPalette.push_back(glm::vec3(1.0f, 0.0f, 1.0f)); + lightColorPalette.push_back(glm::vec3(0.0f, 1.0f, 1.0f)); + lightColorPalette.push_back(glm::vec3(1.0f, 1.0f, 0.0f)); + lightColorPalette.push_back(glm::vec3(0.5f, 1.0f, 0.2f)); + lightColorPalette.push_back(glm::vec3(0.0f, 0.5f, 0.1f)); + lightColorPalette.push_back(glm::vec3(0.3f, 0.1f, 0.8f)); + } + + spherePositions = new glm::vec3[sphereCount]; + sphereRadii = new float[sphereCount]; + sphereAlbedos = new glm::vec3[sphereCount]; + + lightPositions = new glm::vec3[lightCount]; + lightColors = new glm::vec3[lightCount]; + lightBools = new bool[lightCount]; + + srand(time(NULL)); + for (int i = 0; i < sphereCount; i++) + { + // generate uniformly distributed points in a ball + glm::vec3 direction = glm::normalize(glm::gaussRand(glm::vec3(0.0f), glm::vec3(1.0f))); + float radius = glm::pow(glm::linearRand(0.0f, 1.0f), 1.0f / 3.0f) * params.worldBorder; + spherePositions[i] = radius * direction; + sphereRadii[i] = 0.2f * (i % 5 + 1); + sphereAlbedos[i] = colorPalette[i % colorPalette.size()]; + } + + for (int i = 0; i < lightCount; i++) + { + glm::vec3 direction = glm::normalize(glm::gaussRand(glm::vec3(0.0f), glm::vec3(1.0f))); + float radius = glm::pow(glm::linearRand(0.0f, 1.0f), 1.0f / 3.0f) * params.worldBorder; + lightPositions[i] = radius * direction; + lightColors[i] = lightColorPalette[i % lightColorPalette.size()]; + lightBools[i] = true; + } + + size_t sphereVec3ArrSize = sphereCount * sizeof(glm::vec3); + size_t sphereFloatArrSize = sphereCount * sizeof(float); + size_t lightVec3ArrSize = lightCount * sizeof(glm::vec3); + size_t lightBoolArrSize = lightCount * sizeof(bool); + + gpuErrchk(cudaMalloc(&cudaSpherePositions, sphereVec3ArrSize)); + gpuErrchk(cudaMalloc(&cudaSphereAlbedos, sphereVec3ArrSize)); + gpuErrchk(cudaMalloc(&cudaSphereRadii, sphereFloatArrSize)); + gpuErrchk(cudaMalloc(&cudaLightPositions, lightVec3ArrSize)); + gpuErrchk(cudaMalloc(&cudaLightColors, lightVec3ArrSize)); + gpuErrchk(cudaMalloc(&cudaLightBools, lightBoolArrSize)); + + gpuErrchk(cudaMemcpy(cudaSpherePositions, spherePositions, sphereVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaSphereAlbedos, sphereAlbedos, sphereVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaSphereRadii, sphereRadii, sphereFloatArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightBoolArrSize, cudaMemcpyHostToDevice)); +} + +void Scene::free() +{ + delete[] spherePositions; + delete[] sphereRadii; + delete[] sphereAlbedos; + delete[] lightPositions; + delete[] lightColors; + delete[] lightBools; + + gpuErrchk(cudaFree(cudaSpherePositions)); + gpuErrchk(cudaFree(cudaSphereAlbedos)); + gpuErrchk(cudaFree(cudaSphereRadii)); + gpuErrchk(cudaFree(cudaLightPositions)); + gpuErrchk(cudaFree(cudaLightColors)); + gpuErrchk(cudaFree(cudaLightBools)); +} + +void Scene::updateScene(float deltaTime) +{ + lightPositions[0] = glm::vec3( + params.worldBorder * glm::sin(glfwGetTime()), + params.worldBorder * glm::cos(glfwGetTime()), + params.worldBorder * glm::sin(glfwGetTime()) * glm::cos(glfwGetTime()) + ); + + dirty = true; +} + +void Scene::updateCuda() +{ + if (!dirty) + return; + + size_t lightVec3ArrSize = lightCount * sizeof(glm::vec3); + size_t lightBoolArrSize = lightCount * sizeof(bool); + + gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightVec3ArrSize, cudaMemcpyHostToDevice)); + gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightBoolArrSize, cudaMemcpyHostToDevice)); + + dirty = false; +} + +void Scene::drawImGui() +{ + if (ImGui::CollapsingHeader("Information")) + { + ImGui::Text("Number of spheres: %d", sphereCount); + ImGui::Text("Number of light sources: %d", lightCount); + } + + if (ImGui::CollapsingHeader("Camera controls")) + { + ImGui::SeparatorText("Position"); + ImGui::BulletText("W - forward"); + ImGui::BulletText("S - backward"); + ImGui::BulletText("A - left"); + ImGui::BulletText("R - right"); + ImGui::BulletText("Space - up"); + ImGui::BulletText("LShift - down"); + + ImGui::SeparatorText("Angles"); + ImGui::BulletText("Q - look left"); + ImGui::BulletText("E - look right"); + ImGui::BulletText("1 - look up"); + ImGui::BulletText("3 - look down"); + + ImGui::SeparatorText("Misc"); + ImGui::BulletText("F - toggle mouse/keyboard"); + } + + if (ImGui::CollapsingHeader("Environment")) + { + ImGui::ColorEdit3("Sky color", glm::value_ptr(params.skyColor)); + ImGui::ColorEdit3("Ambient color", glm::value_ptr(params.ambientColor)); + } + + if (ImGui::CollapsingHeader("Sphere material")) + { + ImGui::SliderFloat("Diffuse", ¶ms.kDiffuse, 0.0f, 1.0f); + ImGui::SliderFloat("Specular", ¶ms.kSpecular, 0.0f, 1.0f); + ImGui::SliderFloat("Shininess", ¶ms.kShininess, 1.0f, 100.0f); + ImGui::SliderFloat("Ambient", ¶ms.kAmbient, 0.0f, 1.0f); + } + + if (ImGui::CollapsingHeader("Light sources")) + { + static int attenuationEnum = params.startAttIdx; + + if (ImGui::DragInt("Attenuation", &attenuationEnum, 0.1f, 0, 12)) + dirty = true; + + params.linearAtt = params.linearAttValues[attenuationEnum]; + params.quadraticAtt = params.quadraticAttValues[attenuationEnum]; + + if (ImGui::Button("Turn all lights on", ImVec2(150, 0))) + { + for (int i = 0; i < lightCount; i++) + lightBools[i] = true; + dirty = true; + } + if (ImGui::Button("Turn all lights off", ImVec2(150, 0))) + { + for (int i = 0; i < lightCount; i++) + lightBools[i] = false; + dirty = true; + } + + ImGuiWindowFlags window_flags = ImGuiWindowFlags_None; + + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); + ImGui::BeginChild("ChildR", ImVec2(0, 600), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY, window_flags); + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + if (ImGui::BeginTable("split", 1, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings)) + { + for (int i = 0; i < lightCount; ++i) + { + ImGui::TableNextColumn(); + + ImGui::SeparatorText(("Light " + std::to_string(i)).c_str()); + { + float border = params.worldBorder; + ImGui::PushID(i); + if (ImGui::DragFloat3("Position", glm::value_ptr(lightPositions[i]), 0.1f, -border - 5, border + 5)) + dirty = true; + if (ImGui::ColorEdit3("Color", glm::value_ptr(lightColors[i]))) + dirty = true; + + bool& on = lightBools[i]; + + if (ImGui::Checkbox(on ? "Turn off" : "Turn on", &on)) + dirty = true; + } + } + + ImGui::EndTable(); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + } +} \ No newline at end of file diff --git a/scene.hpp b/scene.hpp index afcaa75..1ecba15 100644 --- a/scene.hpp +++ b/scene.hpp @@ -3,13 +3,32 @@ #include "framework.hpp" #include -#include +#include #include #include +#include -#ifndef GPU_ERRCHK -#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } -#endif +struct SceneParams { + glm::vec3 ambientColor{ 1.0f, 1.0f, 1.0f }; + glm::vec3 skyColor{ 0.25f, 0.25f, 0.25f }; + + float kDiffuse = 0.9f; + float kSpecular = 0.4f; + float kAmbient = 0.2f; + float kShininess = 40; + + const float linearAttValues[13] = { + 0.7f, 0.35f, 0.22f, 0.14f, 0.09f, 0.07f, 0.045f, 0.027f, 0.022f, 0.014f, 0.007f, 0.0014f }; + const float quadraticAttValues[13] = { + 1.8f, 0.44f, 0.20f, 0.07f, 0.032f, 0.017f, 0.0075f, 0.0028f, 0.0019f, 0.0007f, 0.0002f, 0.000007f }; + + const int startAttIdx = 5; + + float linearAtt = linearAttValues[startAttIdx]; + float quadraticAtt = quadraticAttValues[startAttIdx]; + + const float worldBorder = 20; +}; class Scene { @@ -23,7 +42,6 @@ class Scene const float lightRadius = 0.2f; bool* lightBools; - // todo: idk, dry, maybe do sth like SceneGPU and SceneCPU? glm::vec3* cudaSpherePositions; glm::vec3* cudaSphereAlbedos; float* cudaSphereRadii; @@ -35,130 +53,15 @@ class Scene const int sphereCount = 1000; const int lightCount = 10; - glm::vec3 ambientColor{ - 1.0f, 1.0f, 1.0f - }; - glm::vec3 skyColor{ - 0.25f, 0.25f, 0.25f }; + SceneParams params; - float kDiffuse = 0.9f; - float kSpecular = 0.4f; - float kAmbient = 0.2f; - float kShininess = 40; + void create(); + void free(); + void updateScene(float deltaTime); + void updateCuda(); + void drawImGui(); + +private: + bool dirty; +}; - float linearAtt = 0.0f; - float quadraticAtt = 0.032f; - - const float worldBorder = 30; - - void create() - { - static std::vector colorPalette; - static std::vector lightColorPalette; - { - //colorPalette.push_back(glm::vec3(0.5, 0.5, 0.5)); - colorPalette.push_back(glm::vec3(155.0f / 255.0f, 34.0f / 255.0f, 38.0f / 255.0f)); - colorPalette.push_back(glm::vec3(0.0f / 255.0f, 18.0f / 255.0f, 25.0f / 255.0f)); - colorPalette.push_back(glm::vec3(0.0f / 255.0f, 95.0f / 255.0f, 115.0f / 255.0f)); - colorPalette.push_back(glm::vec3(10.0f / 255.0f, 147.0f / 255.0f, 150.0f / 255.0f)); - colorPalette.push_back(glm::vec3(148.0f / 255.0f, 210.0f / 255.0f, 189.0f / 255.0f)); - colorPalette.push_back(glm::vec3(233.0f / 255.0f, 216.0f / 255.0f, 166.0f / 255.0f)); - colorPalette.push_back(glm::vec3(238.0f / 255.0f, 155.0f / 255.0f, 0.0f / 255.0f)); - colorPalette.push_back(glm::vec3(202.0f / 255.0f, 103.0f / 255.0f, 2.0f / 255.0f)); - colorPalette.push_back(glm::vec3(187.0f / 255.0f, 62.0f / 255.0f, 3.0f / 255.0f)); - colorPalette.push_back(glm::vec3(174.0f / 255.0f, 32.0f / 255.0f, 18.0f / 255.0f)); - - //colorPalette.push_back(glm::vec3(128.0f / 255.0f, 93.0f / 255.0f, 147.0f / 255.0f)); - //colorPalette.push_back(glm::vec3(244.0f / 255.0f, 159.0f / 255.0f, 188.0f / 255.0f)); - //colorPalette.push_back(glm::vec3(255.0f / 255.0f, 211.0f / 255.0f, 186.0f / 255.0f)); - //colorPalette.push_back(glm::vec3(158.0f / 255.0f, 189.0f / 255.0f, 110.0f / 255.0f)); - //colorPalette.push_back(glm::vec3(22.0f / 255.0f, 152.0f / 255.0f, 115.0f / 255.0f)); - - lightColorPalette.push_back(glm::vec3(1.0f, 1.0f, 1.0f)); - lightColorPalette.push_back(glm::vec3(1.0f, 0.0f, 0.0f)); - lightColorPalette.push_back(glm::vec3(0.0f, 1.0f, 0.0f)); - lightColorPalette.push_back(glm::vec3(0.0f, 0.0f, 1.0f)); - lightColorPalette.push_back(glm::vec3(1.0f, 0.0f, 1.0f)); - lightColorPalette.push_back(glm::vec3(0.0f, 1.0f, 1.0f)); - lightColorPalette.push_back(glm::vec3(1.0f, 1.0f, 0.0f)); - lightColorPalette.push_back(glm::vec3(0.5f, 1.0f, 0.2f)); - lightColorPalette.push_back(glm::vec3(0.0f, 0.5f, 0.1f)); - lightColorPalette.push_back(glm::vec3(0.3f, 0.1f, 0.8f)); - } - - spherePositions = new glm::vec3[sphereCount]; - sphereRadii = new float[sphereCount]; - sphereAlbedos = new glm::vec3[sphereCount]; - - lightPositions = new glm::vec3[lightCount]; - lightColors = new glm::vec3[lightCount]; - lightBools = new bool[lightCount]; - - srand(time(NULL)); - for (int i = 0; i < sphereCount; i++) - { - // generate uniformly distributed points in a ball - glm::vec3 direction = glm::normalize(glm::gaussRand(glm::vec3(0.0f), glm::vec3(1.0f))); - float radius = glm::pow(glm::linearRand(0.0f, 1.0f), 1.0f / 3.0f) * worldBorder; - spherePositions[i] = radius * direction; - sphereRadii[i] = 0.2f * (i % 5 + 1); - sphereAlbedos[i] = colorPalette[i % colorPalette.size()]; - } - - for (int i = 0; i < lightCount; i++) - { - glm::vec3 direction = glm::normalize(glm::gaussRand(glm::vec3(0.0f), glm::vec3(1.0f))); - float radius = glm::pow(glm::linearRand(0.0f, 1.0f), 1.0f / 3.0f) * worldBorder; - lightPositions[i] = radius * direction; - lightColors[i] = lightColorPalette[i % lightColorPalette.size()]; - lightBools[i] = false; - } - - size_t sphereVec3ArrSize = sphereCount * sizeof(glm::vec3); - size_t sphereFloatArrSize = sphereCount * sizeof(float); - size_t lightVec3ArrSize = lightCount * sizeof(glm::vec3); - size_t lightBoolArrSize = lightCount * sizeof(bool); - - gpuErrchk(cudaMalloc(&cudaSpherePositions, sphereVec3ArrSize)); - gpuErrchk(cudaMalloc(&cudaSphereAlbedos, sphereVec3ArrSize)); - gpuErrchk(cudaMalloc(&cudaSphereRadii, sphereFloatArrSize)); - gpuErrchk(cudaMalloc(&cudaLightPositions, lightVec3ArrSize)); - gpuErrchk(cudaMalloc(&cudaLightColors, lightVec3ArrSize)); - gpuErrchk(cudaMalloc(&cudaLightBools, lightBoolArrSize)); - - gpuErrchk(cudaMemcpy(cudaSpherePositions, spherePositions, sphereVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaSphereAlbedos, sphereAlbedos, sphereVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaSphereRadii, sphereRadii, sphereFloatArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightBoolArrSize, cudaMemcpyHostToDevice)); - } - - void free() - { - delete[] spherePositions; - delete[] sphereRadii; - delete[] sphereAlbedos; - delete[] lightPositions; - delete[] lightColors; - delete[] lightBools; - - gpuErrchk(cudaFree(cudaSpherePositions)); - gpuErrchk(cudaFree(cudaSphereAlbedos)); - gpuErrchk(cudaFree(cudaSphereRadii)); - gpuErrchk(cudaFree(cudaLightPositions)); - gpuErrchk(cudaFree(cudaLightColors)); - gpuErrchk(cudaFree(cudaLightBools)); - } - - void updateCuda() - { - size_t lightVec3ArrSize = lightCount * sizeof(glm::vec3); - size_t lightBoolArrSize = lightCount * sizeof(bool); - - gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightBoolArrSize, cudaMemcpyHostToDevice)); - } - -}; \ No newline at end of file diff --git a/utils.hpp b/utils.hpp deleted file mode 100644 index 46dbce1..0000000 --- a/utils.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -#include "glm/glm.hpp" - diff --git a/window.hpp b/window.hpp index 22c3bbc..6328627 100644 --- a/window.hpp +++ b/window.hpp @@ -2,7 +2,7 @@ #include "framework.hpp" -class Application; +#include "application.hpp"; class Window { From a9cb94cc1d5a4483098cebb89fc158817af6a342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82upczy=C5=84ski?= Date: Thu, 18 Jan 2024 12:54:24 +0100 Subject: [PATCH 4/7] File structure reorganized --- application.hpp => src/headers/application.hpp | 0 camera.hpp => src/headers/camera.hpp | 0 cuda.cuh => src/headers/cuda.cuh | 0 framework.hpp => src/headers/framework.hpp | 0 ray.hpp => src/headers/ray.hpp | 0 renderer.hpp => src/headers/renderer.hpp | 0 scene.hpp => src/headers/scene.hpp | 0 shader.hpp => src/headers/shader.hpp | 0 window.hpp => src/headers/window.hpp | 0 fragment.glsl => src/shaders/fragment.glsl | 0 vertex.glsl => src/shaders/vertex.glsl | 0 application.cpp => src/src/application.cpp | 0 camera.cpp => src/src/camera.cpp | 0 cuda.cu => src/src/cuda.cu | 0 glad.c => src/src/glad.c | 0 main.cpp => src/src/main.cpp | 0 renderer.cpp => src/src/renderer.cpp | 0 scene.cpp => src/src/scene.cpp | 0 window.cpp => src/src/window.cpp | 0 19 files changed, 0 insertions(+), 0 deletions(-) rename application.hpp => src/headers/application.hpp (100%) rename camera.hpp => src/headers/camera.hpp (100%) rename cuda.cuh => src/headers/cuda.cuh (100%) rename framework.hpp => src/headers/framework.hpp (100%) rename ray.hpp => src/headers/ray.hpp (100%) rename renderer.hpp => src/headers/renderer.hpp (100%) rename scene.hpp => src/headers/scene.hpp (100%) rename shader.hpp => src/headers/shader.hpp (100%) rename window.hpp => src/headers/window.hpp (100%) rename fragment.glsl => src/shaders/fragment.glsl (100%) rename vertex.glsl => src/shaders/vertex.glsl (100%) rename application.cpp => src/src/application.cpp (100%) rename camera.cpp => src/src/camera.cpp (100%) rename cuda.cu => src/src/cuda.cu (100%) rename glad.c => src/src/glad.c (100%) rename main.cpp => src/src/main.cpp (100%) rename renderer.cpp => src/src/renderer.cpp (100%) rename scene.cpp => src/src/scene.cpp (100%) rename window.cpp => src/src/window.cpp (100%) diff --git a/application.hpp b/src/headers/application.hpp similarity index 100% rename from application.hpp rename to src/headers/application.hpp diff --git a/camera.hpp b/src/headers/camera.hpp similarity index 100% rename from camera.hpp rename to src/headers/camera.hpp diff --git a/cuda.cuh b/src/headers/cuda.cuh similarity index 100% rename from cuda.cuh rename to src/headers/cuda.cuh diff --git a/framework.hpp b/src/headers/framework.hpp similarity index 100% rename from framework.hpp rename to src/headers/framework.hpp diff --git a/ray.hpp b/src/headers/ray.hpp similarity index 100% rename from ray.hpp rename to src/headers/ray.hpp diff --git a/renderer.hpp b/src/headers/renderer.hpp similarity index 100% rename from renderer.hpp rename to src/headers/renderer.hpp diff --git a/scene.hpp b/src/headers/scene.hpp similarity index 100% rename from scene.hpp rename to src/headers/scene.hpp diff --git a/shader.hpp b/src/headers/shader.hpp similarity index 100% rename from shader.hpp rename to src/headers/shader.hpp diff --git a/window.hpp b/src/headers/window.hpp similarity index 100% rename from window.hpp rename to src/headers/window.hpp diff --git a/fragment.glsl b/src/shaders/fragment.glsl similarity index 100% rename from fragment.glsl rename to src/shaders/fragment.glsl diff --git a/vertex.glsl b/src/shaders/vertex.glsl similarity index 100% rename from vertex.glsl rename to src/shaders/vertex.glsl diff --git a/application.cpp b/src/src/application.cpp similarity index 100% rename from application.cpp rename to src/src/application.cpp diff --git a/camera.cpp b/src/src/camera.cpp similarity index 100% rename from camera.cpp rename to src/src/camera.cpp diff --git a/cuda.cu b/src/src/cuda.cu similarity index 100% rename from cuda.cu rename to src/src/cuda.cu diff --git a/glad.c b/src/src/glad.c similarity index 100% rename from glad.c rename to src/src/glad.c diff --git a/main.cpp b/src/src/main.cpp similarity index 100% rename from main.cpp rename to src/src/main.cpp diff --git a/renderer.cpp b/src/src/renderer.cpp similarity index 100% rename from renderer.cpp rename to src/src/renderer.cpp diff --git a/scene.cpp b/src/src/scene.cpp similarity index 100% rename from scene.cpp rename to src/src/scene.cpp diff --git a/window.cpp b/src/src/window.cpp similarity index 100% rename from window.cpp rename to src/src/window.cpp From 9848da1f9a0e6034a68ad692d8d3a96836c824cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82upczy=C5=84ski?= Date: Thu, 18 Jan 2024 13:29:39 +0100 Subject: [PATCH 5/7] File structure again --- pro2.vcxproj | 50 +++++++++++++++++------------------ pro2.vcxproj.filters | 46 ++++++++++++++++---------------- src/src/application.cpp | 2 +- src/src/{main.cpp => main.cu} | 0 4 files changed, 49 insertions(+), 49 deletions(-) rename src/src/{main.cpp => main.cu} (100%) diff --git a/pro2.vcxproj b/pro2.vcxproj index 149a652..dc03c75 100644 --- a/pro2.vcxproj +++ b/pro2.vcxproj @@ -43,12 +43,12 @@ true - F:\studia\semestr 5\gpu\pro2\dependencies\include;$(IncludePath) - F:\studia\semestr 5\gpu\pro2\dependencies\lib;$(LibraryPath) + $(SolutionDir)dependencies\include;$(SolutionDir)src\headers;$(IncludePath) + $(SolutionDir)dependencies\lib;$(LibraryPath) - F:\studia\semestr 5\gpu\pro2\dependencies\include;$(IncludePath) - F:\studia\semestr 5\gpu\pro2\dependencies\lib;$(LibraryPath) + $(SolutionDir)dependencies\include;$(SolutionDir)src\headers;$(IncludePath) + $(SolutionDir)dependencies\lib;$(LibraryPath) @@ -87,13 +87,6 @@ - - - - - - - @@ -105,16 +98,17 @@ - - - - - - + + + + + + + + + - - @@ -123,14 +117,20 @@ - - - - + + + + + + + + + + - - + + diff --git a/pro2.vcxproj.filters b/pro2.vcxproj.filters index 9089edb..b7e912f 100644 --- a/pro2.vcxproj.filters +++ b/pro2.vcxproj.filters @@ -1,10 +1,10 @@  - - + + Source - + Source @@ -39,35 +39,35 @@ Include\ImGUI - - Headers + + Include\GLAD - + Headers - + Headers - + Headers - + Headers - + Headers - + Headers - + Headers - + Headers - - Include\GLAD + + Headers @@ -115,30 +115,30 @@ Include\ImGUI - + Include\GLAD - + Source - + Source - + Source - + Source - + Source - + Shaders - + Shaders diff --git a/src/src/application.cpp b/src/src/application.cpp index 159998b..9ba474d 100644 --- a/src/src/application.cpp +++ b/src/src/application.cpp @@ -6,7 +6,7 @@ Application::Application() { window = new Window(this); - shader = new Shader("vertex.glsl", "fragment.glsl"); + shader = new Shader("src/shaders/vertex.glsl", "src/shaders/fragment.glsl"); renderer = new Renderer(WIDTH, HEIGHT); deltaTime = 0; diff --git a/src/src/main.cpp b/src/src/main.cu similarity index 100% rename from src/src/main.cpp rename to src/src/main.cu From eb6eab6edd562bbce8115b2dc226d3d7cfe64033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82upczy=C5=84ski?= Date: Thu, 18 Jan 2024 15:25:47 +0100 Subject: [PATCH 6/7] Dirty state marker --- src/src/scene.cpp | 59 +++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/src/scene.cpp b/src/src/scene.cpp index 2fa7db9..4ab3526 100644 --- a/src/src/scene.cpp +++ b/src/src/scene.cpp @@ -109,22 +109,32 @@ void Scene::updateScene(float deltaTime) params.worldBorder * glm::sin(glfwGetTime()) * glm::cos(glfwGetTime()) ); - dirty = true; + dirtyLightPos = true; } void Scene::updateCuda() { - if (!dirty) - return; - - size_t lightVec3ArrSize = lightCount * sizeof(glm::vec3); - size_t lightBoolArrSize = lightCount * sizeof(bool); - - gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightVec3ArrSize, cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightBoolArrSize, cudaMemcpyHostToDevice)); + if (dirtyLightPos) + { + gpuErrchk(cudaMemcpy(cudaLightPositions, lightPositions, lightCount * sizeof(glm::vec3), cudaMemcpyHostToDevice)); + dirtyLightPos = false; + } + if (dirtyLightCol) + { + gpuErrchk(cudaMemcpy(cudaLightColors, lightColors, lightCount * sizeof(glm::vec3), cudaMemcpyHostToDevice)); + dirtyLightCol = false; + } + if (dirtyLightBools) + { + gpuErrchk(cudaMemcpy(cudaLightBools, lightBools, lightCount * sizeof(bool), cudaMemcpyHostToDevice)); + dirtyLightBools = false; + } + if (dirtySphereCol) + { + gpuErrchk(cudaMemcpy(cudaSphereAlbedos, sphereAlbedos, sphereCount * sizeof(glm::vec3), cudaMemcpyHostToDevice)); + dirtySphereCol = false; - dirty = false; + } } void Scene::drawImGui() @@ -173,8 +183,7 @@ void Scene::drawImGui() { static int attenuationEnum = params.startAttIdx; - if (ImGui::DragInt("Attenuation", &attenuationEnum, 0.1f, 0, 12)) - dirty = true; + ImGui::DragInt("Attenuation", &attenuationEnum, 0.1f, 0, 12); params.linearAtt = params.linearAttValues[attenuationEnum]; params.quadraticAtt = params.quadraticAttValues[attenuationEnum]; @@ -183,19 +192,19 @@ void Scene::drawImGui() { for (int i = 0; i < lightCount; i++) lightBools[i] = true; - dirty = true; + dirtyLightBools = true; } if (ImGui::Button("Turn all lights off", ImVec2(150, 0))) { for (int i = 0; i < lightCount; i++) lightBools[i] = false; - dirty = true; + dirtyLightBools = true; } ImGuiWindowFlags window_flags = ImGuiWindowFlags_None; ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); - ImGui::BeginChild("ChildR", ImVec2(0, 600), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY, window_flags); + ImGui::BeginChild("Child1", ImVec2(0, 600), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY, ImGuiWindowFlags_None); if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenu("Menu")) @@ -204,7 +213,7 @@ void Scene::drawImGui() } ImGui::EndMenuBar(); } - if (ImGui::BeginTable("split", 1, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings)) + if (ImGui::BeginTable("split1", 1, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings)) { for (int i = 0; i < lightCount; ++i) { @@ -215,14 +224,24 @@ void Scene::drawImGui() float border = params.worldBorder; ImGui::PushID(i); if (ImGui::DragFloat3("Position", glm::value_ptr(lightPositions[i]), 0.1f, -border - 5, border + 5)) - dirty = true; + dirtyLightPos = true; if (ImGui::ColorEdit3("Color", glm::value_ptr(lightColors[i]))) - dirty = true; + dirtyLightCol = true; bool& on = lightBools[i]; if (ImGui::Checkbox(on ? "Turn off" : "Turn on", &on)) - dirty = true; + dirtyLightBools = true; + } + } + + ImGui::EndTable(); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + + } + } } } From 67ba7f22ff48932834ae3ea193e061b3047c61c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C5=82upczy=C5=84ski?= Date: Thu, 18 Jan 2024 15:38:13 +0100 Subject: [PATCH 7/7] Git mishap --- imgui.ini | 4 ++++ src/headers/scene.hpp | 5 ++++- src/src/scene.cpp | 9 --------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/imgui.ini b/imgui.ini index 3fc9af7..370b726 100644 --- a/imgui.ini +++ b/imgui.ini @@ -22,6 +22,10 @@ Size=200,100 IsChild=1 Size=260,243 +[Window][Menu/Child1_92290D92] +IsChild=1 +Size=246,600 + [Table][0xC9935533,3] Column 0 Weight=1.0000 Column 1 Weight=1.0000 diff --git a/src/headers/scene.hpp b/src/headers/scene.hpp index 1ecba15..976aa2e 100644 --- a/src/headers/scene.hpp +++ b/src/headers/scene.hpp @@ -62,6 +62,9 @@ class Scene void drawImGui(); private: - bool dirty; + bool dirtyLightPos = false; + bool dirtyLightCol = false; + bool dirtyLightBools = false; + bool dirtySphereCol = false; }; diff --git a/src/src/scene.cpp b/src/src/scene.cpp index 4ab3526..63c7ca9 100644 --- a/src/src/scene.cpp +++ b/src/src/scene.cpp @@ -241,13 +241,4 @@ void Scene::drawImGui() ImGui::PopStyleVar(); } - } - } - } - - ImGui::EndTable(); - } - ImGui::EndChild(); - ImGui::PopStyleVar(); - } } \ No newline at end of file