diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 395906c8..6d6c9c9b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,3 +12,4 @@ jobs: uses: ./.github/workflows/cmake.yml with: build_type: Release + run_tests: true diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index dce8c120..343d35e7 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -12,6 +12,10 @@ on: description: Should upload artifacts or not type: boolean default: false + run_tests: + description: Run CTest after project build + type: boolean + default: false jobs: build: @@ -35,7 +39,7 @@ jobs: # make && make install INSTALL_INC=/usr/include/lua run: | sudo apt-get update - sudo apt-get install libglfw3-dev libglfw3 libglew-dev libglm-dev libpng-dev libopenal-dev libluajit-5.1-dev libvorbis-dev + sudo apt-get install libglfw3-dev libglfw3 libglew-dev libglm-dev libpng-dev libopenal-dev libluajit-5.1-dev libvorbis-dev libgtest-dev # fix luajit paths sudo ln -s /usr/lib/x86_64-linux-gnu/libluajit-5.1.a /usr/lib/x86_64-linux-gnu/liblua-5.1.a sudo ln -s /usr/include/luajit-2.1 /usr/include/lua @@ -52,14 +56,16 @@ jobs: # make. # # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{inputs.build_type}} + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{inputs.build_type}} -DVOXELENGINE_BUILD_TESTS=ON - name: Build # Build your program with the given configuration run: | cmake --build ${{github.workspace}}/build --config ${{inputs.build_type}} mv ${{github.workspace}}/build/VoxelEngine VoxelEngine - + - name: Run tests + if: ${{ inputs.run_tests }} + run: ctest --test-dir ${{github.workspace}}/build - name: Upload artifacts if: ${{ inputs.upload_artifacts }} uses: actions/upload-artifact@v4 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index a477d3c0..1f9675ca 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -17,7 +17,7 @@ jobs: - name: Install dependencies from brew run: | - brew install glfw3 glew libpng openal-soft luajit libvorbis skypjack/entt/entt + brew install glfw3 glew libpng openal-soft luajit libvorbis skypjack/entt/entt googletest - name: Install specific version of GLM run: | @@ -25,7 +25,7 @@ jobs: brew install --formula glm.rb - name: Configure - run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_APPDIR=1 + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_TESTS=ON -DVOXELENGINE_BUILD_APPDIR=1 - name: Build run: cmake --build build -t install @@ -36,6 +36,9 @@ jobs: - name: Fix dylibs run: ./dev/fix_dylibs.sh VoxelEngine Release build + - name: Run tests + run: ctest --test-dir build + - name: Create DMG run: | mkdir VoxelEngineDmgContent diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 46fe7122..6af90077 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -32,16 +32,17 @@ jobs: run: | mkdir build cd build - cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. + cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON -DVOXELENGINE_BUILD_TESTS=ON .. Remove-Item -Path CMakeFiles -Recurse -Force - cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. + cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON -DVOXELENGINE_BUILD_TESTS=ON .. cmake --build . --config Release - name: Package for Windows run: | mkdir packaged cp -r build/* packaged/ working-directory: ${{ github.workspace }} - + - name: Run tests + run: ctest --test-dir build - uses: actions/upload-artifact@v2 with: name: Windows-Build diff --git a/CMakeLists.txt b/CMakeLists.txt index 579ee11b..2ec82dca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,31 +7,16 @@ cmake_minimum_required(VERSION 3.15) project(VoxelEngine) option(VOXELENGINE_BUILD_APPDIR OFF) +option(VOXELENGINE_BUILD_TESTS OFF) set(CMAKE_CXX_STANDARD 17) -file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp) -file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) - -add_executable(${PROJECT_NAME} ${SOURCES}) +add_subdirectory(src) +add_executable(${PROJECT_NAME} src/voxel_engine.cpp) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) if(VOXELENGINE_BUILD_APPDIR) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/.dirIcon) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) - install(TARGETS VoxelEngine DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) + include(${CMAKE_CURRENT_SOURCE_DIR}/dev/cmake/BuildAppdir.cmake) endif() if(MSVC) @@ -81,67 +66,15 @@ if(VOXELENGINE_BUILD_WINDOWS_VCPKG AND WIN32) endforeach() endif() -find_package(OpenGL REQUIRED) -find_package(GLEW REQUIRED) -find_package(OpenAL REQUIRED) -find_package(ZLIB REQUIRED) -if (NOT APPLE) - find_package(EnTT REQUIRED) -endif() - -if (WIN32) - if(VOXELENGINE_BUILD_WINDOWS_VCPKG) - set(LUA_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/lib/lua51.lib") - set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/include/luajit") - find_package(glfw3 REQUIRED) - find_package(spng REQUIRED) - find_package(glm REQUIRED) - find_package(vorbis REQUIRED) - set(PNGLIB spng::spng) - set(VORBISLIB Vorbis::vorbis Vorbis::vorbisfile) - else() - find_package(Lua REQUIRED) - set(PNGLIB spng) - set(VORBISLIB vorbis vorbisfile) # not tested - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/glfw) - endif() -elseif(APPLE) - find_package(PkgConfig) - pkg_check_modules(LUAJIT REQUIRED luajit) - pkg_check_modules(VORBIS REQUIRED vorbis vorbisfile) - set(LUA_INCLUDE_DIR "/opt/homebrew/include/luajit-2.1") - set(LUA_LIBRARIES "/opt/homebrew/lib/libluajit-5.1.a") - message(STATUS "LUA Libraries: ${LUA_LIBRARIES}") - message(STATUS "LUA Include Dir: ${LUA_INCLUDE_DIR}") - find_package(PNG REQUIRED) - set(PNGLIB PNG::PNG) - set(VORBISLIB ${VORBIS_LDFLAGS}) - message(STATUS "Vorbis Lib: ${VORBIS_LDFLAGS}") -else() - find_package(PkgConfig) - pkg_check_modules(LUAJIT REQUIRED luajit) - pkg_check_modules(VORBIS REQUIRED vorbis vorbisfile) - set(LUA_LIBRARIES ${LUAJIT_LIBRARIES}) - set(LUA_INCLUDE_DIR ${LUAJIT_INCLUDE_DIRS}) - find_package(PNG REQUIRED) - set(PNGLIB PNG::PNG) - set(VORBISLIB ${VORBIS_LDFLAGS}) -endif() - -set(LIBS "") - -if(UNIX) - find_package(glfw3 3.3 REQUIRED) - find_package(Threads REQUIRED) - set(LIBS ${LIBS} Threads::Threads) -endif() - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie -lstdc++fs") endif() -include_directories(${LUA_INCLUDE_DIR}) -target_link_libraries(${PROJECT_NAME} ${LIBS} glfw OpenGL::GL ${OPENAL_LIBRARY} GLEW::GLEW ZLIB::ZLIB ${VORBISLIB} ${PNGLIB} ${LUA_LIBRARIES} ${CMAKE_DL_LIBS}) +target_link_libraries(${PROJECT_NAME} VoxelEngineSrc ${CMAKE_DL_LIBS}) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +if (VOXELENGINE_BUILD_TESTS) + enable_testing() + add_subdirectory(test) +endif() diff --git a/dev/cmake/BuildAppdir.cmake b/dev/cmake/BuildAppdir.cmake new file mode 100644 index 00000000..245b2925 --- /dev/null +++ b/dev/cmake/BuildAppdir.cmake @@ -0,0 +1,15 @@ +file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/.dirIcon) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) +install(TARGETS VoxelEngine DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..8cd21fbd --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,70 @@ +project(VoxelEngineSrc) + +set(CMAKE_CXX_STANDARD 17) + +file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +list(REMOVE_ITEM SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/voxel_engine.cpp) + +add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS}) + +option(VOXELENGINE_BUILD_WINDOWS_VCPKG ON) + +find_package(OpenGL REQUIRED) +find_package(GLEW REQUIRED) +find_package(OpenAL REQUIRED) +find_package(ZLIB REQUIRED) +if (NOT APPLE) + find_package(EnTT REQUIRED) +endif() + +if (WIN32) + if(VOXELENGINE_BUILD_WINDOWS_VCPKG) + set(LUA_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/../vcpkg/packages/luajit_x64-windows/lib/lua51.lib") + set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../vcpkg/packages/luajit_x64-windows/include/luajit") + find_package(glfw3 REQUIRED) + find_package(spng REQUIRED) + find_package(glm REQUIRED) + find_package(vorbis REQUIRED) + set(PNGLIB spng::spng) + set(VORBISLIB Vorbis::vorbis Vorbis::vorbisfile) + else() + find_package(Lua REQUIRED) + set(PNGLIB spng) + set(VORBISLIB vorbis vorbisfile) # not tested + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/glfw) + endif() +elseif(APPLE) + find_package(PkgConfig) + pkg_check_modules(LUAJIT REQUIRED luajit) + pkg_check_modules(VORBIS REQUIRED vorbis vorbisfile) + set(LUA_INCLUDE_DIR "/opt/homebrew/include/luajit-2.1") + set(LUA_LIBRARIES "/opt/homebrew/lib/libluajit-5.1.a") + message(STATUS "LUA Libraries: ${LUA_LIBRARIES}") + message(STATUS "LUA Include Dir: ${LUA_INCLUDE_DIR}") + find_package(PNG REQUIRED) + set(PNGLIB PNG::PNG) + set(VORBISLIB ${VORBIS_LDFLAGS}) + message(STATUS "Vorbis Lib: ${VORBIS_LDFLAGS}") +else() + find_package(PkgConfig) + pkg_check_modules(LUAJIT REQUIRED luajit) + pkg_check_modules(VORBIS REQUIRED vorbis vorbisfile) + set(LUA_LIBRARIES ${LUAJIT_LIBRARIES}) + set(LUA_INCLUDE_DIR ${LUAJIT_INCLUDE_DIRS}) + find_package(PNG REQUIRED) + set(PNGLIB PNG::PNG) + set(VORBISLIB ${VORBIS_LDFLAGS}) +endif() + +set(LIBS "") + +if(UNIX) + find_package(glfw3 3.3 REQUIRED) + find_package(Threads REQUIRED) + set(LIBS ${LIBS} Threads::Threads) +endif() + +include_directories(${LUA_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(${PROJECT_NAME} ${LIBS} glfw OpenGL::GL ${OPENAL_LIBRARY} GLEW::GLEW ZLIB::ZLIB ${VORBISLIB} ${PNGLIB} ${LUA_LIBRARIES} ${CMAKE_DL_LIBS}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..cbe038a6 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,19 @@ +project(VoxelEngineTest) + +set(CMAKE_CXX_STANDARD 17) + +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +find_package(GTest) + +add_executable(${PROJECT_NAME} ${SOURCES}) + +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src) +target_link_libraries( + ${PROJECT_NAME} + VoxelEngineSrc + GTest::gtest_main +) + +include(GoogleTest) +gtest_discover_tests(${PROJECT_NAME}) diff --git a/test/coders/rle.cpp b/test/coders/rle.cpp new file mode 100644 index 00000000..c93a034a --- /dev/null +++ b/test/coders/rle.cpp @@ -0,0 +1,48 @@ +#include + +#include "typedefs.hpp" +#include "coders/rle.hpp" + +TEST(RLE, EncodeDecode) { + const int initial_size = 50'000; + uint8_t initial[initial_size]; + uint8_t next = rand(); + for (int i = 0; i < initial_size; i++) { + initial[i] = next; + if (rand() % 13 == 0) { + next = rand(); + } + } + uint8_t encoded[initial_size * 2]; + auto encoded_size = rle::encode(initial, initial_size, encoded); + uint8_t decoded[initial_size * 2]; + auto decoded_size = rle::decode(encoded, encoded_size, decoded); + + EXPECT_EQ(decoded_size, initial_size); + + for (int i = 0; i < decoded_size; i++) { + EXPECT_EQ(decoded[i], initial[i]); + } +} + +TEST(ExtRLE, EncodeDecode) { + const int initial_size = 50'000; + uint8_t initial[initial_size]; + uint8_t next = rand(); + for (int i = 0; i < initial_size; i++) { + initial[i] = next; + if (rand() % 13 == 0) { + next = rand(); + } + } + uint8_t encoded[initial_size * 2]; + auto encoded_size = extrle::encode(initial, initial_size, encoded); + uint8_t decoded[initial_size * 2]; + auto decoded_size = extrle::decode(encoded, encoded_size, decoded); + + EXPECT_EQ(decoded_size, initial_size); + + for (int i = 0; i < decoded_size; i++) { + EXPECT_EQ(decoded[i], initial[i]); + } +} diff --git a/vcpkg.json b/vcpkg.json index b53f9d40..05fe48e2 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -11,6 +11,7 @@ "zlib", "luajit", "libvorbis", - "entt" + "entt", + "gtest" ] }