diff --git a/CMakeLists.txt b/CMakeLists.txt index d53f63e..35abe80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,6 @@ project(toddcox-faster) set(CMAKE_CXX_STANDARD 20) include(FetchContent) - include(vendor/fmt.cmake) include(vendor/peglib.cmake) include(vendor/glad.cmake) @@ -13,6 +12,8 @@ include(vendor/glm.cmake) include(vendor/gtest.cmake) include(vendor/yaml-cpp.cmake) +include(vendor/embed.cmake) + add_subdirectory(tc) add_subdirectory(vis) diff --git a/vendor/embed.cmake b/vendor/embed.cmake new file mode 100644 index 0000000..d55fd4d --- /dev/null +++ b/vendor/embed.cmake @@ -0,0 +1,85 @@ +find_program(EMBED_LD ${CMAKE_LINKER}) +find_program(EMBED_OBJCOPY ${CMAKE_OBJCOPY}) + +function(_generate_embed_source EMBED_NAME) + set(options) + set(oneValueArgs SOURCE HEADER) + set(multiValueArgs FILES) + cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(VIEW_DECLARATIONS) + set(VOID_DECLARATIONS) + set(DEFINITIONS) + + foreach (FILE IN LISTS PARSE_FILES) + get_filename_component(FILE_NAME "${FILE}" NAME) + + string(MAKE_C_IDENTIFIER "_binary_${FILE}" SYMBOL) + string(MAKE_C_IDENTIFIER "${FILE_NAME}" IDENTIFIER) + + string(APPEND VIEW_DECLARATIONS + " /// ${FILE} Text Contents\n" + " extern std::string_view const ${IDENTIFIER};\n") + + string(APPEND VOID_DECLARATIONS + " /// ${FILE} Binary Contents\n" + " extern void* const ${IDENTIFIER};\n") + + string(APPEND DEFINITIONS + "// ${IDENTIFIER} (${FILE})\n" + "extern \"C\" const char ${SYMBOL}_start[], ${SYMBOL}_end[];\n" + "std::string_view const ${EMBED_NAME}::${IDENTIFIER}(${SYMBOL}_start, ${SYMBOL}_end);\n" + "void* const ${EMBED_NAME}::bin::${IDENTIFIER} = (void *) ${SYMBOL}_start;\n\n") + endforeach () + + file(WRITE "${PARSE_HEADER}" + "#pragma once\n" + "#include \n\n" + "namespace ${EMBED_NAME} {\n${VIEW_DECLARATIONS}}\n\n" + "namespace ${EMBED_NAME}::bin {\n${VOID_DECLARATIONS}}\n") + + file(WRITE "${PARSE_SOURCE}" + "#include <${EMBED_NAME}.hpp>\n\n" + "${DEFINITIONS}") +endfunction() + +function(_embed_file OUTPUT_OBJECT FILE) + set(OBJECT "${CMAKE_CURRENT_BINARY_DIR}/${FILE}.o") + + set(${OUTPUT_OBJECT} ${OBJECT} PARENT_SCOPE) + + add_custom_command( + COMMENT "Embedding ${FILE} in ${OBJECT}" + OUTPUT "${FILE}.o" DEPENDS "${FILE}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND ${EMBED_LD} -r -o "${OBJECT}" -z noexecstack --format=binary "${FILE}" + COMMAND ${EMBED_OBJCOPY} --rename-section .data=.rodata,alloc,load,readonly,data,contents "${OBJECT}" + VERBATIM + ) +endfunction() + +function(add_embed_library EMBED_NAME) + set(FILES ${ARGN}) + + set(EMBED_ROOT ${CMAKE_CURRENT_BINARY_DIR}/_embed/${EMBED_NAME}) + set(EMBED_SOURCE "${EMBED_ROOT}/${EMBED_NAME}.cpp") + set(EMBED_INCLUDE "${EMBED_ROOT}/include") + set(EMBED_HEADER "${EMBED_INCLUDE}/${EMBED_NAME}.hpp") + + set(OBJECTS) + foreach (FILE ${ARGN}) + _embed_file(OBJECT ${FILE}) + list(APPEND OBJECTS ${OBJECT}) + endforeach () + + message(STATUS "Generating embedding library ${EMBED_NAME}") + _generate_embed_source( + ${EMBED_NAME} + SOURCE ${EMBED_SOURCE} + HEADER ${EMBED_HEADER} + FILES ${FILES}) + + add_library(${EMBED_NAME} STATIC ${OBJECTS} "${EMBED_SOURCE}") + target_include_directories(${EMBED_NAME} PUBLIC "${EMBED_INCLUDE}") + set_target_properties(${EMBED_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) +endfunction() diff --git a/vis/CMakeLists.txt b/vis/CMakeLists.txt index fce5b98..52debce 100644 --- a/vis/CMakeLists.txt +++ b/vis/CMakeLists.txt @@ -1,9 +1,11 @@ -add_custom_target(shaders ALL DEPENDS shader_output) -add_custom_command( - OUTPUT shader_output - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/shaders ${CMAKE_CURRENT_BINARY_DIR}/shaders - COMMENT "copied shaders" -) +#add_custom_target(shaders ALL DEPENDS shader_output) +#add_custom_command( +# OUTPUT shader_output +# COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/shaders ${CMAKE_CURRENT_BINARY_DIR}/shaders +# COMMENT "copied shaders" +#) + +add_subdirectory(shaders) add_custom_target(presets ALL DEPENDS preset_output) add_custom_command( @@ -17,5 +19,5 @@ target_include_directories(vis-util INTERFACE include) add_executable(vis src/main.cpp) target_include_directories(vis PRIVATE include) -target_link_libraries(vis PRIVATE tc glad glm glfw yaml-cpp) -add_dependencies(vis shaders presets) +target_link_libraries(vis PRIVATE tc glad glm glfw yaml-cpp shaders) +add_dependencies(vis presets) diff --git a/vis/include/cgl/shaderprogram.hpp b/vis/include/cgl/shaderprogram.hpp index c411790..2098c78 100644 --- a/vis/include/cgl/shaderprogram.hpp +++ b/vis/include/cgl/shaderprogram.hpp @@ -19,7 +19,9 @@ namespace cgl{ glProgramParameteri(id, GL_PROGRAM_SEPARABLE, GL_TRUE); } - ShaderProgram(const std::string &src) : ShaderProgram() { + explicit ShaderProgram(const std::string_view &src) : ShaderProgram(std::string(src)) {} + + explicit ShaderProgram(const std::string &src) : ShaderProgram() { Shader sh(src); attach(sh); diff --git a/vis/shaders/CMakeLists.txt b/vis/shaders/CMakeLists.txt new file mode 100644 index 0000000..965d2d1 --- /dev/null +++ b/vis/shaders/CMakeLists.txt @@ -0,0 +1,10 @@ +add_embed_library(shaders + curve-ortho.gm.glsl + curve-stereo.gm.glsl + diffuse.fs.glsl + direct-ortho.vs.glsl + direct-stereo.vs.glsl + solid.fs.glsl + deferred.vs.glsl + slice.gm.glsl + ) diff --git a/vis/shaders/slice/deferred.vs.glsl b/vis/shaders/deferred.vs.glsl similarity index 100% rename from vis/shaders/slice/deferred.vs.glsl rename to vis/shaders/deferred.vs.glsl diff --git a/vis/shaders/slice/slice.gm.glsl b/vis/shaders/slice.gm.glsl similarity index 100% rename from vis/shaders/slice/slice.gm.glsl rename to vis/shaders/slice.gm.glsl diff --git a/vis/src/main.cpp b/vis/src/main.cpp index cebbedb..6a8d3bf 100644 --- a/vis/src/main.cpp +++ b/vis/src/main.cpp @@ -19,6 +19,8 @@ #include #include +#include + #ifdef _WIN32 extern "C" { __attribute__((unused)) __declspec(dllexport) int NvOptimusEnablement = 0x00000001; @@ -155,12 +157,9 @@ struct SliceProp : public Prop { template struct SliceRenderer : public Renderer { - cgl::pgm::vert defer = cgl::pgm::vert::file( - "shaders/slice/deferred.vs.glsl"); - cgl::pgm::geom slice = cgl::pgm::geom::file( - "shaders/slice/slice.gm.glsl"); - cgl::pgm::frag solid = cgl::pgm::frag::file( - "shaders/solid.fs.glsl"); + cgl::pgm::vert defer = cgl::pgm::vert(shaders::deferred_vs_glsl); + cgl::pgm::geom slice = cgl::pgm::geom(shaders::slice_gm_glsl); + cgl::pgm::frag solid = cgl::pgm::frag(shaders::solid_fs_glsl); cgl::pipeline pipe; @@ -193,8 +192,7 @@ template struct DirectRenderer : public Renderer { cgl::pipeline pipe; - cgl::pgm::frag solid = cgl::pgm::frag::file( - "shaders/solid.fs.glsl"); + cgl::pgm::frag solid = cgl::pgm::frag(shaders::solid_fs_glsl); DirectRenderer() { pipe.stage(solid); @@ -255,10 +253,10 @@ void run(const std::string &config_file, GLFWwindow *window) { SliceRenderer<4> sRen{}; - cgl::pgm::vert o = cgl::pgm::vert::file("shaders/direct-ortho.vs.glsl"); - cgl::pgm::vert s = cgl::pgm::vert::file("shaders/direct-stereo.vs.glsl"); - cgl::pgm::geom co = cgl::pgm::geom::file("shaders/curve-ortho.gm.glsl"); - cgl::pgm::geom cs = cgl::pgm::geom::file("shaders/curve-stereo.gm.glsl"); + cgl::pgm::vert o = cgl::pgm::vert(shaders::direct_ortho_vs_glsl); + cgl::pgm::vert s = cgl::pgm::vert(shaders::direct_stereo_vs_glsl); + cgl::pgm::geom co = cgl::pgm::geom(shaders::curve_ortho_gm_glsl); + cgl::pgm::geom cs = cgl::pgm::geom(shaders::curve_stereo_gm_glsl); DirectRenderer<2> woRen{}; woRen.pipe.stage(o);