check it out

This commit is contained in:
L-Nafaryus 2023-03-13 22:27:09 +05:00
parent 2811c525d3
commit 9599029c3d
159 changed files with 11334 additions and 8402 deletions

8
.gitignore vendored
View File

@ -1,8 +1,10 @@
cmake-wsl-build-debug cmake-build*/
cmake-build-debug/ build*/
.idea/ .idea/
build/
.ccls-cache/ .ccls-cache/
compile_commands.json compile_commands.json
.cache/ .cache/
temp/ temp/

View File

@ -1,29 +1,34 @@
cmake_minimum_required (VERSION 3.16) cmake_minimum_required (VERSION 3.16)
#
set(HPR_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
set(HPR_EXTERNAL_PATH "${HPR_MODULE_PATH}/external")
set(HPR_TOOLCHAINS_PATH "${HPR_MODULE_PATH}/toolchains")
set(HPR_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/source")
# toolchain
#if (MINGW)
# set(CMAKE_TOOLCHAIN_FILE "${HPR_TOOLCHAINS_PATH}/mingw-gcc.cmake")
#else()
# set(CMAKE_TOOLCHAIN_FILE "${HPR_TOOLCHAINS_PATH}/linux-gcc.cmake")
#endif()
# Extract project version from source # Extract project version from source
file(STRINGS "source/hpr/core/common.hpp" include(${HPR_MODULE_PATH}/hpr-macros.cmake)
hpr_version_defines REGEX "#define HPR_VERSION_(MAJOR|MINOR|PATCH) ")
foreach(ver ${hpr_version_defines}) hpr_parse_version("${HPR_SOURCE_DIR}/hpr/hpr.hpp" "#define HPR_VERSION_(MAJOR|MINOR|PATCH)")
if(ver MATCHES [[#define HPR_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])
set(HPR_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
endif()
endforeach()
if(HPR_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
set(hpr_VERSION_TYPE "${CMAKE_MATCH_1}")
endif()
string(REGEX MATCH "^[0-9]+" HPR_VERSION_PATCH "${HPR_VERSION_PATCH}")
set(HPR_PROJECT_VERSION "${HPR_VERSION_MAJOR}.${HPR_VERSION_MINOR}.${HPR_VERSION_PATCH}")
# Main project # Main project
project( project(
hpr hpr
VERSION "${HPR_PROJECT_VERSION}" VERSION "${HPR_VERSION}"
LANGUAGES CXX LANGUAGES CXX
) )
# Compiler settings
set(CMAKE_CXX_STANDARD 20)
# Detect how project is used # Detect how project is used
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
@ -35,133 +40,124 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
message(AUTHOR_WARNING ${lines}) message(AUTHOR_WARNING ${lines})
endif() endif()
set(HPR_MASTER_PROJECT ON) set(HPR_IS_TOP_LEVEL ON)
set(CMAKE_CXX_STANDARD 20)
message(STATUS ${CMAKE_SOURCE_DIR})
else() else()
set(HPR_MASTER_PROJECT OFF) set(HPR_IS_TOP_LEVEL OFF)
endif() endif()
# Project options
option(HPR_INSTALL "Install hpr files?" ${HPR_IS_TOP_LEVEL})
option(HPR_TEST "Build hpr tests?" ${HPR_IS_TOP_LEVEL})
# Installation settings
# Standard includes
include(GNUInstallDirs) include(GNUInstallDirs)
include(CPack)
# Options set(HPR_INSTALL_INTERFACE "$<INSTALL_INTERFACE:include/${PROJECT_NAME}") # ! '>' not included
option(HPR_INSTALL "Install hpr files?" ${HPR_MASTER_PROJECT})
option(HPR_TEST "Build hpr tests?" ${HPR_MASTER_PROJECT}) # Package manager
include(${HPR_MODULE_PATH}/tools/CPM.cmake)
# Testing # Testing
if(HPR_TEST) if(HPR_TEST)
enable_testing() enable_testing()
option(INSTALL_GMOCK "" OFF) include("${HPR_EXTERNAL_PATH}/googletest.cmake")
option(INSTALL_GTEST "" OFF)
include(${CMAKE_SOURCE_DIR}/cmake/external/googletest.cmake)
include(GoogleTest) include(GoogleTest)
endif() endif()
# Modules # Uninstall target
option(WITH_CONTAINERS "" ON) if (NOT TARGET uninstall)
option(WITH_MATH "" ON) configure_file(
option(WITH_IO "" ON) "${CMAKE_CURRENT_LIST_DIR}/cmake/templates/cmake_uninstall.cmake.in" cmake_uninstall.cmake
option(WITH_MESH "" ON) IMMEDIATE @ONLY
option(WITH_CSG "" ON) )
option(USE_SYSTEM_OCCT "" ON)
option(WITH_GPU "" ON)
option(WITH_WINDOW_SYSTEM "" ON)
set_property(GLOBAL PROPERTY HPR_MODULES "") add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${PROJECT_BINARY_DIR}/cmake_uninstall.cmake")
macro(add_module MODULE) endif()
set_property(GLOBAL APPEND PROPERTY HPR_MODULES "${MODULE}")
endmacro()
# Modules
option(HPR_WITH_CONTAINERS "" ON)
option(HPR_WITH_MATH "" ON)
option(HPR_WITH_IO "" ON)
option(HPR_WITH_MESH "" ON)
option(HPR_WITH_CSG "" ON)
option(HPR_WITH_GPU "" ON)
option(HPR_WITH_PARALLEL "" ON)
include_directories(${HPR_SOURCE_DIR})
add_subdirectory(source/hpr) add_subdirectory(source/hpr)
get_property(hpr_modules GLOBAL PROPERTY HPR_MODULES) hpr_collect_modules()
foreach(module ${hpr_modules})
get_target_property(module_type ${module} TYPE)
if(module_type STREQUAL "INTERFACE_LIBRARY")
list(APPEND HPR_INTERFACE_LIBS "${PROJECT_NAME}::${module}")
else()
list(APPEND HPR_PUBLIC_LIBS "${PROJECT_NAME}::${module}")
endif()
set(hpr_modules_summary "${hpr_modules_summary} ${module}")
endforeach()
# Main library # Main library
add_library(hpr SHARED add_library(hpr SHARED source/hpr/hpr.cpp)
source/hpr/hpr.cpp)
add_library(hpr::hpr ALIAS hpr) add_library(hpr::hpr ALIAS hpr)
target_sources(hpr target_sources(hpr
INTERFACE INTERFACE "$<BUILD_INTERFACE:source/hpr/hpr.hpp>" "${HPR_INSTALL_INTERFACE}>"
"$<BUILD_INTERFACE:source/hpr/hpr.hpp>"
"$<INSTALL_INTERFACE:include/${PROJECT_NAME}>"
) )
target_link_libraries(hpr target_link_libraries(hpr
INTERFACE INTERFACE ${HPR_INTERFACE_LIBS}
${HPR_INTERFACE_LIBS} PUBLIC ${HPR_PUBLIC_LIBS}
PUBLIC
${HPR_PUBLIC_LIBS}
) )
include(CMakePackageConfigHelpers)
configure_package_config_file( # Installation
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" if (HPR_INSTALL)
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" include(CMakePackageConfigHelpers)
INSTALL_DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
)
write_basic_package_version_file( configure_package_config_file(
"${PROJECT_NAME}ConfigVersion.cmake" "${HPR_MODULE_PATH}/templates/Config.cmake.in" "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
VERSION ${PROJECT_VERSION} INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
COMPATIBILITY SameMajorVersion )
)
install(FILES write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake "${PROJECT_NAME}ConfigVersion.cmake"
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion
DESTINATION )
${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}-${PROJECT_VERSION}
) install(FILES
install( ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} COMPONENT devel
)
install(
TARGETS ${PROJECT_NAME} TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
NAMELINK_SKIP LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
) INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} COMPONENT devel
install( )
install(
EXPORT ${PROJECT_NAME}Targets EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}-${HPR_PROJECT_VERSION} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} COMPONENT devel
NAMESPACE ${CMAKE_PROJECT_NAME}:: NAMESPACE ${CMAKE_PROJECT_NAME}::
) )
install( install(
TARGETS ${PROJECT_NAME} FILES source/${PROJECT_NAME}/${PROJECT_NAME}.hpp
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} COMPONENT devel
NAMELINK_ONLY )
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
) set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
set(CPACK_PACKAGE_VERSION "${HPR_VERSION}")
include(CPack)
cpack_add_component(devel DISPLAY_NAME "Development")
cpack_add_component(runtime DISPLAY_NAME "Runtime libraries")
endif()
# Project summary # Project summary
set(summary hpr_print_summary()
"Summary:\n"
"Version: ${HPR_PROJECT_VERSION}\n"
"Master: ${HPR_MASTER_PROJECT}\n"
"Modules: ${hpr_modules_summary}"
)
message(STATUS ${summary})
# Documentation # Documentation
#add_subdirectory(docs) #add_subdirectory(docs)
# Additional applications # Additional applications
add_subdirectory(source/creator)
add_subdirectory(source/applications) add_subdirectory(source/applications)
add_subdirectory(source/creator)

View File

@ -0,0 +1,36 @@
# hpr
## Installation from sources
### Prerequisites
- CMake version 3.16 (or newer)
### Configure
```
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -B cmake-build-debug -S .
```
### Build
```
cmake --build cmake-build-debug --target hpr
```
### Install
```
cmake --install cmake-build-debug --component devel
```
The following install components are supported:
- `runtime` - runtime package (core shared libraries and `.dll` files on Windows* OS).
- `devel` - development package (header files, CMake integration files, library symbolic links, and `.lib` files on Windows* OS).
### Pack
```
cd cmake-build-debug[.gitignore](.gitignore)
cpack
```

View File

@ -1,4 +1,3 @@
include(${CMAKE_SOURCE_DIR}/cmake/tools/CPM.cmake)
CPMAddPackage( CPMAddPackage(
NAME glad NAME glad
@ -6,10 +5,45 @@ CPMAddPackage(
#VERSION 2.0.2 #VERSION 2.0.2
VERSION 0.1.36 VERSION 0.1.36
GIT_PROGRESS TRUE GIT_PROGRESS TRUE
OPTIONS "GLAD_EXPORT ON" "GLAD_INSTALL ON" EXCLUDE_FROM_ALL ON
OPTIONS "GLAD_EXPORT OFF" "GLAD_INSTALL OFF"
) )
#if(glad_ADDED) if(glad_ADDED)
# add_subdirectory("${glad_SOURCE_DIR}/cmake" glad_cmake) set(EXTERNAL_PROJECT_NAME glad)
# glad_add_library(glad REPRODUCIBLE API gl:core=3.3)
#endif() include(GNUInstallDirs)
add_library(glad::glad ALIAS glad)
install(
TARGETS ${EXTERNAL_PROJECT_NAME}
EXPORT ${EXTERNAL_PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT runtime
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT devel
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT devel
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT devel
)
install(
EXPORT ${EXTERNAL_PROJECT_NAME}Targets
FILE ${EXTERNAL_PROJECT_NAME}Targets.cmake
NAMESPACE ${EXTERNAL_PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${EXTERNAL_PROJECT_NAME}
COMPONENT devel
)
install(
DIRECTORY ${glad_BINARY_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
)
endif()

View File

@ -1,8 +1,43 @@
include(${CMAKE_SOURCE_DIR}/cmake/tools/CPM.cmake)
CPMAddPackage(
CPMAddPackage( NAME glfw
NAME glfw GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_REPOSITORY https://github.com/glfw/glfw.git GIT_TAG 3.3.7
GIT_TAG 3.3.7 #EXCLUDE_FROM_ALL ON
EXCLUDE_FROM_ALL ON OPTIONS "GLFW_INSTALL OFF" "GLFW_BUILD_EXAMPLES OFF" "GLFW_BUILD_TESTS OFF"
) )
if(glad_ADDED)
set(EXTERNAL_PROJECT_NAME glfw)
include(GNUInstallDirs)
add_library(glfw::glfw ALIAS glfw)
install(DIRECTORY "${glfw_SOURCE_DIR}/include/GLFW" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
COMPONENT devel
FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
install(FILES "${glfw_BINARY_DIR}/src/glfw3Config.cmake"
"${glfw_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/glfw3
COMPONENT devel)
install(EXPORT glfwTargets FILE glfw3Targets.cmake
EXPORT_LINK_INTERFACE_LIBRARIES
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/glfw3
COMPONENT devel)
install(FILES "${glfw_BINARY_DIR}/src/glfw3.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
COMPONENT devel)
install(
TARGETS ${EXTERNAL_PROJECT_NAME}
EXPORT ${EXTERNAL_PROJECT_NAME}Targets
RUNTIME COMPONENT runtime
LIBRARY COMPONENT devel
ARCHIVE COMPONENT devel
INCLUDES COMPONENT devel
)
endif()

5
cmake/external/glm.cmake vendored Normal file
View File

@ -0,0 +1,5 @@
CPMAddPackage(
NAME glm
GIT_REPOSITORY https://github.com/g-truc/glm.git
GIT_TAG 0.9.9.8
)

View File

@ -1,7 +1,8 @@
include(${CMAKE_SOURCE_DIR}/cmake/tools/CPM.cmake)
CPMAddPackage( CPMAddPackage(
NAME googletest NAME googletest
GIT_REPOSITORY https://github.com/google/googletest.git GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1 GIT_TAG release-1.12.1
EXCLUDE_FROM_ALL ON
OPTIONS "BUILD_GMOCK OFF" "INSTALL_GTEST OFF"
) )

View File

@ -1,86 +1,96 @@
include(${CMAKE_SOURCE_DIR}/cmake/tools/CPM.cmake)
# branch: docking
# branch: docking CPMAddPackage(
CPMAddPackage( NAME imgui_external
NAME imgui_external GIT_REPOSITORY https://github.com/ocornut/imgui.git
GIT_REPOSITORY https://github.com/ocornut/imgui.git GIT_TAG 24dfebf455ac1f7685e1a72272d37b72601fe70c
GIT_TAG 24dfebf455ac1f7685e1a72272d37b72601fe70c DOWNLOAD_ONLY YES
DOWNLOAD_ONLY YES )
)
if(imgui_external_ADDED)
if(imgui_external_ADDED) set(EXTERNAL_PROJECT_NAME imgui)
set(EXTERNAL_PROJECT_NAME imgui)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 17)
find_package(PkgConfig REQUIRED)
find_package(PkgConfig REQUIRED) find_package(Freetype REQUIRED)
find_package(Freetype REQUIRED) find_package(OpenGL REQUIRED)
find_package(OpenGL REQUIRED) find_package(GLFW REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
add_library(${EXTERNAL_PROJECT_NAME}
add_library(${EXTERNAL_PROJECT_NAME} STATIC ${imgui_external_SOURCE_DIR}/imgui.cpp
${imgui_external_SOURCE_DIR}/imgui.cpp ${imgui_external_SOURCE_DIR}/imgui_demo.cpp
${imgui_external_SOURCE_DIR}/imgui_demo.cpp ${imgui_external_SOURCE_DIR}/imgui_draw.cpp
${imgui_external_SOURCE_DIR}/imgui_draw.cpp ${imgui_external_SOURCE_DIR}/imgui_tables.cpp
${imgui_external_SOURCE_DIR}/imgui_tables.cpp ${imgui_external_SOURCE_DIR}/imgui_widgets.cpp
${imgui_external_SOURCE_DIR}/imgui_widgets.cpp
${imgui_external_SOURCE_DIR}/backends/imgui_impl_glfw.cpp
${imgui_external_SOURCE_DIR}/backends/imgui_impl_glfw.cpp ${imgui_external_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
${imgui_external_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
${imgui_external_SOURCE_DIR}/misc/freetype/imgui_freetype.cpp
${imgui_external_SOURCE_DIR}/misc/freetype/imgui_freetype.cpp ${imgui_external_SOURCE_DIR}/misc/cpp/imgui_stdlib.cpp
${imgui_external_SOURCE_DIR}/misc/cpp/imgui_stdlib.cpp )
) add_library(imgui::imgui ALIAS ${EXTERNAL_PROJECT_NAME})
add_library(imgui::imgui ALIAS ${EXTERNAL_PROJECT_NAME})
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
target_include_directories(${EXTERNAL_PROJECT_NAME}
target_include_directories(${EXTERNAL_PROJECT_NAME} PUBLIC
PUBLIC $<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}>
$<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}> $<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}/backends>
$<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}/backends> $<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}/misc/freetype>
$<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}/misc/freetype> $<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}/misc/cpp>
$<BUILD_INTERFACE:${imgui_external_SOURCE_DIR}/misc/cpp>
${FREETYPE_INCLUDE_DIRS}
${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS}
${GLFW_INCLUDE_DIRS} )
)
target_link_libraries(${EXTERNAL_PROJECT_NAME}
target_link_libraries(${EXTERNAL_PROJECT_NAME} PUBLIC
PUBLIC Freetype::Freetype
Freetype::Freetype glfw
glfw OpenGL::GL
OpenGL::GL )
)
set_target_properties(${EXTERNAL_PROJECT_NAME}
set_target_properties(${EXTERNAL_PROJECT_NAME} PROPERTIES
PROPERTIES POSITION_INDEPENDENT_CODE ON
POSITION_INDEPENDENT_CODE ON OUTPUT_NAME imgui
OUTPUT_NAME imgui EXCLUDE_FROM_ALL ON
EXCLUDE_FROM_ALL ON )
)
if(IMGUI_INSTALL)
include(GNUInstallDirs) include(GNUInstallDirs)
install( install(
TARGETS ${EXTERNAL_PROJECT_NAME} TARGETS ${EXTERNAL_PROJECT_NAME}
EXPORT ${EXTERNAL_PROJECT_NAME}Targets EXPORT ${EXTERNAL_PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${EXTERNAL_PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
) COMPONENT runtime
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
install( COMPONENT devel
EXPORT ${EXTERNAL_PROJECT_NAME}Targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
FILE ${EXTERNAL_PROJECT_NAME}Targets.cmake COMPONENT devel
NAMESPACE ${EXTERNAL_PROJECT_NAME}:: INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${EXTERNAL_PROJECT_NAME} COMPONENT devel
)
)
install(
DIRECTORY ${imgui_external_SOURCE_DIR} install(
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${EXTERNAL_PROJECT_NAME} EXPORT ${EXTERNAL_PROJECT_NAME}Targets
COMPONENT devel FILE ${EXTERNAL_PROJECT_NAME}Targets.cmake
FILES_MATCHING NAMESPACE ${EXTERNAL_PROJECT_NAME}::
PATTERN "*.h" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${EXTERNAL_PROJECT_NAME}
PATTERN "*.hpp" COMPONENT devel
) )
endif()
install(
DIRECTORY ${imgui_external_SOURCE_DIR}/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${EXTERNAL_PROJECT_NAME}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
)
endif()
endif()

73
cmake/external/implot.cmake vendored Normal file
View File

@ -0,0 +1,73 @@
CPMAddPackage(
NAME implot_external
GIT_REPOSITORY https://github.com/epezent/implot.git
GIT_TAG v0.14
DOWNLOAD_ONLY YES
)
if(implot_external_ADDED)
set(EXTERNAL_PROJECT_NAME implot)
set(CMAKE_CXX_STANDARD 17)
find_package(PkgConfig REQUIRED)
find_package(Freetype REQUIRED)
find_package(OpenGL REQUIRED)
find_package(GLFW REQUIRED)
add_library(${EXTERNAL_PROJECT_NAME}
${implot_external_SOURCE_DIR}/implot.cpp
${implot_external_SOURCE_DIR}/implot_demo.cpp
${implot_external_SOURCE_DIR}/implot_items.cpp
)
add_library(implot::implot ALIAS ${EXTERNAL_PROJECT_NAME})
target_include_directories(${EXTERNAL_PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${implot_external_SOURCE_DIR}>
)
target_link_libraries(${EXTERNAL_PROJECT_NAME}
PUBLIC
imgui::imgui
)
set_target_properties(${EXTERNAL_PROJECT_NAME}
PROPERTIES
POSITION_INDEPENDENT_CODE ON
OUTPUT_NAME implot
EXCLUDE_FROM_ALL ON
)
if(IMPLOT_INSTALL)
include(GNUInstallDirs)
install(
TARGETS ${EXTERNAL_PROJECT_NAME}
EXPORT ${EXTERNAL_PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT devel
)
install(
EXPORT ${EXTERNAL_PROJECT_NAME}Targets
FILE ${EXTERNAL_PROJECT_NAME}Targets.cmake
NAMESPACE ${EXTERNAL_PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${EXTERNAL_PROJECT_NAME}
COMPONENT devel
)
install(
DIRECTORY ${implot_external_SOURCE_DIR}/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${EXTERNAL_PROJECT_NAME}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
)
endif()
endif()

View File

@ -1,76 +1,67 @@
if(USE_SYSTEM_OCCT) find_package(OpenCASCADE QUIET)
find_package(OpenCASCADE REQUIRED)
if (NOT OpenCASCADE_FOUND)
if(OpenCASCADE_FOUND) CPMAddPackage(
message(STATUS "OCCT: Found") NAME OpenCASCADE
else() GIT_REPOSITORY https://github.com/Open-Cascade-SAS/OCCT.git
message(FATAL "OCCT: Not Found") GIT_TAG V7_6_2
endif() DOWNLOAD_ONLY YES
)
else()
include(${CMAKE_SOURCE_DIR}/cmake/tools/CPM.cmake) if(OpenCASCADE_ADDED)
# They are using CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR for the project root, fix it
CPMAddPackage( file(READ ${OpenCASCADE_SOURCE_DIR}/CMakeLists.txt filedata_)
NAME occt string(FIND "${filedata_}" "CMAKE_SOURCE_DIR" need_patch)
GIT_REPOSITORY https://github.com/Open-Cascade-SAS/OCCT.git
GIT_TAG V7_6_2 if(NOT ${need_patch} EQUAL -1)
DOWNLOAD_ONLY YES string(REPLACE "CMAKE_SOURCE_DIR" "OCCT_SOURCE_DIR" filedata_ "${filedata_}")
) string(REPLACE "CMAKE_BINARY_DIR" "OCCT_BINARY_DIR" filedata_ "${filedata_}")
string(REPLACE "project (OCCT)" "" filedata_ "${filedata_}")
if(occt_ADDED) string(PREPEND filedata_ "project(OCCT)\nset(OCCT_BINARY_DIR $\{_OCCT_BINARY_DIR\})\n")
# They are using CMAKE_SOURCE_DIR and CMAKE_BINARY_DIR for the project root, fix it endif()
file(READ ${occt_SOURCE_DIR}/CMakeLists.txt filedata_) file(WRITE ${OpenCASCADE_SOURCE_DIR}/CMakeLists.txt "${filedata_}")
string(FIND "${filedata_}" "CMAKE_SOURCE_DIR" need_patch)
file(GLOB_RECURSE files_to_patch ${OpenCASCADE_SOURCE_DIR}/adm/cmake "occt_*")
if(NOT ${need_patch} EQUAL -1)
string(REPLACE "CMAKE_SOURCE_DIR" "OCCT_SOURCE_DIR" filedata_ "${filedata_}") foreach(file_path ${files_to_patch})
string(REPLACE "CMAKE_BINARY_DIR" "OCCT_BINARY_DIR" filedata_ "${filedata_}") file(READ ${file_path} filedata_)
string(REPLACE "project (OCCT)" "" filedata_ "${filedata_}") string(REPLACE "CMAKE_SOURCE_DIR" "OCCT_SOURCE_DIR" filedata_ "${filedata_}")
string(PREPEND filedata_ "project(OCCT)\nset(OCCT_BINARY_DIR $\{_OCCT_BINARY_DIR\})\n") string(REPLACE "CMAKE_BINARY_DIR" "OCCT_BINARY_DIR" filedata_ "${filedata_}")
endif() file(WRITE ${file_path} "${filedata_}")
file(WRITE ${occt_SOURCE_DIR}/CMakeLists.txt "${filedata_}") endforeach()
file(GLOB_RECURSE files_to_patch ${occt_SOURCE_DIR}/adm/cmake "occt_*") #project(OCCT)
# find better way to pass build directory
foreach(file_path ${files_to_patch}) #set(_OCCT_BINARY_DIR ${OpenCASCADE_BINARY_DIR})
file(READ ${file_path} filedata_) set(INSTALL_DIR ${OpenCASCADE_BINARY_DIR} CACHE BOOL "" FORCE)
string(REPLACE "CMAKE_SOURCE_DIR" "OCCT_SOURCE_DIR" filedata_ "${filedata_}")
string(REPLACE "CMAKE_BINARY_DIR" "OCCT_BINARY_DIR" filedata_ "${filedata_}") set(USE_TK OFF CACHE BOOL "" FORCE)
file(WRITE ${file_path} "${filedata_}") set(USE_FREETYPE OFF CACHE BOOL "" FORCE)
endforeach() set(USE_TCL OFF CACHE INTERNAL "" FORCE)
project(OCCT) set(BUILD_MODULE_Visualization OFF CACHE BOOL "" FORCE)
# find better way to pass build directory set(BUILD_MODULE_ApplicationFramework OFF CACHE BOOL "" FORCE)
set(_OCCT_BINARY_DIR ${occt_BINARY_DIR}) set(BUILD_MODULE_Draw OFF CACHE BOOL "" FORCE)
set(INSTALL_DIR ${occt_BINARY_DIR} CACHE BOOL "" FORCE)
add_subdirectory(${OpenCASCADE_SOURCE_DIR})
set(USE_TK OFF CACHE BOOL "" FORCE) endif()
set(USE_FREETYPE OFF CACHE BOOL "" FORCE) endif()
set(USE_TCL OFF CACHE INTERNAL "" FORCE)
set(OpenCASCADE_LIBS
set(BUILD_MODULE_Visualization OFF CACHE BOOL "" FORCE) TKernel
set(BUILD_MODULE_ApplicationFramework OFF CACHE BOOL "" FORCE) TKService
set(BUILD_MODULE_Draw OFF CACHE BOOL "" FORCE) TKV3d
TKOpenGl
add_subdirectory(${occt_SOURCE_DIR}) TKBRep
endif() TKBool
endif() TKFillet
TKGeomBase
set(OCCT_LIBRARIES TKGeomAlgo
TKernel TKG3d
TKService TKG2d
TKV3d TKTopAlgo
TKOpenGl TKPrim
TKBRep TKSTEP
TKBool )
TKFillet
TKGeomBase
TKGeomAlgo
TKG3d
TKG2d
TKTopAlgo
TKPrim
TKSTEP
)
set(OCCT_INCLUDE_DIRS ${OpenCASCADE_INCLUDE_DIR})

8
cmake/external/onetbb.cmake vendored Normal file
View File

@ -0,0 +1,8 @@
CPMAddPackage(
NAME onetbb
GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git
GIT_TAG v2021.8.0
EXCLUDE_FROM_ALL ON
OPTIONS "TBB_INSTALL ON" "TBB_TEST OFF" "TBB_BENCH OFF" "BUILD_SHARED_LIBS ON"
)

8
cmake/external/openxlsx.cmake vendored Normal file
View File

@ -0,0 +1,8 @@
CPMAddPackage(
NAME OpenXLSX
GIT_REPOSITORY https://github.com/troldal/OpenXLSX.git
GIT_TAG b80da42d1454f361c29117095ebe1989437db390
#EXCLUDE_FROM_ALL ON
)
set(OPENXLSX_LIBRARY_TYPE "STATIC")

View File

@ -1,49 +1,50 @@
include(${CMAKE_SOURCE_DIR}/cmake/tools/CPM.cmake)
CPMAddPackage(
CPMAddPackage( NAME stb_external
NAME stb_external GIT_REPOSITORY https://github.com/nothings/stb.git
GIT_REPOSITORY https://github.com/nothings/stb.git GIT_TAG af1a5bc352164740c1cc1354942b1c6b72eacb8a
GIT_TAG af1a5bc352164740c1cc1354942b1c6b72eacb8a DOWNLOAD_ONLY TRUE
DOWNLOAD_ONLY TRUE )
)
if(stb_external_ADDED)
if(stb_external_ADDED) set(EXTERNAL_PROJECT_NAME stb)
set(EXTERNAL_PROJECT_NAME stb)
add_library(${EXTERNAL_PROJECT_NAME} INTERFACE EXCLUDE_FROM_ALL)
add_library(${EXTERNAL_PROJECT_NAME} INTERFACE) add_library(stb::stb ALIAS ${EXTERNAL_PROJECT_NAME})
add_library(stb::stb ALIAS ${EXTERNAL_PROJECT_NAME})
target_include_directories(${EXTERNAL_PROJECT_NAME}
target_include_directories(${EXTERNAL_PROJECT_NAME} INTERFACE
INTERFACE $<BUILD_INTERFACE:${stb_external_SOURCE_DIR}>
$<BUILD_INTERFACE:${stb_external_SOURCE_DIR}> )
)
set_target_properties(${EXTERNAL_PROJECT_NAME}
set_target_properties(${EXTERNAL_PROJECT_NAME} PROPERTIES
PROPERTIES OUTPUT_NAME stb
OUTPUT_NAME stb )
)
include(GNUInstallDirs)
include(GNUInstallDirs)
install(
install( TARGETS ${EXTERNAL_PROJECT_NAME}
TARGETS ${EXTERNAL_PROJECT_NAME} EXPORT ${EXTERNAL_PROJECT_NAME}Targets
EXPORT ${EXTERNAL_PROJECT_NAME}Targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/${EXTERNAL_PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${EXTERNAL_PROJECT_NAME} COMPONENT devel
) )
install( install(
EXPORT ${EXTERNAL_PROJECT_NAME}Targets EXPORT ${EXTERNAL_PROJECT_NAME}Targets
FILE ${EXTERNAL_PROJECT_NAME}Targets.cmake FILE ${EXTERNAL_PROJECT_NAME}Targets.cmake
NAMESPACE ${EXTERNAL_PROJECT_NAME}:: NAMESPACE ${EXTERNAL_PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${EXTERNAL_PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${EXTERNAL_PROJECT_NAME}
) COMPONENT devel
)
install(
DIRECTORY ${stb_external_SOURCE_DIR} install(
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${EXTERNAL_PROJECT_NAME} DIRECTORY ${stb_external_SOURCE_DIR}/
COMPONENT devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${EXTERNAL_PROJECT_NAME}
FILES_MATCHING COMPONENT devel
PATTERN "*.h" FILES_MATCHING
PATTERN "*.hpp" PATTERN "*.h"
) PATTERN "*.hpp"
endif() )
endif()

137
cmake/hpr-macros.cmake Normal file
View File

@ -0,0 +1,137 @@
# args: <file to parse> <regex>
# provide: HPR_VERSION
macro(hpr_parse_version _file _regex)
file(
STRINGS "${_file}" _version_defines
REGEX "${_regex}"
)
set(_regex_match "${_regex} +([^ ]+)$")
foreach(_ver ${_version_defines})
if(_ver MATCHES ${_regex_match})
set(_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
endif()
endforeach()
if(_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
set(_VERSION_TYPE "${CMAKE_MATCH_1}")
endif()
string(REGEX MATCH "^[0-9]+" _VERSION_PATCH "${_VERSION_PATCH}")
set(HPR_VERSION "${_VERSION_MAJOR}.${_VERSION_MINOR}.${_VERSION_PATCH}")
endmacro()
# args: <project name> <paths to headers>...
# provide : *_HEADERS *_HEADERS_INTERFACE
macro(hpr_collect_interface _project_name)
file(GLOB ${_project_name}_HEADERS ${ARGN})
foreach(_header_path ${${_project_name}_HEADERS})
list(APPEND ${_project_name}_HEADERS_INTERFACE "$<BUILD_INTERFACE:${_header_path}>")
endforeach()
endmacro()
# args: <project name> <paths to sources>...
# provide : *_SOURCES
macro(hpr_collect_sources _project_name)
file(GLOB ${_project_name}_SOURCES ${ARGN})
endmacro()
# Common installation
# args: <project name> <source dir>
macro(hpr_install _project_name _project_source_dir)
if (HPR_INSTALL)
install(
TARGETS ${_project_name}
EXPORT ${_project_name}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} NAMELINK_SKIP COMPONENT runtime
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT devel
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hpr COMPONENT devel
)
if (BUILD_SHARED_LIBS)
install(
TARGETS ${target}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} NAMELINK_ONLY COMPONENT devel
)
endif()
install(
EXPORT ${_project_name}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/hpr COMPONENT devel
NAMESPACE hpr::
)
install(
DIRECTORY ${_project_source_dir}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hpr COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "tests" EXCLUDE
)
install(
FILES ../${_project_name}.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hpr COMPONENT devel
)
endif()
endmacro()
# Common tests template
# args: <project name> <directory with tests>
macro(hpr_tests _project_name _tests_dir)
if (HPR_TEST)
file(GLOB tests_cpp "${_tests_dir}/*.cpp")
add_executable(${_project_name}-tests ${tests_cpp})
target_link_libraries(
${_project_name}-tests
PUBLIC hpr::${_project_name}
PRIVATE GTest::gtest_main
)
gtest_add_tests(TARGET ${_project_name}-tests)
endif()
endmacro()
# Collect modules
# args: -
macro(hpr_collect_modules_)
set_property(GLOBAL PROPERTY _HPR_MODULES "")
endmacro()
# Add module library
# args: <library name> <library type>
macro(hpr_add_library _library_name _library_type)
set_property(GLOBAL APPEND PROPERTY _HPR_MODULES "${_library_name}")
add_library(${_library_name} ${_library_type})
add_library(hpr::${_library_name} ALIAS ${_library_name})
endmacro()
# args: -
# provide: HPR_MODULES HPR_INTERFACE_LIBS HPR_PUBLIC_LIBS
macro(hpr_collect_modules)
get_property(_hpr_modules GLOBAL PROPERTY _HPR_MODULES)
foreach(_module ${_hpr_modules})
get_target_property(_module_type ${_module} TYPE)
if(_module_type STREQUAL "INTERFACE_LIBRARY")
list(APPEND HPR_INTERFACE_LIBS "${PROJECT_NAME}::${_module}")
else()
list(APPEND HPR_PUBLIC_LIBS "${PROJECT_NAME}::${_module}")
endif()
set(HPR_MODULES "${HPR_MODULES} ${_module}")
endforeach()
endmacro()
# args: -
macro(hpr_print_summary)
set(_summary "hpr-${HPR_VERSION}:${HPR_MODULES}")
message(STATUS ${_summary})
endmacro()

View File

@ -1,7 +1,7 @@
@PACKAGE_INIT@ @PACKAGE_INIT@
include(CMakeFindDependencyMacro) include(CMakeFindDependencyMacro)
include("${CMAKE_CURRENT_LIST_DIR}/hprTargets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@") check_required_components("@PROJECT_NAME@")

View File

@ -0,0 +1,29 @@
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif()
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach (file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval)
if (NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif()
elseif (IS_SYMLINK "$ENV{DESTDIR}${file}")
EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval)
if (NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"")
endif()
else()
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif()
endforeach()

View File

@ -0,0 +1,10 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_ARCH x86_64)
set(CMAKE_C_COMPILER /bin/gcc)
set(CMAKE_CXX_COMPILER /bin/g++)
set(CMAKE_MAKE_PROGRAM /bin/ninja)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -0,0 +1,12 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_ARCH x86_64)
set(MINGW_PREFIX /mingw64)
set(CMAKE_C_COMPILER ${MINGW_PREFIX}/bin/gcc)
set(CMAKE_CXX_COMPILER ${MINGW_PREFIX}/bin/g++)
set(CMAKE_MAKE_PROGRAM ${MINGW_PREFIX}/bin/ninja)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -1,23 +1,23 @@
find_package(Doxygen) find_package(Doxygen)
if(NOT ${DOXYGEN_FOUND}) if(NOT ${DOXYGEN_FOUND})
message(STATUS "Doxygen is not found.") message(STATUS "Doxygen is not found.")
endif() endif()
set(doc_api ${CMAKE_CURRENT_BINARY_DIR}/api/Doxyfile) set(doc_api ${CMAKE_CURRENT_BINARY_DIR}/api/Doxyfile)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/api/Doxyfile.in ${doc_api} @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/api/Doxyfile.in ${doc_api} @ONLY)
add_custom_target( add_custom_target(
documentation documentation
COMMAND ${DOXYGEN_EXECUTABLE} ${doc_api} COMMAND ${DOXYGEN_EXECUTABLE} ${doc_api}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/api WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/api
COMMENT "Generating API documentation with Doxygen" COMMENT "Generating API documentation with Doxygen"
VERBATIM VERBATIM
) )
install( install(
DIRECTORY ${PROJECT_BINARY_DIR}/docs/api/html DIRECTORY ${PROJECT_BINARY_DIR}/docs/api/html
DESTINATION share/doc/${CMAKE_PROJECT_NAME}/api DESTINATION share/doc/${CMAKE_PROJECT_NAME}/api
) )

View File

@ -1,389 +1,389 @@
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Project related configuration options # Project related configuration options
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8 DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "@CMAKE_PROJECT_NAME@" PROJECT_NAME = "@CMAKE_PROJECT_NAME@"
PROJECT_NUMBER = @PROJECT_VERSION@ PROJECT_NUMBER = @PROJECT_VERSION@
PROJECT_BRIEF = PROJECT_BRIEF =
PROJECT_LOGO = PROJECT_LOGO =
OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/api OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/api
CREATE_SUBDIRS = NO CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \ ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \ "The $name widget" \
"The $name file" \ "The $name file" \
is \ is \
provides \ provides \
specifies \ specifies \
contains \ contains \
represents \ represents \
a \ a \
an \ an \
the the
ALWAYS_DETAILED_SEC = NO ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO FULL_PATH_NAMES = NO
STRIP_FROM_PATH = # @PROJECT_SOURCE_DIR@/include @PROJECT_SOURCE_DIR@ STRIP_FROM_PATH = # @PROJECT_SOURCE_DIR@/include @PROJECT_SOURCE_DIR@
STRIP_FROM_INC_PATH = STRIP_FROM_INC_PATH =
SHORT_NAMES = NO SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO JAVADOC_AUTOBRIEF = NO
JAVADOC_BANNER = NO JAVADOC_BANNER = NO
QT_AUTOBRIEF = NO QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO MULTILINE_CPP_IS_BRIEF = NO
PYTHON_DOCSTRING = YES PYTHON_DOCSTRING = YES
INHERIT_DOCS = YES INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4 TAB_SIZE = 4
ALIASES = ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO OPTIMIZE_OUTPUT_VHDL = NO
OPTIMIZE_OUTPUT_SLICE = NO OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING = EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5 TOC_INCLUDE_HEADINGS = 5
AUTOLINK_SUPPORT = YES AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0 LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1 NUM_PROC_THREADS = 1
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Build related configuration options # Build related configuration options
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
EXTRACT_ALL = YES EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO EXTRACT_PRIVATE = NO
EXTRACT_PRIV_VIRTUAL = NO EXTRACT_PRIV_VIRTUAL = NO
EXTRACT_PACKAGE = NO EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO EXTRACT_ANON_NSPACES = NO
RESOLVE_UNNAMED_PARAMS = YES RESOLVE_UNNAMED_PARAMS = YES
HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO HIDE_COMPOUND_REFERENCE= NO
SHOW_HEADERFILE = YES SHOW_HEADERFILE = YES
SHOW_INCLUDE_FILES = YES SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES INLINE_INFO = YES
SORT_MEMBER_DOCS = YES SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS = ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30 MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES SHOW_USED_FILES = YES
SHOW_FILES = YES SHOW_FILES = YES
SHOW_NAMESPACES = YES SHOW_NAMESPACES = YES
FILE_VERSION_FILTER = FILE_VERSION_FILTER =
LAYOUT_FILE = LAYOUT_FILE =
CITE_BIB_FILES = CITE_BIB_FILES =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to warning and progress messages # Configuration options related to warning and progress messages
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
QUIET = NO QUIET = NO
WARNINGS = YES WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES WARN_IF_DOC_ERROR = YES
WARN_IF_INCOMPLETE_DOC = YES WARN_IF_INCOMPLETE_DOC = YES
WARN_NO_PARAMDOC = NO WARN_NO_PARAMDOC = NO
WARN_AS_ERROR = NO WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text" WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE = WARN_LOGFILE =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the input files # Configuration options related to the input files
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
INPUT = @PROJECT_SOURCE_DIR@/source INPUT = @PROJECT_SOURCE_DIR@/source
INPUT_ENCODING = UTF-8 INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \ FILE_PATTERNS = *.c \
*.cc \ *.cc \
*.cxx \ *.cxx \
*.cpp \ *.cpp \
*.c++ \ *.c++ \
*.java \ *.java \
*.ii \ *.ii \
*.ixx \ *.ixx \
*.ipp \ *.ipp \
*.i++ \ *.i++ \
*.inl \ *.inl \
*.idl \ *.idl \
*.ddl \ *.ddl \
*.odl \ *.odl \
*.h \ *.h \
*.hh \ *.hh \
*.hxx \ *.hxx \
*.hpp \ *.hpp \
*.h++ \ *.h++ \
*.l \ *.l \
*.cs \ *.cs \
*.d \ *.d \
*.php \ *.php \
*.php4 \ *.php4 \
*.php5 \ *.php5 \
*.phtml \ *.phtml \
*.inc \ *.inc \
*.m \ *.m \
*.markdown \ *.markdown \
*.md \ *.md \
*.mm \ *.mm \
*.dox \ *.dox \
*.py \ *.py \
*.pyw \ *.pyw \
*.f90 \ *.f90 \
*.f95 \ *.f95 \
*.f03 \ *.f03 \
*.f08 \ *.f08 \
*.f18 \ *.f18 \
*.f \ *.f \
*.for \ *.for \
*.vhd \ *.vhd \
*.vhdl \ *.vhdl \
*.ucf \ *.ucf \
*.qsf \ *.qsf \
*.ice \ *.ice \
*.org *.org
RECURSIVE = YES RECURSIVE = YES
EXCLUDE = EXCLUDE =
EXCLUDE_SYMLINKS = NO EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS = EXCLUDE_SYMBOLS =
EXAMPLE_PATH = EXAMPLE_PATH =
EXAMPLE_PATTERNS = * EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO EXAMPLE_RECURSIVE = NO
IMAGE_PATH = IMAGE_PATH =
INPUT_FILTER = INPUT_FILTER =
FILTER_PATTERNS = FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS = FILTER_SOURCE_PATTERNS =
#USE_MDFILE_AS_MAINPAGE = #USE_MDFILE_AS_MAINPAGE =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to source browsing # Configuration options related to source browsing
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
SOURCE_BROWSER = YES SOURCE_BROWSER = YES
INLINE_SOURCES = NO INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES SOURCE_TOOLTIPS = YES
USE_HTAGS = NO USE_HTAGS = NO
VERBATIM_HEADERS = YES VERBATIM_HEADERS = YES
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index # Configuration options related to the alphabetical class index
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES ALPHABETICAL_INDEX = YES
IGNORE_PREFIX = IGNORE_PREFIX =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the HTML output # Configuration options related to the HTML output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_HTML = YES GENERATE_HTML = YES
HTML_OUTPUT = html HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html HTML_FILE_EXTENSION = .html
HTML_HEADER = HTML_HEADER =
HTML_FOOTER = HTML_FOOTER =
HTML_STYLESHEET = HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET = HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES = HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80 HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO HTML_TIMESTAMP = NO
HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100 HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_FEEDURL = DOCSET_FEEDURL =
DOCSET_BUNDLE_ID = org.doxygen.Project DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO GENERATE_HTMLHELP = NO
CHM_FILE = CHM_FILE =
HHC_LOCATION = HHC_LOCATION =
GENERATE_CHI = NO GENERATE_CHI = NO
CHM_INDEX_ENCODING = CHM_INDEX_ENCODING =
BINARY_TOC = NO BINARY_TOC = NO
TOC_EXPAND = NO TOC_EXPAND = NO
GENERATE_QHP = NO GENERATE_QHP = NO
QCH_FILE = QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME = QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS = QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS =
QHG_LOCATION = QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO DISABLE_INDEX = NO
GENERATE_TREEVIEW = YES GENERATE_TREEVIEW = YES
FULL_SIDEBAR = NO FULL_SIDEBAR = NO
ENUM_VALUES_PER_LINE = 4 ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250 TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO EXT_LINKS_IN_WINDOW = NO
OBFUSCATE_EMAILS = YES OBFUSCATE_EMAILS = YES
HTML_FORMULA_FORMAT = png HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10 FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES FORMULA_TRANSPARENT = YES
FORMULA_MACROFILE = FORMULA_MACROFILE =
USE_MATHJAX = NO USE_MATHJAX = NO
MATHJAX_VERSION = MathJax_2 MATHJAX_VERSION = MathJax_2
MATHJAX_FORMAT = HTML-CSS MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = MATHJAX_RELPATH =
MATHJAX_EXTENSIONS = MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE = MATHJAX_CODEFILE =
SEARCHENGINE = YES SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO SERVER_BASED_SEARCH = NO
EXTERNAL_SEARCH = NO EXTERNAL_SEARCH = NO
SEARCHENGINE_URL = SEARCHENGINE_URL =
SEARCHDATA_FILE = searchdata.xml SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID = EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS = EXTRA_SEARCH_MAPPINGS =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the LaTeX output # Configuration options related to the LaTeX output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_LATEX = NO GENERATE_LATEX = NO
LATEX_OUTPUT = latex LATEX_OUTPUT = latex
LATEX_CMD_NAME = LATEX_CMD_NAME =
MAKEINDEX_CMD_NAME = makeindex MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = makeindex LATEX_MAKEINDEX_CMD = makeindex
COMPACT_LATEX = NO COMPACT_LATEX = NO
PAPER_TYPE = a4 PAPER_TYPE = a4
EXTRA_PACKAGES = EXTRA_PACKAGES =
LATEX_HEADER = LATEX_HEADER =
LATEX_FOOTER = LATEX_FOOTER =
LATEX_EXTRA_STYLESHEET = LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES = LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES PDF_HYPERLINKS = YES
USE_PDFLATEX = YES USE_PDFLATEX = YES
LATEX_BATCHMODE = NO LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY = LATEX_EMOJI_DIRECTORY =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the RTF output # Configuration options related to the RTF output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_RTF = NO GENERATE_RTF = NO
RTF_OUTPUT = rtf RTF_OUTPUT = rtf
COMPACT_RTF = NO COMPACT_RTF = NO
RTF_HYPERLINKS = NO RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE = RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE = RTF_EXTENSIONS_FILE =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the man page output # Configuration options related to the man page output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_MAN = NO GENERATE_MAN = NO
MAN_OUTPUT = man MAN_OUTPUT = man
MAN_EXTENSION = .3 MAN_EXTENSION = .3
MAN_SUBDIR = MAN_SUBDIR =
MAN_LINKS = NO MAN_LINKS = NO
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the XML output # Configuration options related to the XML output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_XML = NO GENERATE_XML = NO
XML_OUTPUT = xml XML_OUTPUT = xml
XML_PROGRAMLISTING = YES XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO XML_NS_MEMB_FILE_SCOPE = NO
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output # Configuration options related to the DOCBOOK output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook DOCBOOK_OUTPUT = docbook
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output # Configuration options for the AutoGen Definitions output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO GENERATE_AUTOGEN_DEF = NO
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to Sqlite3 output # Configuration options related to Sqlite3 output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the Perl module output # Configuration options related to the Perl module output
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
GENERATE_PERLMOD = NO GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX = PERLMOD_MAKEVAR_PREFIX =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the preprocessor # Configuration options related to the preprocessor
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES SEARCH_INCLUDES = YES
INCLUDE_PATH = INCLUDE_PATH =
INCLUDE_FILE_PATTERNS = INCLUDE_FILE_PATTERNS =
PREDEFINED = PREDEFINED =
EXPAND_AS_DEFINED = EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES SKIP_FUNCTION_MACROS = YES
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to external references # Configuration options related to external references
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
TAGFILES = TAGFILES =
GENERATE_TAGFILE = GENERATE_TAGFILE =
ALLEXTERNALS = NO ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES EXTERNAL_PAGES = YES
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the dot tool # Configuration options related to the dot tool
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
DIA_PATH = DIA_PATH =
HIDE_UNDOC_RELATIONS = YES HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES HAVE_DOT = YES
DOT_NUM_THREADS = 0 DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10 DOT_FONTSIZE = 10
DOT_FONTPATH = DOT_FONTPATH =
CLASS_GRAPH = YES CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES GROUP_GRAPHS = YES
UML_LOOK = NO UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10 UML_LIMIT_NUM_FIELDS = 10
DOT_UML_DETAILS = NO DOT_UML_DETAILS = NO
DOT_WRAP_THRESHOLD = 17 DOT_WRAP_THRESHOLD = 17
TEMPLATE_RELATIONS = NO TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO CALL_GRAPH = NO
CALLER_GRAPH = NO CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES DIRECTORY_GRAPH = YES
DIR_GRAPH_MAX_DEPTH = 1 DIR_GRAPH_MAX_DEPTH = 1
DOT_IMAGE_FORMAT = png DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO INTERACTIVE_SVG = NO
DOT_PATH = DOT_PATH =
DOTFILE_DIRS = DOTFILE_DIRS =
MSCFILE_DIRS = MSCFILE_DIRS =
DIAFILE_DIRS = DIAFILE_DIRS =
PLANTUML_JAR_PATH = PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE = PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH = PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50 DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0 MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES GENERATE_LEGEND = YES
DOT_CLEANUP = YES DOT_CLEANUP = YES

View File

@ -1 +1,2 @@
add_subdirectory(periodic) #add_subdirectory(periodic)
add_subdirectory(fes)

View File

@ -0,0 +1,29 @@
cmake_minimum_required (VERSION 3.16)
include(${CMAKE_SOURCE_DIR}/cmake/external/imgui.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/external/implot.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/external/openxlsx.cmake)
project(
fes
VERSION 0.1.0
LANGUAGES CXX
)
# Compiler options
set(CMAKE_CXX_STANDARD 20)
add_executable(${PROJECT_NAME}
fes.cpp
)
target_link_libraries(${PROJECT_NAME}
hpr::gpu
imgui::imgui
implot::implot
OpenXLSX::OpenXLSX
)
target_link_libraries(${PROJECT_NAME} -static gcc stdc++ winpthread -dynamic)
#message(STATUS "${OpenXLSX_DIR}")
#target_include_directories(${PROJECT_NAME} PUBLIC ${OpenXLSX_DIR})

View File

@ -0,0 +1,152 @@
#include <iostream>
#include <OpenXLSX.hpp>
#include <hpr/gpu.hpp>
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <imgui_internal.h>
#include <implot.h>
#include <string>
#include <hpr/containers.hpp>
int main()
{
OpenXLSX::XLDocument doc;
doc.open("fes.xlsx");
auto wb = doc.workbook();
auto wks = wb.worksheet("Капилляриметрия");
std::cout << wb.sheetCount() << std::endl;
auto rng = wks.range(OpenXLSX::XLCellReference("B7"), OpenXLSX::XLCellReference("B52"));
//for (auto cell : rng)
// std::cout << cell.value() << std::endl;
//xlnt::workbook wb;
//wb.load("fes.xlsx");
//auto ws = wb.active_sheet();
//std::clog << wb.sheet_count() << std::endl;
auto window = hpr::gpu::Window{50, 50, 1000, 800, "FES", hpr::gpu::Window::Windowed, nullptr, nullptr};
window.keyClickCallback([](hpr::gpu::Window* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE)
window->state(hpr::gpu::Window::Closed);
});
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImPlot::CreateContext();
ImGui_ImplGlfw_InitForOpenGL(window.instance(), true);
ImGui_ImplOpenGL3_Init("#version 430");
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
while (window.state() != hpr::gpu::Window::Closed)
{
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
static int selected = 0;
if (ImGui::Begin("Table"))
{
if (ImGui::BeginTable("##table", 4, ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_BordersOuterV))
{
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthFixed, 100.0f);
ImGui::TableSetupColumn("Core sample", ImGuiTableColumnFlags_NoHide);
ImGui::TableSetupColumn("Depth", ImGuiTableColumnFlags_NoHide);
ImGui::TableSetupColumn("Lithotype", ImGuiTableColumnFlags_NoHide);
ImGui::TableHeadersRow();
const int start = 7;//54;
const int end = 11;//113;
int n = start;
auto sample_range = wks.range(OpenXLSX::XLCellReference("B" + std::to_string(7)), OpenXLSX::XLCellReference("B" + std::to_string(11)));
hpr::darray<OpenXLSX::XLCell> sample {sample_range.begin(), sample_range.end()};
//auto depth_range = wks.range(OpenXLSX::XLCellReference("H" + std::to_string(start)), OpenXLSX::XLCellReference("H" + std::to_string(end)));
//hpr::darray<OpenXLSX::XLCell> depth {sample_range.begin(), sample_range.end()};
//auto lithotype_range = wks.range(OpenXLSX::XLCellReference("K" + std::to_string(start)), OpenXLSX::XLCellReference("K" + std::to_string(end)));
//hpr::darray<OpenXLSX::XLCell> lithotype {sample_range.begin(), sample_range.end()};
for ( ; n < end; ++n)
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextDisabled("#%d", n);
ImGui::TableNextColumn();
//float value = static_cast<float>(cell.value());
if (ImGui::Selectable(sample[n - start].value().get<std::string>().c_str()))
{
selected = n;
}
ImGui::TableNextColumn();
//ImGui::Text(depth[n - start].value().get<std::string>().c_str());
ImGui::TableNextColumn();
//ImGui::Text(lithotype[n - start].value().get<std::string>().c_str());
++n;
}
ImGui::EndTable();
}
ImGui::End();
}
if (ImGui::Begin("Capillarimetry"))
{
hpr::darray<double> P_c { 0.025, 0.05, 0.1, 0.3, 0.5, 0.7, 1.0};
hpr::darray<double> data;
if (ImGui::BeginTabBar("Graphs", ImGuiTabBarFlags_None))
{
const hpr::darray<std::string> vars {"K_w", "P_n"};
std::map<std::string, hpr::darray<std::string>> cols {
{"K_w", hpr::darray<std::string>{"S", "V", "Y", "AB", "AE", "AH", "AK"}},
{"P_n", hpr::darray<std::string>{"U", "X", "AA", "AD", "AG", "AJ", "AM"}}
};
for (const auto& var : vars)
if (ImGui::BeginTabItem(var.data()))
{
//ImPlot::SetNextAxesToFit();
if (ImPlot::BeginPlot(var.data(), ImVec2(-1, -1) ))
{
ImPlot::SetupAxes("P_c",var.data());
for (const auto& col : cols[var])
data.push(wks.cell(col + std::to_string(selected)).value().get<double>());
ImPlot::PlotLine(var.data(), P_c.data(), data.data(), data.size());
ImPlot::EndPlot();
}
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
ImGui::End();
}
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
window.swapBuffers();
window.pollEvents();
}
ImPlot::DestroyContext();
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
return 0;
}

Binary file not shown.

View File

@ -1,16 +1,16 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(periodic project(periodic
VERSION "0.1.0" VERSION "0.1.0"
LANGUAGES CXX LANGUAGES CXX
) )
add_executable(periodic add_executable(periodic
periodic.cpp periodic.cpp
) )
target_link_libraries(periodic target_link_libraries(periodic
hpr::csg hpr::csg
) )

View File

@ -1,205 +1,205 @@
#pragma once #pragma once
#include "../../hpr/math.hpp" #include "../../hpr/math.hpp"
#include "../../hpr/csg.hpp" #include "../../hpr/csg.hpp"
namespace hpr::csg namespace hpr::csg
{ {
void prints(scalar point) void prints(scalar point)
{ {
std::cout << point << std::endl; std::cout << point << std::endl;
} }
class Lattice : public csg::Shape class Lattice : public csg::Shape
{ {
public: public:
enum class System enum class System
{ {
Triclinic, Triclinic,
Monoclinic, Monoclinic,
Orthorhombic, Orthorhombic,
Tetragonal, Tetragonal,
Rhombohedral, Rhombohedral,
Hexagonal, Hexagonal,
Cubic, Cubic,
Unknown Unknown
}; };
enum class Type enum class Type
{ {
Primitive, Primitive,
BaseCentered, BaseCentered,
BodyCentered, BodyCentered,
FaceCentered, FaceCentered,
Unknown Unknown
}; };
protected: protected:
vec3 p_lengths; vec3 p_lengths;
vec3 p_angles; vec3 p_angles;
Type p_type; Type p_type;
scalar p_radius; scalar p_radius;
darray<vec3> p_controlPoints; darray<vec3> p_controlPoints;
public: public:
Lattice() = delete; Lattice() = delete;
Lattice(const vec3& lengths, const vec3& angles, scalar radius, Type type) : Lattice(const vec3& lengths, const vec3& angles, scalar radius, Type type) :
csg::Shape {}, csg::Shape {},
p_lengths {lengths}, p_lengths {lengths},
p_angles {angles}, p_angles {angles},
p_radius {radius}, p_radius {radius},
p_type {type} p_type {type}
{ {
generateControlPoints(); generateControlPoints();
darray<csg::Shape> spheres; darray<csg::Shape> spheres;
for (const auto& point : controlPoints()) { for (const auto& point : controlPoints()) {
spheres.push(csg::sphere(point, p_radius)); spheres.push(csg::sphere(point, p_radius));
print(point); print(point);
} }
p_shape = csg::Compound(spheres).tshape();//csg::fuse({spheres.front()}, spheres.slice(spheres.begin() + 1, spheres.end())).tshape(); p_shape = csg::Compound(spheres).tshape();//csg::fuse({spheres.front()}, spheres.slice(spheres.begin() + 1, spheres.end())).tshape();
} }
darray<vec3> controlPoints() const darray<vec3> controlPoints() const
{ {
return p_controlPoints; return p_controlPoints;
} }
vec3 lengths() const vec3 lengths() const
{ {
return p_lengths; return p_lengths;
} }
vec3 angles() const vec3 angles() const
{ {
return p_angles; return p_angles;
} }
void generateControlPoints() void generateControlPoints()
{ {
if (p_type == Type::Unknown) if (p_type == Type::Unknown)
throw std::runtime_error("Unknown type of lattice"); throw std::runtime_error("Unknown type of lattice");
p_controlPoints.resize(14); p_controlPoints.resize(14);
// //
vec3 ox {1, 0, 0}; vec3 ox {1, 0, 0};
vec3 oy {0, 1, 0}; vec3 oy {0, 1, 0};
vec3 oz {0, 0, 1}; vec3 oz {0, 0, 1};
vec3 ox1 = hpr::rotate(ox, oz, radians(-p_angles[2])); vec3 ox1 = hpr::rotate(ox, oz, rad(-p_angles[2]));
p_controlPoints.push(vec3{0, 0, 0}); p_controlPoints.push(vec3{0, 0, 0});
p_controlPoints.push(vec3{0, p_lengths[0], 0}); p_controlPoints.push(vec3{0, p_lengths[0], 0});
vec3 t1 = hpr::translate(p_controlPoints.back(), ox1 * p_lengths[1]); vec3 t1 = hpr::translate(p_controlPoints.back(), ox1 * p_lengths[1]);
p_controlPoints.push(t1); p_controlPoints.push(t1);
p_controlPoints.push(hpr::translate(p_controlPoints.front(), ox1 * p_lengths[1])); p_controlPoints.push(hpr::translate(p_controlPoints.front(), ox1 * p_lengths[1]));
print(t1); print(t1);
print(ox1); print(ox1);
scalar c1 = cos(radians(p_angles[2])), c2 = cos(radians(p_angles[1])), c3 = cos(radians(p_angles[0])); scalar c1 = cos(rad(p_angles[2])), c2 = cos(rad(p_angles[1])), c3 = cos(rad(p_angles[0]));
scalar D1 = sqrt(mat3( scalar D1 = sqrt(det(mat3(
1, cos(radians(p_angles[2])), cos(radians(p_angles[1])), 1, cos(rad(p_angles[2])), cos(rad(p_angles[1])),
cos(radians(p_angles[2])), 1, cos(radians(p_angles[0])), cos(rad(p_angles[2])), 1, cos(rad(p_angles[0])),
cos(radians(p_angles[1])), cos(radians(p_angles[0])), 1).det()); cos(rad(p_angles[1])), cos(rad(p_angles[0])), 1)));
scalar volume = 1. / 6. * p_lengths[0] * p_lengths[1] * p_lengths[2] * scalar volume = 1. / 6. * p_lengths[0] * p_lengths[1] * p_lengths[2] *
D1; D1;
scalar s1 = sqrt(std::pow(p_lengths[0], 2) + std::pow(p_lengths[1], 2) - 2 * scalar s1 = sqrt(pow(p_lengths[0], 2) + pow(p_lengths[1], 2) - 2 *
p_lengths[0] * p_lengths[1] * cos(radians(p_angles[2]))); p_lengths[0] * p_lengths[1] * cos(rad(p_angles[2])));
scalar s2 = sqrt(std::pow(p_lengths[1], 2) + std::pow(p_lengths[2], 2) - 2 * scalar s2 = sqrt(pow(p_lengths[1], 2) + pow(p_lengths[2], 2) - 2 *
p_lengths[1] * p_lengths[2] * cos(radians(p_angles[1]))); p_lengths[1] * p_lengths[2] * cos(rad(p_angles[1])));
scalar s3 = sqrt(std::pow(p_lengths[0], 2) + std::pow(p_lengths[2], 2) - 2 * scalar s3 = sqrt(pow(p_lengths[0], 2) + pow(p_lengths[2], 2) - 2 *
p_lengths[0] * p_lengths[2] * cos(radians(p_angles[0]))); p_lengths[0] * p_lengths[2] * cos(rad(p_angles[0])));
scalar area = 1. / 2. * p_lengths[0] * p_lengths[1] * scalar area = 1. / 2. * p_lengths[0] * p_lengths[1] *
sqrt(mat2{1, cos(radians(p_angles[2])), cos(radians(p_angles[2])), 1}.det()); sqrt(det(mat2{1, cos(rad(p_angles[2])), cos(rad(p_angles[2])), 1}));
scalar h1 = 3 * volume / area; scalar h1 = 3 * volume / area;
scalar a1 = asin(h1 / p_lengths[2]); scalar a1 = asin(h1 / p_lengths[2]);
scalar sh1 = sqrt(std::pow(p_lengths[2], 2) - std::pow(h1, 2)); scalar sh1 = sqrt(pow(p_lengths[2], 2) - pow(h1, 2));
scalar sh2 = p_lengths[2] * cos(radians(p_angles[0])); scalar sh2 = p_lengths[2] * cos(rad(p_angles[0]));
scalar a2 = acos(sh2 / sh1); scalar a2 = acos(sh2 / sh1);
vec3 ox2 = hpr::rotate(ox, oy, a1); vec3 ox2 = hpr::rotate(ox, oy, a1);
if (!std::isnan(a2)) if (!isnan(a2))
ox2 = hpr::rotate(ox2, oz, a2); ox2 = hpr::rotate(ox2, oz, a2);
print(ox2); print(ox2);
for (auto n = 0; n < 4; ++n) for (auto n = 0; n < 4; ++n)
p_controlPoints.push(hpr::translate(p_controlPoints[n], ox2 * p_lengths[2])); p_controlPoints.push(hpr::translate(p_controlPoints[n], ox2 * p_lengths[2]));
/*p_controlPoints.push(vec3{p_lengths[0], p_lengths[1], 0}); /*p_controlPoints.push(vec3{p_lengths[0], p_lengths[1], 0});
p_controlPoints.push(vec3{p_lengths[0], 0, 0}); p_controlPoints.push(vec3{p_lengths[0], 0, 0});
p_controlPoints.push(vec3{0, 0, p_lengths[2]}); p_controlPoints.push(vec3{0, 0, p_lengths[2]});
p_controlPoints.push(vec3{0, p_lengths[1], p_lengths[2]}); p_controlPoints.push(vec3{0, p_lengths[1], p_lengths[2]});
p_controlPoints.push(vec3{p_lengths[0], p_lengths[1], p_lengths[2]}); p_controlPoints.push(vec3{p_lengths[0], p_lengths[1], p_lengths[2]});
p_controlPoints.push(vec3{p_lengths[0], 0, p_lengths[2]}); p_controlPoints.push(vec3{p_lengths[0], 0, p_lengths[2]});
// central points on base faces // central points on base faces
if (p_type == Type::BaseCentered || p_type == Type::FaceCentered) if (p_type == Type::BaseCentered || p_type == Type::FaceCentered)
{ {
for (int n = 0; n < 2; ++n) for (int n = 0; n < 2; ++n)
{ {
vec3 center; vec3 center;
for (int k = 0; k < 4; ++k) for (int k = 0; k < 4; ++k)
center += p_controlPoints[k + 4 * n]; center += p_controlPoints[k + 4 * n];
p_controlPoints.push(center * 0.25); p_controlPoints.push(center * 0.25);
} }
} }
// central point (center of mass) // central point (center of mass)
if (p_type == Type::BodyCentered) if (p_type == Type::BodyCentered)
{ {
vec3 center; vec3 center;
for (const auto& point : p_controlPoints) for (const auto& point : p_controlPoints)
center += point; center += point;
p_controlPoints.push(center / p_controlPoints.size()); p_controlPoints.push(center / p_controlPoints.size());
} }
// central points on side faces // central points on side faces
if (p_type == Type::FaceCentered) if (p_type == Type::FaceCentered)
{ {
for (int n = 0; n < 3; ++n) for (int n = 0; n < 3; ++n)
{ {
vec3 center; vec3 center;
for (int k = 0; k < 2; ++k) for (int k = 0; k < 2; ++k)
{ {
center += p_controlPoints[n + k]; center += p_controlPoints[n + k];
center += p_controlPoints[n + k + 4]; center += p_controlPoints[n + k + 4];
} }
p_controlPoints.push(center * 0.25); p_controlPoints.push(center * 0.25);
} }
vec3 center; vec3 center;
for (int n = 0; n < 2; ++n) for (int n = 0; n < 2; ++n)
{ {
center += p_controlPoints[n * 3]; center += p_controlPoints[n * 3];
center += p_controlPoints[4 + n * 3]; center += p_controlPoints[4 + n * 3];
} }
p_controlPoints.push(center * 0.25); p_controlPoints.push(center * 0.25);
} }
mat4 trans = mat4::identity(); mat4 trans = mat4::identity();
vec3 ox {1, 0, 0}; vec3 ox {1, 0, 0};
vec3 oy {0, 1, 0}; vec3 oy {0, 1, 0};
vec3 oz {0, 0, 1}; vec3 oz {0, 0, 1};
int n = 0; int n = 0;
for (auto& point : p_controlPoints) for (auto& point : p_controlPoints)
{ {
if (n == 0 || n == 3) if (n == 0 || n == 3)
{ {
++n; ++n;
continue; continue;
} }
trans.row(3, vec4(point, 0)); trans.row(3, vec4(point, 0));
trans = hpr::rotate(trans, oz, -radians(90 - p_angles[2])); trans = hpr::rotate(trans, oz, -radians(90 - p_angles[2]));
if (n >= 4 && n <= 7) if (n >= 4 && n <= 7)
{ {
trans = hpr::rotate(trans, ox, -radians(90 - p_angles[1])); trans = hpr::rotate(trans, ox, -radians(90 - p_angles[1]));
trans = hpr::rotate(trans, oy, -radians(90 - p_angles[0])); trans = hpr::rotate(trans, oy, -radians(90 - p_angles[0]));
} }
point = vec3(trans.row(3)[0], trans.row(3)[1], trans.row(3)[2]); point = vec3(trans.row(3)[0], trans.row(3)[1], trans.row(3)[2]);
++n; ++n;
}*/ }*/
} }
}; };
} }

View File

@ -1,244 +1,244 @@
#include "../../hpr/math.hpp" #include "../../hpr/math.hpp"
#include "../../hpr/csg.hpp" #include "../../hpr/csg.hpp"
#include <iostream> #include <iostream>
#include <map> #include <map>
using namespace hpr; using namespace hpr;
void print(vec3 vs) void print(vec3 vs)
{ {
for (auto& v : vs) for (auto& v : vs)
std::cout << v << " "; std::cout << v << " ";
std::cout << std::endl; std::cout << std::endl;
} }
class Periodic class Periodic
{ {
protected: protected:
scalar p_alpha; scalar p_alpha;
scalar p_initialRadius; scalar p_initialRadius;
scalar p_sideLength; scalar p_sideLength;
scalar p_filletScale; scalar p_filletScale;
vec3 p_direction; vec3 p_direction;
public: public:
Periodic() : Periodic() :
p_alpha {0.1}, p_alpha {0.1},
p_initialRadius {1}, p_initialRadius {1},
p_filletScale {0.8}, p_filletScale {0.8},
p_direction {} p_direction {}
{} {}
Periodic(scalar alpha, scalar initialRadius, scalar filletScale, const vec3& direction) : Periodic(scalar alpha, scalar initialRadius, scalar filletScale, const vec3& direction) :
p_alpha {alpha}, p_alpha {alpha},
p_initialRadius {initialRadius}, p_initialRadius {initialRadius},
p_filletScale {filletScale}, p_filletScale {filletScale},
p_direction {direction} p_direction {direction}
{} {}
virtual virtual
~Periodic() = default; ~Periodic() = default;
scalar& alpha() scalar& alpha()
{ {
return p_alpha; return p_alpha;
} }
scalar& initialRadius() scalar& initialRadius()
{ {
return p_initialRadius; return p_initialRadius;
} }
virtual virtual
scalar sideLength() = 0; scalar sideLength() = 0;
virtual virtual
scalar gamma() = 0; scalar gamma() = 0;
scalar& filletScale() scalar& filletScale()
{ {
return p_filletScale; return p_filletScale;
} }
scalar radius() const scalar radius() const
{ {
return p_initialRadius / (1. - p_alpha); return p_initialRadius / (1. - p_alpha);
} }
scalar filletRadius() scalar filletRadius()
{ {
scalar analytical = p_initialRadius * sqrt(2) / sqrt(1 - cos(gamma())) - radius(); scalar analytical = p_initialRadius * sqrt(2) / sqrt(1 - cos(gamma())) - radius();
return analytical * p_filletScale; return analytical * p_filletScale;
} }
vec3& direction() vec3& direction()
{ {
return p_direction; return p_direction;
} }
virtual virtual
void build() = 0; void build() = 0;
}; };
class Simple : public Periodic, public csg::Shape class Simple : public Periodic, public csg::Shape
{ {
public: public:
Simple() : Simple() :
csg::Shape {}, csg::Shape {},
Periodic {0.01, 1, 0.8, vec3(1., 0., 0.)} Periodic {0.01, 1, 0.8, vec3(1., 0., 0.)}
{} {}
Simple(scalar alpha, const vec3& direction, scalar filletScale = 0.8) : Simple(scalar alpha, const vec3& direction, scalar filletScale = 0.8) :
Simple {} Simple {}
{ {
p_alpha = alpha; p_alpha = alpha;
p_direction = direction; p_direction = direction;
p_filletScale = filletScale; p_filletScale = filletScale;
} }
Simple(scalar alpha, scalar initialRadius, scalar filletScale, const vec3& direction) : Simple(scalar alpha, scalar initialRadius, scalar filletScale, const vec3& direction) :
Periodic {alpha, initialRadius, filletScale, direction} Periodic {alpha, initialRadius, filletScale, direction}
{} {}
~Simple() override = default; ~Simple() override = default;
scalar sideLength() override scalar sideLength() override
{ {
return 2 * initialRadius(); return 2 * initialRadius();
} }
scalar gamma() override scalar gamma() override
{ {
return hpr::PI - 2 * 0.5 * 0.5 * hpr::PI; return hpr::PI - 2 * 0.5 * 0.5 * hpr::PI;
} }
csg::Shape lattice() csg::Shape lattice()
{ {
csg::Shape lattice; csg::Shape lattice;
darray<csg::Shape> spheres; darray<csg::Shape> spheres;
for (int zn = 0; zn < 3; ++zn) for (int zn = 0; zn < 3; ++zn)
{ {
scalar z = zn * sideLength(); scalar z = zn * sideLength();
for (int yn = 0; yn < 3; ++yn) for (int yn = 0; yn < 3; ++yn)
{ {
scalar y = yn * sideLength(); scalar y = yn * sideLength();
for (int xn = 0; xn < 3; ++xn) for (int xn = 0; xn < 3; ++xn)
{ {
scalar x = xn * sideLength(); scalar x = xn * sideLength();
spheres.push(csg::sphere(vec3(x, y, z), radius())); spheres.push(csg::sphere(vec3(x, y, z), radius()));
} }
} }
} }
lattice = csg::fuse({spheres.front()}, spheres.slice(spheres.begin() + 1, spheres.end())); lattice = csg::fuse({spheres.front()}, spheres.slice(spheres.begin() + 1, spheres.end()));
if (filletScale() > 0) if (filletScale() > 0)
{ {
lattice = lattice.scale({0, 0, 0}, 1e+2); lattice = lattice.scale({0, 0, 0}, 1e+2);
lattice = lattice.fillet(lattice.edges(), filletRadius() * 1e+2); lattice = lattice.fillet(lattice.edges(), filletRadius() * 1e+2);
lattice = lattice.scale({0, 0, 0}, 1e-2); lattice = lattice.scale({0, 0, 0}, 1e-2);
} }
std::cout << (int)lattice.type() << std::endl; std::cout << (int)lattice.type() << std::endl;
return lattice; return lattice;
} }
csg::Shape boxCell() csg::Shape boxCell()
{ {
scalar length = sideLength() * sqrt(2); scalar length = sideLength() * sqrt(2);
scalar width = sideLength() * sqrt(2); scalar width = sideLength() * sqrt(2);
scalar height = sideLength(); scalar height = sideLength();
scalar xl = sqrt(pow(length, 2) * 0.5); scalar xl = sqrt(pow(length, 2) * 0.5);
scalar yw = xl; scalar yw = xl;
scalar zh = height; scalar zh = height;
darray<Shape> edges { darray<Shape> edges {
csg::Edge({xl, 0, 0}, {0, yw, 0}), csg::Edge({xl, 0, 0}, {0, yw, 0}),
csg::Edge({0, yw, 0}, {0, yw, zh}), csg::Edge({0, yw, 0}, {0, yw, zh}),
csg::Edge({0, yw, zh}, {xl, 0, zh}), csg::Edge({0, yw, zh}, {xl, 0, zh}),
csg::Edge({xl, 0, zh}, {xl, 0, 0}) csg::Edge({xl, 0, zh}, {xl, 0, 0})
}; };
csg::Face plgm {edges}; csg::Face plgm {edges};
vec3 localX {csg::Surface(plgm).normal(0, 0)}; vec3 localX {csg::Surface(plgm).normal(0, 0)};
vec3 localZ = vec3(0, 0, 1); vec3 localZ = vec3(0, 0, 1);
vec3 localY = cross(localX, localZ); vec3 localY = cross(localX, localZ);
csg::Shape cell = plgm.extrude(localX, width); csg::Shape cell = plgm.extrude(localX, width);
scalar angle; scalar angle;
hpr::vec3 normal; hpr::vec3 normal;
for (auto& face : cell.faces()) for (auto& face : cell.faces())
{ {
normal = csg::Surface(csg::Face(face)).normal(0, 0); normal = csg::Surface(csg::Face(face)).normal(0, 0);
angle = hpr::angle(localX, normal); angle = hpr::angle(localX, normal);
if (face.tshape().Orientation() == TopAbs_FORWARD) if (face.tshape().Orientation() == TopAbs_FORWARD)
{ {
normal = -normal; normal = -normal;
angle = hpr::angle(localX, normal); angle = hpr::angle(localX, normal);
} }
if (equal(angle, 0.)) if (equal(angle, 0.))
face.label("periodic-south"); face.label("periodic-south");
else if (equal(angle, hpr::PI)) else if (equal(angle, hpr::PI))
face.label("periodic-north"); face.label("periodic-north");
angle = hpr::angle(localY, normal); angle = hpr::angle(localY, normal);
if (equal(angle, 0.)) if (equal(angle, 0.))
face.label("periodic-east"); face.label("periodic-east");
else if (equal(angle, hpr::PI)) else if (equal(angle, hpr::PI))
face.label("periodic-west"); face.label("periodic-west");
angle = hpr::angle(localZ, normal); angle = hpr::angle(localZ, normal);
if (equal(angle, hpr::PI)) if (equal(angle, hpr::PI))
face.label("periodic-down"); face.label("periodic-down");
else if (equal(angle, 0.)) else if (equal(angle, 0.))
face.label("periodic-up"); face.label("periodic-up");
} }
std::cout << (int)cell.type() << std::endl; std::cout << (int)cell.type() << std::endl;
return cell; return cell;
} }
csg::Shape hexagonalPrismCell() csg::Shape hexagonalPrismCell()
{ {
return csg::Shape(); return csg::Shape();
} }
void build() override void build() override
{ {
if (direction() == vec3(1., 0., 0.) || direction() == vec3(1., 0., 0.) || direction() == vec3(0., 0., 1.)) if (direction() == vec3(1., 0., 0.) || direction() == vec3(1., 0., 0.) || direction() == vec3(0., 0., 1.))
p_shape = csg::cut(boxCell(), lattice()).tshape(); p_shape = csg::cut(boxCell(), lattice()).tshape();
else if (direction() == vec3(1., 1., 1.)) else if (direction() == vec3(1., 1., 1.))
p_shape = csg::cut(hexagonalPrismCell(), lattice()).tshape(); p_shape = csg::cut(hexagonalPrismCell(), lattice()).tshape();
else else
throw std::runtime_error("Undefined cell for passed direction"); throw std::runtime_error("Undefined cell for passed direction");
p_shape = this->translate(-this->center()).tshape(); p_shape = this->translate(-this->center()).tshape();
p_shape = this->rotate(this->center(), {0, 0, 1}, 45).tshape(); p_shape = this->rotate(this->center(), {0, 0, 1}, 45).tshape();
for (auto& face : faces()) for (auto& face : faces())
if (face.label() == "default") if (face.label() == "default")
face.label("wall"); face.label("wall");
} }
}; };
#include "lattice.hpp" #include "lattice.hpp"
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
/*Simple simple {0.01, {1., 0., 0.}}; /*Simple simple {0.01, {1., 0., 0.}};
simple.build(); simple.build();
std::cout << (int)simple.type() << std::endl; std::cout << (int)simple.type() << std::endl;
std::cout << simple.volume() << std::endl; std::cout << simple.volume() << std::endl;
*/ */
csg::Lattice lattice {{2, 2, 2}, {90, 90, 90}, 1, csg::Lattice::Type::Primitive}; csg::Lattice lattice {{2, 2, 2}, {90, 90, 90}, 1, csg::Lattice::Type::Primitive};
lattice.dump("latticeTest.step", csg::Shape::Format::STEP); lattice.dump("latticeTest.step", csg::Shape::Format::STEP);
return 0; return 0;
} }

View File

@ -1,3 +1,8 @@
cmake_minimum_required (VERSION 3.16)
include(${CMAKE_SOURCE_DIR}/cmake/external/imgui.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/external/implot.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/external/glm.cmake)
project( project(
hyporo-creator hyporo-creator
@ -7,55 +12,36 @@ project(
# Compiler options # Compiler options
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
# Project options # Project options
include(GNUInstallDirs) #include(GNUInstallDirs)
#include (InstallRequiredSystemLibraries)
if (MINGW)
list(APPEND MINGW_SYSTEM_RUNTIME_LIBS
"/mingw64/bin/libgcc_s_seh-1.dll"
"/mingw64/bin/libwinpthread-1.dll"
"/mingw64/bin/libstdc++-6.dll"
)
endif()
#add_executable(${PROJECT_NAME}
# creator.cpp
#)
include(${CMAKE_SOURCE_DIR}/cmake/external/imgui.cmake)
#message(STATUS "project name: ${PROJECT_NAME}")
#target_link_libraries(${PROJECT_NAME}
# hpr::hpr
# imgui
#)
#target_include_directories(${PROJECT_NAME} #find_package(hpr REQUIRED)
# PRIVATE
# ../
#)
#set(CMAKE_CXX_STANDARD 20)
#add_executable(testi
# test.cpp
#)
#target_include_directories(testi
# PRIVATE
# ../
#)
#target_link_libraries(testi
# hpr::hpr
# imgui
#)
set(CMAKE_CXX_STANDARD 20)
add_executable(hyporo-creator add_executable(hyporo-creator
test2.cpp test2.cpp
) )
target_include_directories(hyporo-creator
PRIVATE
../
)
target_link_libraries(hyporo-creator target_link_libraries(hyporo-creator
hpr::gpu hpr::gpu
hpr::window-system imgui::imgui
imgui implot::implot
) glm::glm
)
target_link_libraries(hyporo-creator -static gcc stdc++ winpthread -dynamic)

135
source/creator/camera.hpp Normal file
View File

@ -0,0 +1,135 @@
#pragma once
#include <hpr/math.hpp>
class Camera
{
public:
enum Projection
{
Perspective,
Orthographic
};
protected:
Projection p_projectionType;
hpr::scalar p_distance;
hpr::scalar p_aspect;
hpr::scalar p_fieldOfView;
hpr::scalar p_nearPlane;
hpr::scalar p_farPlane;
hpr::vec3 p_target;
hpr::vec3 p_left;
hpr::vec3 p_front;
hpr::vec3 p_up;
hpr::vec3 p_angles;
hpr::vec3 p_position;
public:
inline
Camera() :
p_projectionType {Perspective},
p_distance {10},
p_aspect {4.f / 3.f},
p_fieldOfView {45},
p_nearPlane {0.1},//{-100},
p_farPlane {100},
p_target {0, 0, 0},
p_left {1, 0, 0},
p_front {0, 0, -1},
p_up {0, 0, 1},
p_angles {45, 45, 0},
p_position {}
{}
virtual
~Camera() = default;
virtual inline
void projection(Projection projection)
{
p_projectionType = projection;
}
hpr::scalar& aspect()
{
return p_aspect;
}
virtual inline
hpr::mat4 projection() const
{
switch (p_projectionType)
{
case Perspective:
return hpr::perspective(hpr::rad(p_fieldOfView), p_aspect, p_nearPlane, p_farPlane);
case Orthographic:
return hpr::ortho(-p_distance * p_aspect, p_distance * p_aspect, -p_distance, p_distance, p_nearPlane, p_farPlane);
}
}
virtual inline
hpr::mat4 view() = 0;
virtual inline
hpr::vec3& position()
{
return p_position;
}
};
class OrbitCamera : public Camera
{
public:
inline
OrbitCamera() :
Camera {}
{}
virtual
~OrbitCamera() = default;
inline
hpr::mat4 view() override
{
hpr::vec3 rotation {
hpr::cos(hpr::rad(p_angles[1])) * hpr::sin(hpr::rad(p_angles[0])),
hpr::cos(hpr::rad(p_angles[1])) * hpr::cos(hpr::rad(p_angles[0])),
hpr::sin(hpr::rad(p_angles[1]))};
hpr::vec3 pos = p_target + p_distance * rotation;
p_front = p_target - pos;
p_front /= hpr::length(p_front);
p_up = hpr::vec3(0, 0, 1);
p_left = hpr::normalize(hpr::cross(p_up, p_front));
p_up = hpr::cross(p_front, p_left);
p_position = pos;
return hpr::lookAt(pos, pos + p_front, p_up);
}
void rotateEvent(float xdelta, float ydelta)
{
p_angles += hpr::vec3(xdelta, ydelta, 0);
}
void moveEvent(float xdelta, float ydelta)
{
p_target += (p_left * xdelta + p_up * ydelta) * 1e-3f;
}
void scrollEvent(float xdelta, float ydelta)
{
p_distance -= ydelta;
}
};

View File

@ -0,0 +1,12 @@
execute_process(
COMMAND ldd "@CPACK_PACKAGE_DIRECTORY@/@PROJECT_NAME@.exe"
COMMAND grep "mingw"
COMMAND cut "-d" " " "-f" "3"
COMMAND xargs "cp" "-t" "@CMAKE_INSTALL_BINDIR@"
RESULT_VARIABLE EXIT_CODE
)
if(NOT EXIT_CODE EQUAL 0)
message(STATUS "Running pre-build command failed with exit code ${EXIT_CODE}.")
endif()

238
source/creator/drawable.hpp Normal file
View File

@ -0,0 +1,238 @@
#pragma once
#include <hpr/gpu.hpp>
#include <hpr/math.hpp>
using hpr::darray;
class Drawable
{
protected:
gpu::ArrayObject p_arrayObject;
gpu::BufferObject p_vertexBuffer;
gpu::BufferObject p_normalBuffer;
gpu::BufferObject p_colorBuffer;
gpu::BufferObject p_indexBuffer;
gpu::ShaderProgram* p_shaderProgram;
gpu::ArrayObject::Mode p_renderMode;
hpr::vec4 p_color;
public:
gpu::ArrayObject& array()
{
return p_arrayObject;
}
friend constexpr void swap(Drawable& main, Drawable& other)
{
using std::swap;
//swap(main.p)
}
Drawable() :
p_arrayObject {},
p_vertexBuffer {gpu::BufferObject::Vertex},
p_normalBuffer {gpu::BufferObject::Vertex},
p_colorBuffer {gpu::BufferObject::Vertex},
p_indexBuffer {gpu::BufferObject::Index},
p_shaderProgram {nullptr},
p_renderMode {gpu::ArrayObject::Triangles},
p_color {0.7, 0.7, 0.7}
{}
inline explicit
Drawable(gpu::ShaderProgram* shaderProgram) :
p_arrayObject {},
p_vertexBuffer {gpu::BufferObject::Vertex},
p_normalBuffer {gpu::BufferObject::Vertex},
p_colorBuffer {gpu::BufferObject::Vertex},
p_indexBuffer {gpu::BufferObject::Index},
p_shaderProgram {shaderProgram},
p_renderMode {gpu::ArrayObject::Triangles},
p_color {0.7, 0.7, 0.7}
{}
inline
Drawable(const Drawable& drawable) = default;
virtual
~Drawable() = default;
void destroy()
{
p_arrayObject.destroy();
p_vertexBuffer.destroy();
p_normalBuffer.destroy();
p_colorBuffer.destroy();
p_indexBuffer.destroy();
}
[[nodiscard]]
constexpr
gpu::ShaderProgram* shaderProgram() const
{
return p_shaderProgram;
}
constexpr virtual
void renderMode(gpu::ArrayObject::Mode mode)
{
p_renderMode = mode;
}
[[nodiscard]]
constexpr virtual
gpu::ArrayObject::Mode renderMode() const
{
return p_renderMode;
}
template <IsVector V>
inline
void addVertices(const darray<V>& vertices)
{
if (!p_arrayObject.valid())
p_arrayObject.create();
p_arrayObject.bind();
darray<float> data;
data.resize(vertices.size() * vertices[0].size());
for (auto v : vertices) for (auto c : v) data.push(c);
p_vertexBuffer.create(data);
p_arrayObject.attribPointer(p_vertexBuffer, 0, vertices[0].size());
p_arrayObject.unbind();
}
template <IsVector V>
inline
void editVertices(const darray<V>& vertices)
{
if (!p_vertexBuffer.valid())
throw std::runtime_error("Invalid buffer object");
p_arrayObject.bind();
darray<float> data;
data.resize(vertices.size() * vertices[0].size());
for (auto v : vertices) for (auto c : v) data.push(c);
p_vertexBuffer.edit(data);
p_arrayObject.unbind();
}
template <IsVector V>
inline
void addNormals(const darray<V>& normals)
{
if (!p_arrayObject.valid())
p_arrayObject.create();
p_arrayObject.bind();
darray<float> data;
data.resize(normals.size() * normals[0].size());
for (auto v : normals) for (auto c : v) data.push(c);
p_normalBuffer.create(data);
p_arrayObject.attribPointer(p_normalBuffer, 1, normals[0].size());
p_arrayObject.unbind();
}
template <IsVector V>
inline
void addColors(const darray<V>& colors)
{
if (!p_arrayObject.valid())
p_arrayObject.create();
p_arrayObject.bind();
darray<float> data;
data.resize(colors.size() * colors[0].size());
for (auto v : colors) for (auto c : v) data.push(c);
p_colorBuffer.create(data);
p_arrayObject.attribPointer(p_colorBuffer, 2, colors[0].size());
p_arrayObject.unbind();
}
template <IsVector V>
inline
void editColors(const darray<V>& colors)
{
if (!p_colorBuffer.valid())
throw std::runtime_error("Invalid buffer object");
p_arrayObject.bind();
darray<float> data;
data.resize(colors.size() * colors[0].size());
for (auto v : colors) for (auto c : v) data.push(c);
p_colorBuffer.edit(data);
p_arrayObject.unbind();
}
template <IsVector V>
inline
void addIndices(const darray<V>& indices)
{
if (!p_arrayObject.valid())
p_arrayObject.create();
p_arrayObject.bind();
darray<unsigned int> data;
data.resize(indices.size() * indices[0].size());
for (auto v : indices) for (auto c : v) data.push(c);
p_indexBuffer.create(data);
p_arrayObject.unbind();
}
inline virtual
void render(gpu::ArrayObject::Mode mode)
{
p_shaderProgram->bind();
//std::cout << p_shaderProgram->index() << std::endl;
p_arrayObject.bind();
if (!p_colorBuffer.valid()) {
shaderProgram()->uniformVector<float, 4>("objectColor", 1, p_color.data());
}
if (p_indexBuffer.valid())
{
p_indexBuffer.bind();
p_arrayObject.drawElements(mode, p_indexBuffer.size());
}
else
{
p_arrayObject.drawArrays(mode, p_vertexBuffer.size());
}
p_arrayObject.unbind();
p_shaderProgram->unbind();
}
inline virtual
void render()
{
render(p_renderMode);
}
inline virtual
void color(const hpr::vec4& color)
{
p_color = color;
}
inline virtual
hpr::vec4& color()
{
return p_color;
}
};

80
source/creator/entity.hpp Normal file
View File

@ -0,0 +1,80 @@
#pragma once
#include <hpr/gpu.hpp>
#include <hpr/math.hpp>
#include "drawable.hpp"
class Entity : public Drawable
{
protected:
hpr::vec3 p_position;
hpr::quat p_rotation;
hpr::vec3 p_scale;
public:
Entity() :
Drawable {}
{}
inline explicit
Entity(gpu::ShaderProgram* shaderProgram) :
Drawable {shaderProgram}
{}
inline
Entity(const Entity& entity) = default;
/*{
std::cout << "copy" << std::endl;
}*/
~Entity() override = default;
inline virtual
void rotation(const hpr::vec3& angles)
{
p_rotation = hpr::quat(hpr::quat::XYZ, angles);
}
inline virtual
hpr::quat& rotation()
{
return p_rotation;
}
inline virtual
void rotate(const hpr::vec3& axis, hpr::scalar angle)
{
p_rotation *= hpr::quat(axis, angle);
}
hpr::mat4 model()
{
hpr::mat4 model = hpr::mat4::identity();
hpr::translate(model, p_position);
hpr::rotate(model, p_rotation);
hpr::scale(model, p_scale);
return model;
}
inline
void render() override
{
shaderProgram()->bind();
//std::cout << shaderProgram()->index() << std::endl;
//for (auto v : model)
// std::cout << v << " ";
//std::cout << std::endl;
shaderProgram()->uniformMatrix<4, 4>("model", 1, true, model().data());
Drawable::render();
shaderProgram()->unbind();
}
};

157
source/creator/grid.hpp Normal file
View File

@ -0,0 +1,157 @@
#pragma once
#include "entity.hpp"
class Grid : public Entity
{
public:
enum Mode
{
XY,
XZ,
YZ
};
protected:
hpr::scalar p_length;
hpr::scalar p_width;
hpr::scalar p_height;
hpr::scalar p_scale;
Mode p_mode;
public:
Grid(gpu::ShaderProgram* shaderProgram, Mode mode = XY, hpr::scalar scale = 1, hpr::scalar length = 100, hpr::scalar width = 100, hpr::scalar height = 100) :
Entity {shaderProgram},
p_length {length},
p_width {width},
p_height {height},
p_scale {scale},
p_mode {mode}
{
darray<vec3> vertices;
darray<vec3> colors;
construct(vertices, colors);
Entity::addVertices(vertices);
Entity::addColors(colors);
Entity::renderMode(gpu::ArrayObject::Lines);
}
protected:
void construct(darray<vec3>& vertices, darray<vec3>& colors)
{
const darray<vec3> red {vec3(0.98f, 0.21f, 0.32f), vec3(0.98f, 0.21f, 0.32f)};
const darray<vec3> green {vec3(0.45f, 0.67f, 0.1f), vec3(0.45f, 0.67f, 0.1f)};
const darray<vec3> blue {vec3(0.17f, 0.47f, 0.80f), vec3(0.17f, 0.47f, 0.80f)};
const darray<vec3> white {vec3(0.5f, 0.5f, 0.5f), vec3(0.5f, 0.5f, 0.5f)};
switch (p_mode) {
case XY: {
// Y
vertices.push({vec3(0.f, -p_width, 0.f), vec3(0.f, p_width, 0.f)});
colors.push(green);
for (hpr::scalar x = p_scale; x <= p_length; )
{
vertices.push({vec3(x, -p_width, 0.f), vec3(x, p_width, 0.f)});
colors.push(white);
vertices.push({vec3(-x, -p_width, 0.f), vec3(-x, p_width, 0.f)});
colors.push(white);
x += p_scale;
}
// X
vertices.push({vec3(-p_length, 0.f, 0.f), vec3(p_length, 0.f, 0.f)});
colors.push(red);
for (hpr::scalar y = p_scale; y <= p_width; )
{
vertices.push({vec3(-p_length, y, 0.f), vec3(p_length, y, 0.f)});
colors.push(white);
vertices.push({vec3(-p_length, -y, 0.f), vec3(p_length, -y, 0.f)});
colors.push(white);
y += p_scale;
}
break;
}
case XZ: {
// Z
vertices.push({vec3(0.f, 0.f, -p_height), vec3(0.f, 0.f, p_height)});
colors.push(blue);
for (hpr::scalar x = p_scale; x <= p_length; )
{
vertices.push({vec3(x, 0.f, -p_height), vec3(x, 0.f, p_height)});
colors.push(white);
vertices.push({vec3(-x, 0.f, -p_height), vec3(-x, 0.f, p_height)});
colors.push(white);
x += p_scale;
}
// X
vertices.push({vec3(-p_length, 0.f, 0.f), vec3(p_length, 0.f, 0.f)});
colors.push(red);
for (hpr::scalar z = p_scale; z <= p_height; )
{
vertices.push({vec3(-p_length, 0.f, z), vec3(p_length, 0.f, z)});
colors.push(white);
vertices.push({vec3(-p_length, 0.f, -z), vec3(p_length, 0.f, -z)});
colors.push(white);
z += p_scale;
}
break;
}
case YZ: {
// Y
vertices.push({vec3(0.f, -p_width, 0.f), vec3(0.f, p_width, 0.f)});
colors.push(green);
for (hpr::scalar z = p_scale; z <= p_height; )
{
vertices.push({vec3(0.f, -p_width, z), vec3(0.f, p_width, z)});
colors.push(white);
vertices.push({vec3(0.f, -p_width, -z), vec3(0.f, p_width, -z)});
colors.push(white);
z += p_scale;
}
// Z
vertices.push({vec3(0.f, 0.f, -p_height), vec3(0.f, 0.f, p_height)});
colors.push(blue);
for (hpr::scalar y = p_scale; y <= p_width; )
{
vertices.push({vec3(0.f, y, -p_height), vec3(0.f, y, p_height)});
colors.push(white);
vertices.push({vec3(0.f, -y, -p_height), vec3(0.f, -y, p_height)});
colors.push(white);
y += p_scale;
}
}
}
}
public:
void rebuild()
{
darray<vec3> vertices;
darray<vec3> colors;
construct(vertices, colors);
Entity::editVertices(vertices);
Entity::editColors(colors);
Entity::renderMode(gpu::ArrayObject::Lines);
}
void mode(Mode mode)
{
p_mode = mode;
}
void scale(hpr::scalar scale)
{
p_scale = scale;
}
};

134
source/creator/ray.hpp Normal file
View File

@ -0,0 +1,134 @@
#pragma once
#include <hpr/math.hpp>
#include "camera.hpp"
#include "entity.hpp"
using namespace hpr;
vec3 unproject(const vec3& win, const mat4& model, const mat4& proj, const vec4& viewport)
{
mat4 inverse = inv(proj * model);
vec4 tmp = vec4(win, 1.);
tmp[0] = (tmp[0] - viewport[0]) / viewport[2];
tmp[1] = (tmp[1] - viewport[1]) / viewport[3];
tmp = tmp * 2.f - 1.f;
vec4 obj = inverse * tmp;
obj /= obj[3];
return vec3(obj);
}
class Ray
{
public:
vec3 p_position;
vec3 p_direction;
Ray() :
p_position {},
p_direction {}
{}
Ray(const vec3& position, const vec3& direction) :
p_position {position},
p_direction {direction}
{}
void fromScreen(int x, int y, int width, int height, Camera* camera, Entity* entity)
{
/*vec4 start {2.f * (float)x / (float)width - 1.f, 2.f * (float)y / (float)height - 1.f, 0.f, 1.f};
vec4 end {2.f * (float)x / (float)width - 1.f, 2.f * (float)y / (float)height - 1.f, 1.f, 1.f};
mat4 invPV = inv(transpose(camera->projection()) * transpose(camera->view()));
vec4 startWorld = invPV * start;
startWorld /= startWorld[3];
vec4 endWorld = invPV * end;
endWorld /= endWorld[3];*/
vec3 end = unproject(vec3(x, y, 0), entity->model(), camera->projection(), vec4(0, 0, width, height));
p_position = vec3(startWorld);
p_direction = normalize(vec3(endWorld - startWorld));
}
bool obb(const vec3& aabbMin, const vec3& aabbMax, Entity* entity, float& tMin, float& tMax)
{
tMin = 0.;
tMax = 1e+5;
mat4 model = entity->model();
vec3 obbPos {model(0, 3), model(1, 3), model(2, 3)};
vec3 delta = obbPos - p_position;
for (auto n = 0; n < 3; ++n)
{
vec3 axis {model(0, n), model(1, n), model(2, n)};
scalar e = dot(axis, delta);
scalar f = dot(p_direction, axis);
if (hpr::abs(f) > 1e-3)
{
scalar t1 = (e + aabbMin[n]) / f;
scalar t2 = (e + aabbMax[n]) / f;
if (t1 > t2)
std::swap(t1, t2);
if (t2 < tMax)
tMax = t2;
if (t1 > tMin)
tMin = t1;
if (tMax < tMin)
return false;
}
else
{
if (-e + aabbMin[n] > 0.f || -e + aabbMax[n] < 0.f)
return false;
}
}
//dist = tMin;
return true;
}
};
/*
bool RayIntersectsTriangle(Vector3D rayOrigin,
Vector3D rayVector,
Triangle* inTriangle,
Vector3D& outIntersectionPoint)
{
const float EPSILON = 0.0000001;
Vector3D vertex0 = inTriangle->vertex0;
Vector3D vertex1 = inTriangle->vertex1;
Vector3D vertex2 = inTriangle->vertex2;
Vector3D edge1, edge2, h, s, q;
float a,f,u,v;
edge1 = vertex1 - vertex0;
edge2 = vertex2 - vertex0;
h = rayVector.crossProduct(edge2);
a = edge1.dotProduct(h);
if (a > -EPSILON && a < EPSILON)
return false; // This ray is parallel to this triangle.
f = 1.0/a;
s = rayOrigin - vertex0;
u = f * s.dotProduct(h);
if (u < 0.0 || u > 1.0)
return false;
q = s.crossProduct(edge1);
v = f * rayVector.dotProduct(q);
if (v < 0.0 || u + v > 1.0)
return false;
// At this stage we can compute t to find out where the intersection point is on the line.
float t = f * edge2.dotProduct(q);
if (t > EPSILON) // ray intersection
{
outIntersectionPoint = rayOrigin + rayVector * t;
return true;
}
else // This means that there is a line intersection but not a ray intersection.
return false;
}
*/

80
source/creator/scene.hpp Normal file
View File

@ -0,0 +1,80 @@
#pragma once
#include "camera.hpp"
#include "entity.hpp"
#include <hpr/containers/graph.hpp>
class Scene
{
protected:
Camera* p_camera;
hpr::darray<hpr::TreeNode<Entity>> p_nodes;
public:
inline
Scene()
{}
virtual
~Scene()
{
delete p_camera;
for (auto& node : p_nodes)
node.data()->destroy();
}
inline
void camera(Camera* camera)
{
p_camera = camera;
}
inline
Camera* camera()
{
return p_camera;
}
inline
void add(const hpr::TreeNode<Entity>& entityNode)
{
p_nodes.push(entityNode);
}
inline
darray<hpr::TreeNode<Entity>>& nodes()
{
return p_nodes;
}
void render()
{
for (auto node : p_nodes)
{
node.data()->render();
node.data()->shaderProgram()->bind();
// camera
node.data()->shaderProgram()->uniformMatrix<4, 4>("view", 1, true, p_camera->view().data());
node.data()->shaderProgram()->uniformMatrix<4, 4>("projection", 1, true, p_camera->projection().data());
node.data()->shaderProgram()->uniformVector<float, 3>("viewPos", 1, p_camera->position().data());
// light
hpr::vec3 lightColor {1.0f, 1.0f, 1.0f};
node.data()->shaderProgram()->uniformVector<float, 3>("lightColor", 1, lightColor.data());
hpr::vec3 lightPos {1.0f, 1.0f, 1.0f};
node.data()->shaderProgram()->uniformVector<float, 3>("lightPos", 1, lightPos.data());
node.data()->shaderProgram()->unbind();
//for (auto descendant : node.descendants())
// descendant->data()->render();
}
}
};

145
source/creator/shaders.hpp Normal file
View File

@ -0,0 +1,145 @@
#pragma once
const char* vertexSource = R"glsl(
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 color;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 lightPos;
out vec3 Normal;
out vec3 Color;
out vec3 FragPos;
out vec3 LightPos;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0);
gl_PointSize = 5;
Normal = mat3(transpose(inverse(model))) * normal;
Color = color;
FragPos = vec3(view * model * vec4(position, 1.0));
LightPos = lightPos; vec3(view * vec4(lightPos, 1.0));
}
)glsl";
const char* fragmentSource = R"glsl(
#version 430 core
in vec3 Normal;
in vec3 Color;
in vec3 FragPos;
in vec3 LightPos;
//uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec4 objectColor;
uniform vec3 viewPos;
out vec4 FragColor;
void main()
{
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(LightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// specular
float specularStrength = 0.2;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
vec3 result = (ambient + diffuse) * vec3(objectColor);
FragColor = vec4(result, 1.0);
}
)glsl";
const char* gridVertexSource = R"glsl(
#version 430 core
uniform mat4 view;
uniform mat4 projection;
vec3 position = vec3(0, 0, 0);
// Grid position are in xy clipped space
vec3 gridPlane[6] = vec3[](
vec3(1, 1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
vec3(-1, -1, 0), vec3(1, 1, 0), vec3(1, -1, 0)
);
// normal vertice projection
void main() {
gl_Position = projection * view * vec4(gridPlane[gl_VertexID].xyz, 1.0);
}
)glsl";
const char* gridFragmentSource = R"glsl(
#version 430 core
const float tileSize = 0.2;
const float borderSize = 0.468;
const float lineBlur = 0.2;
vec2 aGrid(vec2 uv) {
return vec2(mod(uv.x, 1.0), mod(uv.y * 2.0, 1.0));
}
vec2 bGrid(vec2 uv) {
return vec2(mod(uv.x - 0.5, 1.0), mod((uv.y * 2.0) - 0.5, 1.0));
}
float los(vec2 pos) {
vec2 abspos = abs(pos - vec2(0.5));
return smoothstep(borderSize, borderSize + lineBlur, abspos.x + abspos.y);
}
out vec4 fragColor;
void main() {
vec2 uv = vec2(1.0, 0.);//fragCoord;// / iResolution.xy;
vec2 size = uv / tileSize;
float alos = los(aGrid(size));
float blos = los(bGrid(size));
float color = min(alos, blos);
color = pow(color, 1.0 / 2.2);
fragColor = vec4(color);
}
)glsl";
/*
float4 HeatMapColor(float value, float minValue, float maxValue)
{
#define HEATMAP_COLORS_COUNT 6
float4 colors[HEATMAP_COLORS_COUNT] =
{
float4(0.32, 0.00, 0.32, 1.00),
float4(0.00, 0.00, 1.00, 1.00),
float4(0.00, 1.00, 0.00, 1.00),
float4(1.00, 1.00, 0.00, 1.00),
float4(1.00, 0.60, 0.00, 1.00),
float4(1.00, 0.00, 0.00, 1.00),
};
float ratio=(HEATMAP_COLORS_COUNT-1.0)*saturate((value-minValue)/(maxValue-minValue));
float indexMin=floor(ratio);
float indexMax=min(indexMin+1,HEATMAP_COLORS_COUNT-1);
return lerp(colors[indexMin], colors[indexMax], ratio-indexMin);
}
* */

