From cf6dda021dbb971d417a20a0eecea945fc5a9fce Mon Sep 17 00:00:00 2001 From: Philip Abernethy Date: Sat, 19 Mar 2016 18:37:53 +0100 Subject: [PATCH] Implemented Beer-Lambert law (correctly, I hope), properly migrated to CImg and reworked the CMakeLists.txt --- CMakeLists.txt | 82 +++-- examples/example4.xml | 2 + examples/example5.xml | 4 +- examples/example7.xml | 18 +- extern/FindCImg.cmake | 341 ++++++++++++++++++ lib/camera/camera.cpp | 6 +- lib/camera/camera.h | 4 +- lib/camera/perspective_camera.cpp | 19 +- lib/camera/perspective_camera.h | 4 +- lib/camera/realistic_camera.cpp | 15 +- lib/camera/realistic_camera.h | 6 +- lib/geometry/material/lambertian_material.cpp | 2 +- lib/geometry/material/lambertian_material.h | 2 +- lib/geometry/material/material.h | 2 +- lib/geometry/material/phong_material.cpp | 2 +- lib/geometry/material/phong_material.h | 3 +- lib/geometry/material/specular_material.cpp | 2 +- lib/geometry/material/specular_material.h | 3 +- lib/geometry/material/textured_material.cpp | 7 +- lib/geometry/material/textured_material.h | 2 - .../material/transparent_material.cpp | 25 +- lib/geometry/material/transparent_material.h | 2 +- lib/geometry/shapes/shape.cpp | 7 +- lib/geometry/shapes/shape.h | 4 +- lib/light/parallel_light.h | 1 - lib/parser.cpp | 88 ++--- lib/parser.h | 7 +- lib/sampler/random_sampler.cpp | 14 +- lib/sampler/random_sampler.h | 10 +- lib/sampler/sampler.cpp | 15 +- lib/sampler/sampler.h | 8 +- lib/whitted_rt.cpp | 24 +- main.cpp | 1 - 33 files changed, 558 insertions(+), 174 deletions(-) create mode 100644 extern/FindCImg.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ceaf90..62ce343 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,31 +1,67 @@ cmake_minimum_required(VERSION 3.2) project(Ray_Tracer) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +# Prevent compilation in-source +if (${CMAKE_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) + Message(" ") + Message(FATAL_ERROR "Source and build directories are the same. + Create an empty build directory, + change into it and re-invoke cmake") +endif () + +include(CheckCXXCompilerFlag) +CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) +CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) +if (COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +elseif (COMPILER_SUPPORTS_CXX0X) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +else () + message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") +endif () + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/extern) find_package(OpenMP) if (OPENMP_FOUND) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif () -set(SOURCE_FILES lib/whitted_rt.cpp lib/whitted_rt.h lib/math/vec4.cpp lib/math/vec4.h lib/math/vec2.cpp lib/math/vec2.h - lib/math/mat4.cpp lib/math/mat4.h lib/camera/perspective_camera.cpp lib/camera/perspective_camera.h - lib/geometry/ray.h lib/geometry/shapes/sphere.cpp lib/geometry/shapes/sphere.h lib/geometry/shapes/shape.cpp - lib/geometry/shapes/shape.h lib/math/helper.cpp lib/math/helper.h lib/light/light.cpp lib/light/light.h - lib/light/parallel_light.cpp lib/light/parallel_light.h lib/geometry/material/material.h - lib/geometry/material/phong_material.cpp lib/geometry/material/phong_material.h - lib/geometry/material/solid_material.h lib/geometry/point.cpp lib/geometry/point.h lib/geometry/direction.cpp - lib/geometry/direction.h lib/geometry/normal.cpp lib/geometry/normal.h lib/geometry/transform.cpp - lib/geometry/transform.h lib/geometry/intersection.h lib/geometry/color.cpp lib/geometry/color.h - lib/geometry/material/lambertian_material.cpp lib/geometry/material/lambertian_material.h - lib/light/ambient_light.cpp lib/light/ambient_light.h lib/camera/camera.h lib/camera/camera.cpp - lib/geometry/ray.cpp lib/geometry/material/solid_material.cpp lib/light/point_light.cpp lib/light/point_light.h - lib/parser.cpp lib/parser.h lib/geometry/shapes/mesh.cpp lib/geometry/shapes/mesh.h - lib/geometry/shapes/triangle.cpp lib/geometry/shapes/triangle.h lib/tiny_obj_loader.cpp lib/tiny_obj_loader.h - lib/geometry/material/specular_material.cpp lib/geometry/material/specular_material.h - lib/geometry/material/textured_material.cpp lib/geometry/material/textured_material.h - lib/geometry/material/transparent_material.cpp lib/geometry/material/transparent_material.h lib/sampler/sampler.h lib/sampler/random_sampler.cpp lib/sampler/random_sampler.h lib/sampler/sampler.cpp lib/camera/realistic_camera.cpp lib/camera/realistic_camera.h) -add_executable(Ray_Tracer ${SOURCE_FILES} main.cpp) -add_executable(Test ${SOURCE_FILES} test.cpp) -target_link_libraries(Ray_Tracer X11 png pugixml) -target_link_libraries(Test X11 png pugixml) \ No newline at end of file +find_package(CImg REQUIRED) +list(APPEND PROJ_INCLUDE_DIRS ${CImg_INCLUDE_DIRS}) +list(APPEND PROJ_LIBRARY_DIRS ${CImg_SYSTEM_LIBS_DIR}) + +# Add CIMG Flags to Compilation Flags +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CIMG_CFLAGS}") + +link_directories(${CImg_SYSTEM_LIBS_DIR}) +include_directories(${CImg_INCLUDE_DIRS}) + +find_package(pugixml REQUIRED) + +add_library(math STATIC lib/math/vec4.cpp lib/math/vec2.cpp lib/math/mat4.cpp lib/math/helper.cpp) + +add_library(sampler STATIC lib/sampler/random_sampler.cpp lib/sampler/sampler.cpp) +target_link_libraries(sampler math) + +add_library(geometry STATIC lib/geometry/color.cpp lib/geometry/direction.cpp lib/geometry/normal.cpp + lib/geometry/point.cpp lib/geometry/ray.cpp lib/geometry/transform.cpp lib/geometry/intersection.h + lib/geometry/shapes/shape.cpp lib/geometry/shapes/sphere.cpp lib/geometry/shapes/triangle.cpp + lib/geometry/shapes/mesh.cpp lib/geometry/material/material.h lib/geometry/material/solid_material.cpp + lib/geometry/material/phong_material.cpp lib/geometry/material/lambertian_material.cpp + lib/geometry/material/specular_material.cpp lib/geometry/material/textured_material.cpp + lib/geometry/material/transparent_material.cpp) +target_link_libraries(geometry math) + +add_library(light STATIC lib/light/light.cpp lib/light/ambient_light.cpp lib/light/parallel_light.cpp + lib/light/point_light.cpp) +target_link_libraries(light geometry) + +add_library(camera STATIC lib/camera/camera.cpp lib/camera/perspective_camera.cpp lib/camera/realistic_camera.cpp) +target_link_libraries(camera sampler geometry) + +add_library(whitted_rt STATIC lib/whitted_rt.cpp lib/parser.cpp lib/tiny_obj_loader.cpp) +target_link_libraries(whitted_rt camera light pugixml ${CImg_SYSTEM_LIBS}) + +add_executable(Ray_Tracer main.cpp) +target_link_libraries(Ray_Tracer whitted_rt) \ No newline at end of file diff --git a/examples/example4.xml b/examples/example4.xml index 42f4650..67ff7cd 100644 --- a/examples/example4.xml +++ b/examples/example4.xml @@ -11,7 +11,9 @@ + + diff --git a/examples/example5.xml b/examples/example5.xml index 2aa4a96..c6700a8 100644 --- a/examples/example5.xml +++ b/examples/example5.xml @@ -10,8 +10,10 @@ - + + + diff --git a/examples/example7.xml b/examples/example7.xml index 8b1e23b..91b4a4b 100644 --- a/examples/example7.xml +++ b/examples/example7.xml @@ -3,7 +3,7 @@ - + @@ -11,7 +11,9 @@ - + + + @@ -55,6 +57,16 @@ + + + + + + + + + + @@ -93,7 +105,7 @@ - + diff --git a/extern/FindCImg.cmake b/extern/FindCImg.cmake new file mode 100644 index 0000000..a3f43c2 --- /dev/null +++ b/extern/FindCImg.cmake @@ -0,0 +1,341 @@ +# - Try to find CImg lib +# +# The following variables are defined +# +# CImg_FOUND - system has CImg lib +# CImg_INCLUDE_DIRS - the CImg include directory +# CImg_SYSTEM_LIBS - external libraries that CImg uses +# CImg_SYSTEM_LIBS_DIR - external library directories +# CImg_CFLAGS - compilation flags + + +if (CImg_INCLUDE_DIR) + set(CImg_FOUND TRUE) +else (CImg_INCLUDE_DIR) + find_path(CImg_INCLUDE_DIR + NAMES CImg.h + PATHS + ${CMAKE_INSTALL_PREFIX}/include + /usr/include + ) + mark_as_advanced(CImg_INCLUDE_DIR) +endif(CImg_INCLUDE_DIR) +list(APPEND CImg_INCLUDE_DIRS + ${CImg_INCLUDE_DIR} + ) + +# To use PKG_CHECK_MODULES to find some optional packages +find_package(PkgConfig) + + +# ### CIMG related stuff +# Flags to enable fast image display, using the XSHM library. +SET(CIMG_XSHM_CCFLAGS -Dcimg_use_xshm) + +# Flags to enable screen mode switching, using the XRandr library. +SET(CIMG_XRANDR_CCFLAGS -Dcimg_use_xrandr) + +# Flags to enable native support for JPEG image files, using the JPEG library. +# ( http://www.ijg.org/ ) +SET(CIMG_JPEG_CCFLAGS -Dcimg_use_jpeg) + +# Flags to enable native support for TIFF image files, using the TIFF library. +# ( http://www.libtiff.org/ ) +SET(CIMG_TIFF_CCFLAGS -Dcimg_use_tiff) + +# Flags to enable native support for PNG image files, using the PNG library. +# ( http://www.libpng.org/ ) +SET(CIMG_PNG_CCFLAGS -Dcimg_use_png) + +#Flags to enable OPENCV support (Camera) +# ( http://www.opencv.org/ ) +SET(CIMG_OPENCV_CCFLAGS -Dcimg_use_opencv) + +# Flags to enable native support for EXR image files, using the OpenEXR library. +# ( http://www.openexr.com/ ) +SET(CIMG_OPENEXR_CCFLAGS -Dcimg_use_openexr) + +# Flags to enable native support for various video files, using the FFMPEG library. +# ( http://www.ffmpeg.org/ ) +SET(CIMG_FFMPEG_CCFLAGS -Dcimg_use_ffmpeg) + +# Flags to enable native support of most classical image file formats, using the Magick++ library. +# ( http://www.imagemagick.org/Magick++/ ) +SET(CIMG_MAGICK_CCFLAGS -Dcimg_use_magick) + +# Flags to enable faster Discrete Fourier Transform computation, using the FFTW3 library +# ( http://www.fftw.org/ ) +SET(CIMG_FFTW3_CCFLAGS -Dcimg_use_fftw3) + +# Flags to enable zlib. +# ( http://www.zlib.net/ ) +SET(CIMG_ZLIB_CCFLAGS -Dcimg_use_zlib) + +# ### Search Additional Libraries ########## +FIND_PACKAGE(OpenCV) +FIND_PACKAGE(JPEG) +FIND_PACKAGE(TIFF) +FIND_PACKAGE(PNG) +FIND_PACKAGE(ZLIB) +FIND_PACKAGE(LAPACK) +FIND_PACKAGE(BLAS) + +PKG_CHECK_MODULES(FFTW3 fftw3) +PKG_CHECK_MODULES(OPENEXR OpenEXR) +PKG_CHECK_MODULES(MAGICK Magick++) + +# PKG_CHECK_MODULES(LIBAVCODEC libavcodec) +# PKG_CHECK_MODULES(LIBAVFORMAT libavformat) +# PKG_CHECK_MODULES(LIBSWSCALE libswscale) +# PKG_CHECK_MODULES(LIBAVUTIL libavutil) + +if(NOT WIN32) + FIND_PACKAGE(X11) + FIND_PACKAGE(Threads REQUIRED) +endif() + +# #### End of additional libraries search ########## + +### Configure Paths according to detected packages +if(TIFF_FOUND) + get_filename_component(TIFF_LIB_DIRS ${TIFF_LIBRARIES} PATH) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_TIFF_CCFLAGS}") + # link_directories(${TIFF_LIB_DIRS}) + # include_directories(${TIFF_INCLUDE_DIR}) + # SET(CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${TIFF_LIBRARIES}) + list(APPEND CImg_INCLUDE_DIRS + ${TIFF_INCLUDE_DIR} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${TIFF_LIB_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${TIFF_LIBRARIES} + ) +endif() + +if(JPEG_FOUND) + get_filename_component(JPEG_LIB_DIRS ${JPEG_LIBRARIES} PATH) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_JPEG_CCFLAGS}") + # link_directories(${JPEG_LIB_DIRS}) + # include_directories(${JPEG_INCLUDE_DIR}) + # SET(CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${JPEG_LIBRARIES}) + list(APPEND CImg_INCLUDE_DIRS + ${JPEG_INCLUDE_DIR} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${JPEG_LIB_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${JPEG_LIBRARIES} + ) +endif() + +if (ZLIB_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_ZLIB_CCFLAGS}") + # link_directories(${ZLIB_LIB_DIRS}) + # include_directories(${ZLIB_INCLUDE_DIR}) + # SET(CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${ZLIB_LIBRARIES}) + list(APPEND CImg_INCLUDE_DIRS + ${ZLIB_INCLUDE_DIR} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${ZLIB_LIB_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${ZLIB_LIBRARIES} + ) + # PNG requires ZLIB + if(PNG_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_PNG_CCFLAGS}") + # link_directories(${PNG_LIB_DIRS}) + # include_directories(${PNG_INCLUDE_DIR} ) + # SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${PNG_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${PNG_INCLUDE_DIR} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${PNG_LIB_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${PNG_LIBRARIES} + ) + endif() +endif() + +if(FFTW3_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_FFTW3_CCFLAGS}") + #link_directories( ${FFTW3_LIBRARY_DIRS} ) + #include_directories( ${FFTW3_INCLUDE_DIRS} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${FFTW3_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${FFTW3_INCLUDE_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${FFTW3_LIBRARY_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${FFTW3_LIBRARIES} + ) +endif() + +if(OPENEXR_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_OPENEXR_CCFLAGS}") + #link_directories( ${OPENEXR_LIBRARY_DIRS} ) + #include_directories( ${OPENEXR_INCLUDE_DIRS} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${OPENEXR_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${OPENEXR_INCLUDE_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${OPENEXR_LIBRARY_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${OPENEXR_LIBRARIES} + ) +endif() + +if(MAGICK_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_MAGICK_CCFLAGS}") + #link_directories( ${MAGICK_LIBRARY_DIRS} ) + #include_directories( ${MAGICK_INCLUDE_DIRS} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${MAGICK_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${MAGICK_INCLUDE_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${MAGICK_LIBRARY_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${MAGICK_LIBRARIES} + ) +endif() + +if( LIBAVCODEC_FOUND AND LIBAVFORMAT_FOUND AND LIBSWSCALE_FOUND AND LIBAVUTIL_FOUND ) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_FFMPEG_CCFLAGS}") + #link_directories( ${LIBAVFORMAT_LIBRARY_DIRS} ) + #link_directories( ${LIBAVCODEC_LIBRARY_DIRS} ) + #link_directories( ${LIBSWSCALE_LIBRARY_DIRS} ) + #link_directories( ${LIBAVUTIL_LIBRARY_DIRS} ) + #include_directories( ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVFORMAT_INCLUDE_DIRS}/libavformat) + #include_directories( ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVCODEC_INCLUDE_DIRS}/libavcodec ) + #include_directories( ${LIBSWSCALE_INCLUDE_DIRS} ${LIBSWSCALE_INCLUDE_DIRS}/libswscale) + #include_directories( ${LIBAVUTIL_INCLUDE_DIRS} ${LIBAVUTIL_INCLUDE_DIRS}/libavutil ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${LIBAVFORMAT_LIBRARIES} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${LIBAVCODEC_LIBRARIES} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${LIBSWSCALE_LIBRARIES} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${LIBAVUTIL_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVFORMAT_INCLUDE_DIRS}/libavformat + ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVCODEC_INCLUDE_DIRS}/libavcodec + ${LIBSWSCALE_INCLUDE_DIRS} ${LIBSWSCALE_INCLUDE_DIRS}/libswscale + ${LIBAVUTIL_INCLUDE_DIRS} ${LIBAVUTIL_INCLUDE_DIRS}/libavutil + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${LIBAVFORMAT_LIBRARY_DIRS} + ${LIBAVCODEC_LIBRARY_DIRS} + ${LIBSWSCALE_LIBRARY_DIRS} + ${LIBAVUTIL_LIBRARY_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${LIBAVFORMAT_LIBRARIES} + ${LIBAVCODEC_LIBRARIES} + ${LIBSWSCALE_LIBRARIES} + ${LIBAVUTIL_LIBRARIES} + ) +endif() + +if(NOT APPLE) + if(NOT WIN32) + if(X11_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_XSHM_CCFLAGS} ${CIMG_XRANDR_CCFLAGS}") + SET(CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} Xext Xrandr) + endif() + endif(NOT WIN32) +endif(NOT APPLE) + +if(X11_FOUND) + #link_directories(${X11_LIB_DIRS}) + #include_directories(${X11_INCLUDE_DIR}) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${X11_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${X11_INCLUDE_DIR} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${X11_LIB_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${X11_LIBRARIES} + ) +endif() + +if (NOT WIN32) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${CMAKE_THREAD_LIBS_INIT} ) + list(APPEND CImg_SYSTEM_LIBS + ${CMAKE_THREAD_LIBS_INIT} + ) +endif() + +if( WIN32) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} gdi32 ) + list(APPEND CImg_SYSTEM_LIBS + gdi32 + ) +endif() + +if (OpenCV_FOUND) + message("OpenCV Found") + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_OPENCV_CCFLAGS}") + #include_directories(${OpenCV_INCLUDE_DIRS}) + #link_directories(${OpenCV_LIB_DIRS}) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${OpenCV_LIBS} ) + list(APPEND CImg_INCLUDE_DIRS + ${OpenCV_INCLUDE_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${OpenCV_LIB_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${OpenCV_LIBS} + ) +endif() + +if(LAPACK_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_LAPACK_CCFLAGS}") + #link_directories( ${LAPACK_LIBRARY_DIRS} ) + #include_directories( ${LAPACK_INCLUDE_DIRS} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${LAPACK_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${LAPACK_INCLUDE_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${LAPACK_LIBRARY_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${LAPACK_LIBRARIES} + ) +endif() + +if(BLAS_FOUND) + SET(CIMG_CFLAGS "${CIMG_CFLAGS} ${CIMG_BLAS_CCFLAGS}") + #link_directories( ${BLAS_LIBRARY_DIRS} ) + #include_directories( ${BLAS_INCLUDE_DIRS} ) + #SET( CImg_SYSTEM_LIBS ${CImg_SYSTEM_LIBS} ${BLAS_LIBRARIES} ) + list(APPEND CImg_INCLUDE_DIRS + ${BLAS_INCLUDE_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS_DIR + ${BLAS_LIBRARY_DIRS} + ) + list(APPEND CImg_SYSTEM_LIBS + ${BLAS_LIBRARIES} + ) +endif() + +# Add CIMG Flags to Compilation Flags +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CIMG_CFLAGS}") + +foreach(program ${CIMG_FILES}) + add_executable(${program} ${program}.cpp) + target_link_libraries(${program} ${CImg_SYSTEM_LIBS} ) +endforeach(program) \ No newline at end of file diff --git a/lib/camera/camera.cpp b/lib/camera/camera.cpp index 0c2323a..e4cef99 100644 --- a/lib/camera/camera.cpp +++ b/lib/camera/camera.cpp @@ -6,8 +6,8 @@ camera::camera(const point &position, const point &look_at, const direction &up, const std::array &resolution, const unsigned long max_bounces, - const std::shared_ptr s) - : resolution(resolution), max_bounces(max_bounces), s(s) { + const unsigned long &samples, const std::shared_ptr s) + : resolution(resolution), max_bounces(max_bounces), samples(samples), s(s) { assert(resolution[0] > 0 && resolution[1] > 0); direction dir = normalise(look_at - position); direction left = cross(normalise(up), dir); @@ -24,7 +24,7 @@ camera::camera(const point &position, const point &look_at, const direction &up, for (auto &i : data) { i.resize(resolution[1]); for (auto &j : i) - j.resize(s->count); + j.resize(samples); } } diff --git a/lib/camera/camera.h b/lib/camera/camera.h index f6cc178..5df8170 100644 --- a/lib/camera/camera.h +++ b/lib/camera/camera.h @@ -8,7 +8,6 @@ #include "../geometry/transform.h" #include "../geometry/ray.h" #include "../geometry/color.h" -#include "../math/helper.h" #include "../sampler/sampler.h" class camera { @@ -17,6 +16,7 @@ class camera { std::array resolution; std::vector>> data; const unsigned long max_bounces = 0; + unsigned long samples; std::shared_ptr s; camera() { }; @@ -39,7 +39,7 @@ class camera { */ camera(const point &position, const point &look_at, const direction &up, const std::array &resolution, const unsigned long max_bounces, - const std::shared_ptr s); + const unsigned long &samples, const std::shared_ptr s); public: /** diff --git a/lib/camera/perspective_camera.cpp b/lib/camera/perspective_camera.cpp index 072a875..f98c62a 100644 --- a/lib/camera/perspective_camera.cpp +++ b/lib/camera/perspective_camera.cpp @@ -1,26 +1,27 @@ #include "perspective_camera.h" perspective_camera::perspective_camera() : perspective_camera(point(0, 0, 0), point(0, 0, -1), direction(0, 1, 0), - {1024, 768}, 10, 45, - std::make_shared(sampler())) { + {1024, 768}, 10, 45, 1, + (std::shared_ptr(new sampler())), 0) { } perspective_camera::perspective_camera(const point &position, const point &look_at, const direction &up, const std::array &resolution, const unsigned long max_bounces, - const float &fov, const std::shared_ptr s) : - camera(position, look_at, up, resolution, max_bounces, s), fov(fov) { + const float &fov, const unsigned long &samples, + const std::shared_ptr sampler, const float &defocus) : + camera(position, look_at, up, resolution, max_bounces, samples, sampler), fov(fov), defocus(defocus) { assert(0 < fov && fov < 90); - stepwidth = std::tan(helper::to_radians(this->fov)) / (resolution[0] / 2); + assert(defocus >= 0); + stepwidth = std::tan(helper::to_radians(fov)) / (resolution[0] / 2); start = direction(0, 0, 1) + direction(1, 0, 0) * (((resolution[0] - 1) / 2.0) * stepwidth) + direction(0, 1, 0) * (((resolution[1] - 1) / 2.0) * stepwidth); } std::shared_ptr> perspective_camera::get_rays(const unsigned long &x, const unsigned long &y) { - std::shared_ptr> offsets = this->s->get_samples(); + std::shared_ptr> offsets = s->get_samples(defocus, defocus, samples); std::shared_ptr> out(new std::vector()); - direction d = - this->start + direction(-1, 0, 0) * (this->stepwidth * x) + direction(0, -1, 0) * (this->stepwidth * y); + direction d = start + direction(-1, 0, 0) * (stepwidth * x) + direction(0, -1, 0) * (stepwidth * y); for (vec2 o : *offsets) - out->push_back(transforms(ray(point(o[0], o[1], 0), d + direction(o[0], o[1], 0)))); + out->push_back(transforms(ray(point(), d + direction(o[0], o[1], 0)))); return out; } \ No newline at end of file diff --git a/lib/camera/perspective_camera.h b/lib/camera/perspective_camera.h index 4e1b39a..175932d 100644 --- a/lib/camera/perspective_camera.h +++ b/lib/camera/perspective_camera.h @@ -12,6 +12,7 @@ class perspective_camera: public camera { float fov; float stepwidth; direction start; + float defocus; public: /** * @brief Default constructor @@ -45,7 +46,8 @@ class perspective_camera: public camera { */ perspective_camera(const point &position, const point &look_at, const direction &up, const std::array &resolution, const unsigned long max_bounces, - const float &fov, const std::shared_ptr s); + const float &fov, const unsigned long &samples, const std::shared_ptr s, + const float &defocus); virtual std::shared_ptr> get_rays(const unsigned long &x, const unsigned long &y); }; diff --git a/lib/camera/realistic_camera.cpp b/lib/camera/realistic_camera.cpp index 2239a9f..2a97057 100644 --- a/lib/camera/realistic_camera.cpp +++ b/lib/camera/realistic_camera.cpp @@ -7,22 +7,25 @@ realistic_camera::realistic_camera(const point &position, const point &look_at, const direction &up, const std::array &resolution, const unsigned long max_bounces, - const float &fov, const std::shared_ptr &s, float focus) - : perspective_camera(position, look_at, up, resolution, max_bounces, fov, s), focus(focus) { + const float &fov, + const unsigned long &samples, const std::shared_ptr s, const float &defocus, + const float &focus, const float &aperture) + : perspective_camera(position, look_at, up, resolution, max_bounces, fov, + samples, s, defocus), focus(focus), aperture(aperture) { assert(focus > 0); + assert(aperture >= 0); } std::shared_ptr> realistic_camera::get_rays(const unsigned long &x, const unsigned long &y) { - std::shared_ptr> offsets = s->get_samples(); - std::shared_ptr> focus_offsets = s->get_samples(); + std::shared_ptr> offsets = s->get_samples(aperture, aperture, samples); + std::shared_ptr> focus_offsets = s->get_samples(defocus, defocus, samples); std::shared_ptr> out(new std::vector()); direction d = start + direction(-1, 0, 0) * (stepwidth * x) + direction(0, -1, 0) * (stepwidth * y); point fp = point(focus * d); - //for (vec2 os : *offsets) { for (unsigned long i = 0; i < offsets->size(); i++) { point o = point((*offsets)[i][0], (*offsets)[i][1], 0); - out->push_back(transforms(ray(o, fp-o+direction((*focus_offsets)[i][0]/focus, (*focus_offsets)[i][1]/focus, 0)))); + out->push_back(transforms(ray(o, fp-o+direction((*focus_offsets)[i][0], (*focus_offsets)[i][1], 0)))); } return out; } diff --git a/lib/camera/realistic_camera.h b/lib/camera/realistic_camera.h index ebfe9ef..e1420e5 100644 --- a/lib/camera/realistic_camera.h +++ b/lib/camera/realistic_camera.h @@ -11,13 +11,15 @@ class realistic_camera : public perspective_camera { protected: float focus; + float aperture; public: - realistic_camera() : perspective_camera(), focus(std::numeric_limits::max()) { } + realistic_camera() : perspective_camera(), focus(1), aperture(0) { } realistic_camera(const point &position, const point &look_at, const direction &up, const std::array &resolution, const unsigned long max_bounces, const float &fov, - const std::shared_ptr &s, float focus); + const unsigned long &samples, const std::shared_ptr s, const float &defocus, + const float &focus, const float &aperture); virtual std::shared_ptr> get_rays(const unsigned long &x, const unsigned long &y) override; }; diff --git a/lib/geometry/material/lambertian_material.cpp b/lib/geometry/material/lambertian_material.cpp index fa9ea6d..84f4c93 100644 --- a/lib/geometry/material/lambertian_material.cpp +++ b/lib/geometry/material/lambertian_material.cpp @@ -40,7 +40,7 @@ std::shared_ptr> lambertian_material::reflect(const direction & } std::shared_ptr> lambertian_material::refract(const direction &i, const normal &n, const point &x, - const unsigned int &s, const bool internal) const { + const bool internal) const { return std::shared_ptr>(); } diff --git a/lib/geometry/material/lambertian_material.h b/lib/geometry/material/lambertian_material.h index dcc202f..32ea437 100644 --- a/lib/geometry/material/lambertian_material.h +++ b/lib/geometry/material/lambertian_material.h @@ -23,7 +23,7 @@ class lambertian_material: public solid_material { reflect(const direction &i, const normal &n, const point &x, const unsigned int &s) const; virtual std::shared_ptr> - refract(const direction &i, const normal &n, const point &x, const unsigned int &s, const bool internal) const; + refract(const direction &i, const normal &n, const point &x, const bool internal) const; virtual const float get_reflectance() const; diff --git a/lib/geometry/material/material.h b/lib/geometry/material/material.h index 14a3193..da271b0 100644 --- a/lib/geometry/material/material.h +++ b/lib/geometry/material/material.h @@ -61,7 +61,7 @@ class material { * @return The refracted ray(s) */ virtual std::shared_ptr> refract(const direction &i, const normal &n, const point &x, - const unsigned int &s, const bool internal) const = 0; + const bool internal) const = 0; /** * @brief Returns the reflectance diff --git a/lib/geometry/material/phong_material.cpp b/lib/geometry/material/phong_material.cpp index 027aa00..74db44c 100644 --- a/lib/geometry/material/phong_material.cpp +++ b/lib/geometry/material/phong_material.cpp @@ -45,7 +45,7 @@ std::shared_ptr> phong_material::reflect(const direction &i, } std::shared_ptr> phong_material::refract(const direction &i, const normal &n, const point &x, - const unsigned int &s, const bool internal) const { + const bool internal) const { return std::shared_ptr>(); } diff --git a/lib/geometry/material/phong_material.h b/lib/geometry/material/phong_material.h index 49700b3..bfa9cef 100644 --- a/lib/geometry/material/phong_material.h +++ b/lib/geometry/material/phong_material.h @@ -25,7 +25,8 @@ struct phong_material: public solid_material { reflect(const direction &i, const normal &n, const point &x, const unsigned int &s) const; virtual std::shared_ptr> - refract(const direction &i, const normal &n, const point &x, const unsigned int &s, const bool internal) const; + refract(const direction &i, const normal &n, const point &x, + const bool internal) const; virtual const float get_reflectance() const; diff --git a/lib/geometry/material/specular_material.cpp b/lib/geometry/material/specular_material.cpp index 1324b1d..c082a0c 100644 --- a/lib/geometry/material/specular_material.cpp +++ b/lib/geometry/material/specular_material.cpp @@ -46,7 +46,7 @@ std::shared_ptr> specular_material::reflect(const direction &i, } std::shared_ptr> specular_material::refract(const direction &i, const normal &n, const point &x, - const unsigned int &s, const bool internal) const { + const bool internal) const { return std::shared_ptr>(); } diff --git a/lib/geometry/material/specular_material.h b/lib/geometry/material/specular_material.h index eeffaac..227920e 100644 --- a/lib/geometry/material/specular_material.h +++ b/lib/geometry/material/specular_material.h @@ -23,7 +23,8 @@ class specular_material: public phong_material { reflect(const direction &i, const normal &n, const point &x, const unsigned int &s) const; virtual std::shared_ptr> - refract(const direction &i, const normal &n, const point &x, const unsigned int &s, const bool internal) const; + refract(const direction &i, const normal &n, const point &x, + const bool internal) const; virtual const float get_reflectance() const; diff --git a/lib/geometry/material/textured_material.cpp b/lib/geometry/material/textured_material.cpp index c068c06..327d398 100644 --- a/lib/geometry/material/textured_material.cpp +++ b/lib/geometry/material/textured_material.cpp @@ -6,12 +6,7 @@ textured_material::textured_material(const float &ambient, const float &diffuse, const float &specular, const float &exponent, std::shared_ptr>> texture) - : phong_material(color(), - ambient, - diffuse, - specular, - exponent), - texture(texture) { + : phong_material(color(), ambient, diffuse, specular, exponent), texture(texture) { } std::shared_ptr textured_material::shade(const color &lcol, const direction &l, const normal &n, diff --git a/lib/geometry/material/textured_material.h b/lib/geometry/material/textured_material.h index 244f013..2d1f048 100644 --- a/lib/geometry/material/textured_material.h +++ b/lib/geometry/material/textured_material.h @@ -5,8 +5,6 @@ #ifndef RAY_TRACER_TEXTURED_MATERIAL_H #define RAY_TRACER_TEXTURED_MATERIAL_H -#include -#include #include "phong_material.h" class textured_material: public phong_material { diff --git a/lib/geometry/material/transparent_material.cpp b/lib/geometry/material/transparent_material.cpp index 669f824..4df2b3d 100644 --- a/lib/geometry/material/transparent_material.cpp +++ b/lib/geometry/material/transparent_material.cpp @@ -24,40 +24,39 @@ std::shared_ptr transparent_material::shade(const color &lcol, const direction &v, const vec2 &pos, const bool internal) const { - if (this->reflectance + this->transmittance < 1) { + if (reflectance + transmittance < 1) { if (l != direction()) { // Directional light if (!internal) { float phi = std::max(0.0, dot(n, l)); if (phi > 0) { - direction r = n*(2*phi) - l; - return std::make_shared((scale(this->col, lcol*(this->diffuse*phi)) - + lcol*(std::pow(std::max(0.0, dot(v, r)), this->exponent)*this->specular)) - *(1 - this->reflectance - this->transmittance)); + direction r = n * (2 * phi) - l; + return std::make_shared((scale(col, lcol * (diffuse * phi)) + lcol * (std::pow( + std::max(0.0, dot(v, r)), exponent) * specular)) * + (1 - reflectance - transmittance)); } } } else // Ambient light return std::make_shared( - scale(this->col, lcol*this->ambient)*(1 - this->reflectance - this->transmittance)); + scale(col, lcol * ambient) * (1 - reflectance - transmittance)); } return std::make_shared(color()); } std::shared_ptr> transparent_material::refract(const direction &i, const normal &n, const point &x, - const unsigned int &s, const bool internal) const { + const bool internal) const { std::shared_ptr> out(new std::vector()); - // TODO adapt for multisampling const float cosi = dot(n, i); - const float eta = internal ? this->ior : 1/this->ior; - const float sint2 = std::pow(eta, 2)*(1 - std::pow(cosi, 2)); + const float eta = internal ? ior : 1 / ior; + const float sint2 = std::pow(eta, 2) * (1 - std::pow(cosi, 2)); if (sint2 <= 1) - out->push_back(ray(x, -i*eta + n*(eta*cosi - std::sqrt(1 - sint2)))); + out->push_back(ray(x, -i * eta + n * (eta * cosi - std::sqrt(1 - sint2)))); else - out->push_back(ray(x, n*(2*cosi) - i)); + out->push_back(ray(x, n * (2 * cosi) - i)); return out; } const float transparent_material::get_transmittance() const { - return this->transmittance; + return transmittance; } diff --git a/lib/geometry/material/transparent_material.h b/lib/geometry/material/transparent_material.h index 859d4d9..9e8e566 100644 --- a/lib/geometry/material/transparent_material.h +++ b/lib/geometry/material/transparent_material.h @@ -40,7 +40,7 @@ class transparent_material: public specular_material { const bool internal) const override; virtual std::shared_ptr> refract(const direction &i, const normal &n, const point &x, - const unsigned int &s, const bool internal) const override; + const bool internal) const override; virtual const float get_transmittance() const override; }; diff --git a/lib/geometry/shapes/shape.cpp b/lib/geometry/shapes/shape.cpp index b773d6e..0983585 100644 --- a/lib/geometry/shapes/shape.cpp +++ b/lib/geometry/shapes/shape.cpp @@ -46,12 +46,9 @@ std::shared_ptr> shape::reflect(const direction &i, return this->matrl->reflect(i, n, x, s); } -std::shared_ptr> shape::refract(const direction &i, - const normal &n, - const point &x, - const unsigned int &s, +std::shared_ptr> shape::refract(const direction &i, const normal &n, const point &x, const bool internal) const { - return this->matrl->refract(i, n, x, s, internal); + return this->matrl->refract(i, n, x, internal); } const float shape::get_reflectance() const { diff --git a/lib/geometry/shapes/shape.h b/lib/geometry/shapes/shape.h index 5b10a4e..eb8eb44 100644 --- a/lib/geometry/shapes/shape.h +++ b/lib/geometry/shapes/shape.h @@ -73,8 +73,8 @@ class shape: public std::enable_shared_from_this { * @copydoc material::refract() */ std::shared_ptr> - refract(const direction &i, const normal &n, const point &x, const unsigned int &s, - const bool internal) const; + refract(const direction &i, const normal &n, const point &x, + const bool internal) const; /** * Translates the shape according to the given \ref direction vector diff --git a/lib/light/parallel_light.h b/lib/light/parallel_light.h index f55291b..9cb7418 100644 --- a/lib/light/parallel_light.h +++ b/lib/light/parallel_light.h @@ -7,7 +7,6 @@ #include "light.h" #include "../geometry/shapes/shape.h" -#include "../geometry/material/lambertian_material.h" /** * Models a parallel light source diff --git a/lib/parser.cpp b/lib/parser.cpp index a3fccbf..a598c58 100644 --- a/lib/parser.cpp +++ b/lib/parser.cpp @@ -33,14 +33,13 @@ std::shared_ptr parser::parse_perspective_camera(const pugi::xml_node &c nullptr, 10), std::strtoul(cam.child("resolution").attribute("vertical").value(), nullptr, 10)}; - float stepwidth = std::tan( - helper::to_radians(std::strtof(cam.child("horizontal_fov").attribute("angle").value(), nullptr))) / - (resolution[0] / 2); - std::shared_ptr s = parse_sampler(cam.child("sampling"), stepwidth); - std::shared_ptr out(new perspective_camera(*position, *lookat, *up, resolution, - std::strtoul(cam.child("max_bounces").attribute( - "n").value(), nullptr, 10), std::strtof( - cam.child("horizontal_fov").attribute("angle").value(), nullptr), s)); + unsigned long max_bounces = std::strtoul(cam.child("max_bounces").attribute("n").value(), nullptr, 10); + float fov = std::strtof(cam.child("horizontal_fov").attribute("angle").value(), nullptr); + unsigned long samples = 0; + std::shared_ptr s = parse_sampler(cam.child("sampling"), samples); + float defocus = std::strtof(cam.child("defocus").attribute("d").value(), nullptr); + std::shared_ptr out( + new perspective_camera(*position, *lookat, *up, resolution, max_bounces, fov, samples, s, defocus)); return out; } @@ -52,19 +51,17 @@ std::shared_ptr parser::parse_realistic_camera(const pugi::xml_node &cam nullptr, 10), std::strtoul(cam.child("resolution").attribute("vertical").value(), nullptr, 10)}; - float stepwidth = std::tan( - helper::to_radians(std::strtof(cam.child("horizontal_fov").attribute("angle").value(), nullptr))) / - (resolution[0] / 2); - std::shared_ptr s = parse_sampler(cam.child("sampling"), stepwidth); - std::shared_ptr out(new realistic_camera(*position, *lookat, *up, resolution, - std::strtoul(cam.child("max_bounces").attribute( - "n").value(), nullptr, 10), std::strtof( - cam.child("horizontal_fov").attribute("angle").value(), nullptr), s, - std::strtof(cam.child("focus").attribute("d").value(), - nullptr) == 0 - ? std::numeric_limits::max() : std::strtof( - cam.child("focus").attribute("d").value(), - nullptr))); + unsigned long max_bounces = std::strtoul(cam.child("max_bounces").attribute("n").value(), nullptr, 10); + float fov = std::strtof(cam.child("horizontal_fov").attribute("angle").value(), nullptr); + unsigned long samples = 1; + std::shared_ptr s = parse_sampler(cam.child("sampling"), samples); + float defocus = std::strtof(cam.child("defocus").attribute("d").value(), nullptr); + float focus = std::strtof(cam.child("focus").attribute("d").value(), nullptr); + focus = focus == 0 ? std::numeric_limits::max() : focus; + float aperture = std::strtof(cam.child("aperture").attribute("d").value(), nullptr); + std::shared_ptr out( + new realistic_camera(*position, *lookat, *up, resolution, max_bounces, fov, samples, s, defocus, focus, + aperture)); return out; } @@ -184,10 +181,10 @@ std::shared_ptr parser::parse_material(const pugi::xml_node &m) { } else if (std::string(m.attribute("type").value()) == "lambertian") { return std::make_shared(lambertian_material(*parse_color(m.child("color")), std::strtof(m.child("lambertian").attribute( - "ka").value(), + "ka").value(), nullptr), std::strtof(m.child("lambertian").attribute( - "kd").value(), + "kd").value(), nullptr))); } else if (std::string(m.attribute("type").value()) == "specular") { return std::make_shared(specular_material(*parse_color(m.child("color")), @@ -201,34 +198,34 @@ std::shared_ptr parser::parse_material(const pugi::xml_node &m) { m.child("phong").attribute("ks").value(), nullptr), std::strtof(m.child("phong").attribute( - "exponent").value(), + "exponent").value(), nullptr), std::strtof(m.child("reflectance").attribute( - "r").value(), + "r").value(), nullptr))); } else if (std::string(m.attribute("type").value()) == "transparent") { return std::make_shared(transparent_material(*parse_color(m.child("color")), std::strtof(m.child("phong").attribute( - "ka").value(), + "ka").value(), nullptr), std::strtof(m.child("phong").attribute( - "kd").value(), + "kd").value(), nullptr), std::strtof(m.child("phong").attribute( - "ks").value(), + "ks").value(), nullptr), std::strtof(m.child("phong").attribute( - "exponent").value(), + "exponent").value(), nullptr), std::strtof(m.child("reflectance").attribute( - "r").value(), + "r").value(), nullptr), std::strtof( m.child("transmittance").attribute( "t").value(), nullptr), std::strtof(m.child("refraction").attribute( - "iof").value(), + "iof").value(), nullptr))); } else if (std::string(m.attribute("type").value()) == "textured") { return std::make_shared( @@ -264,34 +261,27 @@ std::shared_ptr parser::parse_direction(const pugi::xml_node &d) { } std::shared_ptr>> parser::load_image(const std::string path) { - png::image img(path); + cimg_library::CImg img(path.c_str()); std::shared_ptr>> out(new std::vector>()); - out->reserve(img.get_height()); - for (unsigned long y = 0; y < img.get_height(); y++) { + out->reserve(static_cast(img.height())); + for (unsigned int y = 0; y < img.height(); y++) { out->push_back(std::vector()); - out->at(y).reserve(img.get_width()); - for (unsigned long x = 0; x < img.get_width(); x++) { - png::rgb_pixel tmp = img.get_pixel(x, y); - out->at(y).push_back(color(static_cast(tmp.red) / 255.0f, - static_cast(tmp.green) / 255.0f, - static_cast(tmp.blue) / 255.0f)); + out->at(y).reserve(static_cast(img.width())); + for (unsigned int x = 0; x < img.width(); x++) { + out->at(y).push_back(color(img(x, y, 0) / 255.0f, img(x, y, 1) / 255.0f, img(x, y, 2) / 255.0f)); } } return out; } -std::shared_ptr parser::parse_sampler(const pugi::xml_node &node, - const float &stepwidth) { +std::shared_ptr parser::parse_sampler(const pugi::xml_node &node, unsigned long &samples) { + samples = std::strtoul(node.attribute("n").value(), nullptr, 10); if (std::string(node.attribute("type").value()) == "random") - return parse_random_sampler(node, stepwidth); + return parse_random_sampler(node); else return std::shared_ptr(new sampler()); } -std::shared_ptr parser::parse_random_sampler(const pugi::xml_node &node, - const float &stepwidth) { - - return std::shared_ptr( - new random_sampler(stepwidth, stepwidth, std::strtoul(node.attribute("n").value(), - nullptr, 10))); +std::shared_ptr parser::parse_random_sampler(const pugi::xml_node &node) { + return std::shared_ptr(new random_sampler()); } diff --git a/lib/parser.h b/lib/parser.h index 5266716..e830a10 100644 --- a/lib/parser.h +++ b/lib/parser.h @@ -25,6 +25,7 @@ #include #include #include +#include /** * @brief A parser for input files @@ -146,11 +147,9 @@ class parser { */ static std::shared_ptr>> load_image(const std::string path); - static std::shared_ptr parse_sampler(const pugi::xml_node &node, - const float &stepwidth); + static std::shared_ptr parse_sampler(const pugi::xml_node &node, unsigned long &samples); - static std::shared_ptr parse_random_sampler(const pugi::xml_node &node, - const float &stepwidth); + static std::shared_ptr parse_random_sampler(const pugi::xml_node &node); public: /** diff --git a/lib/sampler/random_sampler.cpp b/lib/sampler/random_sampler.cpp index de913b6..7fe15ce 100644 --- a/lib/sampler/random_sampler.cpp +++ b/lib/sampler/random_sampler.cpp @@ -4,11 +4,19 @@ #include "random_sampler.h" -std::shared_ptr> random_sampler::get_samples() { +random_sampler::random_sampler() { } + +std::shared_ptr> random_sampler::get_samples(const float &width, const float &height, + const unsigned long &count) const { + assert(width >= 0); + assert(height >= 0); + assert(count > 0); std::random_device rd; std::mt19937 gen(rd()); - std::uniform_real_distribution wdis(-width/2, std::nextafter(width/2, std::numeric_limits::max())); - std::uniform_real_distribution hdis(-height/2, std::nextafter(height/2, std::numeric_limits::max())); + std::uniform_real_distribution wdis(-width / 2, + std::nextafter(width / 2, std::numeric_limits::max())); + std::uniform_real_distribution hdis(-height / 2, + std::nextafter(height / 2, std::numeric_limits::max())); std::shared_ptr> out = std::make_shared>(); for (int i = 0; i < count; i++) { out->push_back(vec2(wdis(gen), hdis(gen))); diff --git a/lib/sampler/random_sampler.h b/lib/sampler/random_sampler.h index a5dd968..ffd99d8 100644 --- a/lib/sampler/random_sampler.h +++ b/lib/sampler/random_sampler.h @@ -7,14 +7,12 @@ #include "sampler.h" -class random_sampler: public sampler { +class random_sampler : public sampler { public: - random_sampler() : sampler(width, height, count) { } + random_sampler(); - random_sampler(const float &width, const float &height, const unsigned long &count) : sampler(width, height, - count) { } - - virtual std::shared_ptr> get_samples() override; + virtual std::shared_ptr> get_samples(const float &width, const float &height, + const unsigned long &count) const override; }; diff --git a/lib/sampler/sampler.cpp b/lib/sampler/sampler.cpp index 895dd4f..d66c4a2 100644 --- a/lib/sampler/sampler.cpp +++ b/lib/sampler/sampler.cpp @@ -6,15 +6,14 @@ sampler::sampler() { } -sampler::sampler(const float &width, const float &height, const unsigned long &count) : width(width), height(height), - count(count) { - assert(width > 0); - assert(height > 0); +std::shared_ptr> sampler::get_samples(const float &width, const float &height, + const unsigned long &count) const { + assert(width >= 0); + assert(height >= 0); assert(count > 0); -} - -std::shared_ptr> sampler::get_samples() { std::shared_ptr> out = std::make_shared>(); - out->push_back(vec2()); + for (int i = 0; i < count; i++) { + out->push_back(vec2()); + } return out; } \ No newline at end of file diff --git a/lib/sampler/sampler.h b/lib/sampler/sampler.h index 63936aa..c7161f1 100644 --- a/lib/sampler/sampler.h +++ b/lib/sampler/sampler.h @@ -12,14 +12,10 @@ class sampler { public: - const float width = 0.001953125, height = 0.001953125; - const unsigned long count = 1; - sampler(); - sampler(const float &width, const float &height, const unsigned long &count); - - virtual std::shared_ptr> get_samples(); + virtual std::shared_ptr> get_samples(const float &width, const float &height, + const unsigned long &count) const; }; #endif //RAY_TRACER_SAMPLER_H \ No newline at end of file diff --git a/lib/whitted_rt.cpp b/lib/whitted_rt.cpp index 8060b8a..78bc41c 100644 --- a/lib/whitted_rt.cpp +++ b/lib/whitted_rt.cpp @@ -8,39 +8,41 @@ whitted_rt::whitted_rt(std::shared_ptr background_color, std::shared_ptr cam, std::shared_ptr>> lights, std::shared_ptr>> scene) : background_color( - background_color), cam(cam), lights(lights), scene(scene) { } + background_color), cam(cam), lights(lights), scene(scene) { } color whitted_rt::cast_ray(ray r, int step, bool internal) { - intersection is = this->find_nearest(r); + intersection is = find_nearest(r); if (!is.object) // No intersection - return *this->background_color; + return *background_color; color out = color(); - for (std::shared_ptr &l : *lights) { + for (std::shared_ptr l : *lights) { const std::shared_ptr light_dir(l->get_direction(*is.pos)); - if (!this->cast_shadow(*is.pos, -*light_dir)) { + if (!cast_shadow(*is.pos, -*light_dir)) { *light_dir = normalise(*light_dir); out += *is.object->shade(*l->emit(*light_dir), -*light_dir, *is.norm, -r.d, *is.local_pos, internal); } } if (step < this->cam->get_max_bounces()) { std::shared_ptr> - refl_ray = internal ? nullptr : is.object->reflect(-r.d, *is.norm, *is.pos, 1); + refl_ray = internal ? nullptr : is.object->reflect(-r.d, *is.norm, *is.pos, 1); if (refl_ray != nullptr) { color refl_col = color(); for (ray &rr : *refl_ray) { refl_col += this->cast_ray(rr, step + 1, internal); } - refl_col = (refl_col*(1/refl_ray->size()))*is.object->get_reflectance(); + refl_col = (refl_col * (1 / refl_ray->size())) * is.object->get_reflectance(); out += refl_col; } std::shared_ptr> - refr_ray(is.object->refract(-r.d, internal ? -*is.norm : *is.norm, *is.pos, 1, internal)); + refr_ray(is.object->refract(-r.d, internal ? -*is.norm : *is.norm, *is.pos, internal)); if (refr_ray) { color refr_col = color(); for (ray &rr : *refr_ray) { refr_col += this->cast_ray(rr, step + 1, dot(rr.d, internal ? -*is.norm : *is.norm) < 0 == !internal); } - refr_col = (refr_col*(1/refr_ray->size()))*is.object->get_transmittance(); + refr_col = (refr_col * (1 / refr_ray->size())) * + (internal ? std::exp(-(1-is.object->get_transmittance()) * length(*is.pos - r.o)) + : is.object->get_transmittance()); out += refr_col; } } @@ -50,7 +52,9 @@ color whitted_rt::cast_ray(ray r, int step, bool internal) { void whitted_rt::render() { const std::array resolution = this->cam->get_resolution(); for (unsigned long y = 0; y < resolution[1]; y++) { -#pragma omp parallel for +#ifdef NDEBUG + #pragma omp parallel for +#endif for (unsigned long x = 0; x < resolution[0]; x++) { std::shared_ptr> rays = this->cam->get_rays(x, y); std::vector data; diff --git a/main.cpp b/main.cpp index 6134a99..97661c1 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,5 @@ #include "lib/whitted_rt.h" #include "lib/parser.h" -#include using namespace std;