diff --git a/CMakeLists.txt b/CMakeLists.txt index 936033f..27d3a91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/external/vcpkg/scripts/buil project(RayTracer) - +find_package(glew CONFIG REQUIRED) find_package(assimp CONFIG REQUIRED) find_package(glfw3 CONFIG REQUIRED) find_package(glm CONFIG REQUIRED) @@ -21,6 +21,7 @@ add_executable(RayTracer "") target_include_directories(RayTracer PUBLIC src/) target_link_libraries(RayTracer PUBLIC assimp::assimp) target_link_libraries(RayTracer PUBLIC glfw) +target_link_libraries(RayTracer PUBLIC GLEW::glew) target_link_libraries(RayTracer PUBLIC glm::glm) target_link_libraries(RayTracer PUBLIC KTX::ktx) diff --git a/src/main.cpp b/src/main.cpp index 69ebc94..bdf0afa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,24 @@ -#include "window/Window.h" -#include "util/ModelLoader.h" #include "scene/BVH.h" +#include "util/ModelLoader.h" +#include "window/Window.h" -int main() { +int main() +{ BVH bvh; - bvh.addModels(ModelLoader::loadModel("../../cube.fbx")); + bvh.addModels(ModelLoader::loadModel("../../cube.fbx"), glm::mat4()); bvh.generate(); - Window w(1920, 1080); - while (true) { - w.update(); - } - return 0; + Window w(1920, 1080); + std::vector texture(1920 * 1080); + for (int j = 10; j < 100; ++j) + { + for (int i = 0; i < 1920; ++i) + { + texture[j * 1920 + i] = 0xff00ffff; + } + } + while (true) + { + w.update(texture); + } + return 0; } \ No newline at end of file diff --git a/src/scene/AABB.h b/src/scene/AABB.h index f11ea1e..4f654e7 100644 --- a/src/scene/AABB.h +++ b/src/scene/AABB.h @@ -1,5 +1,6 @@ #pragma once -#include +#include +#include #include struct AABB @@ -21,17 +22,32 @@ struct AABB max.y = std::max(max.y, pos.y); max.z = std::max(max.z, pos.z); } + void transform(glm::mat4 transform) + { + std::array corners; + corners[0] = glm::vec3(min.x, min.y, min.z); + corners[1] = glm::vec3(min.x, min.y, max.z); + corners[2] = glm::vec3(min.x, max.y, min.z); + corners[3] = glm::vec3(min.x, max.y, max.z); + corners[4] = glm::vec3(max.x, min.y, min.z); + corners[5] = glm::vec3(max.x, min.y, max.z); + corners[6] = glm::vec3(max.x, max.y, min.z); + corners[7] = glm::vec3(max.x, max.y, max.z); + min = glm::vec3(std::numeric_limits::max()); + max = glm::vec3(std::numeric_limits::lowest()); + for (int i = 0; i < 8; ++i) + { + glm::vec4 transformed = transform * glm::vec4(corners[i].x, corners[i].y, corners[i].z, 1.0f); + min = glm::vec3(std::min(min.x, transformed.x), std::min(min.y, transformed.y), std::min(min.z, transformed.z)); + max = glm::vec3(std::max(max.x, transformed.x), std::max(max.y, transformed.y), std::max(max.z, transformed.z)); + } + } static AABB combine(AABB lhs, AABB rhs) { - AABB result; - - result.min.x = std::min(lhs.min.x, rhs.min.x); - result.min.y = std::min(lhs.min.y, rhs.min.y); - result.min.z = std::min(lhs.min.z, rhs.min.z); - - result.max.x = std::max(lhs.max.x, rhs.max.x); - result.max.y = std::max(lhs.max.y, rhs.max.y); - result.max.z = std::max(lhs.max.z, rhs.max.z); + AABB result = { + .min = glm::vec3(std::min(lhs.min.x, rhs.min.x), std::min(lhs.min.y, rhs.min.y), std::min(lhs.min.z, rhs.min.z)), + .max = glm::vec3(std::max(lhs.max.x, rhs.max.x), std::max(lhs.max.y, rhs.max.y), std::max(lhs.max.z, rhs.max.z)), + }; return result; } diff --git a/src/scene/BVH.cpp b/src/scene/BVH.cpp index e0c1703..f3f9542 100644 --- a/src/scene/BVH.cpp +++ b/src/scene/BVH.cpp @@ -1,12 +1,17 @@ #include "BVH.h" #include -void BVH::addModel(PModel model) { models.push_back(std::move(model)); } +void BVH::addModel(PModel model, glm::mat4 transform) +{ + model->boundingBox.transform(transform); + models.push_back(std::move(model)); +} -void BVH::addModels(std::vector _models) +void BVH::addModels(std::vector _models, glm::mat4 transform) { for (int i = 0; i < _models.size(); ++i) { + _models[i]->boundingBox.transform(transform); models.push_back(std::move(_models[i])); } } diff --git a/src/scene/BVH.h b/src/scene/BVH.h index 28cb6f9..1c258cb 100644 --- a/src/scene/BVH.h +++ b/src/scene/BVH.h @@ -2,12 +2,13 @@ #include "AABB.h" #include "util/Model.h" #include +#include class BVH { public: - void addModel(PModel model); - void addModels(std::vector models); + void addModel(PModel model, glm::mat4 transform); + void addModels(std::vector models, glm::mat4 transform); void generate(); private: diff --git a/src/scene/Scene.cpp b/src/scene/Scene.cpp index 85e7c07..7e0ed7c 100644 --- a/src/scene/Scene.cpp +++ b/src/scene/Scene.cpp @@ -1 +1,3 @@ -#include "Scene.h" \ No newline at end of file +#include "Scene.h" + +void Scene::render() {} diff --git a/src/scene/Scene.h b/src/scene/Scene.h index bd4980f..066c874 100644 --- a/src/scene/Scene.h +++ b/src/scene/Scene.h @@ -1,8 +1,13 @@ #pragma once +#include "BVH.h" +#include "window/Window.h" class Scene { -public: -private: - + public: + void render(); + private: + Window window; + std::vector image; + BVH bvh; }; \ No newline at end of file diff --git a/src/util/Ray.h b/src/util/Ray.h index e69de29..361293c 100644 --- a/src/util/Ray.h +++ b/src/util/Ray.h @@ -0,0 +1,8 @@ +#pragma once +#include + +struct Ray +{ + glm::vec3 origin; + glm::vec3 direction; +}; \ No newline at end of file diff --git a/src/window/Window.cpp b/src/window/Window.cpp index 8306334..e9f7587 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -1,17 +1,105 @@ #include "Window.h" +#include +#include -Window::Window(int width, int height) +#define GLSL(...) "#version 450\n#extension GL_KHR_vulkan_glsl : enable\n" #__VA_ARGS__ + +Window::Window(int width, int height) : width(width), height(height) { - glfwInit(); - window = glfwCreateWindow(width, height, "RayTracer", nullptr, nullptr); + glewExperimental = true; + assert(glfwInit()); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // We don't want the old OpenGL + window = glfwCreateWindow(width, height, "RayTracer", nullptr, nullptr); + glfwMakeContextCurrent(window); + float vertices[] = { + // positions + 1, -1, 0, + -1, -1, 0, + 1, 1, 0, + 1, -1, 0 + }; + + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). + glBindVertexArray(vao); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // position attribute + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + assert(!glewInit()); + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + program = glCreateProgram(); + vertShader = glCreateShader(GL_VERTEX_SHADER); + fragShader = glCreateShader(GL_FRAGMENT_SHADER); + int logLen = 0; + const char* vertCode = GLSL(layout(location = 0) in vec3 position + layout(location = 0) out vec2 outUV; + + void main() { + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + gl_Position = vec4(outUV * 2.0f + -1.0f, 0.0f, 1.0f); + }); + const char* fragCode = GLSL(layout(location = 0) in vec2 uv; layout(location = 0) out vec4 color; + + uniform sampler2D tex; + + void main() { color = texture(tex, uv); }); + glShaderSource(vertShader, 1, &vertCode, nullptr); + glCompileShader(vertShader); + int success; + char infoLog[1024]; + glGetShaderiv(vertShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(vertShader, 1024, NULL, infoLog); + std::cout << "ERROR::SHADER_COMPILATION_ERROR\n" + << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; + } + + glShaderSource(fragShader, 1, &fragCode, nullptr); + glCompileShader(fragShader); + glGetShaderiv(fragShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(fragShader, 1024, NULL, infoLog); + std::cout << "ERROR::SHADER_COMPILATION_ERROR\n" + << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; + } + + glAttachShader(program, vertShader); + glAttachShader(program, fragShader); + + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &logLen); + if (logLen > 0) + { + std::vector log(logLen); + glGetProgramInfoLog(program, logLen, &logLen, log.data()); + std::cout << log.data() << std::endl; + } + glDeleteShader(vertShader); + glDeleteShader(fragShader); + textureLocation = glGetUniformLocation(program, "tex"); + glClearColor(0, 0, 0, 0); } -Window::~Window() -{ -} +Window::~Window() {} -void Window::update() +void Window::update(const std::vector& textureData) { - glfwPollEvents(); - glfwSwapBuffers(window); + glClear(GL_COLOR_BUFFER_BIT); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, textureData.data()); + glUseProgram(program); + glUniform1i(textureLocation, 0); + glDrawArrays(GL_TRIANGLES, 0, 3); + glfwSwapBuffers(window); + glfwPollEvents(); } diff --git a/src/window/Window.h b/src/window/Window.h index 8919ef3..132a5b1 100644 --- a/src/window/Window.h +++ b/src/window/Window.h @@ -1,12 +1,24 @@ #pragma once +#include #include +#include class Window { -public: - Window(int width, int height); - ~Window(); - void update(); -private: - GLFWwindow* window; + public: + Window(int width, int height); + ~Window(); + void update(const std::vector& textureData); + + private: + int width; + int height; + GLuint vao; + GLuint vbo; + GLuint texture; + GLuint program; + GLuint vertShader; + GLuint fragShader; + GLuint textureLocation; + GLFWwindow* window; }; \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json index b5b3d98..08cd872 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,3 +1,3 @@ { - "dependencies": ["assimp", "ktx", "glfw3", "glm", "stb", "fmt"] + "dependencies": ["assimp", "ktx", "glfw3", "glew", "glm", "stb", "fmt"] } \ No newline at end of file