View File

@ -1,269 +1,269 @@
#ifndef __gl_h_ #ifndef __gl_h_
#include <glad/glad.h> #include <glad/glad.h>
#endif #endif
#include "hpr/window_system/window_system.hpp" #include "hpr/window_system/window_system.hpp"
#include "hpr/window_system/glfw/window_system.hpp" #include "hpr/window_system/glfw/window_system.hpp"
#include "hpr/window_system/glfw/window.hpp" #include "hpr/window_system/glfw/window.hpp"
#include "hpr/gpu.hpp" #include "hpr/gpu.hpp"
#include "hpr/math.hpp" #include "hpr/math.hpp"
#include "hpr/mesh.hpp" #include "hpr/mesh.hpp"
#include <imgui.h> #include <imgui.h>
#include <imgui_impl_glfw.h> #include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h> #include <imgui_impl_opengl3.h>
#include <iostream> #include <iostream>
const char *vertexShaderSource = "#version 330 core\n" const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n" "layout (location = 0) in vec3 aPos;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0"; "}\0";
const char *fragmentShaderSource = "#version 330 core\n" const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n" "out vec4 FragColor;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0"; "}\n\0";
const GLchar* vertexSource = R"glsl( const GLchar* vertexSource = R"glsl(
#version 150 core #version 150 core
in vec3 position; in vec3 position;
in vec3 color; in vec3 color;
in vec2 texcoord; in vec2 texcoord;
out vec3 Color; out vec3 Color;
out vec2 Texcoord; out vec2 Texcoord;
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
uniform mat4 proj; uniform mat4 proj;
uniform vec3 overrideColor; uniform vec3 overrideColor;
void main() void main()
{ {
Color = overrideColor * color; Color = overrideColor * color;
Texcoord = texcoord; Texcoord = texcoord;
gl_Position = proj * view * model * vec4(position, 1.0); gl_Position = proj * view * model * vec4(position, 1.0);
} }
)glsl"; )glsl";
int main() int main()
{ {
using namespace hpr; using namespace hpr;
gpu::WindowSystem *ws = gpu::WindowSystem::create(gpu::WindowContext::Provider::GLFW); gpu::WindowSystem *ws = gpu::WindowSystem::create(gpu::WindowContext::Provider::GLFW);
gpu::Window *w = ws->newWindow(); gpu::Window *w = ws->newWindow();
w->init("test", gpu::Window::Style::Windowed, 0, 0, 600, 400, nullptr, nullptr); w->init("test", gpu::Window::Style::Windowed, 0, 0, 600, 400, nullptr, nullptr);
if (gpu::opengl::Device::loadLoader()) if (gpu::opengl::Device::loadLoader())
std::cerr << "Load gl loader error" << std::endl; std::cerr << "Load gl loader error" << std::endl;
// build and compile our shader program // build and compile our shader program
// ------------------------------------ // ------------------------------------
// vertex shader // vertex shader
/*unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); /*unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader); glCompileShader(vertexShader);
// check for shader compile errors // check for shader compile errors
int success; int success;
char infoLog[512]; char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) if (!success)
{ {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
} }
// fragment shader // fragment shader
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader); glCompileShader(fragmentShader);
// check for shader compile errors // check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) if (!success)
{ {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
} }
// link shaders // link shaders
unsigned int shaderProgram = glCreateProgram(); unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader); glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram); glLinkProgram(shaderProgram);
// check for linking errors // check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) { if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
} }
glDeleteShader(vertexShader); glDeleteShader(vertexShader);
glDeleteShader(fragmentShader); glDeleteShader(fragmentShader);
*/ */
mesh::Mesh mesh; mesh::Mesh mesh;
mesh.addVertex(-1, 1, 0.5); mesh.addVertex(-1, 1, 0.5);
mesh.addVertex(1, 1, 0.5); mesh.addVertex(1, 1, 0.5);
mesh.addVertex(1, -1, 0.5); mesh.addVertex(1, -1, 0.5);
mesh.addVertex(-1, -1, 0.5); mesh.addVertex(-1, -1, 0.5);
mesh.addEdge(mesh.vertex(0), mesh.vertex(1)); mesh.addEdge(mesh.vertex(0), mesh.vertex(1));
mesh.addEdge(mesh.vertex(1), mesh.vertex(2)); mesh.addEdge(mesh.vertex(1), mesh.vertex(2));
mesh.addEdge(mesh.vertex(2), mesh.vertex(3)); mesh.addEdge(mesh.vertex(2), mesh.vertex(3));
mesh.addEdge(mesh.vertex(3), mesh.vertex(0)); mesh.addEdge(mesh.vertex(3), mesh.vertex(0));
mesh.addEdge(mesh.vertex(0), mesh.vertex(2)); mesh.addEdge(mesh.vertex(0), mesh.vertex(2));
mesh.addFace(mesh.edge(0), mesh.edge(1), mesh.edge(4)); mesh.addFace(mesh.edge(0), mesh.edge(1), mesh.edge(4));
mesh.addFace(mesh.edge(2), mesh.edge(3), mesh.edge(4)); mesh.addFace(mesh.edge(2), mesh.edge(3), mesh.edge(4));
/*darray<float> data (3 * 6, 0.f); /*darray<float> data (3 * 6, 0.f);
auto arr = mesh.face(0)->vertices() + mesh.face(1)->vertices(); auto arr = mesh.face(0)->vertices() + mesh.face(1)->vertices();
for (auto n = 0; n < arr.size(); ++n) for (auto n = 0; n < arr.size(); ++n)
for (auto k = 0; k < 3; ++k) for (auto k = 0; k < 3; ++k)
data[k + 3 * n] = *(arr[n]->data() + k);*/ data[k + 3 * n] = *(arr[n]->data() + k);*/
darray<unsigned short> indices (6, 0); darray<unsigned short> indices (6, 0);
darray<float> data; darray<float> data;
for (auto v : mesh.vertices()) for (auto v : mesh.vertices())
for (auto c : *v) for (auto c : *v)
data.push(c); data.push(c);
indices[0] = 3; indices[0] = 3;
indices[1] = 1; indices[1] = 1;
indices[2] = 0; indices[2] = 0;
indices[3] = 1; indices[3] = 1;
indices[4] = 2; indices[4] = 2;
indices[5] = 3; indices[5] = 3;
std::cout << "Data: "; std::cout << "Data: ";
for (auto p : data) for (auto p : data)
std::cout << p << " "; std::cout << p << " ";
std::cout << std::endl; std::cout << std::endl;
std::cout << "Indices: "; std::cout << "Indices: ";
for (auto p : indices) for (auto p : indices)
std::cout << p << " "; std::cout << p << " ";
std::cout << std::endl; std::cout << std::endl;
darray<float> vertices { darray<float> vertices {
0.5f, 0.5f, 0.0f, // top right 0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right 0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left -0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left -0.5f, 0.5f, 0.0f // top left
}; };
darray<unsigned int> indices2 { // note that we start from 0! darray<unsigned int> indices2 { // note that we start from 0!
0, 1, 3, // first Triangle 0, 1, 3, // first Triangle
1, 2, 3 // second Triangle 1, 2, 3 // second Triangle
}; };
/* /*
unsigned int VBO, VAO, EBO; unsigned int VBO, VAO, EBO;
glGenVertexArrays(1, &VAO); glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO); glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO); glGenBuffers(1, &EBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO); glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO);
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//data.size(), data.data(), GL_STATIC_DRAW); //glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//data.size(), data.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);//indices.size(), indices.data(), GL_STATIC_DRAW); //glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);//indices.size(), indices.data(), GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indices2.size(), indices2.data(), GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indices2.size(), indices2.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound. // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray(0); glBindVertexArray(0);
*/ */
gpu::Device* device; gpu::Device* device;
gpu::Device::create(&device, gpu::Device::DeviceAPI::OpenGL); gpu::Device::create(&device, gpu::Device::DeviceAPI::OpenGL);
device->initialize(); device->initialize();
gpu::Shader* vertexShader; gpu::Shader* vertexShader;
device->createVertexShader(&vertexShader, "shaders/test.vert.glsl", "VS"); device->createVertexShader(&vertexShader, "shaders/test.vert.glsl", "VS");
gpu::Shader* fragmentShader; gpu::Shader* fragmentShader;
device->createFragmentShader(&fragmentShader, "shaders/test.frag.glsl", "FS"); device->createFragmentShader(&fragmentShader, "shaders/test.frag.glsl", "FS");
gpu::ShaderProgram* shaderProgram; gpu::ShaderProgram* shaderProgram;
device->createShaderProgram(&shaderProgram); device->createShaderProgram(&shaderProgram);
device->attachShader(shaderProgram, vertexShader); device->attachShader(shaderProgram, vertexShader);
device->attachShader(shaderProgram, fragmentShader); device->attachShader(shaderProgram, fragmentShader);
device->linkProgram(shaderProgram); device->linkProgram(shaderProgram);
gpu::Buffer* vertexBuffer; gpu::Buffer* vertexBuffer;
device->createVertexBuffer(&vertexBuffer, sizeof(float) * data.size(), (char*)data.data()); device->createVertexBuffer(&vertexBuffer, sizeof(float) * data.size(), (char*)data.data());
gpu::Buffer* indexBuffer; gpu::Buffer* indexBuffer;
device->createIndexBuffer(&indexBuffer, sizeof(unsigned short) * indices.size(), (char*)indices.data()); device->createIndexBuffer(&indexBuffer, sizeof(unsigned short) * indices.size(), (char*)indices.data());
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(dynamic_cast<gpu::glfw::Window*>(w)->instance(), true); ImGui_ImplGlfw_InitForOpenGL(dynamic_cast<gpu::glfw::Window*>(w)->instance(), true);
ImGui_ImplOpenGL3_Init("#version 420"); ImGui_ImplOpenGL3_Init("#version 420");
while (w->isOpen()) while (w->isOpen())
{ {
glViewport(0, 0, 600, 400); glViewport(0, 0, 600, 400);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw our first triangle // draw our first triangle
/*glUseProgram(shaderProgram); /*glUseProgram(shaderProgram);
glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
//glDrawArrays(GL_TRIANGLES, 0, 6); //glDrawArrays(GL_TRIANGLES, 0, 6);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);*/ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);*/
device->useShaderProgram(shaderProgram); device->useShaderProgram(shaderProgram);
device->useVertexBuffer(vertexBuffer, 0, 0); device->useVertexBuffer(vertexBuffer, 0, 0);
device->useIndexBuffer(indexBuffer, 0); device->useIndexBuffer(indexBuffer, 0);
//dynamic_cast<gpu::opengl::Device*>(device)->Draw(2, 0, 0); //dynamic_cast<gpu::opengl::Device*>(device)->Draw(2, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
bool yes = true; bool yes = true;
ImGui::ShowDemoWindow(&yes); ImGui::ShowDemoWindow(&yes);
ImGui::Begin("Hello, world!"); ImGui::Begin("Hello, world!");
{ {
if (ImGui::Button("Exit")) if (ImGui::Button("Exit"))
w->state(gpu::Window::State::Closed); w->state(gpu::Window::State::Closed);
ImGui::End(); ImGui::End();
} }
ImGui::Render(); ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
dynamic_cast<gpu::glfw::Window*>(w)->swapBuffers(); dynamic_cast<gpu::glfw::Window*>(w)->swapBuffers();
dynamic_cast<gpu::glfw::Window*>(w)->pollEvents(); dynamic_cast<gpu::glfw::Window*>(w)->pollEvents();
} }
ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown(); ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
device->destroyShaderProgram(shaderProgram, false); device->destroyShaderProgram(shaderProgram, false);
device->destroyShader(vertexShader); device->destroyShader(vertexShader);
device->destroyShader(fragmentShader); device->destroyShader(fragmentShader);
device->destroyBuffer(vertexBuffer); device->destroyBuffer(vertexBuffer);
device->destroyBuffer(indexBuffer); device->destroyBuffer(indexBuffer);
delete dynamic_cast<gpu::opengl::Device*>(device); delete dynamic_cast<gpu::opengl::Device*>(device);
/*glDeleteVertexArrays(1, &VAO); /*glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO); glDeleteBuffers(1, &EBO);
glDeleteProgram(shaderProgram);*/ glDeleteProgram(shaderProgram);*/
ws->destroyWindow(w); ws->destroyWindow(w);
gpu::WindowSystem::destroy(ws); gpu::WindowSystem::destroy(ws);
return 0; return 0;
} }

