cmake_minimum_required(VERSION 3.20)
project(volumeRendering)

enable_language(CUDA)
find_package(CUDAToolkit REQUIRED)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD 20)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)

set(BUILD_SHARED_LIBS OFF)

set(COMPILE_FLAGS "--extended-lambda")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
    set(COMPILE_FLAGS "${COMPILE_FLAGS} -lineinfo")
endif ()
if ((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914))
    set(COMPILE_FLAGS "${COMPILE_FLAGS} -Xcompiler \"/Zc:__cplusplus\"")
endif ()

set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${COMPILE_FLAGS}")

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external)

find_package(OpenGL REQUIRED)

set(IMGUI_DIR external/imgui)

# optix
set(OPTIX_INCLUDE "" CACHE STRING "Optix include dir")
if (NOT OPTIX_INCLUDE STREQUAL "")
    add_compile_definitions(ENABLE_OPTIX)
endif ()

set(PROJECT_INCLUDE_DIRS
        include
        cuda
        ${STB_INCLUDE}
        ${OPTIX_INCLUDE}
        ${GLFW_INCLUDE}
        ${GLAD_INCLUDE}
        ${IMGUI_DIR}
        ${IMGUI_DIR}/backends
        ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
        Renderer
)

set(SOURCES_IMGUI
        ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
        ${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp
        ${IMGUI_DIR}/imgui.cpp
        ${IMGUI_DIR}/imgui_draw.cpp
        ${IMGUI_DIR}/imgui_demo.cpp
        ${IMGUI_DIR}/imgui_tables.cpp
        ${IMGUI_DIR}/imgui_widgets.cpp
)

set(SOURCES
        ${SOURCES_IMGUI}
        src/Window.cpp
        src/stb_helper.cpp
        main.cpp
)

set(SOURCES_CUDA
        cuda/Renderer.cu
        cuda/Denoiser.cu
        cuda/Volume.cu
        Renderer/ArrayRenderer.cu
        Renderer/RaymarchRenderer.cu
)

add_executable(volumeRendering ${SOURCES} ${SOURCES_CUDA})

set_property(TARGET volumeRendering PROPERTY CUDA_ARCHITECTURES native)
target_include_directories(volumeRendering PUBLIC ${PROJECT_INCLUDE_DIRS})
target_link_libraries(volumeRendering glfw OpenGL::GL glad)
if ((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914))
    target_compile_options(volumeRendering INTERFACE $<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus>)
endif ()
if (MSVC)
    target_compile_options(volumeRendering INTERFACE $<$<COMPILE_LANGUAGE:CXX>:/W4;/WX>)
else ()
    target_compile_options(volumeRendering INTERFACE
            $<$<COMPILE_LANGUAGE:CUDA>:SHELL:--compiler-options -Werror,-Wall>
            $<$<COMPILE_LANGUAGE:CXX>:-Werror;-Wall;-Wextra;-Wpedantic>
    )
endif ()
