diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bcc539..3ac2c28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,27 +1,20 @@ cmake_minimum_required (VERSION 2.8) -project (tinyraytracer) +project(tinyraytracer) -include(CheckCXXCompilerFlag) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) -function(enable_cxx_compiler_flag_if_supported flag) - string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_already_set) - if(flag_already_set EQUAL -1) - check_cxx_compiler_flag("${flag}" flag_supported) - if(flag_supported) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE) - endif() - unset(flag_supported CACHE) - endif() -endfunction() +find_package(OpenMP) +if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +endif() -enable_cxx_compiler_flag_if_supported("-Wall") -enable_cxx_compiler_flag_if_supported("-Wextra") -enable_cxx_compiler_flag_if_supported("-pedantic") -enable_cxx_compiler_flag_if_supported("-std=c++14") -enable_cxx_compiler_flag_if_supported("-O3") -enable_cxx_compiler_flag_if_supported("-fopenmp") +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() file(GLOB SOURCES *.h *.cpp) - add_executable(${PROJECT_NAME} ${SOURCES}) diff --git a/tinyraytracer.cpp b/tinyraytracer.cpp index 62067ab..a6cf46f 100644 --- a/tinyraytracer.cpp +++ b/tinyraytracer.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -58,17 +59,16 @@ static const std::vector lights = { {{ 30, 20, 30}, 1.7} }; -bool ray_sphere_intersect(const vec3 &orig, const vec3 &dir, const Sphere &s, float &t0) { +std::tuple ray_sphere_intersect(const vec3 &orig, const vec3 &dir, const Sphere &s) { // ret value is a pair [intersection found, distance] vec3 L = s.center - orig; float tca = L*dir; float d2 = L*L - tca*tca; - if (d2 > s.radius*s.radius) return false; + if (d2 > s.radius*s.radius) return {false, 0.f}; float thc = std::sqrt(s.radius*s.radius - d2); - t0 = tca - thc; - float t1 = tca + thc; - if (t0 < 1e-3) t0 = t1; // offset the original point to avoid occlusion by the object itself - if (t0 < 1e-3) return false; - return true; + float t0 = tca-thc, t1 = tca+thc; + if (t0>1e-3) return {true, t0}; // offset the original point by 1e-3 to avoid occlusion by the object itself + if (t1>1e-3) return {true, t1}; + return {false, 0.f}; } vec3 reflect(const vec3 &I, const vec3 &N) { @@ -83,13 +83,12 @@ vec3 refract(const vec3 &I, const vec3 &N, const float eta_t, const float eta_i= return k<0 ? vec3{1,0,0} : I*eta + N*(eta*cosi - std::sqrt(k)); // k<0 = total reflection, no ray to refract. I refract it anyways, this has no physical meaning } -bool scene_intersect(const vec3 &orig, const vec3 &dir, vec3 &hit, vec3 &N, Material &material) { +bool scene_intersect(const vec3 &orig, const vec3 &dir, vec3 &hit, vec3 &N, Material &material) { // TODO: move output values to a return tuple float spheres_dist = std::numeric_limits::max(); for (const Sphere &s : spheres) { - float dist_i; - if (ray_sphere_intersect(orig, dir, s, dist_i) && dist_i < spheres_dist) { - spheres_dist = dist_i; - hit = orig + dir*dist_i; + if (auto [intersection, dist] = ray_sphere_intersect(orig, dir, s); intersection && dist < spheres_dist) { + spheres_dist = dist; + hit = orig + dir*dist; N = (hit - s.center).normalized(); material = s.material; }