View File

@ -0,0 +1,551 @@
/*
#include "hpr/gpu.hpp"
#include "hpr/window_system/window_system.hpp"
#include "hpr/window_system/glfw/window_system.hpp"
#include "hpr/window_system/glfw/window.hpp"
#include "hpr/math.hpp"
#include "hpr/mesh.hpp"
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
void GLAPIENTRY
MessageCallback( GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam )
{
fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n\n",
( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
type, severity, message );
}
*/
/*
const char *vertexShaderSource = "#version 430 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 430 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
const GLchar* vertexSource = R"glsl(
#version 150 core
in vec2 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";
const GLchar* fragmentSource = R"glsl(
#version 150 core
in vec3 Color;
out vec4 outColor;
void main()
{
outColor = vec4(Color, 1.0);
}
)glsl";
int main()
{
using namespace hpr;
gpu::WindowSystem *ws = gpu::WindowSystem::create(gpu::WindowContext::Provider::GLFW);
gpu::Window *w = ws->newWindow();
w->init("test", gpu::Window::Style::Windowed, 50, 50, 600, 400, nullptr, nullptr);
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
throw std::runtime_error("Cannot initialize gl context");
// During init, enable debug output
glEnable ( GL_DEBUG_OUTPUT );
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback( glDebugOutput, nullptr);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
gpu::Shader vshader {gpu::Shader::Type::Vertex, vertexShaderSource};
gpu::Shader fshader {gpu::Shader::Type::Fragment, fragmentShaderSource};
gpu::ShaderProgram sprogram {};
vshader.create();
fshader.create();
sprogram.create();
sprogram.attach(vshader);
sprogram.attach(fshader);
sprogram.link();
gpu::Shader vshader2 {gpu::Shader::Type::Vertex, vertexSource};
gpu::Shader fshader2 {gpu::Shader::Type::Fragment, fragmentSource};
gpu::ShaderProgram sprogram2 {};
vshader2.create();
fshader2.create();
sprogram2.create();
sprogram2.attach(vshader2);
sprogram2.attach(fshader2);
sprogram2.link();
//vshader.destroy();
//fshader.destroy();
for (auto& sh : sprogram.shaders())
std::cout << sh.index() << std::endl;
std::cout << sprogram.index() << std::endl;
darray<float> vertices {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
darray<unsigned int> indices2 { // note that we start from 0!
0, 1, 3, // first Triangle
1, 2, 3 // second Triangle
};
gpu::ArrayObject vao {};
gpu::BufferObject vbo {gpu::BufferObject::Type::Vertex};
gpu::BufferObject ebo {gpu::BufferObject::Type::Index};
vao.create();
vao.bind();
vbo.create<float>(vertices);
ebo.create<unsigned int>(indices2);
vao.attribPointer(vbo, 0, 3);
vao.unbind();
// Create Vertex Array Object
GLuint vao2;
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo2;
glGenBuffers(1, &vbo2);
GLfloat vertices2[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices2, GL_STATIC_DRAW);
// Create an element array
GLuint ebo2;
glGenBuffers(1, &ebo2);
GLuint elements2[] = {
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo2);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements2), elements2, GL_STATIC_DRAW);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(sprogram2.index(), "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(sprogram2.index(), "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
std::cout << sprogram2.index() << std::endl;
gpu::Viewport viewport {{0, 0}, {600, 400}};
gpu::ColorBuffer colorBuffer;
gpu::DepthBuffer depthBuffer {true};
/*IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.IniFilename = nullptr;
io.LogFilename = nullptr;
ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(dynamic_cast<gpu::glfw::Window*>(w)->instance(), true);
ImGui_ImplOpenGL3_Init("#version 430");
while (w->isOpen())
{
viewport.set();
//colorBuffer.clear({0.2f, 0.2f, 0.2f, 1.0f});
//depthBuffer.clear();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
sprogram.bind();
vao.bind();
ebo.bind();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
sprogram2.bind();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
/*
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
bool yes = true;
ImGui::ShowDemoWindow(&yes);
ImGui::Begin("Hello, world!");
{
if (ImGui::Button("Exit"))
w->state(gpu::Window::State::Closed);
ImGui::End();
}
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
dynamic_cast<gpu::glfw::Window*>(w)->swapBuffers();
dynamic_cast<gpu::glfw::Window*>(w)->pollEvents();
}
sprogram.destroy();
vbo.destroy();
ebo.destroy();
vao.destroy();
/*
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
ws->destroyWindow(w);
gpu::WindowSystem::destroy(ws);
return 0;
}
*/
// Link statically with GLEW
#define GLEW_STATIC
// Headers
//#include <GL/glew.h>
//#include <SFML/Window.hpp>
#include "hpr/gpu.hpp"
#include <iostream>
void APIENTRY glDebugOutput(
GLenum source,
GLenum type,
unsigned int id,
GLenum severity,
GLsizei length,
const char* message,
const void* userParam
)
{
// ignore non-significant error/warning codes
if (id == 131169 || id == 131185 || id == 131218 || id == 131204)
return;
std::cout << "Debug::GL[" << id << "]: " << message << std::endl;
switch (source)
{
case GL_DEBUG_SOURCE_API:
std::cout << "Source: API";
break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
std::cout << "Source: Window System";
break;
case GL_DEBUG_SOURCE_SHADER_COMPILER:
std::cout << "Source: Shader Compiler";
break;
case GL_DEBUG_SOURCE_THIRD_PARTY:
std::cout << "Source: Third Party";
break;
case GL_DEBUG_SOURCE_APPLICATION:
std::cout << "Source: Application";
break;
case GL_DEBUG_SOURCE_OTHER:
std::cout << "Source: Other";
break;
}
std::cout << std::endl;
switch (type)
{
case GL_DEBUG_TYPE_ERROR:
std::cout << "Type: Error";
break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
std::cout << "Type: Deprecated Behaviour";
break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
std::cout << "Type: Undefined Behaviour";
break;
case GL_DEBUG_TYPE_PORTABILITY:
std::cout << "Type: Portability";
break;
case GL_DEBUG_TYPE_PERFORMANCE:
std::cout << "Type: Performance";
break;
case GL_DEBUG_TYPE_MARKER:
std::cout << "Type: Marker";
break;
case GL_DEBUG_TYPE_PUSH_GROUP:
std::cout << "Type: Push Group";
break;
case GL_DEBUG_TYPE_POP_GROUP:
std::cout << "Type: Pop Group";
break;
case GL_DEBUG_TYPE_OTHER:
std::cout << "Type: Other";
break;
}
std::cout << std::endl;
switch (severity)
{
case GL_DEBUG_SEVERITY_HIGH:
std::cout << "Severity: high";
break;
case GL_DEBUG_SEVERITY_MEDIUM:
std::cout << "Severity: medium";
break;
case GL_DEBUG_SEVERITY_LOW:
std::cout << "Severity: low";
break;
case GL_DEBUG_SEVERITY_NOTIFICATION:
std::cout << "Severity: notification";
break;
}
std::cout << std::endl;
}
// Shader sources
const GLchar* vertexSource = R"glsl(
#version 430 core
layout (location = 0) in vec2 position;
layout (location = 1) in vec3 color;
//in vec2 position;
//in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";
const GLchar* fragmentSource = R"glsl(
#version 430 core
in vec3 Color;
out vec4 outColor;
void main()
{
//outColor = vec4(1.0, 1.0, 1.0, 1.0); //vec4(Color, 1.0);
outColor = vec4(Color, 1.0);
}
)glsl";
int main()
{
/*sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.majorVersion = 3;
settings.minorVersion = 2;
sf::Window window(sf::VideoMode(800, 600, 32), "OpenGL", sf::Style::Titlebar | sf::Style::Close, settings);
*/
using namespace hpr;
//gpu::WindowSystem *ws = gpu::WindowSystem::create(gpu::WindowContext::Provider::GLFW);
//gpu::Window *w = ws->newWindow();
//w->init("test", gpu::Window::Style::Windowed, 50, 50, 600, 400, nullptr, nullptr);
gpu::Window w {50, 50, 600, 400, "Test", gpu::Window::Style::Windowed, nullptr, nullptr};
w.keyClickCallback([](gpu::Window* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE)
window->state(gpu::Window::Closed);
});
w.context().debug();
// Initialize GLEW
//glewExperimental = GL_TRUE;
//glewInit();
// Create Vertex Array Object
/*GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);*/
gpu::ArrayObject vao {};
vao.create();
vao.bind();
// Create a Vertex Buffer Object and copy the vertex data to it
//GLuint vbo;
//glGenBuffers(1, &vbo);
gpu::BufferObject vbo2 {gpu::BufferObject::Type::Vertex};
darray<float> vertices {
-0.5f, 0.5f, //1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, //0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, //0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, //1.0f, 1.0f, 1.0f // Bottom-left
};
darray<float> colors {
1.0f, 0.0f, 0.0f, // Top-left
0.0f, 1.0f, 0.0f, // Top-right
0.0f, 0.0f, 1.0f, // Bottom-right
1.0f, 1.0f, 1.0f // Bottom-left
};
float vertices2[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
//glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
//glBindBuffer(GL_ARRAY_BUFFER, vbo.index());
//glBufferData(static_cast<GLenum>(gpu::BufferObject::Type::Vertex), sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
//vbo.bind();
vbo2.create(vertices);
vbo2.bind();
gpu::BufferObject vboColors {gpu::BufferObject::Type::Vertex};
vboColors.create(colors);
vboColors.bind();
//vbo2.destroy();
// Create an element array
/*GLuint ebo;
glGenBuffers(1, &ebo);
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};*/
darray<unsigned int> elements {
0, 1, 2,
2, 3, 0
};
/*
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
*/
gpu::BufferObject els {gpu::BufferObject::Type::Index};
els.create(elements);
els.bind();
// Create and compile the vertex shader
/*GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);*/
gpu::Shader vshader {gpu::Shader::Type::Vertex, vertexSource};
vshader.create();
// Create and compile the fragment shader
/*GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);*/
gpu::Shader fshader {gpu::Shader::Type::Fragment, fragmentSource};
fshader.create();
// Link the vertex and fragment shader into a shader program
/*GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
//glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);*/
gpu::ShaderProgram sprogram {};
sprogram.create();
sprogram.attach(vshader);
sprogram.attach(fshader);
sprogram.link();
sprogram.bind();
// Specify the layout of the vertex data
/*GLint posAttrib = glGetAttribLocation(sprogram.index(), "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);*/
vao.attribPointer(vbo2, 0, 2);
vao.attribPointer(vboColors, 1, 3);
/*vbo2.bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
vboColors.bind();
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);*/
/*GLint colAttrib = glGetAttribLocation(sprogram.index(), "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));*/
gpu::ColorBuffer cb;
bool running = true;
while (w.state() != gpu::Window::Closed)
{
/*sf::Event windowEvent;
while (window.pollEvent(windowEvent))
{
switch (windowEvent.type)
{
case sf::Event::Closed:
running = false;
break;
}
}*/
// Clear the screen to black
//glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//glClear(GL_COLOR_BUFFER_BIT);
cb.clear(vec4(0.0f, 0.0f, 0.0f, 1.0f));
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
// Swap buffers
//window.display();
w.swapBuffers();
w.pollEvents();
}
sprogram.destroy();
vshader.destroy();
fshader.destroy();
/*glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);*/
//glDeleteBuffers(1, &ebo);
//glDeleteBuffers(1, &vbo);
vbo2.destroy();
//glDeleteVertexArrays(1, &vao);
vao.destroy();
w.destroy();
return 0;
}

