diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ab9a6a..3bc8d3b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,52 +12,64 @@ include(cmake/palladium.cmake) option(PD_BUILD_TESTS "Sets if TestApp and TestBench get build" OFF) option(PD_BUILD_SHARED "Build Shared Library" OFF) option(PD_BUILD_TOOLS "Build Palladium Tools" OFF) +option(PD_INCLUDE_STB_IMAGE "Inlude stb image symbols in palladium" ON) if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") - add_compile_options(-Wno-psabi) + add_compile_options(-Wno-psabi) endif() if(${PD_BUILD_TOOLS}) - add_subdirectory(tools) + add_subdirectory(tools) endif() add_subdirectory(vendor) # # Include Library Source set(PD_SOURCES - # Common - source/common.cpp + # Common + source/common.cpp - # Core - source/core/bits.cpp - source/core/color.cpp - source/core/io.cpp - source/core/mat.cpp - source/core/strings.cpp - source/core/timer.cpp - source/core/timetrace.cpp + # Core + source/core/bits.cpp + source/core/color.cpp + source/core/io.cpp + source/core/mat.cpp + source/core/strings.cpp + source/core/timer.cpp + source/core/timetrace.cpp - # Drivers - source/drivers/os.cpp - source/drivers/gfx.cpp + # Image + source/image/image.cpp - # Lithium - source/lithium/pools.cpp - source/lithium/math.cpp - source/lithium/drawlist.cpp + # Drivers + source/drivers/os.cpp + source/drivers/gfx.cpp + + # Lithium + source/lithium/pools.cpp + source/lithium/math.cpp + source/lithium/drawlist.cpp ) if(${PD_BUILD_SHARED}) - add_library(palladium SHARED ${PD_SOURCES}) - target_compile_definitions(palladium PRIVATE PD_BUILD_SHARED) + add_library(palladium SHARED ${PD_SOURCES}) + target_compile_definitions(palladium PRIVATE PD_BUILD_SHARED) else() - add_library(palladium STATIC ${PD_SOURCES}) - target_compile_definitions(palladium PUBLIC PD_BUILD_STATIC) + add_library(palladium STATIC ${PD_SOURCES}) + target_compile_definitions(palladium PUBLIC PD_BUILD_STATIC) endif() -target_compile_definitions(palladium PUBLIC PD_DEBUG) +target_link_libraries(palladium + PUBLIC stb +) + +target_compile_definitions(palladium + PUBLIC + PD_DEBUG + $<$,$>:PD_INCLUDE_STB_IMAGE> # Always on in shared build +) target_compile_options(palladium - PUBLIC $<$: + PUBLIC $<$: -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include > @@ -66,75 +78,75 @@ target_compile_options(palladium add_library(palladium::palladium ALIAS palladium) target_include_directories(palladium - PUBLIC - $ - $ + PUBLIC + $ + $ ) target_compile_options(palladium - PRIVATE - $<$,$>:-O0 -g> - $<$,$>:-O3> + PRIVATE + $<$,$>:-O0 -g> + $<$,$>:-O3> - $<$,$>:/Od /Zi> - $<$,$>:/O2> + $<$,$>:/Od /Zi> + $<$,$>:/O2> ) install( - TARGETS palladium - EXPORT palladiumTargets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + TARGETS palladium + EXPORT palladiumTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) install( - DIRECTORY include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + DIRECTORY include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) install(EXPORT palladiumTargets - FILE palladiumTargets.cmake - NAMESPACE palladium:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium + FILE palladiumTargets.cmake + NAMESPACE palladium:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium ) include(CMakePackageConfigHelpers) configure_package_config_file( - cmake/palladiumConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake - INSTALL_DESTINATION - ${CMAKE_INSTALL_LIBDIR}/cmake/palladium + cmake/palladiumConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake + INSTALL_DESTINATION + ${CMAKE_INSTALL_LIBDIR}/cmake/palladium ) write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake - VERSION - ${PROJECT_VERSION} - COMPATIBILITY - SameMajorVersion + ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake + VERSION + ${PROJECT_VERSION} + COMPATIBILITY + SameMajorVersion ) install( - FILES - ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium + FILES + ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/palladiumConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/palladium ) find_program(CLANG_FORMAT clang-format) file(GLOB_RECURSE PD_FMTFILES - CONFIGURE_DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/backends/source/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/backends/include/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/core/source/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/gfx/source/*.cpp + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/backends/source/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/backends/include/*.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/core/source/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/gfx/source/*.cpp ) add_custom_target(pd-clang-format - COMMAND ${CLANG_FORMAT} --style=file -i ${PD_FMTFILES} - COMMENT "Formatting Project Sources" + COMMAND ${CLANG_FORMAT} --style=file -i ${PD_FMTFILES} + COMMENT "Formatting Project Sources" ) add_subdirectory(backends) diff --git a/include/palladium b/include/palladium index 7b93830..32392d7 100755 --- a/include/palladium +++ b/include/palladium @@ -25,4 +25,5 @@ SOFTWARE. #include #include +#include #include \ No newline at end of file diff --git a/include/pd/common.hpp b/include/pd/common.hpp index 1afbc13..3b8901b 100644 --- a/include/pd/common.hpp +++ b/include/pd/common.hpp @@ -44,6 +44,7 @@ SOFTWARE. namespace PD { enum class LogLevel { + None, Info, Warning, Error, @@ -56,6 +57,7 @@ using u16 = unsigned short; using u32 = unsigned int; using u64 = unsigned long long; using ptr = uintptr_t; +PD_API void LogFilter(LogLevel minimum); PD_API void Log(const std::string& txt, LogLevel lvl = LogLevel::Info); template void Log(std::format_string fmt, Args&&... args) { diff --git a/include/pd/image/image.hpp b/include/pd/image/image.hpp new file mode 100644 index 0000000..33dd54f --- /dev/null +++ b/include/pd/image/image.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include + +namespace PD { +class PD_API Image { + public: + enum class Format { + RGBA, // bpp == 4 + RGB, // bpp == 3 + RGB565, // bpp == 2 (not supported in laoding) + BGR, // bpp == 3 + ABGR, // bpp == 4 + BGRA, // bpp == 4 + }; + Image(); + Image(const std::string& path); + Image(const std::vector& buf); + Image(const std::vector& pixels, int w, int h, int bpp = 4); + ~Image(); + + void Load(const std::string& path); + void Load(const std::vector& buf); + void Load(const u8* buf, size_t size); + void Copy(const std::vector& pixels, int w, int h, int bpp = 4); + + const int& Width() const { return pSize.x; } + const int& Height() const { return pSize.x; } + const ivec2& Size() const { return pSize; } + + const std::vector& data() const { return pData; } + std::vector& data() { return pData; } + operator const std::vector&() const { return pData; } + operator std::vector&() { return pData; } + operator const ivec2&() const { return pSize; } + operator const Format&() const { return pFormat; } + + void Flip(bool horizontal = true, bool vertical = true); + + static int Format2Bpp(Format fmt); + static Format GuessFmtFromBpp(int bpp); + + private: + std::vector pData; + ivec2 pSize; + Format pFormat = Format::RGBA; +}; +} // namespace PD \ No newline at end of file diff --git a/source/common.cpp b/source/common.cpp index 84a5fdb..eec128d 100644 --- a/source/common.cpp +++ b/source/common.cpp @@ -6,6 +6,11 @@ constexpr const char* pColorNo = "\033[0m"; constexpr const char* pColorYellow = "\033[33m"; constexpr const char* pColorRed = "\033[31m"; static LogLevel pFilter = LogLevel::Info; + +PD_API void LogFilter(LogLevel lvl) { + pFilter = lvl; +} + PD_API void Log(const std::string& txt, LogLevel lvl) { if ((int)lvl < (int)pFilter) return; const char* clr = pColorNo; diff --git a/source/image/image.cpp b/source/image/image.cpp new file mode 100644 index 0000000..89a32b9 --- /dev/null +++ b/source/image/image.cpp @@ -0,0 +1,90 @@ +#include + +#if defined(PD_INCLUDE_STB_IMAGE) +#define STB_IMAGE_IMPLEMENTATION +#endif +#include + +namespace PD { +PD_API Image::Image() {} + +PD_API Image::Image(const std::string& path) { Load(path); } + +PD_API Image::Image(const std::vector& buf) { Load(buf); } + +PD_API Image::Image(const std::vector& pixels, int w, int h, int bpp) { + Copy(pixels, w, h, bpp); +} + +PD_API Image::~Image() {} + +PD_API void Image::Load(const u8* buf, size_t size) { + int w = 0, h = 0, c = 0; + u8* img = stbi_load_from_memory(buf, size, &w, &h, &c, 4); + if (c == 3) { + stbi_image_free(img); + img = stbi_load_from_memory(buf, size, &w, &h, &c, 3); + pFormat = Format::RGB; + } + pData.assign(img, img + (w * h * c)); + pSize = ivec2(w, h); + stbi_image_free(img); +} + +PD_API void Image::Load(const std::string& path) { + int w = 0, h = 0, c = 0; + u8* img = stbi_load(path.c_str(), &w, &h, &c, 4); + if (c == 3) { + stbi_image_free(img); + img = stbi_load(path.c_str(), &w, &h, &c, 3); + pFormat = Format::RGB; + } + pData.assign(img, img + (w * h * c)); + pSize = ivec2(w, h); + stbi_image_free(img); +} + +PD_API void Image::Load(const std::vector& buf) { + Load(buf.data(), buf.size()); +} + +PD_API void Image::Copy(const std::vector& pixels, int w, int h, int bpp) { + pData = pixels; + pSize = ivec2(w, h); + pFormat = GuessFmtFromBpp(bpp); +} + +PD_API int Image::Format2Bpp(Format fmt) { + switch (fmt) { + case Format::RGBA: + case Format::ABGR: + case Format::BGRA: + return 4; + case Format::BGR: + case Format::RGB: + return 3; + case Format::RGB565: + return 2; + } + return 0; +} + +PD_API Image::Format Image::GuessFmtFromBpp(int bpp) { + /** Only return defaults here */ + switch (bpp) { + case 4: + return Format::RGBA; + case 3: + return Format::RGB; + case 2: + return Format::RGB565; + default: + return Format::RGBA; + } +} + +PD_API void Image::Flip(bool hz, bool vt) { + // TODO +} + +} // namespace PD \ No newline at end of file diff --git a/tests/gfx/source/main.cpp b/tests/gfx/source/main.cpp index 4fdefe6..110550c 100644 --- a/tests/gfx/source/main.cpp +++ b/tests/gfx/source/main.cpp @@ -16,6 +16,7 @@ const char* ResourcePath(const char* in) { } int main(int argc, char** argv) { + PD::LogFilter(PD::LogLevel::Warning); Driver drv = Driver::OpenGL3; if (argc == 2) { if (std::string(argv[1]) == "gl2") { @@ -36,16 +37,22 @@ int main(int argc, char** argv) { pOs->Init(); PD::Gfx::Init(); PD::Li::Drawlist pList; + PD::Image img(ResourcePath("icon.png")); + auto pTex = PD::Gfx::LoadTexture(img, img.Width(), img.Height()); while (pOs->Mainloop()) { pOs->ClearViewPort(); PD::Li::ResetPools(); pList.PathRect(pOs->SizeTranslate(0.05), pOs->SizeTranslate(0.4f), 10.f); pList.PathFill(0xff00ffff); + pList.BindTexture(pTex); + pList.DrawRectFilled(pOs->SizeTranslate(PD::fvec2(0.02f, 0.5f)), + pOs->SizeTranslate(PD::fvec2(0.14, 0.3)), 0xffffffff); PD::Gfx::Reset(); PD::Gfx::Draw(pList); pList.Clear(); pOs->SwapBuffers(); } + PD::Gfx::DeleteTexture(pTex); PD::Gfx::Deinit(); pOs->Deinit(); delete pOs; diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index b7d6cb9..a6cd7b8 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -14,7 +14,15 @@ endif() # STB add_library(stb INTERFACE) -target_include_directories(stb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/stb) +target_include_directories(stb + INTERFACE + $ + $ +) +install(TARGETS stb + EXPORT palladiumTargets + INCLUDES DESTINATION include +) if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS" AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "NintendoSwitch") # GLFW