View File

@ -1,133 +1,319 @@
#include "hpr/gpu.hpp" #include <iostream>
#include "hpr/window_system/window_system.hpp"
#include "hpr/window_system/glfw/window_system.hpp" #include "visual.hpp"
#include "hpr/window_system/glfw/window.hpp" #include "entity.hpp"
#include "hpr/math.hpp" #include "ui.hpp"
#include "hpr/mesh.hpp" //#include "transform.hpp"
#include "camera.hpp"
#include <imgui.h> #include "scene.hpp"
#include <imgui_impl_glfw.h> #include "grid.hpp"
#include <imgui_impl_opengl3.h> #include <implot.h>
#include <iostream> #include "ray.hpp"
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n" int main()
"void main()\n" {
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" Visual visual;
"}\0";
const char *fragmentShaderSource = "#version 330 core\n" visual.window()->keyClickCallback([](gpu::Window* window, int key, int scancode, int action, int mods)
"out vec4 FragColor;\n" {
"void main()\n" if (key == GLFW_KEY_ESCAPE)
"{\n" window->state(gpu::Window::Closed);
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" });
"}\n\0";
visual.window()->context().debug();
int main()
{ UI ui {visual.window()};
using namespace hpr;
gpu::WindowSystem *ws = gpu::WindowSystem::create(gpu::WindowContext::Provider::GLFW); darray<vec3> vertices {
gpu::Window *w = ws->newWindow(); /*vec2(-0.5f, 0.5f),
w->init("test", gpu::Window::Style::Windowed, 0, 0, 600, 400, nullptr, nullptr); vec2(0.5f, 0.5f),
vec2(0.5f, -0.5f),
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) vec2(-0.5f, -0.5f)*/
throw std::runtime_error("Cannot initialize gl context"); vec3(-0.5f, -0.5f, -0.5f),
vec3(0.5f, -0.5f, -0.5f),
gpu::Shader vshader {gpu::Shader::Type::Vertex, vertexShaderSource}; vec3(0.5f, 0.5f, -0.5f),
gpu::Shader fshader {gpu::Shader::Type::Fragment, fragmentShaderSource}; vec3(0.5f, 0.5f, -0.5f),
gpu::ShaderProgram sprogram {}; vec3(-0.5f, 0.5f, -0.5f),
vec3(-0.5f, -0.5f, -0.5f),
vshader.create();
fshader.create(); vec3(-0.5f, -0.5f, 0.5f),
sprogram.create(); vec3(0.5f, -0.5f, 0.5f),
sprogram.attach(vshader); vec3(0.5f, 0.5f, 0.5f),
sprogram.attach(fshader); vec3(0.5f, 0.5f, 0.5f),
sprogram.link(); vec3(-0.5f, 0.5f, 0.5f),
for (auto& sh : sprogram.shaders()) vec3(-0.5f, -0.5f, 0.5f),
std::cout << sh.index() << std::endl;
vec3(-0.5f, 0.5f, 0.5f),
vec3(-0.5f, 0.5f, -0.5f),
darray<float> vertices { vec3(-0.5f, -0.5f, -0.5f),
0.5f, 0.5f, 0.0f, // top right vec3(-0.5f, -0.5f, -0.5f),
0.5f, -0.5f, 0.0f, // bottom right vec3(-0.5f, -0.5f, 0.5f),
-0.5f, -0.5f, 0.0f, // bottom left vec3(-0.5f, 0.5f, 0.5f),
-0.5f, 0.5f, 0.0f // top left
}; vec3(0.5f, 0.5f, 0.5f),
darray<unsigned int> indices2 { // note that we start from 0! vec3(0.5f, 0.5f, -0.5f),
0, 1, 3, // first Triangle vec3(0.5f, -0.5f, -0.5f),
1, 2, 3 // second Triangle vec3(0.5f, -0.5f, -0.5f),
}; vec3(0.5f, -0.5f, 0.5f),
vec3(0.5f, 0.5f, 0.5f),
gpu::ArrayObject vao {};
gpu::BufferObject vbo {gpu::BufferObject::Type::Vertex}; vec3(-0.5f, -0.5f, -0.5f),
gpu::BufferObject ebo {gpu::BufferObject::Type::Index}; vec3(0.5f, -0.5f, -0.5f),
vec3(0.5f, -0.5f, 0.5f),
vao.create(); vec3(0.5f, -0.5f, 0.5f),
vao.bind(); vec3(-0.5f, -0.5f, 0.5f),
vbo.create<float>(vertices); vec3(-0.5f, -0.5f, -0.5f),
ebo.create<unsigned int>(indices2);
vao.attribPointer(vbo, 0, 3); vec3(-0.5f, 0.5f, -0.5f),
vao.unbind(); vec3(0.5f, 0.5f, -0.5f),
vec3(0.5f, 0.5f, 0.5f),
gpu::Viewport viewport {{0, 0}, {600, 400}}; vec3(0.5f, 0.5f, 0.5f),
gpu::ColorBuffer colorBuffer; vec3(-0.5f, 0.5f, 0.5f),
gpu::DepthBuffer depthBuffer {true}; vec3(-0.5f, 0.5f, -0.5f)
};
IMGUI_CHECKVERSION(); darray<vec3> normals {
ImGui::CreateContext(); vec3(0.0f, 0.0f, -1.0f),
vec3(0.0f, 0.0f, -1.0f),
ImGuiIO& io = ImGui::GetIO(); vec3(0.0f, 0.0f, -1.0f),
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; vec3(0.0f, 0.0f, -1.0f),
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; vec3(0.0f, 0.0f, -1.0f),
vec3(0.0f, 0.0f, -1.0f),
ImGui::StyleColorsDark();
vec3(0.0f, 0.0f, 1.0f),
ImGui_ImplGlfw_InitForOpenGL(dynamic_cast<gpu::glfw::Window*>(w)->instance(), true); vec3(0.0f, 0.0f, 1.0f),
ImGui_ImplOpenGL3_Init("#version 420"); vec3(0.0f, 0.0f, 1.0f),
vec3(0.0f, 0.0f, 1.0f),
while (w->isOpen()) vec3(0.0f, 0.0f, 1.0f),
{ vec3(0.0f, 0.0f, 1.0f),
viewport.set();
vec3(-1.0f, 0.0f, 0.0f),
colorBuffer.clear({0.8f, 0.2f, 0.2f, 1.0f}); vec3(-1.0f, 0.0f, 0.0f),
depthBuffer.clear(); vec3(-1.0f, 0.0f, 0.0f),
vec3(-1.0f, 0.0f, 0.0f),
sprogram.bind(); vec3(-1.0f, 0.0f, 0.0f),
vao.bind(); vec3(-1.0f, 0.0f, 0.0f),
glDrawArrays(GL_TRIANGLES, 0, 6); vec3(1.0f, 0.0f, 0.0f),
vec3(1.0f, 0.0f, 0.0f),
ImGui_ImplOpenGL3_NewFrame(); vec3(1.0f, 0.0f, 0.0f),
ImGui_ImplGlfw_NewFrame(); vec3(1.0f, 0.0f, 0.0f),
ImGui::NewFrame(); vec3(1.0f, 0.0f, 0.0f),
vec3(1.0f, 0.0f, 0.0f),
bool yes = true;
ImGui::ShowDemoWindow(&yes); vec3(0.0f, -1.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f),
ImGui::Begin("Hello, world!"); vec3(0.0f, -1.0f, 0.0f),
{ vec3(0.0f, -1.0f, 0.0f),
if (ImGui::Button("Exit")) vec3(0.0f, -1.0f, 0.0f),
w->state(gpu::Window::State::Closed); vec3(0.0f, -1.0f, 0.0f),
ImGui::End();
} vec3(0.0f, 1.0f, 0.0f),
vec3(0.0f, 1.0f, 0.0f),
ImGui::Render(); vec3(0.0f, 1.0f, 0.0f),
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); vec3(0.0f, 1.0f, 0.0f),
dynamic_cast<gpu::glfw::Window*>(w)->swapBuffers(); vec3(0.0f, 1.0f, 0.0f),
dynamic_cast<gpu::glfw::Window*>(w)->pollEvents(); vec3(0.0f, 1.0f, 0.0f)
} };
darray<vec3> colors {
sprogram.destroy(); vec3(1.0f, 0.0f, 0.0f),
vshader.destroy(); vec3(0.0f, 1.0f, 0.0f),
fshader.destroy(); vec3(0.0f, 0.0f, 1.0f),
vbo.destroy(); vec3(1.0f, 1.0f, 1.0f)
ebo.destroy(); };
vao.destroy(); darray<Vector<unsigned int, 3>> indices {
Vector<unsigned int, 3>(0, 1, 2),
ws->destroyWindow(w); Vector<unsigned int, 3>(2, 3, 0)
gpu::WindowSystem::destroy(ws); };
return 0; Entity entity {visual.shaderProgram()};
} entity.addVertices(vertices);
entity.addNormals(normals);
//entity.addColors(colors);
//entity.addIndices(indices);
Scene scene;
scene.camera(new OrbitCamera());
scene.add(TreeNode<Entity>(entity));
//Transform transform {&entity};
//gpu::DepthBuffer depthBuffer {true};
visual.depthBuffer().bind();
//gpu::CullFace cullFace {gpu::CullFace::Mode::FrontAndBack};
float angle = 0;
glEnable(GL_PROGRAM_POINT_SIZE);
/*gpu::ShaderProgram shaderProgram;
gpu::Shader vertexShader {gpu::Shader::Type::Vertex, gridVertexSource};
vertexShader.create();
gpu::Shader fragmentShader {gpu::Shader::Type::Fragment, gridFragmentSource};
fragmentShader.create();
shaderProgram.create();
shaderProgram.attach(vertexShader);
shaderProgram.attach(fragmentShader);
shaderProgram.link();
shaderProgram.bind();
shaderProgram.uniformMatrix<4, 4>("view", 1, true, scene.camera()->view().data());
shaderProgram.uniformMatrix<4, 4>("projection", 1, true, scene.camera()->projection().data());
shaderProgram.unbind();*/
/*Entity grid {visual.shaderProgram()};
darray<vec3> vertices2;
auto genVert = [](float x, float y){;
return darray<vec3>{
vec3(-1.0f + x, 0.f + y, 0.f),
vec3(1.0f + x, 0.f + y, 0.f),
vec3(0.f + x, -1.0f + y, 0.f),
vec3(0.f + x, 1.0f + y, 0.f)
};};
for (auto x = -100; x < 100; ++x)
for (auto y = -100; y < 100; ++y)
vertices2.push(genVert(x, y));
grid.addVertices(vertices2);
grid.color(vec4(1, 1, 1, 1));
grid.renderMode(gpu::ArrayObject::Lines);*/
//Grid grid {visual.shaderProgram()};
//scene.add(TreeNode<Entity>(grid));
/*
gpu::ArrayObject ao;
gpu::BufferObject bo;
ao.create();
ao.bind();
bo.create(vertices2);
bo.bind();
ao.attribPointer(bo, 0, 3);
ao.unbind();
bo.unbind();*/
glfwWindowHint(GLFW_SAMPLES, 4);
ImPlot::CreateContext();
glEnable(GL_MULTISAMPLE);
/*gpu::Texture tex;
tex.create();
gpu::Renderbuffer rb;
rb.create();*/
gpu::Framebuffer framebuffer;
framebuffer.create();
gpu::Viewport viewport;
/*framebuffer.bind();
framebuffer.attach(tex);
framebuffer.attach(rb);
framebuffer.unbind();*/
const vec4 background = vec4(0.2f, 0.2f, 0.2f, 1.0f);
while (visual.window()->state() != gpu::Window::Closed)
{
visual.colorBuffer().clear(background);
visual.depthBuffer().clear();
//cullFace.bind();
//entity.render(hpr::gpu::ArrayObject::Triangles);
//angle += 1;
//transform.rotate({0, 1, 0}, angle);
//transform.rotate({0, 0, 1}, angle);
//transform.render();
viewport.size() = vec2(framebuffer.width(), framebuffer.height());
viewport.set();
framebuffer.bind();
framebuffer.rescale();
visual.colorBuffer().clear(background);
visual.depthBuffer().clear();
scene.camera()->aspect() = (float)framebuffer.width() / (float)framebuffer.height();
scene.render();
framebuffer.unbind();
viewport.size() = vec2((float)visual.window()->width(), (float)visual.window()->height());
viewport.set();
//shaderProgram.bind();
ui.createFrame();
bool yes = true;
ImGui::ShowDemoWindow(&yes);
ImPlot::ShowDemoWindow(&yes);
ImGui::Begin("Hello, world!");
{
if (ImGui::Button("Exit"))
visual.window()->state(gpu::Window::Closed);
ImGui::End();
}
ui.render();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
if (ImGui::Begin("Scene"))
{
ImGui::PopStyleVar();
if (!ImGui::IsWindowCollapsed())
{
framebuffer.width() = static_cast<int>(ImGui::GetContentRegionAvail().x);
framebuffer.height() = static_cast<int>(ImGui::GetContentRegionAvail().y);
ImGui::Image(reinterpret_cast<void *>(framebuffer.texture().index()), ImGui::GetContentRegionAvail(),
ImVec2{0, 1}, ImVec2{1, 0});
ImGuiIO& io = ImGui::GetIO();
Ray ray;
ray.fromScreen(io.MousePos.x, io.MousePos.y, framebuffer.width(), framebuffer.height(), scene.camera());
float tMin, tMax;
Entity* ent = scene.nodes()[0].data();
bool rayOBB = ray.obb({-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f}, ent, tMin, tMax);
//std::cout << rayOBB << std::endl;
if (rayOBB)
ent->color(vec4(1.f, 0.f, 0.f, 1.f));
else
ent->color(vec4(0.f, 1.f, 0.f, 1.f));
if (ImGui::Begin("Properties"))
{
ImGui::DragFloat3("position", ray.p_position.data());
ImGui::DragFloat3("direction", ray.p_direction.data());
vec2 mouse {io.MousePos.x, io.MousePos.y};
ImGui::DragFloat2("mouse", mouse.data());
ImGui::Checkbox("ray", &rayOBB);
ImGui::DragFloat("dist", &tMin);
ImGui::DragFloat("dist", &tMax);
ImGui::End();
}
if (ImGui::IsWindowHovered())
{
if (io.WantCaptureMouse)
{
dynamic_cast<OrbitCamera*>(scene.camera())->scrollEvent(0, io.MouseWheel);
if (ImGui::IsMouseDown(ImGuiMouseButton_Middle)) //(io.MouseDown[ImGuiMouseButton_Middle])
{
if (ImGui::IsKeyDown(ImGuiKey_LeftShift)) //(io.KeysDown[ImGuiKey_LeftShift])
{
dynamic_cast<OrbitCamera*>(scene.camera())->moveEvent(io.MouseDelta.x, io.MouseDelta.y);
}
else
{
dynamic_cast<OrbitCamera*>(scene.camera())->rotateEvent(io.MouseDelta.x, io.MouseDelta.y);
}
}
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
}
}
}
}
ImGui::End();
}
ui.renderFrame();
visual.render();
}
ImPlot::DestroyContext();
framebuffer.destroy();
return 0;
}

View File

@ -0,0 +1,184 @@
#pragma once
#include <hpr/math.hpp>
#include <hpr/gpu/shader_program.hpp>
#include "entity.hpp"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
class Transform
{
public:
enum Projection
{
Perspective,
Orthographic
};
protected:
Projection p_projection;
hpr::scalar p_distance;
hpr::scalar p_aspect;
hpr::scalar p_fieldOfView;
hpr::scalar p_nearPlane;
hpr::scalar p_farPlane;
hpr::vec3 p_target;
hpr::vec3 p_left;
hpr::vec3 p_front;
hpr::vec3 p_up;
hpr::vec3 p_rotation;
hpr::mat4 p_model;
Entity* p_entity;
hpr::vec3 p_position;
public:
inline Transform() = delete;
inline Transform(Entity* entity) :
p_projection {Orthographic},
p_distance {10},
p_aspect {800.f / 600},
p_fieldOfView {45},
p_nearPlane {0.1},
p_farPlane {100},
p_target {0, 0, 0},
p_left {1, 0, 0},
p_front {0, 0, -1},
p_up {0, 0, 1},
p_rotation {45, 45, 0},
p_model {hpr::mat4::identity()},
p_entity {entity},
p_position {}
{
//for (auto v : p_model)
// std::cout << v << std::endl;
}
hpr::mat4 view()
{
hpr::vec3 rotation {
hpr::cos(hpr::rad(p_rotation[1])) * hpr::sin(hpr::rad(p_rotation[0])),
hpr::cos(hpr::rad(p_rotation[1])) * hpr::cos(hpr::rad(p_rotation[0])),
hpr::sin(hpr::rad(p_rotation[1]))};
hpr::vec3 pos = p_target + p_distance * rotation;
p_front = p_target - pos;
p_front /= hpr::length(p_front);
p_up = hpr::vec3(0, 0, 1);
p_left = hpr::normalize(hpr::cross(p_up, p_front));
p_up = hpr::cross(p_front, p_left);
auto dd = glm::lookAt(glm::vec3(pos[0], pos[1], pos[2]), glm::vec3(pos[0] + p_front[0], pos[1] + p_front[1], pos[2] + p_front[2]), glm::vec3(p_up[0], p_up[1], p_up[2]));
auto dd2 = hpr::lookAt(pos, pos + p_front, p_up);
p_position = pos;
//for (auto v : dd2)
// std::cout << v << " ";
//std::cout << std::endl;
return dd2;
}
/*
-0.707107 0.707107 0 -0
-0.5 -0.5 0.707107 -1.90735e-06
0.5 0.5 0.707107 -10
0 0 0 1
*/
void rotateEvent(float xdelta, float ydelta)
{
p_rotation += hpr::vec3(xdelta, ydelta, 0);
}
void moveEvent(float xdelta, float ydelta)
{
p_target += (p_left * xdelta + p_up * ydelta) * 1e-3f;
}
void scrollEvent(float xdelta, float ydelta)
{
p_distance -= ydelta;
}
hpr::mat4 projection(Projection projection)
{
p_projection = projection;
switch (p_projection)
{
case Perspective:
return hpr::perspective(hpr::rad(p_fieldOfView), p_aspect, p_nearPlane, p_farPlane);
case Orthographic:
return hpr::ortho(-p_distance * p_aspect, p_distance * p_aspect, -p_distance, p_distance, p_nearPlane, p_farPlane);
}
}
void clear()
{
p_model = hpr::mat4::identity();
}
void translate(const hpr::vec3& position)
{
p_model = hpr::translate(p_model, position);
}
void rotate(const hpr::vec3& axis, hpr::scalar angle)
{
p_model = hpr::rotate(p_model, axis, hpr::rad(angle));
}
void scale(const hpr::vec3& size)
{
p_model = hpr::scale(p_model, size);
}
/*struct Vec {
float x, y, z, w;
};*/
void render()
{
//double model[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//Vec model2[] = {Vec{0, 0, 0, 0}, Vec{0, 0, 0, 0},Vec{0, 0, 0, 0},Vec{0, 0, 0, 0}};
//static_assert(sizeof(model2) == sizeof(float) * 16 && std::is_standard_layout_v<Vec>);
//static_assert((sizeof(hpr::StaticArray<float, 16>::pointer) == (sizeof(GLfloat) * 16)) &&
// (std::is_standard_layout<hpr::mat4>::value),
// "Matrix4 does not satisfy contiguous storage requirements");
p_entity->shaderProgram()->bind();
//glUniformMatrix4fv(glGetUniformLocation(p_entity->shaderProgram()->index(), "model"),
// 1, GL_FALSE, p_model.data());
p_entity->shaderProgram()->uniformMatrix<4, 4, float>("model", 1, true, p_model.data());
hpr::mat4 _view = view();
p_entity->shaderProgram()->uniformMatrix<4, 4, float>("view", 1, true, _view.data());
hpr::mat4 _projection = projection(p_projection);
p_entity->shaderProgram()->uniformVector<float, 3>("viewPos", 1, p_position.data());
//for (auto v : _projection)
// std::cout << v << std::endl;
glm::mat4 _proj = glm::ortho(-p_distance * p_aspect, p_distance * p_aspect, -p_distance, p_distance, p_nearPlane, p_farPlane);
p_entity->shaderProgram()->uniformMatrix<4, 4, float>("projection", 1, true, _projection.data());
hpr::vec3 objectColor {1.0f, 0.5f, 0.31f};
p_entity->shaderProgram()->bind();
p_entity->shaderProgram()->uniformVector<float, 3>("objectColor", 1, objectColor.data());
p_entity->render(gpu::ArrayObject::Mode::Triangles);
objectColor = {1.0f, 1.0f, 1.0f};
p_entity->shaderProgram()->bind();
p_entity->shaderProgram()->uniformVector<float, 3>("objectColor", 1, objectColor.data());
p_entity->render(gpu::ArrayObject::Mode::LineLoop);
p_entity->shaderProgram()->unbind();
clear();
}
};

157
source/creator/ui.hpp Normal file
View File

@ -0,0 +1,157 @@
#pragma once
#include <hpr/gpu/window.hpp>
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <imgui_internal.h>
//#include <imgui_stdlib.h>
using namespace hpr;
class UI
{
public:
UI(gpu::Window* window)
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui_ImplGlfw_InitForOpenGL(window->instance(), true);
ImGui_ImplOpenGL3_Init("#version 430");
io().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
}
~UI()
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void createFrame()
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void renderFrame()
{
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
inline
ImGuiIO& io()
{
return ImGui::GetIO();
}
inline
void render()
{
static auto first_time = true;
static bool show_object_explorer = true;
static bool show_properties = true;
static bool show_demo = false;
if (ImGui::BeginMainMenuBar())
{
if (ImGui::BeginMenu("Options"))
{
ImGui::MenuItem("Undo", "CTRL+Z");
ImGui::EndMenu();
}
if (ImGui::BeginMenu("View"))
{
ImGui::MenuItem("Object explorer", nullptr, &show_object_explorer);
ImGui::MenuItem("Properties", nullptr, &show_properties);
ImGui::MenuItem("Demo", nullptr, &show_demo);
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
if (show_demo)
ImGui::ShowDemoWindow();
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
ImGui::SetNextWindowViewport(viewport->ID);
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar; // ImGuiWindowFlags_NoDocking;
window_flags |= ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
//window_flags |= ImGuiWindowFlags_MenuBar;
//window_flags |= ImGuiWindowFlags_NoBackground;
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
if (ImGui::Begin("Main dockspace", nullptr, window_flags))
{
ImGui::PopStyleVar(3);
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
if (first_time)
{
first_time = false;
ImGui::DockBuilderRemoveNode(dockspace_id);
ImGui::DockBuilderAddNode(dockspace_id, dockspace_flags | ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
ImGuiID dock_id_left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.2f, nullptr, &dockspace_id);
//ImGuiID dock_id_down = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 1.0f, &dockspace_id, nullptr);
ImGuiID dock_id_down = ImGui::DockBuilderSplitNode(dock_id_left, ImGuiDir_Down, 0.5f, nullptr, &dock_id_left);
ImGuiDockNode* node = ImGui::DockBuilderGetNode(dockspace_id);
node->LocalFlags |= ImGuiDockNodeFlags_NoCloseButton;
ImGui::DockBuilderDockWindow("Scene", dockspace_id);
ImGui::DockBuilderDockWindow("Object explorer", dock_id_left);
// Properties
node = ImGui::DockBuilderGetNode(dock_id_down);
node->LocalFlags |= ImGuiDockNodeFlags_NoCloseButton | ImGuiDockNodeFlags_NoTabBar;
ImGui::DockBuilderDockWindow("Properties", dock_id_down);
//ImGui::DockBuilderDockWindow("Scene_", dock_id_down);
ImGui::DockBuilderFinish(dockspace_id);
}
ImGui::End();
}
ImGuiViewport* viewport2 = ImGui::GetMainViewport();
ImGuiWindowFlags window_flags2 = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar;
float height = ImGui::GetFrameHeight();
if (ImGui::BeginViewportSideBar("##SecondaryMenuBar", viewport2, ImGuiDir_Up, height, window_flags2)) {
if (ImGui::BeginMenuBar()) {
ImGui::Text("menu bar");
ImGui::EndMenuBar();
}
ImGui::End();
}
if (ImGui::BeginViewportSideBar("#MainStatusBar", viewport2, ImGuiDir_Down, height, window_flags2)) {
if (ImGui::BeginMenuBar()) {
ImGui::Text("status bar");
ImGui::EndMenuBar();
}
ImGui::End();
}
}
};

78
source/creator/visual.hpp Normal file
View File

@ -0,0 +1,78 @@
#pragma once
#include <hpr/gpu.hpp>
#include "shaders.hpp"
using namespace hpr;
class Visual
{
protected:
gpu::Window* p_window;
gpu::ShaderProgram* p_shaderProgram;
gpu::ColorBuffer p_colorBuffer;
gpu::DepthBuffer p_depthBuffer;
public:
Visual() :
p_window {new gpu::Window{50, 50, 1000, 800, "Hyporo", gpu::Window::Windowed, nullptr, nullptr}},
p_shaderProgram {new gpu::ShaderProgram},
p_colorBuffer {},
p_depthBuffer {}
{
gpu::Shader vertexShader {gpu::Shader::Type::Vertex, vertexSource};
vertexShader.create();
gpu::Shader fragmentShader {gpu::Shader::Type::Fragment, fragmentSource};
fragmentShader.create();
p_shaderProgram->create();
p_shaderProgram->attach(vertexShader);
p_shaderProgram->attach(fragmentShader);
p_shaderProgram->link();
vertexShader.destroy();
fragmentShader.destroy();
p_window->framebufferResizeCallback([](gpu::Window* w, int width, int height){
w->size(width, height);
});
}
~Visual()
{
p_shaderProgram->destroy();
delete p_shaderProgram;
p_window->destroy();
delete p_window;
}
gpu::Window* window()
{
return p_window;
}
gpu::ShaderProgram* shaderProgram()
{
return p_shaderProgram;
}
gpu::ColorBuffer& colorBuffer()
{
return p_colorBuffer;
}
gpu::DepthBuffer& depthBuffer()
{
return p_depthBuffer;
}
void render()
{
p_window->swapBuffers();
p_window->pollEvents();
}
};

View File

@ -1,22 +1,39 @@
# Modules # Modules and dependencies
add_subdirectory(core)
add_subdirectory(containers) if (HPR_WITH_CONTAINERS)
add_subdirectory(math) add_subdirectory(containers)
add_subdirectory(io) endif()
add_subdirectory(mesh)
add_subdirectory(geometry) if (HPR_WITH_MATH)
add_subdirectory(math)
if(WITH_CSG) endif()
include(${CMAKE_SOURCE_DIR}/cmake/external/occt.cmake)
add_subdirectory(csg) if (HPR_WITH_IO)
endif() add_subdirectory(io)
if(WITH_GPU) endif()
include(${CMAKE_SOURCE_DIR}/cmake/external/glad.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/external/stb.cmake) if (HPR_WITH_MESH)
add_subdirectory(gpu) add_subdirectory(mesh)
endif() endif()
if(WITH_WINDOW_SYSTEM)
include(${CMAKE_SOURCE_DIR}/cmake/external/glfw.cmake) if (HPR_WITH_GEOMETRY)
add_subdirectory(window_system) add_subdirectory(geometry)
endif() endif()
if(HPR_WITH_CSG)
include(${HPR_EXTERNAL_PATH}/occt.cmake)
add_subdirectory(csg)
endif()
if(HPR_WITH_GPU)
include(${HPR_EXTERNAL_PATH}/glad.cmake)
include(${HPR_EXTERNAL_PATH}/glfw.cmake)
include(${HPR_EXTERNAL_PATH}/stb.cmake)
add_subdirectory(gpu)
endif()
if(HPR_WITH_PARALLEL)
include(${HPR_EXTERNAL_PATH}/onetbb.cmake)
add_subdirectory(parallel)
endif()

View File

@ -1,3 +1,3 @@
#pragma once #pragma once
#include "containers/array.hpp" #include <hpr/containers/array.hpp>

View File

@ -1,62 +1,21 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(containers project(containers
VERSION "${HPR_PROJECT_VERSION}" VERSION "${HPR_VERSION}"
LANGUAGES CXX LANGUAGES CXX
) )
add_library(${PROJECT_NAME} INTERFACE) hpr_add_library(${PROJECT_NAME} INTERFACE)
add_library(${CMAKE_PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
add_module(${PROJECT_NAME}) hpr_collect_interface(${PROJECT_NAME}
"../containers.hpp"
file(GLOB ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS "*.hpp"
"../containers.hpp" "*.hpp" "array/*.hpp" "array/*.hpp"
) )
foreach(_header_path ${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS}) target_sources(${PROJECT_NAME}
list(APPEND ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE "$<BUILD_INTERFACE:${_header_path}>") INTERFACE ${${PROJECT_NAME}_HEADERS_INTERFACE} ${HPR_INSTALL_INTERFACE}/${PROJECT_NAME}>
endforeach() )
target_sources(${PROJECT_NAME} hpr_tests(${PROJECT_NAME} tests)
INTERFACE hpr_install(${PROJECT_NAME} ${PROJECT_SOURCE_DIR})
${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE}
$<INSTALL_INTERFACE:include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME}>
)
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_SKIP
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}-${HPR_PROJECT_VERSION}
NAMESPACE ${CMAKE_PROJECT_NAME}::
)
install(
TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_ONLY
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
DIRECTORY ${PROJECT_SOURCE_DIR}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "tests" EXCLUDE
)
install(
FILES ../${PROJECT_NAME}.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
)
if(HPR_TEST)
add_subdirectory(tests)
endif()

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "array/dynamic_array.hpp" #include <hpr/containers/array/iterator.hpp>
#include "array/static_array.hpp" #include <hpr/containers/array/dynamic_array.hpp>
#include <hpr/containers/array/static_array.hpp>

View File

@ -1,427 +1,297 @@
#pragma once #pragma once
#include "iterator.hpp" #include <hpr/containers/array/sequence.hpp>
#include <limits>
#include <memory> #include <functional>
#include <functional> #include <limits>
namespace hpr namespace hpr
{ {
template <typename Type> // forward declaration
class DynamicArray
{ template <typename T>
class DynamicArray;
public:
// type traits
using difference_type = std::ptrdiff_t;
using value_type = Type; template <typename T>
using size_type = size_t; struct is_sequence<DynamicArray<T>> : public std::true_type
using pointer = Type*; {};
using reference = Type&;
using iterator = Iterator<Type>; // aliases
using const_pointer = Type const*;
using const_reference = Type const&; template <typename T>
using const_iterator = Iterator<const Type>; using darray = DynamicArray<T>;
protected: // class definition
size_type p_size; template <typename T>
size_type p_capacity; class DynamicArray : public Sequence<T>
pointer p_start; {
pointer p_end;
pointer p_storage_end; using base = Sequence<T>;
public: public:
inline using difference_type = std::ptrdiff_t;
DynamicArray() : using value_type = T;
p_size {0}, using size_type = Size;
p_capacity {1}, using pointer = T*;
p_start {new value_type[p_capacity]}, using reference = T&;
p_end {p_start}, using iterator = Iterator<T>;
p_storage_end {p_end + p_capacity} using const_pointer = T const*;
{} using const_reference = T const&;
using const_iterator = Iterator<const T>;
inline
DynamicArray(const DynamicArray& arr) : public:
p_size {arr.p_size},
p_capacity {arr.p_capacity}, friend constexpr
p_start {new value_type[arr.p_size]}, void swap(DynamicArray& main, DynamicArray& other) noexcept
p_end {p_start + p_size}, {
p_storage_end {p_start + p_capacity} using std::swap;
{ swap(static_cast<base&>(main), static_cast<base&>(other));
std::copy(arr.p_start, arr.p_end, p_start); }
}
constexpr
//! Move constructor DynamicArray() noexcept :
inline base {}
DynamicArray(DynamicArray&& arr) noexcept : {}
DynamicArray {}
{ constexpr explicit
swap(*this, arr); DynamicArray(const base& b) noexcept :
} base {b}
{}
inline
DynamicArray(const_iterator start, const_iterator end) : constexpr
p_size {size_type(end.operator->() - start.operator->())}, DynamicArray(const DynamicArray& arr) noexcept :
p_capacity {p_size}, base {static_cast<base>(arr)}
p_start {new value_type[p_size]}, {}
p_end {p_start + p_size},
p_storage_end {p_start + p_capacity} //! Move constructor
{ constexpr
std::copy(start, end, p_start); DynamicArray(DynamicArray&& arr) noexcept :
} base {std::forward<base>(static_cast<base>(arr))}
{}
inline
DynamicArray(iterator start, iterator end) : template <typename Iter>
p_size {size_type(end.operator->() - start.operator->())}, constexpr
p_capacity {p_size}, DynamicArray(Iter start, Iter end) :
p_start {new value_type[p_size]}, base {start, end}
p_end {p_start + p_size}, {}
p_storage_end {p_start + p_capacity}
{ constexpr
std::copy(start, end, p_start); DynamicArray(typename base::iterator start, typename base::iterator end) :
} base {start, end}
{}
inline
DynamicArray(std::initializer_list<value_type> list) : constexpr
p_size {list.size()}, DynamicArray(typename base::const_iterator start, typename base::const_iterator end) :
p_capacity {list.size()}, base {start, end}
p_start {new value_type[p_capacity]}, {}
p_end {p_start + p_size},
p_storage_end {p_start + p_capacity} constexpr
{ DynamicArray(typename base::iterator start, typename base::iterator end, size_type capacity) :
std::copy(list.begin(), list.end(), p_start); base {start, end, capacity}
} {}
inline constexpr
DynamicArray(size_type size, value_type value) : DynamicArray(typename base::const_iterator start, typename base::const_iterator end, size_type capacity) :
p_size {0}, base {start, end, capacity}
p_capacity {size}, {}
p_start {new value_type[p_capacity]},
p_end {p_start + p_size}, constexpr
p_storage_end {p_start + p_capacity} DynamicArray(std::initializer_list<value_type> list) :
{ base {list.begin(), list.end()}
for (auto n = 0; n < size; ++n) {}
push(value);
} constexpr
DynamicArray(size_type size, value_type value) noexcept :
inline base {size, value}
DynamicArray& operator=(const DynamicArray& vs) noexcept {}
{
delete[] p_start; constexpr
p_size = vs.p_size; DynamicArray& operator=(DynamicArray other) noexcept
p_capacity = vs.p_size; {
p_start = new value_type[p_capacity]; swap(*this, other);
p_end = p_start + p_size; return *this;
p_storage_end = p_start + p_capacity; }
std::copy(vs.begin(), vs.end(), begin());
return *this; constexpr
} DynamicArray& operator=(DynamicArray&& arr) noexcept
{
inline swap(*this, arr);
DynamicArray& operator=(DynamicArray&& arr) noexcept return *this;
{ }
swap(*this, arr);
return *this; virtual
} ~DynamicArray() = default;
virtual // Member functions
~DynamicArray()
{ [[nodiscard]] virtual constexpr
//std::destroy(p_start, p_end); size_type capacity() const noexcept
delete[] p_start; {
} return base::p_capacity;
}
// Member functions
[[nodiscard]] virtual constexpr
virtual bool is_empty() const
iterator begin() {
{ return base::begin() == base::end();
return iterator(p_start); }
}
virtual constexpr
[[nodiscard]] virtual iterator storage_end()
const_iterator begin() const {
{ return iterator(base::p_start + base::p_capacity);
return const_iterator(p_start); }
}
virtual constexpr
virtual const_iterator storage_end() const
iterator end() {
{ return const_iterator(base::p_start + base::p_capacity);
return iterator(p_end); }
}
virtual constexpr
virtual void resize(size_type newCapacity)
const_iterator end() const {
{ if (newCapacity == base::p_capacity)
return const_iterator(p_end); return;
}
if (std::numeric_limits<size_type>::max() - base::size() < newCapacity)
throw hpr::LengthError("Invalid capacity value passed");
[[nodiscard]] virtual
size_type size() const if (newCapacity > base::p_capacity)
{ {
return size_type(p_end - p_start); DynamicArray tmp {base::begin(), base::end(), newCapacity};
} swap(*this, tmp);
}
[[nodiscard]] virtual else
size_type capacity() const {
{ if (newCapacity >= base::p_size)
return size_type(p_storage_end - p_start); {
} DynamicArray tmp {base::begin(), base::end()};
swap(*this, tmp);
[[nodiscard]] virtual }
bool is_empty() const else
{ {
return begin() == end(); DynamicArray tmp {base::begin(), base::begin() + newCapacity};
} swap(*this, tmp);
}
virtual }
reference operator[](size_type n) }
{
if (n >= size()) virtual constexpr
throw std::out_of_range("Index out of bounds"); void push(const value_type& val)
return *(p_start + n); {
} if (base::end() == storage_end())
resize(base::p_capacity * 2);
virtual *base::end() = val;
const_reference operator[](size_type n) const ++base::p_size;
{ }
if (n >= size())
throw std::out_of_range("Index out of bounds"); virtual constexpr
return *(p_start + n); void push(value_type&& val)
} {
if (base::end() == storage_end())
virtual resize(base::p_capacity * 2);
reference front() *base::end() = std::move(val);
{ ++base::p_size;
return *p_start; }
}
virtual constexpr
virtual void push(const DynamicArray<T>& arr)
reference back() {
{ for (const value_type& el : arr)
return *(p_end - 1); push(el);
} }
virtual virtual constexpr
pointer data() value_type pop()
{ {
return p_start; if (is_empty())
} throw hpr::LengthError("Cannot pop element from empty array");
value_type val = base::back();
[[nodiscard]] virtual std::destroy_at(base::p_start + base::p_size);
const_pointer data() const --base::p_size;
{ return val;
return p_start; }
}
virtual constexpr
virtual void insert(size_type position, const value_type& val)
void resize(size_type newCapacity) {
{ if (base::end() == storage_end())
if (newCapacity == p_capacity) resize(base::p_capacity * 2);
return; for (size_type n = base::p_size; n > position; --n)
if (std::numeric_limits<size_type>::max() - size() < newCapacity) *(base::p_start + n) = std::move(*(base::p_start + n - 1));
throw std::length_error("Wrong capacity value passed (possibly negative)"); *(base::p_start + position) = val;
++base::p_size;
pointer newStart = new value_type[newCapacity]; }
if (newCapacity > p_capacity) virtual constexpr
{ void insert(size_type position, value_type&& val)
std::move(p_start, p_end, newStart); {
} if (base::end() == storage_end())
else if (newCapacity < p_capacity) resize(base::p_capacity * 2);
{ for (size_type n = base::p_size; n > position; --n)
if (newCapacity < p_size) { *(base::p_start + n) = std::move(*(base::p_start + n - 1));
std::move(p_start, p_start + newCapacity, newStart); *(base::p_start + position) = std::move(val);
p_size = newCapacity; ++base::p_size;
} }
else
{ virtual constexpr
std::move(p_start, p_end, newStart); void remove(size_type position)
} {
} for (size_type n = position; n < base::p_size - 1; ++n)
*(base::p_start + n) = std::move(*(base::p_start + n + 1));
delete[] p_start; std::destroy_at(base::p_start + base::p_size);
std::swap(p_start, newStart); --base::p_size;
p_capacity = newCapacity; }
p_end = p_start + p_size;
p_storage_end = p_start + p_capacity; virtual constexpr
} void remove(iterator position)
{
virtual if (position + 1 != base::end())
void push(const value_type& val) std::copy(position + 1, base::end(), position);
{ std::destroy_at(base::p_start + base::p_size);
if (p_end == p_storage_end) --base::p_size;
resize(p_capacity * 2); }
*p_end = val;
++p_end; virtual constexpr
++p_size; void remove(const std::function<bool(value_type)>& condition)
} {
size_type newSize = base::p_size;
virtual for (size_type offset = 0; offset < newSize; ++offset)
void push(value_type&& val) {
{ if (condition(*(base::p_start + offset)))
if (p_end == p_storage_end) {
resize(p_capacity * 2); for (size_type n = offset; n < newSize; ++n)
*p_end = std::move(val); *(base::p_start + n) = std::move(*(base::p_start + n + 1));
++p_end;
++p_size; --newSize;
} --offset;
}
virtual }
value_type pop() base::p_size = newSize;
{ }
if (is_empty())
throw std::length_error("Cannot pop element from empty array"); virtual constexpr
value_type val = back(); void clear()
std::destroy_at(p_end); {
--p_end; delete[] base::p_start;
--p_size; base::p_size = 0;
return val; base::p_capacity = 1;
} base::p_start = new value_type[base::p_capacity];
}
virtual
void insert(size_type position, const value_type& val) DynamicArray slice(iterator start, iterator end)
{ {
if (p_end == p_storage_end) return DynamicArray {start, end};
resize(p_capacity * 2); }
for (size_type n = p_size; n > position; --n)
*(p_start + n) = std::move(*(p_start + n - 1)); };
*(p_start + position) = val;
++p_size;
++p_end;
}
virtual
void insert(size_type position, value_type&& val)
{
if (p_end == p_storage_end)
resize(p_capacity * 2);
for (size_type n = p_size; n > position; --n)
*(p_start + n) = std::move(*(p_start + n - 1));
*(p_start + position) = std::move(val);
++p_size;
++p_end;
}
/*virtual
int findByAddress(const value_type& value)
{
// TODO: make better approach
for (int n = 0; n < p_size; ++n) {
std::equal_to
pointer lhs = (p_start + n); //*std::addressof(*(p_start + n));
pointer rhs = *value; //*std::addressof(value);
if (lhs == rhs)
return n;
}
return -1;
}*/
virtual
void remove(size_type position)
{
for (size_type n = position; n < p_size - 1; ++n)
*(p_start + n) = std::move(*(p_start + n + 1));
std::destroy_at(p_end);
--p_end;
--p_size;
}
virtual
void remove(iterator position)
{
if (position + 1 != end())
std::copy(position + 1, end(), position);
std::destroy_at(p_end);
--p_end;
--p_size;
}
virtual
void remove(const std::function<bool(value_type)>& condition)
{
size_type newSize = p_size;
for (size_type offset = 0; offset < newSize; ++offset)
if (condition(*(p_start + offset))) {
for (size_type n = offset; n < newSize; ++n) {
*(p_start + n) = std::move(*(p_start + n + 1));
}
--newSize;
--offset;
}
p_size = newSize;
p_end = p_start + p_size;
}
/*virtual
void remove(const value_type& value)
{
int index = findByAddress(value);
if (index != -1)
remove(index);
else
throw std::runtime_error("Value is not found to remove it");
}*/
virtual
void clear()
{
delete[] p_start;
p_size = 0;
p_capacity = 1;
p_start = new value_type[p_capacity];
p_end = p_start;
p_storage_end = p_end + p_capacity;
}
DynamicArray slice(iterator start, iterator end)
{
return DynamicArray {start, end};
}
// Friend functions
friend
void swap(DynamicArray& lhs, DynamicArray& rhs)
{
std::swap(lhs.p_size, rhs.p_size);
std::swap(lhs.p_capacity, rhs.p_capacity);
std::swap(lhs.p_start, rhs.p_start);
std::swap(lhs.p_end, rhs.p_end);
std::swap(lhs.p_storage_end, rhs.p_storage_end);
}
friend
bool operator==(const DynamicArray& lhs, const DynamicArray& rhs)
{
for (auto n = 0; n < lhs.size(); ++n)
if (lhs[n] != rhs[n])
return false;
return true;
}
friend
DynamicArray operator+(const DynamicArray& lhs, const DynamicArray& rhs)
{
DynamicArray arr {rhs.size() + lhs.size(), {}};
for (auto n = 0; n < rhs.size(); ++n)
{
arr[n] = rhs[n];
arr[n + rhs.size()] = lhs[n];
}
return arr;
}
};
// Aliases
template <typename Type>
using darray = DynamicArray<Type>;
} }

View File

@ -1,95 +1,98 @@
#pragma once #pragma once
#include <iterator> #include <iterator>
namespace hpr namespace hpr
{ {
template <typename Type, typename Category = std::forward_iterator_tag> template <typename Type, typename Category = std::forward_iterator_tag>
class Iterator class Iterator
{ {
public:
using iterator_category = Category; public:
using difference_type = std::ptrdiff_t;
using value_type = Type; using iterator_category = Category;
using pointer = Type*; using difference_type = std::ptrdiff_t;
using reference = Type&; using value_type = Type;
using iterator = Iterator; using pointer = Type*;
using const_pointer = Type const*; using reference = Type&;
using const_reference = Type const&; using iterator = Iterator;
using const_iterator = Iterator const; using const_pointer = Type const*;
using const_reference = Type const&;
protected: using const_iterator = Iterator const;
pointer p_ptr;
protected:
public:
pointer p_ptr;
Iterator() :
p_ptr {nullptr} public:
{}
Iterator() :
Iterator(pointer ptr) : p_ptr {nullptr}
p_ptr {ptr} {}
{}
Iterator(pointer ptr) :
reference operator*() p_ptr {ptr}
{ {}
return *p_ptr;
} reference operator*()
{
const_reference operator*() const return *p_ptr;
{ }
return *p_ptr;
} const_reference operator*() const
{
pointer operator->() return *p_ptr;
{ }
return p_ptr;
} pointer operator->()
{
const_pointer operator->() const return p_ptr;
{ }
return p_ptr;
} const_pointer operator->() const
{
iterator& operator++() return p_ptr;
{ }
p_ptr++;
return *this; iterator& operator++()
} {
p_ptr++;
const_iterator& operator++() const return *this;
{ }
p_ptr++;
return *this; const_iterator& operator++() const
} {
p_ptr++;
iterator operator++(int) return *this;
{ }
iterator temp {*this};
++(*this); iterator operator++(int)
return temp; {
} iterator temp {*this};
++(*this);
iterator operator+(int value) return temp;
{ }
iterator temp {*this};
temp.p_ptr += value; iterator operator+(int value)
return temp; {
} iterator temp {*this};
temp.p_ptr += value;
friend return temp;
bool operator==(const iterator& lhs, const iterator& rhs) }
{
return lhs.p_ptr == rhs.p_ptr; friend
} bool operator==(const iterator& lhs, const iterator& rhs)
{
friend return lhs.p_ptr == rhs.p_ptr;
bool operator!=(const iterator& lhs, const iterator& rhs) }
{
return lhs.p_ptr != rhs.p_ptr; friend
} bool operator!=(const iterator& lhs, const iterator& rhs)
}; {
return lhs.p_ptr != rhs.p_ptr;
} }
};
}

View File

@ -0,0 +1,314 @@
#pragma once
#include <hpr/containers/array/iterator.hpp>
#include <hpr/exception.hpp>
#include <hpr/math/integer.hpp>
namespace hpr
{
// forward declaration
template <typename T>
class Sequence;
// type traits
template <typename T>
struct is_sequence : public std::false_type
{};
template <typename T>
struct is_sequence<Sequence<T>> : public std::true_type
{};
// class definition
template <typename T>
class Sequence
{
public:
using difference_type = std::ptrdiff_t;
using value_type = T;
using size_type = Size;
using pointer = T*;
using reference = T&;
using iterator = Iterator<T>;
using const_pointer = T const*;
using const_reference = T const&;
using const_iterator = Iterator<const T>;
protected:
size_type p_size;
size_type p_capacity;
pointer p_start;
protected:
constexpr
Sequence(size_type size, size_type capacity, pointer start) :
p_size {size},
p_capacity {capacity},
p_start {start}
{}
constexpr explicit
Sequence(size_type size, size_type capacity) :
p_size {size},
p_capacity {capacity},
p_start {p_capacity ? new value_type[p_capacity] : nullptr}
{}
public:
friend constexpr
void swap(Sequence& main, Sequence& other) noexcept
{
using std::swap;
swap(main.p_size, other.p_size);
swap(main.p_capacity, other.p_capacity);
swap(main.p_start, other.p_start);
}
constexpr
Sequence() noexcept :
p_size {0},
p_capacity {1},
p_start {new value_type[p_capacity]}
{}
constexpr
Sequence(const Sequence& seq) noexcept :
p_size {seq.p_size},
p_capacity {seq.p_capacity},
p_start {p_capacity ? new value_type[seq.p_capacity] : nullptr}
{
std::copy(seq.p_start, seq.p_start + seq.p_size, p_start);
}
//! Move constructor
constexpr
Sequence(Sequence&& seq) noexcept :
Sequence {}
{
swap(*this, seq);
}
template <typename Iter>
constexpr
Sequence(Iter start, Iter end) :
p_size {static_cast<size_type>(std::distance(start, end))},//size_type(end.operator->() - start.operator->())},
p_capacity {p_size},
p_start {p_capacity ? new value_type[p_capacity] : nullptr}
{
std::copy(start, end, p_start);
}
constexpr
Sequence(iterator start, iterator end) :
p_size {static_cast<size_type>(std::distance(start, end))},//size_type(end.operator->() - start.operator->())},
p_capacity {p_size},
p_start {p_capacity ? new value_type[p_capacity] : nullptr}
{
std::copy(start, end, p_start);
}
constexpr
Sequence(const_iterator start, const_iterator end) :
p_size {std::distance(start, end)},//{size_type(end.operator->() - start.operator->())},
p_capacity {p_size},
p_start {p_capacity ? new value_type[p_capacity] : nullptr}
{
std::copy(start, end, p_start);
}
constexpr
Sequence(iterator start, iterator end, size_type capacity) :
p_size {static_cast<size_type>(std::distance(start, end))},//size_type(end.operator->() - start.operator->())},
p_capacity {capacity},
p_start {p_capacity ? new value_type[p_capacity] : nullptr}
{
std::copy(start, end, p_start);
}
constexpr
Sequence(const_iterator start, const_iterator end, size_type capacity) :
p_size {std::distance(start, end)},//{size_type(end.operator->() - start.operator->())},
p_capacity {capacity},
p_start {p_capacity ? new value_type[p_capacity] : nullptr}
{
std::copy(start, end, p_start);
}
/*constexpr
Sequence(std::initializer_list<value_type> list) :
Sequence {list.begin(), list.end()}
{}*/
constexpr
Sequence(size_type size, value_type value) noexcept:
p_size {size},
p_capacity {size},
p_start {p_capacity ? new value_type[p_capacity] : nullptr}
{
for (auto n = 0; n < size; ++n)
*(p_start + n) = value;
}
constexpr
Sequence& operator=(Sequence other) noexcept
{
swap(*this, other);
return *this;
}
constexpr
Sequence& operator=(Sequence&& seq) noexcept
{
swap(*this, seq);
return *this;
}
virtual
~Sequence()
{
delete[] p_start;
}
// Member functions
virtual constexpr
iterator begin()
{
return iterator(p_start);
}
[[nodiscard]] virtual constexpr
const_iterator begin() const
{
return const_iterator(p_start);
}
virtual constexpr
iterator end()
{
return iterator(p_start + p_size);
}
virtual constexpr
const_iterator end() const
{
return const_iterator(p_start + p_size);
}
virtual constexpr
iterator storage_end()
{
return iterator(p_start + p_capacity);
}
virtual constexpr
const_iterator storage_end() const
{
return const_iterator(p_start + p_capacity);
}
[[nodiscard]] virtual constexpr
size_type size() const noexcept
{
return p_size;
}
virtual constexpr
reference operator[](size_type n)
{
if (n >= size())
throw hpr::OutOfRange();
return *(p_start + n);
}
virtual constexpr
const_reference operator[](size_type n) const
{
if (n >= size())
throw hpr::OutOfRange();
return *(p_start + n);
}
virtual constexpr
reference at(size_type n)
{
return operator[](n);
}
virtual constexpr
const_reference at(size_type n) const
{
return operator[](n);
}
virtual constexpr
reference front()
{
return *begin();
}
virtual constexpr
const_reference front() const
{
return *begin();
}
virtual constexpr
reference back()
{
return *(p_start + p_size - 1);
}
virtual constexpr
const_reference back() const
{
return *(p_start + p_size - 1);
}
virtual constexpr
pointer data()
{
return p_start;
}
[[nodiscard]] virtual constexpr
const_pointer data() const
{
return p_start;
}
// Friend functions
friend
bool operator==(const Sequence& lhs, const Sequence& rhs)
{
for (auto n = 0; n < lhs.size(); ++n)
if (lhs[n] != rhs[n])
return false;
return true;
}
friend
Sequence operator+(const Sequence& lhs, const Sequence& rhs)
{
Sequence seq {rhs.size() + lhs.size(), {}};
for (auto n = 0; n < rhs.size(); ++n)
{
seq[n] = rhs[n];
seq[n + rhs.size()] = lhs[n];
}
return seq;
}
};
}

View File

@ -1,257 +1,150 @@
#pragma once #pragma once
#include "iterator.hpp" #include <hpr/containers/array/sequence.hpp>
#include <limits>
#include <functional> namespace hpr
#include <concepts> {
// forward declaration
namespace hpr
{ template <typename T, Size S>
requires (S > 0)
template <typename Type, size_t Size> class StaticArray;
class StaticArray
{ // type traits
public: template <typename T, Size S>
struct is_sequence<StaticArray<T, S>> : public std::true_type
using difference_type = std::ptrdiff_t; {};
using value_type = Type;
using size_type = size_t; // aliases
using pointer = Type*;
using reference = Type&; template <typename T, Size S>
using iterator = Iterator<Type>; using sarray = StaticArray<T, S>;
using const_pointer = Type const*;
using const_reference = Type const&; // class definition
using const_iterator = Iterator<const Type>;
template <typename T, Size S>
protected: requires (S > 0)
class StaticArray : public Sequence<T>
const size_type p_size; {
pointer p_start;
pointer p_end; using base = Sequence<T>;
protected: public:
inline using difference_type = std::ptrdiff_t;
StaticArray(size_type size, pointer start, pointer end) : using value_type = T;
p_size {size}, using size_type = Size;
p_start {start}, using pointer = T*;
p_end {end} using reference = T&;
{} using iterator = Iterator<T>;
using const_pointer = T const*;
public: using const_reference = T const&;
using const_iterator = Iterator<const T>;
inline
StaticArray() : public:
p_size {Size},
p_start {new value_type[p_size] {}}, friend constexpr
p_end {p_start + p_size} void swap(StaticArray& main, StaticArray& other) noexcept
{} {
using std::swap;
inline swap(static_cast<base&>(main), static_cast<base&>(other));
StaticArray(const StaticArray& arr) : }
p_size {arr.p_size},
p_start {new value_type[arr.p_size]}, //! Default constructor
p_end {p_start + p_size} constexpr
{ StaticArray() noexcept :
std::copy(arr.p_start, arr.p_end, p_start); base {S, S, new value_type[S] {}}
} {}
//! Move constructor constexpr explicit
inline StaticArray(const base& b) noexcept :
StaticArray(StaticArray&& arr) noexcept : base {b}
StaticArray {} {}
{
swap(*this, arr); //! Copy constructor
} constexpr
StaticArray(const StaticArray& arr) noexcept :
inline base {static_cast<base>(arr)}
StaticArray(const_iterator start, const_iterator end) : {}
p_size {Size},
p_start {new value_type[p_size]}, //! Move constructor
p_end {p_start + p_size} constexpr
{ StaticArray(StaticArray&& arr) noexcept :
std::copy(start, end, p_start); base {std::forward<base>(static_cast<base>(arr))}
} {}
inline constexpr
StaticArray(iterator start, iterator end) : StaticArray(typename base::iterator start, typename base::iterator end) :
p_size {Size}, base {start, end}
p_start {new value_type[p_size]}, {}
p_end {p_start + p_size}
{ constexpr
std::copy(start, end, p_start); StaticArray(typename base::const_iterator start, typename base::const_iterator end) :
} base {start, end}
{}
inline
StaticArray(std::initializer_list<value_type> list) : constexpr
StaticArray {list.begin(), list.end()} StaticArray(typename base::iterator start, typename base::iterator end, size_type capacity) :
{} base {start, end, capacity}
{}
template <std::convertible_to<value_type>... Args>
inline constexpr
StaticArray(const value_type& v, const Args& ...args) : StaticArray(typename base::const_iterator start, typename base::const_iterator end, size_type capacity) :
StaticArray {std::initializer_list<value_type>({std::forward<value_type>(v), base {start, end, capacity}
std::forward<value_type>(static_cast<value_type>(args))...})} {}
{
static_assert(1 + sizeof...(args) == Size, "Number of arguments must be equal to size of array"); constexpr
} StaticArray(std::initializer_list<value_type> list) :
base {list.begin(), list.end()}
template <std::convertible_to<value_type>... Args> {}
inline
StaticArray(value_type&& v, Args&& ...args) : template <std::convertible_to<value_type>... Args>
StaticArray {std::initializer_list<value_type>({std::forward<value_type>(v), constexpr explicit
std::forward<value_type>(static_cast<value_type>(args))...})} StaticArray(const value_type& v, const Args& ...args)
{ requires (1 + sizeof...(args) == S) :
static_assert(1 + sizeof...(args) == Size, "Number of arguments must be equal to size of array"); StaticArray {std::initializer_list<value_type>({v, static_cast<value_type>(args)...})}
} {}
template <size_type SubSize, std::convertible_to<value_type>... Args> template <std::convertible_to<value_type>... Args>
inline constexpr explicit
StaticArray(const StaticArray<value_type, SubSize>& subarr, const value_type& v, const Args& ...args) : StaticArray(value_type&& v, Args&& ...args)
p_size {Size}, requires (1 + sizeof...(args) == S) :
p_start {new value_type[p_size]}, StaticArray {std::initializer_list<value_type>({std::forward<value_type>(v), std::forward<value_type>(static_cast<value_type>(args))...})}
p_end {p_start + p_size} {}
{
static_assert(SubSize + 1 + sizeof...(args) == Size, template <size_type SS, std::convertible_to<value_type>... Args>
"Number of arguments and sub-array elements must be equal to size of main array"); constexpr
std::initializer_list<value_type> list {v, static_cast<value_type>(args)...}; StaticArray(const StaticArray<value_type, SS>& subArr, const value_type& v, const Args& ...args) noexcept
std::copy(subarr.begin(), subarr.end(), begin()); requires (SS + 1 + sizeof...(args) == S) :
size_type pos {subarr.size()}; base {S, S, new value_type[S] {}}
for (auto& val : list) {
(*this)[pos++] = val; std::copy(subArr.begin(), subArr.end(), base::begin());
} std::initializer_list<value_type> list {v, static_cast<value_type>(args)...};
std::copy(list.begin(), list.end(), base::begin() + subArr.size());
inline }
StaticArray& operator=(const StaticArray& vs)
{ constexpr
std::copy(vs.begin(), vs.end(), begin()); StaticArray& operator=(StaticArray other)
return *this; {
} swap(*this, other);
return *this;
inline }
StaticArray& operator=(StaticArray&& arr) noexcept
{ constexpr
swap(*this, arr); StaticArray& operator=(StaticArray&& other) noexcept
return *this; {
} swap(*this, other);
return *this;
virtual }
~StaticArray()
{ virtual
//std::destroy(p_start, p_end); ~StaticArray() = default;
delete[] p_start;
}
};
// Member functions
virtual }
iterator begin()
{
return iterator(p_start);
}
[[nodiscard]] virtual
const_iterator begin() const
{
return const_iterator(p_start);
}
virtual
iterator end()
{
return iterator(p_end);
}
virtual
const_iterator end() const
{
return const_iterator(p_end);
}
[[nodiscard]] virtual constexpr
size_type size() const
{
return size_type(p_end - p_start);
}
[[nodiscard]] virtual
bool is_empty() const
{
return begin() == end();
}
virtual
reference operator[](size_type n)
{
if (n >= size())
throw std::out_of_range("Index out of bounds");
return *(p_start + n);
}
virtual
const_reference operator[](size_type n) const
{
if (n >= size())
throw std::out_of_range("Index out of bounds");
return *(p_start + n);
}
virtual
reference front()
{
return *p_start;
}
virtual
reference back()
{
return *(p_end - 1);
}
virtual
pointer data()
{
return p_start;
}
[[nodiscard]] virtual
const_pointer data() const
{
return p_start;
}
// Friend functions
friend
void swap(StaticArray& lhs, StaticArray& rhs)
{
std::swap(lhs.p_start, rhs.p_start);
std::swap(lhs.p_end, rhs.p_end);
}
friend
void swap(StaticArray&& lhs, StaticArray&& rhs)
{
std::swap(lhs.p_start, rhs.p_start);
std::swap(lhs.p_end, rhs.p_end);
}
friend
bool operator==(const StaticArray& lhs, const StaticArray& rhs)
{
for (auto n = 0; n < Size; ++n)
if (lhs[n] != rhs[n])
return false;
return true;
}
};
// Aliases
template <typename Type, size_t Size>
using sarray = StaticArray<Type, Size>;
}

View File

@ -0,0 +1,3 @@
#pragma once
#include <hpr/containers/graph/tree_node.hpp>

View File

@ -0,0 +1,180 @@
#pragma once
#include <hpr/containers/array/dynamic_array.hpp>
#include <memory>
namespace hpr
{
template <typename Type>
class TreeNode
{
public:
using value_type = Type;
using pointer = Type*;
using reference = Type&;
using const_pointer = Type const*;
using const_reference = Type const&;
protected:
pointer p_data;
darray<TreeNode*> p_descendants;
TreeNode* p_ancestor;
public:
friend constexpr
void swap(TreeNode& main, TreeNode& other) noexcept
{
using std::swap;
swap(main.p_data, other.p_data);
swap(main.p_descendants, other.p_descendants);
swap(main.p_ancestor, other.p_ancestor);
}
inline
TreeNode() :
p_data {new value_type {}},
p_descendants {},
p_ancestor {}
{}
inline
TreeNode(const TreeNode& node) :
p_data {new value_type {*node.p_data}},
p_descendants {},
p_ancestor {}
{}
inline
TreeNode(TreeNode&& node) noexcept :
p_data {},
p_descendants {},
p_ancestor {}
{
swap(*this, node);
/*std::swap(p_data, node.p_data);
std::swap(p_descendants, node.p_descendants);
std::swap(p_ancestor, node.p_ancestor);*/
}
inline
TreeNode& operator=(TreeNode other)
{
swap(*this, other);
return *this;
}
inline explicit
TreeNode(const value_type& data) :
p_data {new value_type {data}},
p_descendants {},
p_ancestor {}
{}
inline
TreeNode(const value_type& data, const darray<TreeNode*>& descendants, TreeNode* ancestor) :
p_data {new value_type {data}},
p_descendants {descendants},
p_ancestor {ancestor}
{
for (auto descendant : p_descendants)
descendant->ancestor(this);
}
inline
TreeNode(const value_type& data, const darray<TreeNode*>& descendants) :
p_data {new value_type {data}},
p_descendants {descendants},
p_ancestor {}
{
for (auto descendant : p_descendants)
descendant->ancestor(this);
}
virtual
~TreeNode()
{
delete p_data;
//delete p_ancestor;
}
// Member functions
inline
pointer data()
{
return p_data;
}
inline
void ancestor(TreeNode* node)
{
p_ancestor = node;
}
inline
TreeNode* ancestor()
{
return p_ancestor;
}
inline
void descendants(const darray<TreeNode*>& descendants)
{
p_descendants = descendants;
}
inline
darray<TreeNode*>& descendants()
{
return p_descendants;
}
darray<TreeNode*> traverse_descendants()
{
std::function<darray<TreeNode*>(TreeNode*)> collect = [&](TreeNode* node)
{
darray<TreeNode*> ds;
if (!node->descendants().is_empty())
{
for (TreeNode* dnode: node->descendants())
{
ds.push(dnode);
if (!dnode->descendants().is_empty())
ds.push(collect(dnode));
}
}
return ds;
};
return collect(this);
}
darray<TreeNode*> traverse_ancestors()
{
std::function<darray<TreeNode*>(TreeNode*)> collect = [&](TreeNode* node)
{
darray<TreeNode*> ds;
if (node->p_ancestor)
{
ds.push(node);
ds.push(collect(node->p_ancestor));
}
return ds;
};
return collect(this);
}
};
}

View File

@ -1,15 +0,0 @@
file(GLOB tests_cpp "*.cpp")
add_executable(${PROJECT_NAME}-tests
${tests_cpp}
)
target_link_libraries(${PROJECT_NAME}-tests
PUBLIC
hpr::containers
PRIVATE
GTest::gtest_main
)
gtest_add_tests(TARGET ${PROJECT_NAME}-tests)

View File

@ -1,37 +1,93 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "../array.hpp" #include <hpr/containers/array.hpp>
#include <hpr/containers/graph.hpp>
TEST(containers, StaticArray)
{ TEST(containers, StaticArray)
hpr::StaticArray<float, 3> arr {1, 3, 2}; {
hpr::StaticArray<float, 4> sarr {arr, 5}; hpr::StaticArray<float, 3> arr {7, 3, 2};
hpr::StaticArray<float, 4> sarr2 {1, 3, 2, 5}; hpr::StaticArray<float, 4> sarr {arr, 5};
EXPECT_EQ(sarr, sarr2); hpr::StaticArray<float, 4> sarr2 {7, 3, 2, 5};
} //hpr::StaticArray<float, 0> sarr4;
TEST(containers, DynamicArray) EXPECT_EQ(sarr, sarr2);
{ //EXPECT_EQ(sarr4.data(), nullptr);
hpr::DynamicArray<float> arr {1, 3, 2}; //EXPECT_EQ(sarr4.is_empty(), true);
hpr::DynamicArray<float> arr2 {1, 3, 2}; EXPECT_EQ(sarr.size(), 4);
EXPECT_EQ(arr, arr2); EXPECT_EQ(sarr2.size(), 4);
arr.remove(1); EXPECT_EQ(sarr[0], 7);
EXPECT_EQ(arr, hpr::darray<float>({1, 2})); EXPECT_EQ(sarr[1], 3);
auto iter = arr2.begin(); EXPECT_EQ(sarr[2], 2);
++iter; EXPECT_EQ(sarr[3], 5);
arr2.remove(iter); }
EXPECT_EQ(arr2, hpr::darray<float>({1, 2}));
TEST(containers, DynamicArray)
hpr::DynamicArray<float> arr3 {1, 3, 0, 2, 9, 0, 5}; {
arr3.remove([](float num) { return num == 0; }); hpr::DynamicArray<float> arr {1, 3, 2};
EXPECT_EQ(arr3, hpr::darray<float>({1, 3, 2, 9, 5})); hpr::DynamicArray<float> arr2 {1, 3, 2};
EXPECT_EQ(arr3.size(), 5); EXPECT_EQ(arr, arr2);
EXPECT_TRUE(arr == arr2);
hpr::DynamicArray<float*> arr4; arr.remove(1);
arr4.push(new float(5)); EXPECT_EQ(arr, hpr::darray<float>({1, 2}));
arr4.push(new float(7)); auto iter = arr2.begin();
arr4.push(new float(9)); ++iter;
EXPECT_EQ(*arr4[0], 5.f); arr2.remove(iter);
EXPECT_EQ(*arr4[2], 9.f); EXPECT_EQ(arr2, hpr::darray<float>({1, 2}));
}
hpr::DynamicArray<float> arr3 {1, 3, 0, 2, 9, 0, 5};
arr3.remove([](float num) { return num == 0; });
EXPECT_EQ(arr3, hpr::darray<float>({1, 3, 2, 9, 5}));
EXPECT_EQ(arr3.size(), 5);
arr3.insert(3, 19);
EXPECT_EQ(arr3.size(), 6);
EXPECT_EQ(arr3[3], 19);
EXPECT_EQ(arr3.pop(), 5);
EXPECT_EQ(arr3.size(), 5);
arr3.resize(3);
EXPECT_EQ(arr3.size(), 3);
EXPECT_EQ(arr3.capacity(), 3);
EXPECT_EQ(arr3.back(), 2);
arr3.resize(4);
EXPECT_EQ(arr3.back(), 2);
arr3.push(17);
arr3.push(14);
EXPECT_EQ(arr3.back(), 14);
EXPECT_EQ(arr3.size(), 5);
arr3.clear();
EXPECT_EQ(arr3.is_empty(), true);
hpr::DynamicArray<float*> arr4;
arr4.push(new float(5));
arr4.push(new float(7));
arr4.push(new float(9));
EXPECT_EQ(*arr4[0], 5.f);
EXPECT_EQ(*arr4[2], 9.f);
for (auto& v : arr4)
delete v;
}
TEST(containers, TreeNode)
{
hpr::TreeNode<float> node1 (5);
//std::shared_ptr<hpr::TreeNode<float>> ptr {node1};
hpr::TreeNode<float> node2 {7, {&node1}};
hpr::TreeNode<float> node3 {9, {&node2, &node1}};
hpr::TreeNode<float> node4 {11, {&node3}};
EXPECT_EQ(*node1.data(), 5);
//EXPECT_EQ(*node1->data(), *node2.ancestor()->data());
hpr::darray<hpr::TreeNode<float>*> tr = node1.traverse_descendants();
EXPECT_EQ(tr.size(), 0);
hpr::darray<hpr::TreeNode<float>*> tr2 = node4.traverse_descendants();
EXPECT_EQ(tr2.size(), 4);
hpr::darray<hpr::TreeNode<float>*> tr3 = node1.traverse_ancestors();
EXPECT_EQ(tr3.size(), 2); // node1 has changed ancestor
//
}

View File

View File

@ -1,55 +0,0 @@
cmake_minimum_required(VERSION 3.16)
project(core
VERSION "${HPR_PROJECT_VERSION}"
LANGUAGES CXX
)
add_library(${PROJECT_NAME} INTERFACE)
add_library(${CMAKE_PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
add_module(${PROJECT_NAME})
file(GLOB ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS "../core.hpp" "*.hpp")
foreach(_header_path ${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS})
list(APPEND ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE "$<BUILD_INTERFACE:${_header_path}>")
endforeach()
target_sources(${PROJECT_NAME}
INTERFACE
${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE}
$<INSTALL_INTERFACE:include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME}>
)
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_SKIP
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}-${HPR_PROJECT_VERSION}
NAMESPACE ${CMAKE_PROJECT_NAME}::
)
install(
TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_ONLY
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
DIRECTORY ${PROJECT_SOURCE_DIR}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "tests" EXCLUDE
)
install(
FILES ../${PROJECT_NAME}.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
)

View File

@ -1,5 +0,0 @@
#pragma once
#define HPR_VERSION_MAJOR 0
#define HPR_VERSION_MINOR 10
#define HPR_VERSION_PATCH 0

View File

@ -1,12 +1,12 @@
#pragma once #pragma once
#include "csg/shape.hpp" #include <hpr/csg/shape.hpp>
#include "csg/vertex.hpp" #include <hpr/csg/vertex.hpp>
#include "csg/edge.hpp" #include <hpr/csg/edge.hpp>
#include "csg/wire.hpp" #include <hpr/csg/wire.hpp>
#include "csg/face.hpp" #include <hpr/csg/face.hpp>
#include "csg/shell.hpp" #include <hpr/csg/shell.hpp>
#include "csg/solid.hpp" #include <hpr/csg/solid.hpp>
#include "csg/compound.hpp" #include <hpr/csg/compound.hpp>
#include "csg/geometry.hpp" #include <hpr/csg/geometry.hpp>
#include "csg/surface.hpp" #include <hpr/csg/surface.hpp>

View File

@ -1,77 +1,33 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(csg project(csg
VERSION "${HPR_PROJECT_VERSION}" VERSION "${HPR_VERSION}"
LANGUAGES CXX LANGUAGES CXX
) )
add_library(${PROJECT_NAME}) hpr_add_library(${PROJECT_NAME} STATIC)
add_library(${CMAKE_PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
add_module(${PROJECT_NAME}) hpr_collect_interface(${PROJECT_NAME}
"../csg.hpp"
file(GLOB ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS "*.hpp"
"../csg.hpp" "*.hpp" )
)
hpr_collect_sources(${PROJECT_NAME}
foreach(_header_path ${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS}) "*.cpp"
list(APPEND ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE "$<BUILD_INTERFACE:${_header_path}>") )
endforeach()
target_sources(${PROJECT_NAME}
file(GLOB ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_SOURCES INTERFACE ${${PROJECT_NAME}_HEADERS_INTERFACE} ${HPR_INSTALL_INTERFACE}/${PROJECT_NAME}>
"*.cpp" PRIVATE ${${PROJECT_NAME}_SOURCES}
) )
target_sources(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
INTERFACE ${OpenCASCADE_LIBS}
${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE} )
$<INSTALL_INTERFACE:include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME}>
PRIVATE target_include_directories(${PROJECT_NAME}
${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_SOURCES} PUBLIC ${OpenCASCADE_INCLUDE_DIR}
) )
target_link_libraries(${PROJECT_NAME} hpr_install(${PROJECT_NAME} ${PROJECT_SOURCE_DIR})
${OCCT_LIBRARIES} hpr_tests(${PROJECT_NAME} tests)
)
target_include_directories(${PROJECT_NAME}
PUBLIC
${OCCT_INCLUDE_DIRS}
)
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_SKIP
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}-${HPR_PROJECT_VERSION}
NAMESPACE ${CMAKE_PROJECT_NAME}::
)
install(
TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_ONLY
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
DIRECTORY ${PROJECT_SOURCE_DIR}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "tests" EXCLUDE
)
install(
FILES ../${PROJECT_NAME}.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
)
if(HPR_TEST)
add_subdirectory(tests)
endif()

View File

@ -1,45 +1,45 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
#include "solid.hpp" #include <hpr/csg/solid.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Compound : public Shape class Compound : public Shape
{ {
public: public:
Compound() = default; Compound() = default;
~Compound() override = default; ~Compound() override = default;
explicit explicit
Compound(const Shape& shape) : Compound(const Shape& shape) :
Shape {shape.type() == Type::Compound ? shape : throw std::runtime_error("")} Shape {shape.type() == Type::Compound ? shape : throw std::runtime_error("")}
{} {}
explicit explicit
Compound(const darray<Shape>& shapes) : Compound(const darray<Shape>& shapes) :
Shape {} Shape {}
{ {
BRep_Builder builder; BRep_Builder builder;
TopoDS_Compound compound; TopoDS_Compound compound;
builder.MakeCompound(compound); builder.MakeCompound(compound);
for (auto& shape : shapes) for (auto& shape : shapes)
builder.Add(compound, shape.tshape()); builder.Add(compound, shape.tshape());
p_shape = compound; p_shape = compound;
} }
[[nodiscard]] [[nodiscard]]
TopoDS_Compound tcast() const TopoDS_Compound tcast() const
{ {
return TopoDS::Compound(p_shape); return TopoDS::Compound(p_shape);
} }
}; };
} }

View File

@ -1,39 +1,39 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
#include "vertex.hpp" #include <hpr/csg/vertex.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Edge : public Shape class Edge : public Shape
{ {
public: public:
Edge() = default; Edge() = default;
~Edge() override = default; ~Edge() override = default;
explicit explicit
Edge(const Shape& shape) : Edge(const Shape& shape) :
Shape {shape.type() == Type::Edge ? shape : throw std::runtime_error("")} Shape {shape.type() == Type::Edge ? shape : throw std::runtime_error("")}
{} {}
Edge(const vec3& p1, const vec3& p2) : Edge(const vec3& p1, const vec3& p2) :
Shape {BRepBuilderAPI_MakeEdge(gp_Pnt(p1[0], p1[1], p1[2]), gp_Pnt(p2[0], p2[1], p2[2])).Shape()} Shape {BRepBuilderAPI_MakeEdge(gp_Pnt(p1[0], p1[1], p1[2]), gp_Pnt(p2[0], p2[1], p2[2])).Shape()}
{} {}
Edge(const Vertex& v1, const Vertex& v2) : Edge(const Vertex& v1, const Vertex& v2) :
Shape {BRepBuilderAPI_MakeEdge(v1.tcast(), v2.tcast()).Shape()} Shape {BRepBuilderAPI_MakeEdge(v1.tcast(), v2.tcast()).Shape()}
{} {}
[[nodiscard]] [[nodiscard]]
TopoDS_Edge tcast() const TopoDS_Edge tcast() const
{ {
return TopoDS::Edge(p_shape); return TopoDS::Edge(p_shape);
} }
}; };
} }

View File

@ -1,42 +1,42 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
#include "wire.hpp" #include <hpr/csg/wire.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Face : public Shape class Face : public Shape
{ {
public: public:
Face() = default; Face() = default;
~Face() override = default; ~Face() override = default;
explicit explicit
Face(const Shape& shape) : Face(const Shape& shape) :
Shape {shape.type() == Type::Face ? shape : throw std::runtime_error("")} Shape {shape.type() == Type::Face ? shape : throw std::runtime_error("")}
{} {}
explicit explicit
Face(const Wire& wire) : Face(const Wire& wire) :
Shape {BRepBuilderAPI_MakeFace(wire.tcast()).Shape()} Shape {BRepBuilderAPI_MakeFace(wire.tcast()).Shape()}
{} {}
explicit explicit
Face(const darray<Shape>& edges) : Face(const darray<Shape>& edges) :
Face {Wire(edges)} Face {Wire(edges)}
{} {}
[[nodiscard]] [[nodiscard]]
TopoDS_Face tcast() const TopoDS_Face tcast() const
{ {
return TopoDS::Face(p_shape); return TopoDS::Face(p_shape);
} }
}; };
} }

View File

@ -1,21 +1,21 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Geometry class Geometry
{ {
public: public:
Geometry() = default; Geometry() = default;
virtual virtual
~Geometry() = default; ~Geometry() = default;
}; };
} }

View File

@ -1,27 +1,27 @@
#include "shape.hpp" #include <hpr/csg/shape.hpp>
bool std::less<hpr::csg::Shape>::operator()(const hpr::csg::Shape& s1, const hpr::csg::Shape& s2) const bool std::less<hpr::csg::Shape>::operator()(const hpr::csg::Shape& s1, const hpr::csg::Shape& s2) const
{ {
return s1.tshape().HashCode(std::numeric_limits<Standard_Integer>::max()) < return s1.tshape().HashCode(std::numeric_limits<Standard_Integer>::max()) <
s2.tshape().HashCode(std::numeric_limits<Standard_Integer>::max()); s2.tshape().HashCode(std::numeric_limits<Standard_Integer>::max());
} }
namespace hpr::csg namespace hpr::csg
{ {
std::map<Shape, Shape::Metadata> Shape::metadata; std::map<Shape, Shape::Metadata> Shape::metadata;
Shape sphere(vec3 center, double radius) Shape sphere(vec3 center, double radius)
{ {
BRepPrimAPI_MakeSphere prim {gp_Pnt(center[0], center[1], center[2]), radius}; BRepPrimAPI_MakeSphere prim {gp_Pnt(center[0], center[1], center[2]), radius};
return Shape {prim.Shape()}; return Shape {prim.Shape()};
} }
Shape box(vec3 corner, double dx, double dy, double dz) Shape box(vec3 corner, double dx, double dy, double dz)
{ {
BRepPrimAPI_MakeBox prim {gp_Pnt(corner[0], corner[1], corner[2]), dx, dy, dz}; BRepPrimAPI_MakeBox prim {gp_Pnt(corner[0], corner[1], corner[2]), dx, dy, dz};
return Shape {prim.Shape()}; return Shape {prim.Shape()};
} }
} }

View File

@ -1,490 +1,490 @@
#pragma once #pragma once
#include "../containers/array.hpp" #include <hpr/containers/array.hpp>
#include "../math/scalar.hpp" #include <hpr/math/scalar.hpp>
#include "../math/vector.hpp" #include <hpr/math/vector.hpp>
#include <map> #include <map>
#include <string> #include <string>
#include <Geom_Surface.hxx> #include <Geom_Surface.hxx>
#include <GeomLProp_SLProps.hxx> #include <GeomLProp_SLProps.hxx>
#include <Poly_Triangle.hxx> #include <Poly_Triangle.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx> #include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx> #include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx> #include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx> #include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx> #include <TopoDS_Compound.hxx>
#include <TopoDS_CompSolid.hxx> #include <TopoDS_CompSolid.hxx>
#include <TopoDS_Shell.hxx> #include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx> #include <TopoDS_Solid.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx> #include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx> #include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeFace.hxx> #include <BRepBuilderAPI_MakeFace.hxx>
#include <BRep_Builder.hxx> #include <BRep_Builder.hxx>
#include <BRepBndLib.hxx> #include <BRepBndLib.hxx>
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <BRepTools.hxx> #include <BRepTools.hxx>
#include <BRepGProp.hxx> #include <BRepGProp.hxx>
#include <GProp_GProps.hxx> #include <GProp_GProps.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx> #include <ShapeUpgrade_UnifySameDomain.hxx>
#include <BRepExtrema_DistShapeShape.hxx> #include <BRepExtrema_DistShapeShape.hxx>
#include <BRepBuilderAPI_Transform.hxx> #include <BRepBuilderAPI_Transform.hxx>
#include <BRepFilletAPI_MakeFillet.hxx> #include <BRepFilletAPI_MakeFillet.hxx>
#include <BRepAlgoAPI_Fuse.hxx> #include <BRepAlgoAPI_Fuse.hxx>
#include <BRepAlgoAPI_Common.hxx> #include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Cut.hxx> #include <BRepAlgoAPI_Cut.hxx>
#include <BRepPrimAPI_MakeSphere.hxx> #include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeBox.hxx> #include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakePrism.hxx> #include <BRepPrimAPI_MakePrism.hxx>
#include <STEPControl_Writer.hxx> #include <STEPControl_Writer.hxx>
#include <Interface_Static.hxx> #include <Interface_Static.hxx>
#include <BRepMesh_IncrementalMesh.hxx> #include <BRepMesh_IncrementalMesh.hxx>
#include <Poly_PolygonOnTriangulation.hxx> #include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx> #include <Poly_Triangulation.hxx>
#include <TopAbs_ShapeEnum.hxx> #include <TopAbs_ShapeEnum.hxx>
#include <TopLoc_Location.hxx> #include <TopLoc_Location.hxx>
#include <NCollection_List.hxx> #include <NCollection_List.hxx>
#include <ShapeFix_Solid.hxx> #include <ShapeFix_Solid.hxx>
#include <ShapeFix_Shell.hxx> #include <ShapeFix_Shell.hxx>
#include <ShapeFix_Face.hxx> #include <ShapeFix_Face.hxx>
namespace hpr::csg namespace hpr::csg
{ {
class Shape; class Shape;
} }
namespace std namespace std
{ {
template<> template<>
struct less<hpr::csg::Shape> struct less<hpr::csg::Shape>
{ {
bool operator() (const hpr::csg::Shape& s1, const hpr::csg::Shape& s2) const; bool operator() (const hpr::csg::Shape& s1, const hpr::csg::Shape& s2) const;
}; };
} }
namespace hpr::csg namespace hpr::csg
{ {
// Forward declaration of friend functions // Forward declaration of friend functions
double distance(const Shape& lhs, const Shape& rhs); double distance(const Shape& lhs, const Shape& rhs);
Shape fuse(const Shape& lhs, const Shape& rhs); Shape fuse(const Shape& lhs, const Shape& rhs);
Shape fuse(const darray<Shape>& args, const darray<Shape>& tools); Shape fuse(const darray<Shape>& args, const darray<Shape>& tools);
Shape common(const Shape& lhs, const Shape& rhs); Shape common(const Shape& lhs, const Shape& rhs);
Shape cut(const Shape& lhs, const Shape& rhs); Shape cut(const Shape& lhs, const Shape& rhs);
// Class declaration // Class declaration
class Shape class Shape
{ {
public: public:
enum class Type enum class Type
{ {
Compound, Compound,
Compsolid, Compsolid,
Solid, Solid,
Shell, Shell,
Face, Face,
Wire, Wire,
Edge, Edge,
Vertex, Vertex,
Shape, Shape,
Unknown Unknown
}; };
enum class Format enum class Format
{ {
Unknown, Unknown,
STEP STEP
}; };
class Metadata class Metadata
{ {
public: public:
std::string label; std::string label;
public: public:
Metadata() : Metadata() :
label {"default"} label {"default"}
{} {}
void merge(const Metadata& data) void merge(const Metadata& data)
{ {
if (label == "default" && data.label != "default") if (label == "default" && data.label != "default")
label = data.label; label = data.label;
} }
}; };
public: public:
// TODO: clean up map // TODO: clean up map
static static
std::map<Shape, Shape::Metadata> metadata; std::map<Shape, Shape::Metadata> metadata;
protected: protected:
TopoDS_Shape p_shape; TopoDS_Shape p_shape;
public: public:
[[nodiscard]] [[nodiscard]]
TopoDS_Shape tshape() const { return p_shape; } TopoDS_Shape tshape() const { return p_shape; }
Shape(const TopoDS_Shape& s) : Shape(const TopoDS_Shape& s) :
p_shape {s} p_shape {s}
{} {}
Shape(TopoDS_Shape&& s) noexcept: Shape(TopoDS_Shape&& s) noexcept:
p_shape {std::forward<TopoDS_Shape>(s)} p_shape {std::forward<TopoDS_Shape>(s)}
{} {}
public: public:
Shape() : Shape() :
p_shape {} p_shape {}
{} {}
virtual virtual
~Shape() = default; ~Shape() = default;
//{ //{
//if (metadata.contains(*this)) //if (metadata.contains(*this))
// metadata.erase(*this); // metadata.erase(*this);
//} //}
[[nodiscard]] [[nodiscard]]
Type type() const Type type() const
{ {
switch (p_shape.ShapeType()) switch (p_shape.ShapeType())
{ {
case TopAbs_VERTEX: case TopAbs_VERTEX:
return Type::Vertex; return Type::Vertex;
case TopAbs_EDGE: case TopAbs_EDGE:
return Type::Edge; return Type::Edge;
case TopAbs_FACE: case TopAbs_FACE:
return Type::Face; return Type::Face;
case TopAbs_WIRE: case TopAbs_WIRE:
return Type::Wire; return Type::Wire;
case TopAbs_SHELL: case TopAbs_SHELL:
return Type::Shell; return Type::Shell;
case TopAbs_SOLID: case TopAbs_SOLID:
return Type::Solid; return Type::Solid;
case TopAbs_COMPOUND: case TopAbs_COMPOUND:
return Type::Compound; return Type::Compound;
case TopAbs_COMPSOLID: case TopAbs_COMPSOLID:
return Type::Compsolid; return Type::Compsolid;
case TopAbs_SHAPE: case TopAbs_SHAPE:
return Type::Shape; return Type::Shape;
default: default:
return Type::Unknown; return Type::Unknown;
} }
} }
[[nodiscard]] [[nodiscard]]
vec3 center() const vec3 center() const
{ {
GProp_GProps props; GProp_GProps props;
switch (type()) switch (type())
{ {
case Type::Solid: case Type::Solid:
case Type::Compsolid: case Type::Compsolid:
case Type::Compound: case Type::Compound:
BRepGProp::VolumeProperties(p_shape, props); BRepGProp::VolumeProperties(p_shape, props);
case Type::Shell: case Type::Shell:
case Type::Face: case Type::Face:
BRepGProp::SurfaceProperties(p_shape, props); BRepGProp::SurfaceProperties(p_shape, props);
default: default:
BRepGProp::LinearProperties(p_shape, props); BRepGProp::LinearProperties(p_shape, props);
} }
gp_Pnt center {props.CentreOfMass()}; gp_Pnt center {props.CentreOfMass()};
return vec3 {center.X(), center.Y(), center.Z()}; return vec3 {center.X(), center.Y(), center.Z()};
} }
[[nodiscard]] [[nodiscard]]
double length() const double length() const
{ {
GProp_GProps props; GProp_GProps props;
switch (type()) switch (type())
{ {
case Type::Vertex: case Type::Vertex:
return 0; return 0;
default: default:
BRepGProp::LinearProperties(p_shape, props); BRepGProp::LinearProperties(p_shape, props);
return props.Mass(); return props.Mass();
} }
} }
[[nodiscard]] [[nodiscard]]
double area() const double area() const
{ {
GProp_GProps props; GProp_GProps props;
switch (type()) switch (type())
{ {
case Type::Vertex: case Type::Vertex:
case Type::Edge: case Type::Edge:
case Type::Wire: case Type::Wire:
return 0; return 0;
default: default:
BRepGProp::SurfaceProperties(p_shape, props); BRepGProp::SurfaceProperties(p_shape, props);
return props.Mass(); return props.Mass();
} }
} }
[[nodiscard]] [[nodiscard]]
double volume() const double volume() const
{ {
GProp_GProps props; GProp_GProps props;
switch (type()) switch (type())
{ {
case Type::Compsolid: case Type::Compsolid:
case Type::Solid: case Type::Solid:
BRepGProp::VolumeProperties(p_shape, props); BRepGProp::VolumeProperties(p_shape, props);
return props.Mass(); return props.Mass();
default: default:
return 0; return 0;
} }
} }
void label(const std::string& label) const void label(const std::string& label) const
{ {
metadata[*this].label = label; metadata[*this].label = label;
} }
[[nodiscard]] [[nodiscard]]
std::string label() const std::string label() const
{ {
return metadata[*this].label; return metadata[*this].label;
} }
void dump(const std::string& filename, Format format) const void dump(const std::string& filename, Format format) const
{ {
if (p_shape.IsNull()) if (p_shape.IsNull())
throw std::runtime_error("Trying to export null shape"); throw std::runtime_error("Trying to export null shape");
switch (format) switch (format)
{ {
case Format::STEP: case Format::STEP:
{ {
STEPControl_Writer writer; STEPControl_Writer writer;
Interface_Static::SetCVal("xstep.cascade.unit", "MM"); Interface_Static::SetCVal("xstep.cascade.unit", "MM");
Interface_Static::SetCVal("write.step.unit", "MM"); Interface_Static::SetCVal("write.step.unit", "MM");
Interface_Static::SetIVal("write.step.nonmanifold", 1); Interface_Static::SetIVal("write.step.nonmanifold", 1);
writer.Transfer(p_shape, STEPControl_AsIs); writer.Transfer(p_shape, STEPControl_AsIs);
writer.Write(filename.c_str()); writer.Write(filename.c_str());
break; break;
} }
case Format::Unknown: case Format::Unknown:
default: default:
throw std::invalid_argument("Unknown export format"); throw std::invalid_argument("Unknown export format");
} }
} }
// //
[[nodiscard]] [[nodiscard]]
sarray<vec3, 2> boundingBox() const sarray<vec3, 2> boundingBox() const
{ {
Bnd_Box bbox; Bnd_Box bbox;
BRepBndLib::Add(p_shape, bbox, true); BRepBndLib::Add(p_shape, bbox, true);
gp_Pnt p1 {bbox.CornerMin()}; gp_Pnt p1 {bbox.CornerMin()};
gp_Pnt p2 {bbox.CornerMax()}; gp_Pnt p2 {bbox.CornerMax()};
return sarray<vec3, 2> {{p1.X(), p1.Y(), p1.Z()}, {p2.X(), p2.Y(), p2.Z()}}; return sarray<vec3, 2> {{p1.X(), p1.Y(), p1.Z()}, {p2.X(), p2.Y(), p2.Z()}};
} }
void incrementalMesh(double deflection) void incrementalMesh(double deflection)
{ {
BRepTools::Clean(p_shape); BRepTools::Clean(p_shape);
BRepMesh_IncrementalMesh(p_shape, deflection, true); BRepMesh_IncrementalMesh(p_shape, deflection, true);
} }
darray<Shape> subShapes(Type type) const darray<Shape> subShapes(Type type) const
{ {
darray<Shape> subshapes; darray<Shape> subshapes;
for (TopExp_Explorer exp(p_shape, static_cast<TopAbs_ShapeEnum>(type)); exp.More(); exp.Next()) for (TopExp_Explorer exp(p_shape, static_cast<TopAbs_ShapeEnum>(type)); exp.More(); exp.Next())
subshapes.push(Shape(exp.Current())); subshapes.push(Shape(exp.Current()));
return subshapes; return subshapes;
} }
darray<Shape> edges() const darray<Shape> edges() const
{ {
return subShapes(Type::Edge); return subShapes(Type::Edge);
} }
darray<Shape> faces() const darray<Shape> faces() const
{ {
return subShapes(Type::Face); return subShapes(Type::Face);
} }
darray<Shape> shells() const darray<Shape> shells() const
{ {
return subShapes(Type::Shell); return subShapes(Type::Shell);
} }
// Member functions: transformations // Member functions: transformations
Shape translate(const vec3& dir) Shape translate(const vec3& dir)
{ {
gp_Trsf transform; gp_Trsf transform;
transform.SetTranslation(gp_Vec(dir[0], dir[1], dir[2])); transform.SetTranslation(gp_Vec(dir[0], dir[1], dir[2]));
BRepBuilderAPI_Transform builder {p_shape, transform, true}; BRepBuilderAPI_Transform builder {p_shape, transform, true};
return builder.Shape(); return builder.Shape();
} }
Shape rotate(const vec3& pos, const vec3& axis, double angle) Shape rotate(const vec3& pos, const vec3& axis, double angle)
{ {
gp_Trsf transform; gp_Trsf transform;
transform.SetRotation(gp_Ax1({pos[0], pos[1], pos[2]}, {axis[0], axis[1], axis[2]}), rad(angle)); transform.SetRotation(gp_Ax1({pos[0], pos[1], pos[2]}, {axis[0], axis[1], axis[2]}), rad(angle));
BRepBuilderAPI_Transform builder {p_shape, transform, true}; BRepBuilderAPI_Transform builder {p_shape, transform, true};
return builder.Shape(); return builder.Shape();
} }
Shape scale(const vec3& center, double scale) Shape scale(const vec3& center, double scale)
{ {
gp_Trsf transform; gp_Trsf transform;
transform.SetScale(gp_Pnt(center[0], center[1], center[2]), scale); transform.SetScale(gp_Pnt(center[0], center[1], center[2]), scale);
BRepBuilderAPI_Transform builder {p_shape, transform, true}; BRepBuilderAPI_Transform builder {p_shape, transform, true};
return builder.Shape(); return builder.Shape();
} }
Shape& scaled(const vec3& center, double scale) Shape& scaled(const vec3& center, double scale)
{ {
p_shape = this->scale(center, scale).p_shape; p_shape = this->scale(center, scale).p_shape;
return *this; return *this;
} }
Shape extrude(const vec3& dir, double length) Shape extrude(const vec3& dir, double length)
{ {
BRepPrimAPI_MakePrism builder {p_shape, length * gp_Vec(dir[0], dir[1], dir[2]), true}; BRepPrimAPI_MakePrism builder {p_shape, length * gp_Vec(dir[0], dir[1], dir[2]), true};
for (auto& type : { Type::Solid, Type::Face, Type::Edge, Type::Vertex }) for (auto& type : { Type::Solid, Type::Face, Type::Edge, Type::Vertex })
for (TopExp_Explorer exp {p_shape, static_cast<TopAbs_ShapeEnum>(type)}; exp.More(); exp.Next()) for (TopExp_Explorer exp {p_shape, static_cast<TopAbs_ShapeEnum>(type)}; exp.More(); exp.Next())
{ {
auto data = metadata[Shape(exp.Current())]; auto data = metadata[Shape(exp.Current())];
for (auto& mod : builder.Generated(exp.Current())) for (auto& mod : builder.Generated(exp.Current()))
metadata[Shape(mod)].merge(data); metadata[Shape(mod)].merge(data);
} }
return builder.Shape(); return builder.Shape();
} }
Shape fillet(darray<Shape> edges, double radius) Shape fillet(darray<Shape> edges, double radius)
{ {
BRepFilletAPI_MakeFillet fillet {p_shape}; BRepFilletAPI_MakeFillet fillet {p_shape};
for (auto& e : edges) for (auto& e : edges)
fillet.Add(radius, TopoDS::Edge(e.p_shape)); fillet.Add(radius, TopoDS::Edge(e.p_shape));
fillet.Build(); fillet.Build();
return fillet.Shape(); return fillet.Shape();
} }
// Friend functions // Friend functions
friend friend
double distance(const Shape& lhs, const Shape& rhs) double distance(const Shape& lhs, const Shape& rhs)
{ {
return BRepExtrema_DistShapeShape(lhs.tshape(), rhs.tshape()).Value(); return BRepExtrema_DistShapeShape(lhs.tshape(), rhs.tshape()).Value();
} }
friend friend
Shape fuse(const Shape& lhs, const Shape& rhs) Shape fuse(const Shape& lhs, const Shape& rhs)
{ {
BRepAlgoAPI_Fuse builder {lhs.p_shape, rhs.p_shape}; BRepAlgoAPI_Fuse builder {lhs.p_shape, rhs.p_shape};
builder.Build(); builder.Build();
return Shape {builder.Shape()}; return Shape {builder.Shape()};
} }
friend friend
Shape fuse(const darray<Shape>& args, const darray<Shape>& tools) Shape fuse(const darray<Shape>& args, const darray<Shape>& tools)
{ {
BRepAlgoAPI_Fuse builder; BRepAlgoAPI_Fuse builder;
NCollection_List<TopoDS_Shape> args_, tools_; NCollection_List<TopoDS_Shape> args_, tools_;
for (auto& arg : args) for (auto& arg : args)
args_.Append(arg.tshape()); args_.Append(arg.tshape());
for (auto& tool : tools) for (auto& tool : tools)
tools_.Append(tool.tshape()); tools_.Append(tool.tshape());
builder.SetArguments(args_); builder.SetArguments(args_);
builder.SetTools(tools_); builder.SetTools(tools_);
builder.Build(); builder.Build();
return Shape {builder.Shape()}; return Shape {builder.Shape()};
} }
friend friend
Shape common(const Shape& lhs, const Shape& rhs) Shape common(const Shape& lhs, const Shape& rhs)
{ {
BRepAlgoAPI_Common builder {lhs.p_shape, rhs.p_shape}; BRepAlgoAPI_Common builder {lhs.p_shape, rhs.p_shape};
builder.Build(); builder.Build();
return Shape {builder.Shape()}; return Shape {builder.Shape()};
} }
friend friend
Shape cut(const Shape& lhs, const Shape& rhs) Shape cut(const Shape& lhs, const Shape& rhs)
{ {
BRepAlgoAPI_Cut builder {lhs.p_shape, rhs.p_shape}; BRepAlgoAPI_Cut builder {lhs.p_shape, rhs.p_shape};
builder.Build(); builder.Build();
for (auto& type : { Type::Solid, Type::Face, Type::Edge, Type::Vertex }) for (auto& type : { Type::Solid, Type::Face, Type::Edge, Type::Vertex })
for (TopExp_Explorer exp {lhs.p_shape, static_cast<TopAbs_ShapeEnum>(type)}; exp.More(); exp.Next()) for (TopExp_Explorer exp {lhs.p_shape, static_cast<TopAbs_ShapeEnum>(type)}; exp.More(); exp.Next())
{ {
auto data = metadata[Shape(exp.Current())]; auto data = metadata[Shape(exp.Current())];
for (auto& mod : builder.Modified(exp.Current())) for (auto& mod : builder.Modified(exp.Current()))
metadata[Shape(mod)].merge(data); metadata[Shape(mod)].merge(data);
} }
for (auto& type : { Type::Solid, Type::Face, Type::Edge, Type::Vertex }) for (auto& type : { Type::Solid, Type::Face, Type::Edge, Type::Vertex })
for (TopExp_Explorer exp {rhs.p_shape, static_cast<TopAbs_ShapeEnum>(type)}; exp.More(); exp.Next()) for (TopExp_Explorer exp {rhs.p_shape, static_cast<TopAbs_ShapeEnum>(type)}; exp.More(); exp.Next())
{ {
auto data = metadata[Shape(exp.Current())]; auto data = metadata[Shape(exp.Current())];
for (auto& mod : builder.Modified(exp.Current())) for (auto& mod : builder.Modified(exp.Current()))
metadata[Shape(mod)].merge(data); metadata[Shape(mod)].merge(data);
} }
return Shape {builder.Shape()}; return Shape {builder.Shape()};
} }
}; };
// Global functions: primitives // Global functions: primitives
Shape sphere(vec3 center, double radius); Shape sphere(vec3 center, double radius);
Shape box(vec3 corner, double dx, double dy, double dz); Shape box(vec3 corner, double dx, double dy, double dz);
} }

View File

@ -1,52 +1,52 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
#include "face.hpp" #include <hpr/csg/face.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Shell : public Shape class Shell : public Shape
{ {
public: public:
Shell() = default; Shell() = default;
~Shell() override = default; ~Shell() override = default;
explicit explicit
Shell(const Shape& shape) : Shell(const Shape& shape) :
Shape {shape.type() == Type::Shell ? shape : throw std::runtime_error("")} Shape {shape.type() == Type::Shell ? shape : throw std::runtime_error("")}
{} {}
explicit explicit
Shell(const darray<Shape>& faces) : Shell(const darray<Shape>& faces) :
Shape {} Shape {}
{ {
BRep_Builder builder; BRep_Builder builder;
TopoDS_Shell shell; TopoDS_Shell shell;
builder.MakeShell(shell); builder.MakeShell(shell);
for (auto& shape : faces) for (auto& shape : faces)
switch (shape.type()) switch (shape.type())
{ {
case Type::Face: case Type::Face:
builder.Add(shell, Face(shape).tcast()); builder.Add(shell, Face(shape).tcast());
break; break;
default: default:
throw std::runtime_error(""); throw std::runtime_error("");
} }
p_shape = shell; p_shape = shell;
} }
[[nodiscard]] [[nodiscard]]
TopoDS_Shell tcast() const TopoDS_Shell tcast() const
{ {
return TopoDS::Shell(p_shape); return TopoDS::Shell(p_shape);
} }
}; };
} }

View File

@ -1,45 +1,45 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
#include "shell.hpp" #include <hpr/csg/shell.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Solid : public Shape class Solid : public Shape
{ {
public: public:
Solid() = default; Solid() = default;
~Solid() override = default; ~Solid() override = default;
explicit explicit
Solid(const Shape& shape) : Solid(const Shape& shape) :
Shape {shape.type() == Type::Solid ? shape : throw std::runtime_error("")} Shape {shape.type() == Type::Solid ? shape : throw std::runtime_error("")}
{} {}
explicit explicit
Solid(const Shell& shell) : Solid(const Shell& shell) :
Shape {} Shape {}
{ {
BRep_Builder builder; BRep_Builder builder;
TopoDS_Solid solid; TopoDS_Solid solid;
builder.MakeSolid(solid); builder.MakeSolid(solid);
builder.Add(solid, shell.tcast()); builder.Add(solid, shell.tcast());
p_shape = solid; p_shape = solid;
} }
[[nodiscard]] [[nodiscard]]
TopoDS_Solid tcast() const TopoDS_Solid tcast() const
{ {
return TopoDS::Solid(p_shape); return TopoDS::Solid(p_shape);
} }
}; };
} }

View File

@ -1,64 +1,64 @@
#pragma once #pragma once
#include "geometry.hpp" #include <hpr/csg/geometry.hpp>
#include "face.hpp" #include <hpr/csg/face.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Surface : public Geometry class Surface : public Geometry
{ {
protected: protected:
Handle(Geom_Surface) p_surface; Handle(Geom_Surface) p_surface;
public: public:
Surface() = default; Surface() = default;
~Surface() override = default; ~Surface() override = default;
explicit explicit
Surface(const Face& face) : Surface(const Face& face) :
Geometry {}, Geometry {},
p_surface {BRep_Tool::Surface(face.tcast())} p_surface {BRep_Tool::Surface(face.tcast())}
{} {}
[[nodiscard]] [[nodiscard]]
Handle(Geom_Surface) tcast() const Handle(Geom_Surface) tcast() const
{ {
return p_surface; return p_surface;
} }
[[nodiscard]] [[nodiscard]]
vec3 value(double u, double v) const vec3 value(double u, double v) const
{ {
gp_Pnt p {p_surface->Value(u, v)}; gp_Pnt p {p_surface->Value(u, v)};
return vec3 {p.X(), p.Y(), p.Z()}; return vec3 {p.X(), p.Y(), p.Z()};
} }
[[nodiscard]] [[nodiscard]]
vec3 normal(double u, double v) const vec3 normal(double u, double v) const
{ {
GeomLProp_SLProps props {p_surface, u, v, 1, 1e-8}; GeomLProp_SLProps props {p_surface, u, v, 1, 1e-8};
gp_Dir dir {props.Normal()}; gp_Dir dir {props.Normal()};
return vec3 {dir.X(), dir.Y(), dir.Z()}; return vec3 {dir.X(), dir.Y(), dir.Z()};
} }
vec3 normal() vec3 normal()
{ {
gp_Vec du, dv; gp_Vec du, dv;
gp_Pnt p; gp_Pnt p;
p_surface->D1(0, 0, p, du, dv); p_surface->D1(0, 0, p, du, dv);
gp_Vec dir {du ^ dv}; gp_Vec dir {du ^ dv};
return vec3 {dir.X(), dir.Y(), dir.Z()}; return vec3 {dir.X(), dir.Y(), dir.Z()};
} }
}; };
} }

View File

@ -1,14 +0,0 @@
file(GLOB tests_cpp "*.cpp")
add_executable(${PROJECT_NAME}-tests
${tests_cpp}
)
target_link_libraries(${PROJECT_NAME}-tests
PUBLIC
hpr::${PROJECT_NAME}
PRIVATE
GTest::gtest_main
)
gtest_add_tests(TARGET ${PROJECT_NAME}-tests)

View File

@ -1,24 +1,25 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "../../csg.hpp" #include <hpr/csg.hpp>
TEST(csgTest, Shape)
{ TEST(csgTest, Shape)
using namespace hpr; {
double radius = 1.; using namespace hpr;
double volume = 4. / 3. * PI; double radius = 1.;
auto sphere = csg::sphere({0, 0, 0}, radius); double volume = 4. / 3. * pi();
EXPECT_TRUE(equal(sphere.volume(), volume, 1e-6)); auto sphere = csg::sphere({0, 0, 0}, radius);
auto box = csg::box({0, 0, 0}, 1, 1, 1); EXPECT_TRUE(equal(sphere.volume(), volume, 1e-6));
EXPECT_TRUE(equal(box.volume(), 1.)); auto box = csg::box({0, 0, 0}, 1, 1, 1);
auto edge = csg::Edge(); EXPECT_TRUE(equal(box.volume(), 1.));
int n = 0; auto edge = csg::Edge();
for (auto& face : box.subShapes(csg::Shape::Type::Face)) int n = 0;
{ for (auto& face : box.subShapes(csg::Shape::Type::Face))
std::stringstream name; {
name << "face" << n; std::stringstream name;
csg::Face(face).label(name.str()); name << "face" << n;
++n; csg::Face(face).label(name.str());
} ++n;
box.scale(box.center(), 5); }
EXPECT_EQ(box.subShapes(csg::Shape::Type::Face)[2].label(), "face2"); box.scale(box.center(), 5);
EXPECT_EQ(box.subShapes(csg::Shape::Type::Face)[2].label(), "face2");
} }

View File

@ -1,43 +1,43 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Vertex : public Shape class Vertex : public Shape
{ {
public: public:
Vertex() = default; Vertex() = default;
~Vertex() override = default; ~Vertex() override = default;
explicit explicit
Vertex(const Shape& shape) : Vertex(const Shape& shape) :
Shape {shape.type() == Type::Vertex ? shape : throw std::runtime_error("")} Shape {shape.type() == Type::Vertex ? shape : throw std::runtime_error("")}
{} {}
explicit explicit
Vertex(const vec3& point) : Vertex(const vec3& point) :
Shape {BRepBuilderAPI_MakeVertex(gp_Pnt(point[0], point[1], point[2])).Shape()} Shape {BRepBuilderAPI_MakeVertex(gp_Pnt(point[0], point[1], point[2])).Shape()}
{} {}
[[nodiscard]] [[nodiscard]]
TopoDS_Vertex tcast() const TopoDS_Vertex tcast() const
{ {
return TopoDS::Vertex(p_shape); return TopoDS::Vertex(p_shape);
} }
[[nodiscard]] [[nodiscard]]
vec3 cast() const vec3 cast() const
{ {
gp_Pnt point = BRep_Tool::Pnt(tcast()); gp_Pnt point = BRep_Tool::Pnt(tcast());
return vec3 {point.X(), point.Y(), point.Z()}; return vec3 {point.X(), point.Y(), point.Z()};
} }
}; };
} }

View File

@ -1,53 +1,53 @@
#pragma once #pragma once
#include "shape.hpp" #include <hpr/csg/shape.hpp>
#include "edge.hpp" #include <hpr/csg/edge.hpp>
namespace hpr::csg namespace hpr::csg
{ {
class Wire : public Shape class Wire : public Shape
{ {
public: public:
Wire() = default; Wire() = default;
~Wire() override = default; ~Wire() override = default;
explicit explicit
Wire(const Shape& shape) : Wire(const Shape& shape) :
Shape {shape.type() == Type::Wire ? shape : throw std::runtime_error("")} Shape {shape.type() == Type::Wire ? shape : throw std::runtime_error("")}
{} {}
explicit explicit
Wire(const darray<Shape>& edges) : Wire(const darray<Shape>& edges) :
Shape {} Shape {}
{ {
BRepBuilderAPI_MakeWire builder; BRepBuilderAPI_MakeWire builder;
for (auto& shape : edges) for (auto& shape : edges)
switch (shape.type()) switch (shape.type())
{ {
case Type::Edge: case Type::Edge:
builder.Add(Edge(shape).tcast()); builder.Add(Edge(shape).tcast());
break; break;
case Type::Wire: case Type::Wire:
builder.Add(Wire(shape).tcast()); builder.Add(Wire(shape).tcast());
break; break;
default: default:
throw std::runtime_error(""); throw std::runtime_error("");
} }
p_shape = builder.Shape(); p_shape = builder.Shape();
} }
[[nodiscard]] [[nodiscard]]
TopoDS_Wire tcast() const TopoDS_Wire tcast() const
{ {
return TopoDS::Wire(p_shape); return TopoDS::Wire(p_shape);
} }
}; };
} }

54
source/hpr/exception.hpp Normal file
View File

@ -0,0 +1,54 @@
#pragma once
#include <exception>
#include <string>
#include <source_location>
#include <sstream>
#include <utility>
#include <vector>
namespace hpr
{
class Exception : public std::exception
{
protected:
std::string p_message;
public:
inline explicit
Exception(std::source_location location = std::source_location::current()) :
p_message {}
{
std::stringstream _message;
_message << "\t" << p_message
<< "\n where:\t\t" << location.file_name() << ":" << location.line() << ":" << location.column()
<< "\n function:\t" << location.function_name();
p_message = _message.str();
}
inline explicit
Exception(const std::string& message, std::source_location location = std::source_location::current()) :
p_message {message}
{
std::stringstream _message;
_message << "\t" << p_message
<< "\n where:\t" << location.file_name() << ":" << location.line() << ":" << location.column()
<< "\n function:\t" << location.function_name();
p_message = _message.str();
}
[[nodiscard]] const char* what() const noexcept override {
std::vector<float> vv;
return p_message.data();
}
};
struct OutOfRange : public Exception
{
inline explicit OutOfRange(std::source_location location = std::source_location::current()) : Exception {"Out of range", location} {}
inline explicit OutOfRange(const std::string& message, std::source_location location = std::source_location::current()) : Exception {message, location} {}
};
struct LengthError : public Exception
{
inline explicit LengthError(std::source_location location = std::source_location::current()) : Exception {"Length error", location} {}
inline explicit LengthError(const std::string& message, std::source_location location = std::source_location::current()) : Exception {message, location} {}
};
}

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include "geometry/polytope.hpp" #include <hpr/geometry/polytope.hpp>
#include "geometry/triangle.hpp" #include <hpr/geometry/triangle.hpp>
#include "geometry/tetrahedron.hpp" #include <hpr/geometry/tetrahedron.hpp>

View File

@ -1,57 +1,21 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(geometry project(geometry
VERSION "${HPR_PROJECT_VERSION}" VERSION "${HPR_VERSION}"
LANGUAGES CXX LANGUAGES CXX
) )
add_library(${PROJECT_NAME} INTERFACE) hpr_add_library(${PROJECT_NAME} INTERFACE)
add_library(${CMAKE_PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
add_module(${PROJECT_NAME})
file(GLOB ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS hpr_collect_interface(${PROJECT_NAME}
"../geometry.hpp" "*.hpp" "../geometry.hpp"
"*.hpp"
) )
foreach(_header_path ${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS})
list(APPEND ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE "$<BUILD_INTERFACE:${_header_path}>")
endforeach()
target_sources(${PROJECT_NAME} target_sources(${PROJECT_NAME}
INTERFACE INTERFACE ${${PROJECT_NAME}_HEADERS_INTERFACE} ${HPR_INSTALL_INTERFACE}/${PROJECT_NAME}>
${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE}
$<INSTALL_INTERFACE:include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME}>
) )
install(
TARGETS ${PROJECT_NAME} hpr_install(${PROJECT_NAME} ${PROJECT_SOURCE_DIR})
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_SKIP
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}-${HPR_PROJECT_VERSION}
NAMESPACE ${CMAKE_PROJECT_NAME}::
)
install(
TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_ONLY
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
DIRECTORY ${PROJECT_SOURCE_DIR}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "tests" EXCLUDE
)
install(
FILES ../${PROJECT_NAME}.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
)

View File

@ -1,48 +1,48 @@
#pragma once #pragma once
#include "../containers.hpp" #include <hpr/containers.hpp>
#include "../math.hpp" #include <hpr/math.hpp>
namespace hpr::geometry namespace hpr::geometry
{ {
template <int Dim, int Space> template <int Dim, int Space>
class Polytope class Polytope
{ {
public: public:
enum class Type enum class Type
{ {
Nullitope = -1, Nullitope = -1,
Monon, Monon,
Dion, Dion,
Polygon, Polygon,
Polyhedron, Polyhedron,
Polychoron, Polychoron,
Unknown Unknown
}; };
protected: protected:
const int p_dimension; const int p_dimension;
const int p_space; const int p_space;
Type p_type; Type p_type;
darray<VectorSpace<scalar, Space>> p_points; darray<VectorSpace<scalar, Space>> p_points;
public: public:
Polytope() : Polytope() :
p_dimension {Dim}, p_dimension {Dim},
p_space {Space}, p_space {Space},
p_type {Type::Unknown}, p_type {Type::Unknown},
p_points {} p_points {}
{} {}
virtual virtual
~Polytope() = default; ~Polytope() = default;
}; };
} }

View File

@ -1,19 +1,21 @@
#include "../math.hpp" #pragma once
namespace hpr::geometry #include <hpr/math.hpp>
{
namespace hpr::geometry
vec3 circumCentre(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {
{
vec3 e1 = p2 - p1; vec3 circumCentre(vec3 p1, vec3 p2, vec3 p3, vec3 p4)
vec3 e2 = p3 - p1; {
vec3 e3 = p4 - p1; vec3 e1 = p2 - p1;
mat3 A; vec3 e2 = p3 - p1;
A.row(0, e1); vec3 e3 = p4 - p1;
A.row(1, e2); mat3 A;
A.row(2, e3); A.row(0, e1);
vec3 B = 0.5 * vec3(sum(pow(p2, 2)) - sum(pow(p1, 2)), sum(pow(p3, 2)) - sum(pow(p1, 2)), sum(pow(p4, 2)) - sum(pow(p1, 2))); A.row(1, e2);
return A.inv() * B; A.row(2, e3);
} vec3 B = 0.5 * vec3(sum(pow(p2, 2)) - sum(pow(p1, 2)), sum(pow(p3, 2)) - sum(pow(p1, 2)), sum(pow(p4, 2)) - sum(pow(p1, 2)));
return A.inv() * B;
}
} }

View File

@ -1,15 +1,17 @@
#include "../math.hpp" #pragma once
namespace hpr::geometry #include <hpr/math.hpp>
{
namespace hpr::geometry
vec2 circumCentre(vec2 p1, vec2 p2, vec2 p3) {
{
vec2 pb1 {(p1 + p2) * 0.5}; vec2 circumCentre(vec2 p1, vec2 p2, vec2 p3)
vec2 pb2 {(p2 + p3) * 0.5}; {
scalar s1 = (p2[1] - p1[1]) / (p2[0] - p1[0]); vec2 pb1 {(p1 + p2) * 0.5};
scalar s2 = (p3[1] - p2[1]) / (p3[0] - p2[0]); vec2 pb2 {(p2 + p3) * 0.5};
return vec2(pb1[0] + s1 * pb1[1], pb2[0] + s2 * pb2[1]) * mat2(1, s1, 1, s2).inv(); scalar s1 = (p2[1] - p1[1]) / (p2[0] - p1[0]);
} scalar s2 = (p3[1] - p2[1]) / (p3[0] - p2[0]);
return vec2(pb1[0] + s1 * pb1[1], pb2[0] + s2 * pb2[1]) * mat2(1, s1, 1, s2).inv();
}
} }

View File

@ -1,15 +1,18 @@
#pragma once #pragma once
#include "gpu/array_object.hpp" #include <hpr/gpu/array_object.hpp>
#include "gpu/buffer_object.hpp" #include <hpr/gpu/buffer_object.hpp>
#include "gpu/color_buffer.hpp" #include <hpr/gpu/color_buffer.hpp>
#include "gpu/cull_face.hpp" #include <hpr/gpu/cull_face.hpp>
#include "gpu/depth_buffer.hpp" #include <hpr/gpu/depth_buffer.hpp>
#include "gpu/framebuffer.hpp" #include <hpr/gpu/framebuffer.hpp>
#include "gpu/renderbuffer.hpp" #include <hpr/gpu/renderbuffer.hpp>
#include "gpu/shader.hpp" #include <hpr/gpu/shader.hpp>
#include "gpu/shader_program.hpp" #include <hpr/gpu/shader_program.hpp>
#include "gpu/stencil_buffer.hpp" #include <hpr/gpu/stencil_buffer.hpp>
#include "gpu/texture.hpp" #include <hpr/gpu/texture.hpp>
#include "gpu/viewport.hpp" #include <hpr/gpu/viewport.hpp>
#include <hpr/gpu/monitor.hpp>
#include <hpr/gpu/window.hpp>
#include <hpr/gpu/context.hpp>

View File

@ -1,68 +1,32 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(gpu project(gpu
VERSION "${HPR_PROJECT_VERSION}" VERSION "${HPR_VERSION}"
LANGUAGES CXX LANGUAGES CXX
) )
add_library(${PROJECT_NAME}) hpr_add_library(${PROJECT_NAME} INTERFACE)
add_library(${CMAKE_PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
add_module(${PROJECT_NAME}) hpr_collect_interface(${PROJECT_NAME}
"../gpu.hpp"
file(GLOB ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS "*.hpp"
"../gpu.hpp" "*.hpp" )
)
#hpr_collect_sources(${PROJECT_NAME}
foreach(_header_path ${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS}) # "*.cpp"
list(APPEND ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE "$<BUILD_INTERFACE:${_header_path}>") #)
endforeach()
target_sources(${PROJECT_NAME}
file(GLOB ${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_SOURCES INTERFACE ${${PROJECT_NAME}_HEADERS_INTERFACE} ${HPR_INSTALL_INTERFACE}/${PROJECT_NAME}>
"*.cpp" PRIVATE ${${PROJECT_NAME}_SOURCES}
) )
target_sources(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
INTERFACE INTERFACE
${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_HEADERS_INTERFACE} glad::glad
$<INSTALL_INTERFACE:include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME}> glfw::glfw
PRIVATE stb::stb
${${CMAKE_PROJECT_NAME}_${PROJECT_NAME}_SOURCES} )
)
target_link_libraries(${PROJECT_NAME} hpr_install(${PROJECT_NAME} ${PROJECT_SOURCE_DIR})
glad
stb
)
install(
TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_SKIP
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT ${PROJECT_NAME}Targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}-${HPR_PROJECT_VERSION}
NAMESPACE ${CMAKE_PROJECT_NAME}::
)
install(
TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
NAMELINK_ONLY
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
DIRECTORY ${PROJECT_SOURCE_DIR}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
PATTERN "tests" EXCLUDE
)
install(
FILES ../${PROJECT_NAME}.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}
COMPONENT devel
)

View File

@ -1,2 +0,0 @@
#include <glad/glad.h>
#include "array_object.hpp"

View File

@ -1,104 +1,125 @@
#pragma once #pragma once
#include "buffer_object.hpp" #include <hpr/gpu/buffer_object.hpp>
#include <string> #include <string>
#ifndef __gl_h_ #ifndef __gl_h_
#include <glad/glad.h> #include <glad/glad.h>
#endif #endif
namespace hpr::gpu namespace hpr::gpu
{ {
class ArrayObject class ArrayObject
{ {
public:
protected: enum Mode
{
unsigned int p_index; Points = GL_POINTS,
int p_size; LineStrip = GL_LINE_STRIP,
int p_stride; LineLoop = GL_LINE_LOOP,
bool p_binded; Lines = GL_LINES,
LineStripAdjacency = GL_LINE_STRIP_ADJACENCY,
public: LinesAdjacency = GL_LINES_ADJACENCY,
TriangleStrip = GL_TRIANGLE_STRIP,
inline TriangleFan = GL_TRIANGLE_FAN,
ArrayObject() : Triangles = 0x0004, //GL_TRIANGLES,
p_index {0}, TriangleStripAdjacency = GL_TRIANGLE_STRIP_ADJACENCY,
p_size {0}, TrianglesAdjacency = GL_TRIANGLES_ADJACENCY,
p_stride {0}, Patches = GL_PATCHES
p_binded {false} };
{}
protected:
virtual
~ArrayObject() = default; GLuint p_index;
int p_size;
[[nodiscard]] int p_stride;
int size() const bool p_binded;
{
return p_size; public:
}
inline
[[nodiscard]] ArrayObject() :
unsigned int index() const p_index {0},
{ p_size {0},
return p_index; p_stride {0},
} p_binded {false}
{}
void create()
{ virtual
glGenVertexArrays(1, &p_index); ~ArrayObject() = default;
}
[[nodiscard]]
void bind() int size() const
{ {
glBindVertexArray(p_index); return p_size;
p_binded = true; }
}
[[nodiscard]]
void unbind() unsigned int index() const
{ {
glBindVertexArray(0); return p_index;
p_binded = false; }
}
void create()
bool binded() const {
{ glGenVertexArrays(1, &p_index);
return p_binded; }
}
void bind()
void destroy() {
{ glBindVertexArray(p_index);
glDeleteVertexArrays(1, &p_index); p_binded = true;
} }
void attribPointer(BufferObject& buffer, unsigned int location, unsigned int size) void unbind()
{ {
if (buffer.type() == BufferObject::Type::Unknown) glBindVertexArray(0);
throw std::runtime_error("Unknown buffer type"); p_binded = false;
if (!binded()) }
throw std::runtime_error("ArrayObject is not binded");
if (!buffer.valid()) bool binded() const
throw std::runtime_error("BufferObject is invalid"); {
return p_binded;
buffer.bind(); }
glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, sizeof(float) * buffer.offset(), static_cast<void*>(nullptr));
glEnableVertexAttribArray(location); void destroy()
buffer.unbind(); {
} glDeleteVertexArrays(1, &p_index);
}
void draw()
{ void attribPointer(BufferObject& buffer, unsigned int location, int size)
{
} if (buffer.type() == BufferObject::Type::Unknown)
throw std::runtime_error("Unknown buffer type");
inline if (!binded())
bool valid() const throw std::runtime_error("ArrayObject is not binded");
{ if (!buffer.valid())
return p_index > 0; throw std::runtime_error("BufferObject is invalid");
}
}; buffer.bind();
glEnableVertexAttribArray(location);
} glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, sizeof(float) * buffer.offset(), static_cast<void*>(nullptr));
buffer.unbind();
}
void drawElements(Mode mode, int count) const
{
glDrawElements(mode, count, GL_UNSIGNED_INT, nullptr);
}
void drawArrays(Mode mode, int count) const
{
glDrawArrays(mode, 0, count);
}
inline
bool valid() const
{
return p_index > 0;
}
};
}

View File

@ -1,27 +0,0 @@
#include <glad/glad.h>
#include "buffer_object.hpp"
namespace hpr::gpu
{
void BufferObject::bind()
{
glBindBuffer((GLenum)p_type, p_index);
p_binded = true;
}
void BufferObject::unbind()
{
glBindBuffer((GLenum)p_type, 0);
p_binded = false;
}
void BufferObject::destroy()
{
if (p_type == Type::Unknown)
std::runtime_error("Unknown buffer type");
glDeleteBuffers(1, &p_index);
}
}

View File

@ -1,134 +1,153 @@
#pragma once #pragma once
#include "../containers.hpp" #include <hpr/containers.hpp>
#include <string>
#ifndef __gl_h_ #include <string>
#include <glad/glad.h> #ifndef __gl_h_
#endif #include <glad/glad.h>
#endif
namespace hpr::gpu
{ namespace hpr::gpu
{
class BufferObject
{ class BufferObject
{
public:
public:
enum class Type
{ enum Type
Vertex = 0x8892, //GL_ARRAY_BUFFER, {
Index = 0x8893, //GL_ELEMENT_ARRAY_BUFFER, Vertex = 0x8892, // GL_ARRAY_BUFFER,
Uniform = 0x8A11, //GL_UNIFORM_BUFFER, Index = 0x8893, // GL_ELEMENT_ARRAY_BUFFER,
Unknown = -1 Uniform = 0x8A11, // GL_UNIFORM_BUFFER,
}; Unknown = -1
};
protected:
protected:
Type p_type;
unsigned int p_index; Type p_type;
int p_size; unsigned int p_index;
int p_offset; int p_size;
bool p_binded; unsigned int p_offset;
bool p_binded;
public:
public:
inline
BufferObject() : inline
p_type {Type::Unknown}, BufferObject() :
p_index {0}, p_type {Type::Unknown},
p_size {0}, p_index {0},
p_offset {0}, p_size {0},
p_binded {false} p_offset {0},
{} p_binded {false}
{}
explicit inline
BufferObject(Type type) : explicit inline
p_type {type}, BufferObject(Type type) :
p_index {0}, p_type {type},
p_size {0}, p_index {0},
p_offset {0}, p_size {0},
p_binded {false} p_offset {0},
{} p_binded {false}
{}
virtual
~BufferObject() = default; virtual
~BufferObject() = default;
[[nodiscard]]
int size() const [[nodiscard]]
{ int size() const
return p_size; {
} return p_size;
}
[[nodiscard]]
Type type() const [[nodiscard]]
{ Type type() const
return p_type; {
} return p_type;
}
[[nodiscard]]
unsigned int index() const [[nodiscard]]
{ unsigned int index() const
return p_index; {
} return p_index;
}
[[nodiscard]]
unsigned int offset() const [[nodiscard]]
{ unsigned int offset() const
return p_offset; {
} return p_offset;
}
void bind() ;
void bind()
void unbind(); {
glBindBuffer((GLenum)p_type, p_index);
[[nodiscard]] p_binded = true;
bool binded() const }
{
return p_binded; void unbind()
} {
glBindBuffer((GLenum)p_type, 0);
template <typename T> p_binded = false;
void create(const darray<T>& data, unsigned int offset = 0) }
{
if (p_type == Type::Unknown) [[nodiscard]]
std::runtime_error("Unknown buffer type"); bool binded() const
{
unsigned int drawType; return p_binded;
}
if (p_type == Type::Uniform)
drawType = GL_DYNAMIC_DRAW; template <typename T>
else void create(const darray<T>& data, unsigned int offset = 0)
drawType = GL_STATIC_DRAW; {
if (p_type == Type::Unknown)
glGenBuffers(1, &p_index); throw std::runtime_error("Unknown buffer type");
bind();
glBufferData((GLenum)p_type, sizeof(T) * data.size(), data.data(), drawType); unsigned int drawType;
unbind();
if (p_type == Type::Uniform)
p_offset = offset; drawType = GL_DYNAMIC_DRAW;
} else
drawType = GL_STATIC_DRAW;
template <typename T>
void edit(const darray<T>& data, unsigned int offset = 0) glGenBuffers(1, &p_index);
{ bind();
if (p_type == Type::Unknown) glBufferData(static_cast<GLenum>(p_type), sizeof(T) * data.size(), data.data(), drawType);
std::runtime_error("Unknown buffer type"); unbind();
bind(); p_offset = offset;
glBufferSubData(p_type, offset, sizeof(T) * data.size(), data.data()); p_size = data.size();
unbind(); }
}
template <typename T>
void destroy(); void edit(const darray<T>& data, unsigned int offset = 0)
{
[[nodiscard]] if (p_type == Type::Unknown)
inline throw std::runtime_error("Unknown buffer type");
bool valid() const
{ bind();
return p_index > 0; glBufferSubData(p_type, offset, sizeof(T) * data.size(), data.data());
} unbind();
};
p_offset = offset;
p_size = data.size();
}
void destroy()
{
if (p_type == Type::Unknown)
throw std::runtime_error("Unknown buffer type");
glDeleteBuffers(1, &p_index);
}
[[nodiscard]]
inline
bool valid() const
{
return p_index > 0;
}
};
} }

View File

@ -1,40 +1,40 @@
#pragma once #pragma once
#include "../math.hpp" #include <hpr/math.hpp>
namespace hpr::gpu namespace hpr::gpu
{ {
class Camera class Camera
{ {
protected: protected:
vec3 p_front; vec3 p_front;
vec3 p_up; vec3 p_up;
vec3 p_left; vec3 p_left;
scalar p_yaw; scalar p_yaw;
scalar p_pitch; scalar p_pitch;
scalar p_roll; scalar p_roll;
vec3 p_position; vec3 p_position;
vec3 p_target; vec3 p_target;
scalar p_distance; scalar p_distance;
public: public:
Camera() : Camera() :
p_front {0., 0., -1.}, p_front {0., 0., -1.},
p_up {0., 0., 1.}, p_up {0., 0., 1.},
p_left {1., 0., 0.} p_left {1., 0., 0.}
{} {}
virtual virtual
~Camera() = default; ~Camera() = default;
}; };
} }

View File

@ -1,68 +1,70 @@
#pragma once #pragma once
#include "../math/vector.hpp" #include <hpr/math/vector.hpp>
#ifndef __gl_h_
#include <glad/glad.h> #ifndef __gl_h_
#endif #include <glad/glad.h>
#endif
namespace hpr::gpu
{ namespace hpr::gpu
{
class ColorBuffer
{ class ColorBuffer
{
protected:
protected:
bool p_enabledRed;
bool p_enabledGreen; bool p_enabledRed;
bool p_enabledBlue; bool p_enabledGreen;
bool p_enabledAlpha; bool p_enabledBlue;
vec4 p_color; bool p_enabledAlpha;
vec4 p_color;
public:
public:
inline
ColorBuffer() : inline
p_enabledRed {true}, ColorBuffer() :
p_enabledGreen {true}, p_enabledRed {true},
p_enabledBlue {true}, p_enabledGreen {true},
p_enabledAlpha {true}, p_enabledBlue {true},
p_color {} p_enabledAlpha {true},
{} p_color {}
{}
inline
ColorBuffer(bool red, bool green, bool blue, bool alpha) : inline
p_enabledRed {red}, ColorBuffer(bool red, bool green, bool blue, bool alpha) :
p_enabledGreen {green}, p_enabledRed {red},
p_enabledBlue {blue}, p_enabledGreen {green},
p_enabledAlpha {alpha}, p_enabledBlue {blue},
p_color {} p_enabledAlpha {alpha},
{} p_color {}
{}
virtual
~ColorBuffer() = default; virtual
~ColorBuffer() = default;
void mask(bool red, bool green, bool blue, bool alpha)
{ inline
glColorMask(red, green, blue, alpha); void mask(bool red, bool green, bool blue, bool alpha) const
} {
glColorMask(red, green, blue, alpha);
inline }
void clear(const vec4& color)
{ inline
p_color = color; void clear(const vec4& color)
glClearColor(color[0], color[1], color[2], color[3]); {
glClear(GL_COLOR_BUFFER_BIT); p_color = color;
} glClearColor(color[0], color[1], color[2], color[3]);
glClear(GL_COLOR_BUFFER_BIT);
inline }
void clear()
{ inline
clear(p_color); void clear()
} {
}; clear(p_color);
}
} };
}

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include <glad/glad.h> #include <glad/glad.h>

122
source/hpr/gpu/context.hpp Normal file
View File

@ -0,0 +1,122 @@
#pragma once
#ifndef __gl_h_
#include <glad/glad.h>
#endif
#include <GLFW/glfw3.h>
#include <stdexcept>
#include <iostream>
namespace hpr::gpu
{
class Context
{
protected:
bool p_glInitialized;
bool p_glfwInitialized;
public:
inline
Context() :
p_glInitialized {false},
p_glfwInitialized {false}
{
if (glfwInit())
p_glfwInitialized = true;
else
throw std::runtime_error("Cannot initialize GLFW context");
}
void link()
{
if (gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
p_glInitialized = true;
else
throw std::runtime_error("Cannot initialize GLAD context");
}
constexpr
bool valid() const
{
return p_glInitialized && p_glfwInitialized;
}
inline
void destroy() const
{
glfwTerminate();
}
inline
void debug(bool enable = true)
{
const auto debugOutput = [](GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char* message, const void* userParam)
{
// ignore non-significant error/warning codes
if (id == 131169 || id == 131185 || id == 131218 || id == 131204)
return;
std::cout << "Debug::GL[" << id << "]::";
switch (source)
{
case GL_DEBUG_SOURCE_API: std::cout << "API"; break;
case GL_DEBUG_SOURCE_WINDOW_SYSTEM: std::cout << "Window_System"; break;
case GL_DEBUG_SOURCE_SHADER_COMPILER: std::cout << "Shader_Compiler"; break;
case GL_DEBUG_SOURCE_THIRD_PARTY: std::cout << "Third_Party"; break;
case GL_DEBUG_SOURCE_APPLICATION: std::cout << "Application"; break;
case GL_DEBUG_SOURCE_OTHER: std::cout << "Other"; break;
default: break;
}
std::cout << "::";
switch (type)
{
case GL_DEBUG_TYPE_ERROR: std::cout << "Error";break;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: std::cout << "Deprecated_Behaviour"; break;
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: std::cout << "Undefined_Behaviour"; break;
case GL_DEBUG_TYPE_PORTABILITY: std::cout << "Portability"; break;
case GL_DEBUG_TYPE_PERFORMANCE: std::cout << "Performance"; break;
case GL_DEBUG_TYPE_MARKER: std::cout << "Marker"; break;
case GL_DEBUG_TYPE_PUSH_GROUP: std::cout << "Push_Group"; break;
case GL_DEBUG_TYPE_POP_GROUP: std::cout << "Pop_Group"; break;
case GL_DEBUG_TYPE_OTHER: std::cout << "Other"; break;
default: break;
}
std::cout << " ";
switch (severity)
{
case GL_DEBUG_SEVERITY_HIGH: std::cout << "(high)"; break;
case GL_DEBUG_SEVERITY_MEDIUM: std::cout << "(medium)"; break;
case GL_DEBUG_SEVERITY_LOW: std::cout << "(low)"; break;
case GL_DEBUG_SEVERITY_NOTIFICATION: std::cout << "(notification)"; break;
default: break;
}
std::cout << ": " << message << std::endl;
};
if (enable)
{
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(debugOutput, nullptr);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
}
else
{
glDisable(GL_DEBUG_OUTPUT);
glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
}
}
};
}

View File

@ -1,76 +1,80 @@
#pragma once #pragma once
#ifndef __gl_h_ #ifndef __gl_h_
#include <glad/glad.h> #include <glad/glad.h>
#endif #endif
namespace hpr::gpu namespace hpr::gpu
{ {
class CullFace class CullFace
{ {
enum class Mode public:
{
Front = GL_FRONT, enum Mode
Back = GL_BACK, {
FrontAndBack = GL_FRONT_AND_BACK, Front = GL_FRONT,
None = GL_NONE Back = GL_BACK,
}; FrontAndBack = GL_FRONT_AND_BACK,
None = GL_NONE
protected: };
bool p_binded; protected:
Mode p_mode;
bool p_binded;
public: Mode p_mode;
inline public:
CullFace() :
p_binded {false}, inline
p_mode {Mode::FrontAndBack} CullFace() :
{} p_binded {false},
p_mode {Mode::FrontAndBack}
inline {}
CullFace(Mode mode) :
p_binded {false}, inline
p_mode {mode} CullFace(Mode mode) :
{} p_binded {false},
p_mode {mode}
virtual {
~CullFace() = default; set(mode);
}
inline
void bind() virtual
{ ~CullFace() = default;
p_binded = true;
glEnable(GL_CULL_FACE); inline
} void bind()
{
inline p_binded = true;
void unbind() glEnable(GL_CULL_FACE);
{ }
p_binded = false;
glDisable(GL_CULL_FACE); inline
void unbind()
} {
p_binded = false;
inline glDisable(GL_CULL_FACE);
bool binded() const
{ }
return p_binded;
} inline
bool binded() const
inline {
void set(Mode mode) return p_binded;
{ }
p_mode = mode;
glCullFace(static_cast<GLenum>(mode)); inline
} void set(Mode mode)
{
}; p_mode = mode;
glCullFace(static_cast<GLenum>(mode));
} }
};
}

View File

@ -1,84 +1,84 @@
#pragma once #pragma once
#ifndef __gl_h_ #ifndef __gl_h_
#include <glad/glad.h> #include <glad/glad.h>
#endif #endif
namespace hpr::gpu namespace hpr::gpu
{ {
class DepthBuffer class DepthBuffer
{ {
protected: protected:
bool p_enabled; bool p_enabled;
bool p_binded; bool p_binded;
public: public:
inline inline
DepthBuffer() : DepthBuffer() :
p_enabled {true}, p_enabled {true},
p_binded {false} p_binded {false}
{} {}
inline inline
DepthBuffer(bool enabled) : DepthBuffer(bool enabled) :
p_enabled {enabled}, p_enabled {enabled},
p_binded {false} p_binded {false}
{} {}
virtual virtual
~DepthBuffer() = default; ~DepthBuffer() = default;
inline inline
void bind() void bind()
{ {
p_binded = true; p_binded = true;
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
} }
inline inline
void unbind() void unbind()
{ {
p_binded = false; p_binded = false;
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
} }
inline inline
bool binded() const bool binded() const
{ {
return p_binded; return p_binded;
} }
inline inline
void enable() void enable()
{ {
p_enabled = true; p_enabled = true;
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
} }
inline inline
void disable() void disable()
{ {
p_enabled = false; p_enabled = false;
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
} }
[[nodiscard]] [[nodiscard]]
inline inline
bool enabled() const bool enabled() const
{ {
return p_enabled; return p_enabled;
} }
inline inline
void clear() const void clear() const
{ {
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
} }
}; };
} }

View File

@ -1,131 +1,178 @@
#pragma once #pragma once
#include "texture.hpp" #include <hpr/gpu/texture.hpp>
#include "renderbuffer.hpp" #include <hpr/gpu/renderbuffer.hpp>
#ifndef __gl_h_
#include <glad/glad.h> #ifndef __gl_h_
#endif #include <glad/glad.h>
#endif
namespace hpr::gpu
{ namespace hpr::gpu
{
class Framebuffer
{ class Framebuffer
{
protected:
protected:
Texture p_texture;
Renderbuffer p_renderbuffer; Texture p_texture;
unsigned int p_index; Renderbuffer p_renderbuffer;
bool p_binded; unsigned int p_index;
bool p_binded;
public:
public:
inline
Framebuffer() : inline
p_index {0}, Framebuffer() :
p_texture {}, p_index {0},
p_renderbuffer {} p_texture {1, 1}, // non zero
{} p_renderbuffer {}
{}
virtual
~Framebuffer() = default; virtual
~Framebuffer() = default;
[[nodiscard]]
unsigned int index() const [[nodiscard]]
{ unsigned int index() const
return p_index; {
} return p_index;
}
void bind()
{ void bind()
glBindFramebuffer(GL_FRAMEBUFFER, p_index); {
p_binded = true; glBindFramebuffer(GL_FRAMEBUFFER, p_index);
} p_binded = true;
}
void unbind()
{ void unbind()
glBindFramebuffer(GL_FRAMEBUFFER, 0); {
p_binded = false; glBindFramebuffer(GL_FRAMEBUFFER, 0);
} p_binded = false;
}
bool binded() const
{ bool binded() const
return p_binded; {
} return p_binded;
}
void attach(const Texture& texture)
{ void attach(const Texture& texture)
if (!binded() && valid()) {
std::runtime_error("Framebuffer not binded or invalid"); if (!binded() && valid())
if (!texture.valid()) throw std::runtime_error("Framebuffer not binded or invalid");
std::runtime_error("Texture is not valid"); if (!texture.valid())
throw std::runtime_error("Texture is not valid");
p_texture = texture;
p_texture.bind(); p_texture = texture;
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture.index(), 0); p_texture.bind();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture.index(), 0);
p_texture.unbind();
} p_texture.unbind();
}
void attach(const Renderbuffer& renderbuffer)
{ void attach(const Renderbuffer& renderbuffer)
if (!binded() && valid()) {
std::runtime_error("Framebuffer not binded or invalid"); if (!binded() && valid())
if (!renderbuffer.valid()) throw std::runtime_error("Framebuffer not binded or invalid");
std::runtime_error("Renderbuffer is not valid"); if (!renderbuffer.valid())
throw std::runtime_error("Renderbuffer is not valid");
p_renderbuffer = renderbuffer;
p_renderbuffer.bind(); p_renderbuffer = renderbuffer;
p_renderbuffer.storage(p_texture.width(), p_texture.height()); p_renderbuffer.bind();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, p_renderbuffer.index()); p_renderbuffer.storage(p_texture.width(), p_texture.height());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, p_renderbuffer.index());
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw std::runtime_error("Framebuffer is not complete"); std::stringstream ss;
ss << "Framebuffer is not complete: " << glCheckFramebufferStatus(GL_FRAMEBUFFER);
p_renderbuffer.unbind(); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
} throw std::runtime_error(ss.str());
void create() p_renderbuffer.unbind();
{ }
glGenFramebuffers(1, &p_index);
bind(); void create()
{
if (!p_texture.valid()) glGenFramebuffers(1, &p_index);
p_texture.create(); bind();
attach(p_texture);
if (!p_texture.valid())
if (!p_renderbuffer.valid()) {
p_renderbuffer.create(); p_texture.create();
attach(p_renderbuffer); attach(p_texture);
}
unbind();
} if (!p_renderbuffer.valid())
{
void rescale(int width, int height) p_renderbuffer.create();
{ attach(p_renderbuffer);
p_texture.bind(); }
p_texture.rescale(width, height);
unbind();
p_renderbuffer.bind(); }
p_renderbuffer.storage(p_texture.width(), p_texture.height());
void rescale()
p_texture.unbind(); {
p_renderbuffer.unbind(); p_texture.bind();
} p_texture.rescale();
void destroy() p_renderbuffer.bind();
{ p_renderbuffer.storage(p_texture.width(), p_texture.height());
p_texture.destroy();
p_renderbuffer.destroy(); p_texture.unbind();
glDeleteFramebuffers(1, &p_index); p_renderbuffer.unbind();
} }
bool valid() const void rescale(int width, int height)
{ {
return p_index != 0; p_texture.bind();
} p_texture.rescale(width, height);
};
p_renderbuffer.bind();
p_renderbuffer.storage(p_texture.width(), p_texture.height());
p_texture.unbind();
p_renderbuffer.unbind();
}
void destroy()
{
p_texture.destroy();
p_renderbuffer.destroy();
glDeleteFramebuffers(1, &p_index);
}
[[nodiscard]]
bool valid() const
{
return p_index != 0;
}
Texture& texture()
{
return p_texture;
}
int& width()
{
return p_texture.width();
}
[[nodiscard]]
int width() const
{
return p_texture.width();
}
int& height()
{
return p_texture.height();
}
[[nodiscard]]
int height() const
{
return p_texture.height();
}
};
} }

View File

@ -1,3 +0,0 @@
//
// Created by L-Nafaryus on 12/16/2022.
//

View File

@ -0,0 +1,34 @@
#pragma once
#include <GLFW/glfw3.h>
namespace hpr::gpu
{
class Monitor
{
protected:
GLFWmonitor* p_instance;
public:
inline
Monitor() :
p_instance {glfwGetPrimaryMonitor()}
{}
virtual
~Monitor() = default;
inline
GLFWmonitor* instance() const
{
return p_instance;
}
};
}

View File

@ -1,69 +1,69 @@
#pragma once #pragma once
#ifndef __gl_h_ #ifndef __gl_h_
#include <glad/glad.h> #include <glad/glad.h>
#endif #endif
namespace hpr::gpu namespace hpr::gpu
{ {
class Renderbuffer class Renderbuffer
{ {
protected: protected:
unsigned int p_index; unsigned int p_index;
public: public:
inline inline
Renderbuffer() : Renderbuffer() :
p_index {0} p_index {0}
{} {}
virtual virtual
~Renderbuffer() = default; ~Renderbuffer() = default;
[[nodiscard]] [[nodiscard]]
unsigned int index() const unsigned int index() const
{ {
return p_index; return p_index;
} }
void bind() void bind()
{ {
glBindRenderbuffer(GL_RENDERBUFFER, p_index); glBindRenderbuffer(GL_RENDERBUFFER, p_index);
} }
void unbind() void unbind()
{ {
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
} }
void create() void create()
{ {
glGenRenderbuffers(1, &p_index); glGenRenderbuffers(1, &p_index);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, p_index); //glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, p_index);
} }
void storage(int width, int height) void storage(int width, int height)
{ {
glBindRenderbuffer(GL_RENDERBUFFER, p_index); glBindRenderbuffer(GL_RENDERBUFFER, p_index);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
} }
void destroy() void destroy()
{ {
glDeleteRenderbuffers(1, &p_index); glDeleteRenderbuffers(1, &p_index);
} }
bool valid() const bool valid() const
{ {
return p_index != 0; return p_index != 0;
} }
}; };
} }

View File

@ -1,8 +0,0 @@
//
// Created by L-Nafaryus on 12/16/2022.
//
#ifndef HPR_SCENE_HPP
#define HPR_SCENE_HPP
#endif //HPR_SCENE_HPP

View File

@ -1,129 +1,129 @@
#pragma once #pragma once
#include <string> #include <string>
#ifndef __gl_h_ #ifndef __gl_h_
#include <glad/glad.h> #include <glad/glad.h>
#endif #endif
namespace hpr::gpu namespace hpr::gpu
{ {
class Shader class Shader
{ {
public: public:
enum class Type enum class Type
{ {
Vertex = GL_VERTEX_SHADER, Vertex = GL_VERTEX_SHADER,
TessControl = GL_TESS_CONTROL_SHADER, TessControl = GL_TESS_CONTROL_SHADER,
TessEvaluation = GL_TESS_EVALUATION_SHADER, TessEvaluation = GL_TESS_EVALUATION_SHADER,
Geometry = GL_GEOMETRY_SHADER, Geometry = GL_GEOMETRY_SHADER,
Fragment = GL_FRAGMENT_SHADER, Fragment = GL_FRAGMENT_SHADER,
Compute = GL_COMPUTE_SHADER, Compute = GL_COMPUTE_SHADER,
Unknown = -1 Unknown = -1
}; };
protected: protected:
std::string p_filename; std::string p_filename;
std::string p_source; std::string p_source;
std::string p_label; std::string p_label;
Type p_type; Type p_type;
unsigned int p_index; unsigned int p_index;
public: public:
// Constructors // Constructors
inline inline
Shader() : Shader() :
p_filename {}, p_filename {},
p_source {}, p_source {},
p_label {}, p_label {},
p_type {Type::Unknown}, p_type {Type::Unknown},
p_index {0} p_index {0}
{} {}
inline inline
Shader(Type type) : Shader(Type type) :
p_filename {}, p_filename {},
p_source {}, p_source {},
p_label {}, p_label {},
p_type {type} p_type {type}
{} {}
inline inline
Shader(Type type, const std::string& source) : Shader(Type type, const std::string& source) :
p_filename {}, p_filename {},
p_source {source}, p_source {source},
p_label {}, p_label {},
p_type {type}, p_type {type},
p_index {0} p_index {0}
{} {}
virtual virtual
~Shader() = default; ~Shader() = default;
// Member functions // Member functions
[[nodiscard]] [[nodiscard]]
std::string filename() const std::string filename() const
{ {
return p_filename; return p_filename;
} }
[[nodiscard]] [[nodiscard]]
std::string label() const std::string label() const
{ {
return p_label; return p_label;
} }
[[nodiscard]] [[nodiscard]]
Type type() const Type type() const
{ {
return p_type; return p_type;
} }
[[nodiscard]] [[nodiscard]]
unsigned int index() const unsigned int index() const
{ {
return p_index; return p_index;
} }
void create(const std::string& label = "") void create(const std::string& label = "")
{ {
if (p_type == Type::Unknown) if (p_type == Type::Unknown)
throw std::runtime_error("Unknown shader type"); throw std::runtime_error("Unknown shader type");
p_index = glCreateShader(static_cast<GLenum>(p_type)); p_index = glCreateShader(static_cast<GLenum>(p_type));
if (p_index == 0) if (p_index == 0)
throw std::runtime_error("Cannot create shader"); throw std::runtime_error("Cannot create shader");
const char* shaderSource = p_source.c_str(); const char* shaderSource = p_source.c_str();
glShaderSource(p_index, 1, &shaderSource, nullptr); glShaderSource(p_index, 1, &shaderSource, nullptr);
GLenum result = glGetError(); GLenum result = glGetError();
glCompileShader(p_index); glCompileShader(p_index);
int shaderStatus; int shaderStatus;
glGetShaderiv(p_index, GL_COMPILE_STATUS, &shaderStatus); glGetShaderiv(p_index, GL_COMPILE_STATUS, &shaderStatus);
if (!shaderStatus) if (!shaderStatus)
{ {
char error[2048 + 1]; char error[2048 + 1];
glGetShaderInfoLog(p_index, 2048, nullptr, error); glGetShaderInfoLog(p_index, 2048, nullptr, error);
throw std::runtime_error(error); throw std::runtime_error(error);
} }
p_label = label; p_label = label;
} }
void destroy() void destroy()
{ {
glDeleteShader(p_index); glDeleteShader(p_index);
} }
}; };
} }

View File

@ -1,96 +1,268 @@
#pragma once #pragma once
#include "../containers.hpp" #include <hpr/containers.hpp>
#include <hpr/gpu/shader.hpp>
#include <string> #include <hpr/exception.hpp>
#ifndef __gl_h_ #include <string>
#include <glad/glad.h>
#endif #ifndef __gl_h_
#include <glad/glad.h>
namespace hpr::gpu #endif
{
namespace hpr::gpu
class ShaderProgram {
{
struct ShaderProgramLinkError : public Exception
protected: {
inline explicit ShaderProgramLinkError(std::source_location location = std::source_location::current()) : Exception {"Shader program link error", location} {}
unsigned int p_index; inline explicit ShaderProgramLinkError(const std::string& message, std::source_location location = std::source_location::current()) : Exception {message, location} {}
darray<Shader> p_shaders; };
public: class ShaderProgram
{
// Constructors
protected:
inline
ShaderProgram() : unsigned int p_index;
p_index {0}
{} public:
virtual // Constructors
~ShaderProgram() = default;
inline
[[nodiscard]] ShaderProgram() :
unsigned int index() const p_index {0}
{ {}
return p_index;
} virtual
~ShaderProgram() = default;
darray<Shader> shaders()
{ [[nodiscard]]
return p_shaders; unsigned int index() const
} {
return p_index;
void create(const std::string& label = "") }
{
p_index = glCreateProgram(); void create()
} {
p_index = glCreateProgram();
void attach(const Shader& shader) }
{
glAttachShader(p_index, shader.index()); void attach(const Shader& shader)
p_shaders.push(shader); {
} glAttachShader(p_index, shader.index());
}
void detach(const Shader& shader)
{ void detach(const Shader& shader)
// WARNING: segfault, destroy_at (char) {
p_shaders.remove([shader](const Shader& _shader) glDetachShader(p_index, shader.index());
{ }
return shader.index() == _shader.index();
}); void link()
{
glDetachShader(p_index, shader.index()); glLinkProgram(p_index);
}
GLint status;
void link() glGetProgramiv(p_index, GL_LINK_STATUS, &status);
{
glLinkProgram(p_index); if (status == GL_FALSE)
{
GLint status; GLsizei log_length = 0;
glGetProgramiv(p_index, GL_LINK_STATUS, &status); GLchar message[1024];
glGetProgramInfoLog(p_index, 1024, &log_length, message);
if (status == GL_FALSE) throw ShaderProgramLinkError(message);
throw std::runtime_error("Shader program link error"); }
} }
void destroy() void destroy()
{ {
//for (auto& shader : p_shaders) glDeleteProgram(p_index);
// detach(shader); }
glDeleteShader(p_index);
} void bind()
{
void bind() glUseProgram(p_index);
{ }
glUseProgram(p_index);
} void unbind()
{
void unbind() glUseProgram(0);
{ }
glUseProgram(0);
} inline
}; int uniformLocation(const std::string& label) const
{
} return glGetUniformLocation(p_index, label.c_str());
}
template <typename T, std::convertible_to<T>... Args>
inline
void uniformValue(int location, T value, Args ...args)
{
auto arr = {value, static_cast<T>(args)...};
if constexpr (std::is_same<T, int>::value)
{
switch (arr.size())
{
case 1: glUniform1i(location, arr[0]); break;
case 2: glUniform2i(location, arr[0], arr[1]); break;
case 3: glUniform3i(location, arr[0], arr[1], arr[2]); break;
case 4: glUniform4i(location, arr[0], arr[1], arr[2], arr[3]); break;
}
}
else if constexpr (std::is_same<T, unsigned int>::value)
{
switch (arr.size())
{
case 1: glUniform1ui(location, arr[0]); break;
case 2: glUniform2ui(location, arr[0], arr[1]); break;
case 3: glUniform3ui(location, arr[0], arr[1], arr[2]); break;
case 4: glUniform4ui(location, arr[0], arr[1], arr[2], arr[3]); break;
}
}
else if constexpr (std::is_same<T, float>::value)
{
switch (arr.size())
{
case 1: glUniform1f(location, arr[0]); break;
case 2: glUniform2f(location, arr[0], arr[1]); break;
case 3: glUniform3f(location, arr[0], arr[1], arr[2]); break;
case 4: glUniform4f(location, arr[0], arr[1], arr[2], arr[3]); break;
}
}
else if constexpr (std::is_same<T, double>::value)
{
switch (arr.size())
{
case 1: glUniform1d(location, arr[0]); break;
case 2: glUniform2d(location, arr[0], arr[1]); break;
case 3: glUniform3d(location, arr[0], arr[1], arr[2]); break;
case 4: glUniform4d(location, arr[0], arr[1], arr[2], arr[3]); break;
}
}
else
throw std::runtime_error("Unsupported value type");
}
template <typename T, std::convertible_to<T>... Args>
inline
void uniformValue(const std::string& label, T value, Args ...args)
{
uniformValue(uniformLocation(label), value, std::forward<T>(args)...);
}
template <typename T, Size S>
inline
void uniformVector(int location, hpr::Size size, T* data)
{
if constexpr (std::is_same<T, int>::value)
{
switch (S)
{
case 1: glUniform1iv(location, size, data); break;
case 2: glUniform2iv(location, size, data); break;
case 3: glUniform3iv(location, size, data); break;
case 4: glUniform4iv(location, size, data); break;
}
}
else if constexpr (std::is_same<T, unsigned int>::value)
{
switch (S)
{
case 1: glUniform1uiv(location, size, data); break;
case 2: glUniform2uiv(location, size, data); break;
case 3: glUniform3uiv(location, size, data); break;
case 4: glUniform4uiv(location, size, data); break;
}
}
else if constexpr (std::is_same<T, float>::value)
{
switch (S)
{
case 1: glUniform1fv(location, size, data); break;
case 2: glUniform2fv(location, size, data); break;
case 3: glUniform3fv(location, size, data); break;
case 4: glUniform4fv(location, size, data); break;
}
}
else if constexpr (std::is_same<T, double>::value)
{
switch (size)
{
case 1: glUniform1dv(location, size, data); break;
case 2: glUniform2dv(location, size, data); break;
case 3: glUniform3dv(location, size, data); break;
case 4: glUniform4dv(location, size, data); break;
}
}
else
throw std::runtime_error("Unsupported value type");
}
template <typename T, Size S>
inline
void uniformVector(const std::string& label, hpr::Size size, T* data)
{
uniformVector<T, S>(uniformLocation(label), size, data);
}
template <typename T, hpr::Size C, hpr::Size R>
inline
void uniformMatrix(int location, hpr::Size size, bool transpose, T* data)
{
if constexpr (std::is_same<T, float>::value)
{
if constexpr (C == 2 && R == 2)
glUniformMatrix2fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 3 && R == 3)
glUniformMatrix3fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 4 && R == 4)
glUniformMatrix4fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 2 && R == 3)
glUniformMatrix2x3fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 3 && R == 2)
glUniformMatrix3x2fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 2 && R == 4)
glUniformMatrix2x4fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 4 && R == 2)
glUniformMatrix4x2fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 3 && R == 4)
glUniformMatrix3x4fv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 4 && R == 3)
glUniformMatrix4x3fv(location, static_cast<GLsizei>(size), transpose, data);
}
else if constexpr (std::is_same<T, double>::value)
{
if constexpr (C == 2 && R == 2)
glUniformMatrix2dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 3 && R == 3)
glUniformMatrix3dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 4 && R == 4)
glUniformMatrix4dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 2 && R == 3)
glUniformMatrix2x3dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 3 && R == 2)
glUniformMatrix3x2dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 2 && R == 4)
glUniformMatrix2x4dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 4 && R == 2)
glUniformMatrix4x2dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 3 && R == 4)
glUniformMatrix3x4dv(location, static_cast<GLsizei>(size), transpose, data);
else if constexpr (C == 4 && R == 3)
glUniformMatrix4x3dv(location, static_cast<GLsizei>(size), transpose, data);
}
else
throw std::runtime_error("Unsupported value type");
}
template <hpr::Size C, hpr::Size R, typename T>
inline
void uniformMatrix(const std::string& label, hpr::Size size, bool transpose, T* data)
{
uniformMatrix<T, C, R>(uniformLocation(label), size, transpose, data);
}
};
}

View File

@ -1,9 +1,9 @@
#version 330 #version 330
uniform vec3 color; uniform vec3 color;
out vec4 out_color; out vec4 out_color;
void main(void) void main(void)
{ {
out_color = vec4(color, 0.5f); out_color = vec4(color, 0.5f);
} }

View File

@ -1,11 +1,11 @@
#version 330 core #version 330 core
layout (location = 0) in vec3 aPos; layout (location = 0) in vec3 aPos;
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
uniform mat4 projection; uniform mat4 projection;
void main() void main()
{ {
gl_Position = projection * view * model * vec4(aPos, 1.0); gl_Position = projection * view * model * vec4(aPos, 1.0);
} }

View File

@ -1,84 +1,84 @@
#pragma once #pragma once
#ifndef __gl_h_ #ifndef __gl_h_
#include <glad/glad.h> #include <glad/glad.h>
#endif #endif
namespace hpr::gpu namespace hpr::gpu
{ {
class StencilBuffer class StencilBuffer
{ {
protected: protected:
bool p_enabled; bool p_enabled;
bool p_binded; bool p_binded;
public: public:
inline inline
StencilBuffer() : StencilBuffer() :
p_enabled {false}, p_enabled {false},
p_binded {false} p_binded {false}
{} {}
inline inline
StencilBuffer(bool enabled) : StencilBuffer(bool enabled) :
p_enabled {enabled}, p_enabled {enabled},
p_binded {false} p_binded {false}
{} {}
virtual virtual
~StencilBuffer() = default; ~StencilBuffer() = default;
inline inline
void bind() void bind()
{ {
p_binded = true; p_binded = true;
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
} }
inline inline
void unbind() void unbind()
{ {
p_binded = false; p_binded = false;
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
} }
inline inline
bool binded() const bool binded() const
{ {
return p_binded; return p_binded;
} }
inline inline
void enable() void enable()
{ {
p_enabled = true; p_enabled = true;
glStencilMask(GL_TRUE); glStencilMask(GL_TRUE);
} }
inline inline
void disable() void disable()
{ {
p_enabled = false; p_enabled = false;
glStencilMask(GL_FALSE); glStencilMask(GL_FALSE);
} }
[[nodiscard]] [[nodiscard]]
inline inline
bool enabled() const bool enabled() const
{ {
return p_enabled; return p_enabled;
} }
inline inline
void clear() const void clear() const
{ {
glClear(GL_STENCIL_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT);
} }
}; };
} }

Some files were not shown because too many files have changed in this diff Show More