diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..d0d682e --- /dev/null +++ b/.clangd @@ -0,0 +1,5 @@ +CompileFlags: + Add: [] + +Completion: + HeaderInsertion: Never \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index d848d52..777c9cb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "vendor/glfw"] path = vendor/glfw url = https://github.com/glfw/glfw.git +[submodule "vendor/libpicasso"] + path = vendor/libpicasso + url = https://github.com/tobid7/libpicasso diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e30baa..da6d844 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,42 +14,41 @@ option(PD_BUILD_SHARED "Build Shared Library" OFF) option(PD_BUILD_TOOLS "Build Palladium Tools" OFF) 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/mat.cpp - source/core/strings.cpp + # Core + source/core/bits.cpp + source/core/color.cpp + source/core/mat.cpp + source/core/strings.cpp - # Drivers - source/drivers/os.cpp - source/drivers/gfx.cpp + # Drivers + source/drivers/os.cpp + source/drivers/gfx.cpp - # Lithium - source/lithium/pools.cpp + # Lithium + source/lithium/pools.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_compile_options(palladium - PUBLIC - $<$: + PUBLIC $<$: -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include > @@ -58,71 +57,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 + 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/backends/CMakeLists.txt b/backends/CMakeLists.txt index a23c9a7..95fce20 100644 --- a/backends/CMakeLists.txt +++ b/backends/CMakeLists.txt @@ -9,37 +9,43 @@ option(PD_ENABLE_CITRO3D "Enable Citro3D Support (3DS)" OFF) option(PD_ENABLE_VULKAN "Not implemented yet" OFF) if(NOT WIN32) # cause we are not on windows... - set(PD_ENABLE_DIRECTX9 OFF) + set(PD_ENABLE_DIRECTX9 OFF) +endif() +if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") + set(PD_ENABLE_OPENGL2 OFF) + set(PD_ENABLE_OPENGL3 OFF) + set(PD_ENABLE_VULKAN OFF) + set(PD_ENABLE_CITRO3D ON) endif() add_library(pd-system STATIC - ${CMAKE_CURRENT_SOURCE_DIR}/source/gl-helper.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl2.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl3.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_directx9.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_citro3d.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/gl-helper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl2.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_opengl3.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_directx9.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/gfx_citro3d.cpp ) target_include_directories(pd-system - PUBLIC - $ - $ + PUBLIC + $ + $ ) target_compile_options(palladium - PUBLIC - $<$: + PUBLIC $<$: -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include > ) target_compile_definitions(pd-system - PUBLIC - $<$:PD_ENABLE_OPENGL2> - $<$:PD_ENABLE_OPENGL3> - $<$:PD_ENABLE_VULKAN> - $<$:PD_ENABLE_DIRECTX9> + PUBLIC + $<$:PD_ENABLE_OPENGL2> + $<$:PD_ENABLE_OPENGL3> + $<$:PD_ENABLE_VULKAN> + $<$:PD_ENABLE_DIRECTX9> + $<$:PD_ENABLE_CITRO3D> ) # Palladium @@ -47,17 +53,20 @@ target_link_libraries(pd-system PUBLIC palladium::palladium) # glad (if we have any OpenGL version included) if(PD_ENABLE_OPENGL2 OR PD_ENABLE_OPENGL3) - target_link_libraries(pd-system - PUBLIC - glad - ) + target_link_libraries(pd-system + PUBLIC glad + ) endif() # DirectX9 if(PD_ENABLE_DIRECTX9) - target_link_libraries(pd-system - PUBLIC - d3d9 - d3dcompiler - ) + target_link_libraries(pd-system + PUBLIC + d3d9 + d3dcompiler + ) endif() + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") + target_link_libraries(pd-system PUBLIC pica::pica citro3d ctru) +endif() \ No newline at end of file diff --git a/backends/include/pd_system/gfx_citro3d.hpp b/backends/include/pd_system/gfx_citro3d.hpp index 122ace8..13e08c1 100644 --- a/backends/include/pd_system/gfx_citro3d.hpp +++ b/backends/include/pd_system/gfx_citro3d.hpp @@ -26,10 +26,11 @@ class GfxCitro3D : public GfxDriverBase { void Submit(size_t count, size_t start) override; void BindTexture(TextureID id) override; void SysReset() override; - TextureID LoadTexture(const std::vector& pixels, int w, int h, - TextureFormat type = TextureFormat::RGBA32, - TextureFilter filter = TextureFilter::Linear) override; - void DeleteTexture(const TextureID& tex) override; + Li::Texture LoadTexture( + const std::vector& pixels, int w, int h, + TextureFormat type = TextureFormat::RGBA32, + TextureFilter filter = TextureFilter::Linear) override; + void DeleteTexture(const Li::Texture& tex) override; private: struct Impl; diff --git a/backends/include/pd_system/gfx_directx9.hpp b/backends/include/pd_system/gfx_directx9.hpp index 9d50dd3..178eaae 100644 --- a/backends/include/pd_system/gfx_directx9.hpp +++ b/backends/include/pd_system/gfx_directx9.hpp @@ -26,10 +26,11 @@ class GfxDirectX9 : public GfxDriverBase { void Submit(size_t count, size_t start) override; void BindTexture(TextureID id) override; void SysReset() override; - TextureID LoadTexture(const std::vector& pixels, int w, int h, - TextureFormat type = TextureFormat::RGBA32, - TextureFilter filter = TextureFilter::Linear) override; - void DeleteTexture(const TextureID& tex) override; + Li::Texture LoadTexture( + const std::vector& pixels, int w, int h, + TextureFormat type = TextureFormat::RGBA32, + TextureFilter filter = TextureFilter::Linear) override; + void DeleteTexture(const Li::Texture& tex) override; private: struct Impl; diff --git a/backends/include/pd_system/gfx_opengl2.hpp b/backends/include/pd_system/gfx_opengl2.hpp index e53c7f9..7423093 100644 --- a/backends/include/pd_system/gfx_opengl2.hpp +++ b/backends/include/pd_system/gfx_opengl2.hpp @@ -25,10 +25,11 @@ class GfxOpenGL2 : public GfxDriverBase { void Submit(size_t count, size_t start) override; void BindTexture(TextureID id) override; void SysReset() override; - TextureID LoadTexture(const std::vector& pixels, int w, int h, - TextureFormat type = TextureFormat::RGBA32, - TextureFilter filter = TextureFilter::Linear) override; - void DeleteTexture(const TextureID& tex) override; + Li::Texture LoadTexture( + const std::vector& pixels, int w, int h, + TextureFormat type = TextureFormat::RGBA32, + TextureFilter filter = TextureFilter::Linear) override; + void DeleteTexture(const Li::Texture& tex) override; private: void pSetupShaderAttribs(u32 shader); diff --git a/backends/include/pd_system/gfx_opengl3.hpp b/backends/include/pd_system/gfx_opengl3.hpp index da80e53..c8f04e3 100644 --- a/backends/include/pd_system/gfx_opengl3.hpp +++ b/backends/include/pd_system/gfx_opengl3.hpp @@ -25,10 +25,11 @@ class GfxOpenGL3 : public GfxDriverBase { void Submit(size_t count, size_t start) override; void BindTexture(TextureID id) override; void SysReset() override; - TextureID LoadTexture(const std::vector& pixels, int w, int h, - TextureFormat type = TextureFormat::RGBA32, - TextureFilter filter = TextureFilter::Linear) override; - void DeleteTexture(const TextureID& tex) override; + Li::Texture LoadTexture( + const std::vector& pixels, int w, int h, + TextureFormat type = TextureFormat::RGBA32, + TextureFilter filter = TextureFilter::Linear) override; + void DeleteTexture(const Li::Texture& tex) override; private: u32 pShader = 0; diff --git a/backends/source/gfx_citro3d.cpp b/backends/source/gfx_citro3d.cpp index 779a6d8..588d0d2 100644 --- a/backends/source/gfx_citro3d.cpp +++ b/backends/source/gfx_citro3d.cpp @@ -1,25 +1,140 @@ // Well yes, i finally try it +#include +#include #include -#if defined(PD_ENABLE_CITRO3D) // && defined(__3DS__) +#if defined(PD_ENABLE_CITRO3D) && defined(__3DS__) #include <3ds.h> #include #include +#include namespace PD { -struct GfxCitro3D::Impl {}; +const char* LIShaderCTR = R"( +; LI7 Shader +; Constants +.constf myconst(0.0, 1.0, 0.00392156862745, 0.0) +.alias ones myconst.yyyy ; Vector full of ones + +; Uniforms +.fvec projection[4] + +; Outputs +.out out_position position +.out out_color color +.out out_uv texcoord0 + +; Inputs +.alias in_xy v0 +.alias in_uvc v1 +.alias in_col v2 + +.entry vmain +.proc vmain + mov r0.xy, in_xy.xy + mov r0.w, ones + + dp4 out_position.x, projection[0], r0 + dp4 out_position.y, projection[1], r0 + dp4 out_position.z, projection[2], r0 + dp4 out_position.w, projection[3], r0 + + mov out_uv, in_uvc.xy + + mul r1, myconst.zzzz, in_col + mov out_color, r1 + end +.end +)"; + +struct GfxCitro3D::Impl { + C3D_AttrInfo pAttr; + shaderProgram_s pShader; + DVLB_s* pCode; + int uLocProjection = 0; + std::vector pShaderRaw; + + GPU_TEXCOLOR TextureTranslateFormat(TextureFormat fmt) { + switch (fmt) { + case PD::TextureFormat::A8: + return GPU_A8; + case PD::TextureFormat::RGB24: + return GPU_RGB8; + case PD::TextureFormat::RGBA32: + return GPU_RGBA8; + default: + return GPU_RGBA8; + } + } + + int TextureFormat2Bpp(TextureFormat fmt) { + switch (fmt) { + case PD::TextureFormat::A8: + return 1; + case PD::TextureFormat::RGB24: + return 3; + case PD::TextureFormat::RGBA32: + return 4; + default: + return 0; + } + } + + void SetupPixelStage(GPU_TEXCOLOR clr) { + shaderProgramUse(&pShader); + C3D_BindProgram(&pShader); + C3D_SetAttrInfo(&pAttr); + C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvInit(env); + switch (clr) { + case GPU_A4: + case GPU_A8: + case GPU_L4: + case GPU_L8: + C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); + break; + case GPU_RGB565: + C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); + break; + + default: + C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + break; + } + } +}; void GfxCitro3D::SysInit() { if (impl) return; PDLOG("GfxCitro3D::SysInit();"); impl = new Impl(); + impl->pShaderRaw = Pica::AssembleCode(LIShaderCTR); + impl->pCode = DVLB_ParseFile((uint32_t*)impl->pShaderRaw.data(), + impl->pShaderRaw.size()); + shaderProgramInit(&impl->pShader); + shaderProgramSetVsh(&impl->pShader, &impl->pCode->DVLE[0]); + impl->uLocProjection = shaderInstanceGetUniformLocation( + impl->pShader.vertexShader, "projection"); + + AttrInfo_Init(&impl->pAttr); + AttrInfo_AddLoader(&impl->pAttr, 0, GPU_FLOAT, 2); + AttrInfo_AddLoader(&impl->pAttr, 1, GPU_FLOAT, 2); + AttrInfo_AddLoader(&impl->pAttr, 2, GPU_UNSIGNED_BYTE, 4); } void GfxCitro3D::SysDeinit() { if (!impl) return; + shaderProgramFree(&impl->pShader); + DVLB_Free(impl->pCode); delete impl; impl = nullptr; PDLOG("GfxCitro3D::SysDeinit()"); @@ -31,21 +146,74 @@ void GfxCitro3D::Submit(size_t count, size_t start) { void GfxCitro3D::BindTexture(TextureID id) { if (!impl) return; + C3D_TexBind(0, (C3D_Tex*)id); } void GfxCitro3D::SysReset() { if (!impl) return; } -TextureID GfxCitro3D::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { - if (!impl) return 0; - return 0; +Li::Texture GfxCitro3D::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { + if (!impl || w > 1024 || h > 1024) return Li::Texture(); + // Don't check here as check done before + PD::Li::Texture res; + int bpp = impl->TextureFormat2Bpp(type); + ivec2 tex_size(w, h); + // Pow2 + if (!PD::Bits::IsSingleBit(w)) { + tex_size.x = PD::Bits::GetPow2((unsigned int)w); + } + if (!PD::Bits::IsSingleBit(h)) { + tex_size.y = PD::Bits::GetPow2((unsigned int)h); + } + res.SetSize(w, h); + res.SetUV(0.f, 1.f, ((float)w / (float)tex_size.x), + 1.0 - ((float)h / (float)tex_size.y)); + + // Texture Setup + auto fltr = (filter == TextureFilter::Linear ? GPU_NEAREST : GPU_LINEAR); + auto tex_fmt = impl->TextureTranslateFormat(type); + auto tex = new C3D_Tex; + C3D_TexInit(tex, (u16)tex_size.x, (u16)tex_size.y, tex_fmt); + C3D_TexSetFilter(tex, fltr, fltr); + + std::memset((PD::u8*)tex->data, 0x0, tex->size); + + /// Probably Remove this if statement in future + /// This are the things confirmed as working + if (bpp == 3 || bpp == 4 || bpp == 1) { + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + int dst_pos = ((((y >> 3) * ((int)tex_size.x >> 3) + (x >> 3)) << 6) + + ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | + ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) * + bpp; + int src_pos = (y * w + x) * bpp; + /// Best idea i had + for (int i = 0; i < bpp; i++) { + ((u8*)tex->data)[dst_pos + bpp - 1 - i] = pixels[src_pos + i]; + } + } + } + C3D_TexFlush(tex); + } + + tex->border = 0x00000000; + C3D_TexSetWrap(tex, GPU_REPEAT, GPU_REPEAT); + res.SetID((TextureID)tex); + RegisterTexture(res); + PDLOG("GfxCitro3D::LoadTexture -> {{ {} }}, [{}, {}]", res, type, filter); + return res; } -void GfxCitro3D::DeleteTexture(const TextureID& tex) { - if (!tex) return; +void GfxCitro3D::DeleteTexture(const Li::Texture& tex) { + if (!tex.GetID()) return; + UnRegisterTexture(tex); + C3D_Tex* t = reinterpret_cast(tex.GetID()); + C3D_TexDelete(t); + delete t; } } // namespace PD #else @@ -59,11 +227,11 @@ void GfxCitro3D::SysDeinit() {} void GfxCitro3D::Submit(size_t count, size_t start) {} void GfxCitro3D::BindTexture(TextureID id) {} void GfxCitro3D::SysReset() {} -TextureID GfxCitro3D::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { - return 0; +Li::Texture GfxCitro3D::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { + return Li::Texture(); } -void GfxCitro3D::DeleteTexture(const TextureID& tex) {} +void GfxCitro3D::DeleteTexture(const Li::Texture& tex) {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_directx9.cpp b/backends/source/gfx_directx9.cpp index ce7a7d7..d71b745 100644 --- a/backends/source/gfx_directx9.cpp +++ b/backends/source/gfx_directx9.cpp @@ -1,5 +1,6 @@ // Well yes, i finally try it +#include #include // Sicher ist sicher @@ -182,9 +183,9 @@ void GfxDirectX9::SysReset() { impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); } -TextureID GfxDirectX9::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { +Li::Texture GfxDirectX9::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { if (!impl || !impl->Device) return 0; IDirect3DTexture9* tex = nullptr; D3DFORMAT fmt = D3DFMT_A8R8G8B8; @@ -234,15 +235,19 @@ TextureID GfxDirectX9::LoadTexture(const std::vector& pixels, int w, } tex->UnlockRect(0); - - PDLOG("GfxDirectX9::LoadTexture -> [{}] 0x{:X}, [{}, {}]", PD::ivec2(w, h), - (TextureID)tex, type, filter); - return (TextureID)tex; + Li::Texture res; + res.SetID((TextureID)tex); + res.SetSize(w, h); + res.SetUV(0.f, 0.f, 1.f, 1.f); + RegisterTexture(res); + PDLOG("GfxDirectX9::LoadTexture -> {{ {} }}, [{}, {}]", res, type, filter); + return res; } -void GfxDirectX9::DeleteTexture(const TextureID& tex) { - if (!tex) return; - IDirect3DTexture9* t = (IDirect3DTexture9*)tex; +void GfxDirectX9::DeleteTexture(const Li::Texture& tex) { + if (!tex.GetID()) return; + UnRegisterTexture(tex); + IDirect3DTexture9* t = (IDirect3DTexture9*)tex.GetID(); t->Release(); } } // namespace PD @@ -257,11 +262,11 @@ void GfxDirectX9::SysDeinit() {} void GfxDirectX9::Submit(size_t count, size_t start) {} void GfxDirectX9::BindTexture(TextureID id) {} void GfxDirectX9::SysReset() {} -TextureID GfxDirectX9::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { - return 0; +Li::Texture GfxDirectX9::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { + return Li::Texture(); } -void GfxDirectX9::DeleteTexture(const TextureID& tex) {} +void GfxDirectX9::DeleteTexture(const Li::Texture& tex) {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_opengl2.cpp b/backends/source/gfx_opengl2.cpp index 12919b6..ff5686a 100644 --- a/backends/source/gfx_opengl2.cpp +++ b/backends/source/gfx_opengl2.cpp @@ -1,3 +1,4 @@ +#include #include #if defined(PD_ENABLE_OPENGL2) @@ -128,9 +129,9 @@ void GfxOpenGL2::SysReset() { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } -TextureID GfxOpenGL2::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { +Li::Texture GfxOpenGL2::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { GLuint texID; glGenTextures(1, &texID); glBindTexture(GL_TEXTURE_2D, texID); @@ -152,13 +153,18 @@ TextureID GfxOpenGL2::LoadTexture(const std::vector& pixels, int w, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } glBindTexture(GL_TEXTURE_2D, 0); - PDLOG("GfxOpenGL2::LoadTexture -> [{}] {}, [{}, {}]", PD::ivec2(w, h), texID, - type, filter); - return texID; + Li::Texture res; + res.SetID(texID); + res.SetSize(w, h); + res.SetUV(0.f, 0.f, 1.f, 1.f); + RegisterTexture(res); + PDLOG("GfxOpenGL2::LoadTexture -> {{ {} }}, [{}, {}]", res, type, filter); + return res; } -void GfxOpenGL2::DeleteTexture(const TextureID& tex) { - GLuint tex_ = tex; +void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) { + UnregisterTexture(tex); + GLuint tex_ = tex.GetID(); glDeleteTextures(1, &tex_); } } // namespace PD @@ -173,12 +179,12 @@ void GfxOpenGL2::SysDeinit() {} void GfxOpenGL2::Submit(size_t count, size_t start) {} void GfxOpenGL2::BindTexture(TextureID id) {} void GfxOpenGL2::SysReset() {} -TextureID GfxOpenGL2::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { - return 0; +Li::Texture GfxOpenGL2::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { + return Li::Texture(); } -void GfxOpenGL2::DeleteTexture(const TextureID& tex) {} +void GfxOpenGL2::DeleteTexture(const Li::Texture& tex) {} void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gfx_opengl3.cpp b/backends/source/gfx_opengl3.cpp index 407780d..9901030 100644 --- a/backends/source/gfx_opengl3.cpp +++ b/backends/source/gfx_opengl3.cpp @@ -1,4 +1,6 @@ +#include #include + #if defined(PD_ENABLE_OPENGL3) #include @@ -124,9 +126,9 @@ void GfxOpenGL3::SysReset() { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } -TextureID GfxOpenGL3::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { +Li::Texture GfxOpenGL3::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { GLuint texID; glGenTextures(1, &texID); glBindTexture(GL_TEXTURE_2D, texID); @@ -148,13 +150,18 @@ TextureID GfxOpenGL3::LoadTexture(const std::vector& pixels, int w, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } glBindTexture(GL_TEXTURE_2D, 0); - PDLOG("GfxOpenGL3::LoadTexture -> [{}] {}, [{}, {}]", PD::ivec2(w, h), texID, - type, filter); - return texID; + Li::Texture res; + res.SetID(texID); + res.SetSize(w, h); + res.SetUV(0.f, 0.f, 1.f, 1.f); + RegisterTexture(res); + PDLOG("GfxOpenGL3::LoadTexture -> {{ {} }}, [{}, {}]", res, type, filter); + return res; } -void GfxOpenGL3::DeleteTexture(const TextureID& tex) { - GLuint tex_ = tex; +void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) { + UnregisterTexture(tex); + GLuint tex_ = tex.GetID(); glDeleteTextures(1, &tex_); } } // namespace PD @@ -169,12 +176,11 @@ void GfxOpenGL3::SysDeinit() {} void GfxOpenGL3::Submit(size_t count, size_t start) {} void GfxOpenGL3::BindTexture(TextureID id) {} void GfxOpenGL3::SysReset() {} -TextureID GfxOpenGL3::LoadTexture(const std::vector& pixels, int w, - int h, TextureFormat type, - TextureFilter filter) { - return 0; +Li::Texture GfxOpenGL3::LoadTexture(const std::vector& pixels, int w, + int h, TextureFormat type, + TextureFilter filter) { + return Li::Texture(); } -void GfxOpenGL3::DeleteTexture(const TextureID& tex) {} -void GfxOpenGL3::pSetupShaderAttribs(u32 shader) {} +void GfxOpenGL3::DeleteTexture(const Li::Texture& tex) {} } // namespace PD #endif \ No newline at end of file diff --git a/backends/source/gl-helper.cpp b/backends/source/gl-helper.cpp index c118927..8402a6a 100644 --- a/backends/source/gl-helper.cpp +++ b/backends/source/gl-helper.cpp @@ -1,3 +1,4 @@ +#if defined(PD_ENABLE_OPENGL2) || defined(PD_ENABLE_OPENGL3) #include #include @@ -43,4 +44,5 @@ u32 CreateShaderProgram(const char* vert, const char* frag) { return shaderProgram; } -} // namespace PD \ No newline at end of file +} // namespace PD +#endif diff --git a/include/pd/common.hpp b/include/pd/common.hpp index c8104ac..01405d8 100644 --- a/include/pd/common.hpp +++ b/include/pd/common.hpp @@ -27,12 +27,15 @@ SOFTWARE. #include #include #include +#include +#include #include #include #include #include #include #include +#include #include namespace PD { diff --git a/include/pd/core/pool.hpp b/include/pd/core/pool.hpp index 9ad6a2a..391b494 100644 --- a/include/pd/core/pool.hpp +++ b/include/pd/core/pool.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include namespace PD { diff --git a/include/pd/drivers/drivers.hpp b/include/pd/drivers/drivers.hpp index 0295bd7..7ad8d80 100755 --- a/include/pd/drivers/drivers.hpp +++ b/include/pd/drivers/drivers.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include diff --git a/include/pd/drivers/formatters.hpp b/include/pd/drivers/formatters.hpp deleted file mode 100644 index de2af8f..0000000 --- a/include/pd/drivers/formatters.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include - -template <> -struct std::formatter { - constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } - - template - auto format(const PD::TextureFilter& value, FormatContext& ctx) const { - std::string_view ret = "Unknown"; - switch (value) { - case PD::TextureFilter::Linear: - ret = "Linear"; - break; - case PD::TextureFilter::Nearest: - ret = "Nearest"; - break; - } - return std::format_to(ctx.out(), "{}", ret); - } -}; - -template <> -struct std::formatter { - constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } - - template - auto format(const PD::TextureFormat& value, FormatContext& ctx) const { - std::string_view ret = "Unknown"; - switch (value) { - case PD::TextureFormat::RGBA32: - ret = "RGBA32"; - break; - case PD::TextureFormat::RGB24: - ret = "RGB24"; - break; - case PD::TextureFormat::A8: - ret = "A8"; - break; - } - return std::format_to(ctx.out(), "{}", ret); - } -}; \ No newline at end of file diff --git a/include/pd/drivers/gfx.hpp b/include/pd/drivers/gfx.hpp index a1a9dd3..6cf6e43 100755 --- a/include/pd/drivers/gfx.hpp +++ b/include/pd/drivers/gfx.hpp @@ -3,6 +3,7 @@ #include #include #include +#include using LiBackendFlags = PD::u32; enum LiBackendFlags_ { @@ -11,23 +12,12 @@ enum LiBackendFlags_ { }; namespace PD { -using TextureID = ptr; -enum class TextureFilter { - Linear, - Nearest, -}; - -enum class TextureFormat { - RGBA32, - RGB24, - A8, -}; // Pre interface class class PD_API GfxDriver : public DriverInterface { public: GfxDriver(std::string_view name); - virtual ~GfxDriver() = default; + virtual ~GfxDriver(); virtual void Init() {} virtual void Deinit() { SysDeinit(); } @@ -36,12 +26,13 @@ class PD_API GfxDriver : public DriverInterface { void SetViewPort(int x, int y); virtual void BindTexture(TextureID id) {} void Reset(); - virtual TextureID LoadTexture(const std::vector& pixels, int w, int h, - TextureFormat type = TextureFormat::RGBA32, - TextureFilter filter = TextureFilter::Linear) { - return 0; + virtual Li::Texture LoadTexture( + const std::vector& pixels, int w, int h, + TextureFormat type = TextureFormat::RGBA32, + TextureFilter filter = TextureFilter::Linear) { + return Li::Texture(); } - virtual void DeleteTexture(const TextureID& tex) {} + virtual void DeleteTexture(const Li::Texture& tex) {} virtual void Draw(const Pool& commands) {} protected: @@ -50,6 +41,8 @@ class PD_API GfxDriver : public DriverInterface { virtual void SysReset() {} virtual void Submit(size_t count, size_t start) {} virtual void ResetPools() = 0; + void RegisterTexture(const Li::Texture& tex); + void UnregisterTexture(const Li::Texture& tex); // Counters size_t CountDrawcalls = 0; @@ -61,6 +54,7 @@ class PD_API GfxDriver : public DriverInterface { TextureID CurrentTex = 0; Mat4 Projection; ivec2 ViewPort; + std::unordered_map pTextureRegestry; }; struct DefaultGfxConfig { @@ -152,11 +146,15 @@ class PD_API Gfx { static void Draw(const Pool& commands) { driver->Draw(commands); } - static TextureID LoadTexture(const std::vector& pixels, int w, int h, - TextureFormat type = TextureFormat::RGBA32, - TextureFilter filter = TextureFilter::Linear) { + static Li::Texture LoadTexture(const std::vector& pixels, int w, + int h, + TextureFormat type = TextureFormat::RGBA32, + TextureFilter filter = TextureFilter::Linear) { return driver->LoadTexture(pixels, w, h, type, filter); } + static void DeleteTexture(const Li::Texture& tex) { + driver->DeleteTexture(tex); + } static const char* GetDriverName() { return driver->GetName(); } diff --git a/include/pd/lithium/atlas.hpp b/include/pd/lithium/atlas.hpp new file mode 100644 index 0000000..124fdf9 --- /dev/null +++ b/include/pd/lithium/atlas.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +namespace PD { +namespace Li { +enum class AtlasState { + Invalid, + ReqCreate, + ReqUpdate, + ReqDestroy, +}; + +class Atlas { + public: + Atlas() {} + ~Atlas() {} + + private: + AtlasState pState = AtlasState::Invalid; + TextureID pID; +}; +} // namespace Li +} // namespace PD \ No newline at end of file diff --git a/include/pd/lithium/formatters.hpp b/include/pd/lithium/formatters.hpp new file mode 100644 index 0000000..8e51c6a --- /dev/null +++ b/include/pd/lithium/formatters.hpp @@ -0,0 +1,109 @@ +#pragma once + +#include +#include +#include +#include + +template <> +struct std::formatter { + constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const PD::TextureFilter& value, FormatContext& ctx) const { + std::string_view ret = "Unknown"; + switch (value) { + case PD::TextureFilter::Linear: + ret = "Linear"; + break; + case PD::TextureFilter::Nearest: + ret = "Nearest"; + break; + } + return std::format_to(ctx.out(), "{}", ret); + } +}; + +template <> +struct std::formatter { + constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const PD::TextureFormat& value, FormatContext& ctx) const { + std::string_view ret = "Unknown"; + switch (value) { + case PD::TextureFormat::RGBA32: + ret = "RGBA32"; + break; + case PD::TextureFormat::RGB24: + ret = "RGB24"; + break; + case PD::TextureFormat::A8: + ret = "A8"; + break; + } + return std::format_to(ctx.out(), "{}", ret); + } +}; + +template <> +struct std::formatter : std::formatter { + constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const PD::Li::Rect& value, FormatContext& ctx) const { + // {l, t, r, t, l, b, r, b} + return std::format_to(ctx.out(), "{}, {}, {}, {}, {}, {}, {}, {}", + value.Top.x, value.Top.y, value.Top.z, value.Top.w, + value.Bot.x, value.Bot.y, value.Bot.z, value.Bot.w); + } +}; + +template <> +struct std::formatter : std::formatter { + constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const PD::Li::Texture& value, FormatContext& ctx) const { + // {ID, [w, h], [l, t, r, t, l, b, r, b]} + return std::format_to(ctx.out(), "{}, [{}], [{}]", value.GetID(), + value.GetSize(), value.GetUV()); + } +}; + +template <> +struct std::formatter : std::formatter { + constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const PD::Li::Vertex& value, FormatContext& ctx) const { + // { [x, y], [u, v], colorhex } + return std::format_to(ctx.out(), "[{}], [{}], #{:08X}", value.pos, value.uv, + value.color); + } +}; + +template <> +struct std::formatter : std::formatter { + constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const PD::Li::AtlasState& value, FormatContext& ctx) const { + std::string_view ret = "Unknown"; + switch (value) { + case PD::Li::AtlasState::Invalid: + ret = "Invalid"; + break; + case PD::Li::AtlasState::ReqCreate: + ret = "RequestCreate"; + break; + case PD::Li::AtlasState::ReqUpdate: + ret = "RequestUpdate"; + break; + case PD::Li::AtlasState::ReqDestroy: + ret = "RequestDestroy"; + break; + } + return std::format_to(ctx.out(), "{}", ret); + } +}; \ No newline at end of file diff --git a/include/pd/lithium/rect.hpp b/include/pd/lithium/rect.hpp new file mode 100644 index 0000000..ae61f0a --- /dev/null +++ b/include/pd/lithium/rect.hpp @@ -0,0 +1,149 @@ +#pragma once + +/* +MIT License +Copyright (c) 2024 - 2026 René Amthor (tobid7) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +#include + +namespace PD { +namespace Li { +class Rect { + public: + Rect() : Top(0), Bot(0) {} + ~Rect() = default; + /** + * Constructor that initializes the rectangle using top and bottom positions. + * @param t Top left and right corner positions. + * @param b Bottom left and right corner positions. + */ + Rect(const fvec4& t, const fvec4& b) { + Top = t; + Bot = b; + } + /** + * Constructor that initializes the rectangle using individual corner + * positions. + * @param tl Top left corner position. + * @param tr Top right corner position. + * @param bl Bottom left corner position. + * @param br Bottom right corner position. + */ + Rect(const fvec2& tl, const fvec2& tr, const fvec2& bl, const fvec2& br) { + Top = fvec4(tl, tr); + Bot = fvec4(bl, br); + } + + /** + * Constructor that initializes the rectangle using a UV mapping vector. + * + * - The old API used vec4 for UV mapping. + * - Spritesheets have rotated images, so this was updated to use Rect for UV. + * + * @param uv Vec4 UV map. + */ + Rect(const fvec4& uv) { + Top = vec4(uv.x, uv.y, uv.z, uv.y); + Bot = vec4(uv.x, uv.w, uv.z, uv.w); + } + + /** + * Get the top-left corner position. + * @return Top-left position as vec2. + */ + fvec2 TopLeft() const { return fvec2(Top.x, Top.y); } + /** + * Get the top-right corner position. + * @return Top-right position as vec2. + */ + fvec2 TopRight() const { return fvec2(Top.z, Top.w); } + /** + * Get the bottom-left corner position. + * @return Bottom-left position as vec2. + */ + fvec2 BotLeft() const { return fvec2(Bot.x, Bot.y); } + /** + * Get the bottom-right corner position. + * @return Bottom-right position as vec2. + */ + fvec2 BotRight() const { return fvec2(Bot.z, Bot.w); } + + /** + * Set the top-left corner position. + * @param v New top-left position. + * @return Reference to the updated Rect. + */ + Rect& TopLeft(const fvec2& v) { + Top.x = v.x; + Top.y = v.y; + return *this; + } + + /** + * Set the top-right corner position. + * @param v New top-right position. + * @return Reference to the updated Rect. + */ + Rect& TopRight(const fvec2& v) { + Top.z = v.x; + Top.w = v.y; + return *this; + } + + /** + * Set the bottom-left corner position. + * @param v New bottom-left position. + * @return Reference to the updated Rect. + */ + Rect& BotLeft(const fvec2& v) { + Bot.x = v.x; + Bot.y = v.y; + return *this; + } + + /** + * Set the bottom-right corner position. + * @param v New bottom-right position. + * @return Reference to the updated Rect. + */ + Rect& BotRight(const fvec2& v) { + Bot.z = v.x; + Bot.w = v.y; + return *this; + } + + bool operator==(const Rect& r) const { return Top == r.Top && Bot == r.Bot; } + + void SwapVec2XY() { + Top.SwapXY(); + Top.SwapZW(); + Bot.SwapXY(); + Bot.SwapZW(); + } + + /** Data Section */ + + fvec4 Top; + fvec4 Bot; +}; +} // namespace Li +} // namespace PD \ No newline at end of file diff --git a/include/pd/lithium/texture.hpp b/include/pd/lithium/texture.hpp new file mode 100644 index 0000000..9b476e8 --- /dev/null +++ b/include/pd/lithium/texture.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +namespace PD { +using TextureID = ptr; +enum class TextureFilter { + Linear, + Nearest, +}; + +enum class TextureFormat { + RGBA32, + RGB24, + A8, +}; +namespace Li { +class Texture { + public: + Texture() : pID(0), pSize(0, 0), pUV(fvec4(0, 0, 1, 1)) {} + Texture(TextureID id, ivec2 size) + : pID(id), pSize(size), pUV(fvec4(0, 0, 1, 1)) {} + + const ivec2& GetSize() const { return pSize; } + TextureID GetID() { return pID; } + const TextureID& GetID() const { return pID; } + const Rect& GetUV() const { return pUV; } + + void SetSize(int x, int y) { + pSize.x = x; + pSize.y = y; + } + void SetSize(const ivec2& size) { pSize = size; } + void SetID(TextureID id) { pID = id; } + void SetUV(const Rect& uv) { pUV = uv; } + void SetUV(const fvec4& uv) { pUV = uv; } + void SetUV(float t, float l, float b, float r) { SetUV(fvec4(t, l, b, r)); } + + private: + TextureID pID; + ivec2 pSize; + Rect pUV; +}; +} // namespace Li +} // namespace PD \ No newline at end of file diff --git a/source/drivers/gfx.cpp b/source/drivers/gfx.cpp old mode 100755 new mode 100644 index dfce080..bf1558b --- a/source/drivers/gfx.cpp +++ b/source/drivers/gfx.cpp @@ -1,16 +1,24 @@ #include +#include namespace PD { PD_API std::unique_ptr Gfx::driver; PD_API GfxDriver::GfxDriver(std::string_view name) : DriverInterface(name) {} +PD_API GfxDriver::~GfxDriver() { + if (pTextureRegestry.size()) { + PDLOG("GfxDriver: {} is still holding {} texture{}!", GetName(), + pTextureRegestry.size(), (pTextureRegestry.size() == 1 ? "" : "s")); + } +} + PD_API void GfxDriver::SetViewPort(const ivec2& size) { ViewPort = size; Projection = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f); } -PD_API void GfxDriver::SetViewPort(int x, int y) { +PD_API void GfxDriver::SetViewPort(int x, int y) { ViewPort.x = x; ViewPort.y = y; Projection = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f); @@ -22,4 +30,18 @@ PD_API void GfxDriver::Reset() { ResetPools(); SysReset(); } + +PD_API void GfxDriver::RegisterTexture(const Li::Texture& tex) { + pTextureRegestry[tex.GetID()] = tex; +} + +PD_API void GfxDriver::UnregisterTexture(const Li::Texture& tex) { + if (pTextureRegestry.count(tex.GetID())) { + pTextureRegestry.erase(pTextureRegestry.find(tex.GetID())); + PDLOG("GfxDriver: Texture {{ {} }} has been deleted!", tex); + } else { + PDLOG("GfxDriver: WARNING Texture {{ {} }} does not exist in regestry!", + tex); + } +} } // namespace PD \ No newline at end of file diff --git a/source/lithium/pools.cpp b/source/lithium/pools.cpp index 256af19..2bb21c2 100644 --- a/source/lithium/pools.cpp +++ b/source/lithium/pools.cpp @@ -1,9 +1,6 @@ +#include #include -#include "pd/common.hpp" -#include "pd/core/pool.hpp" -#include "pd/lithium/vertex.hpp" - namespace PD { namespace Li { PD::Pool pVtxPool; @@ -14,7 +11,9 @@ PD_API void InitPools(size_t max_vertices) { pIdxPool.Init(max_vertices * 2); } -PD_API Vertex* AllocateVertices(size_t count) { return pVtxPool.Allocate(count); } +PD_API Vertex* AllocateVertices(size_t count) { + return pVtxPool.Allocate(count); +} PD_API u16* AllocateIndices(size_t count) { return pIdxPool.Allocate(count); } diff --git a/tests/gfx/CMakeLists.txt b/tests/gfx/CMakeLists.txt index 8f48b51..5e2d4ea 100644 --- a/tests/gfx/CMakeLists.txt +++ b/tests/gfx/CMakeLists.txt @@ -3,4 +3,8 @@ cmake_minimum_required(VERSION 3.22) project(gfx-tests) add_executable(gfx-tests ${CMAKE_CURRENT_SOURCE_DIR}/source/main.cpp) -target_link_libraries(gfx-tests PRIVATE palladium::palladium pd-system glfw stb) +target_link_libraries(gfx-tests PRIVATE palladium::palladium pd-system stb) + +if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") + target_link_libraries(gfx-tests PRIVATE glfw) +endif() diff --git a/tests/gfx/source/main.cpp b/tests/gfx/source/main.cpp index 7ebae17..217b212 100644 --- a/tests/gfx/source/main.cpp +++ b/tests/gfx/source/main.cpp @@ -1,16 +1,14 @@ +#ifndef __3DS__ #include ////////////////////////// #include +#endif #include #include #include #include -#include "pd/core/vec2.hpp" -#include "pd/lithium/pools.hpp" -#include "pd/lithium/vertex.hpp" - #ifdef _WIN32 #include #define GLFW_EXPOSE_NATIVE_WIN32 @@ -27,7 +25,7 @@ enum class Driver { DirectX9 = 3, }; -PD::TextureID LoadTex(const std::string& path) { +PD::Li::Texture LoadTex(const std::string& path) { int w, h, c; stbi_uc* buf = stbi_load(path.c_str(), &w, &h, &c, 4); return PD::Gfx::LoadTexture(std::vector(buf, buf + (w * h * 4)), w, @@ -38,6 +36,7 @@ class App { public: App(Driver d = Driver::OpenGL3) : pDriver(d) { PD::Os::UseDriver(); +#ifndef __3DS__ glfwInit(); std::string winname = "gfx_test"; if (d == Driver::OpenGL2) { @@ -80,9 +79,16 @@ class App { } #endif glfwSwapInterval(1); +#else + PD::Gfx::UseDriver(); +#endif PD::Gfx::Init(); PD::Li::InitPools(8192); +#ifdef __3DS__ + pTex = LoadTex("sdmc:/icon.png"); +#else pTex = LoadTex("icon.png"); +#endif /*std::vector img(16 * 16 * 4, 0xff); pTex = PD::Gfx::LoadTexture(img, 16, 16);*/ std::cout << "GfxDriver: " << PD::Gfx::GetDriverName() << std::endl; @@ -92,18 +98,27 @@ class App { cmd->Add(0, 1, 2); cmd->Add(0, 2, 3); cmd->Add(PD::Li::Vertex(PD::fvec2(0, 0), PD::fvec2(0, 0), 0xffffffff)); - cmd->Add(PD::Li::Vertex(PD::fvec2(256, 0), PD::fvec2(1, 0), 0xffffffff)); - cmd->Add(PD::Li::Vertex(PD::fvec2(256, 256), PD::fvec2(1, 1), 0xffffffff)); - cmd->Add(PD::Li::Vertex(PD::fvec2(0, 256), PD::fvec2(0, 1), 0xffffffff)); - cmd->Tex = pTex; + cmd->Add(PD::Li::Vertex(PD::fvec2(pTex.GetSize().x, 0), PD::fvec2(1, 0), + 0xffffffff)); + cmd->Add(PD::Li::Vertex(PD::fvec2(pTex.GetSize().x, pTex.GetSize().y), + PD::fvec2(1, 1), 0xffffffff)); + cmd->Add(PD::Li::Vertex(PD::fvec2(0, pTex.GetSize().y), PD::fvec2(0, 1), + 0xffffffff)); + cmd->Tex = pTex.GetID(); } ~App() { + PD::Gfx::DeleteTexture(pTex); PD::Gfx::Deinit(); +#ifndef __3DS__ glfwDestroyWindow(window); glfwTerminate(); +#endif } void Run() { +#ifdef __3DS__ + while (aptMainLoop()) { +#else while (!glfwWindowShouldClose(window)) { if (pDriver == Driver::OpenGL2 || pDriver == Driver::OpenGL3) { glClearColor(0.1, 0.1, 0.1, 0.1); @@ -118,9 +133,12 @@ class App { } #endif } +#endif PD::Gfx::Reset(); PD::Gfx::SetViewPort(1280, 720); PD::Gfx::Draw(pPool); +#ifdef __3DS__ +#else glfwPollEvents(); if (pDriver == Driver::DirectX9) { #ifdef _WIN32 @@ -132,13 +150,16 @@ class App { } else { glfwSwapBuffers(window); } +#endif } } private: +#ifndef __3DS__ GLFWwindow* window = nullptr; +#endif PD::Pool pPool; - PD::ptr pTex = 0; + PD::Li::Texture pTex; Driver pDriver; #ifdef _WIN32 IDirect3D9* d3d = nullptr; diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index 64cdd42..41e5f4b 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -1,14 +1,20 @@ cmake_minimum_required(VERSION 3.22) -# GLAD -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad) +if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libpicasso) +else() + # GLAD + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad) +endif() # STB add_library(stb INTERFACE) target_include_directories(stb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/stb) -# GLFW -set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "") -set(GLFW_BUILD_TESTS OFF CACHE BOOL "") -set(GLFW_BUILD_DOCS OFF CACHE BOOL "") -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glfw) \ No newline at end of file +if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") + # GLFW + set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "") + set(GLFW_BUILD_TESTS OFF CACHE BOOL "") + set(GLFW_BUILD_DOCS OFF CACHE BOOL "") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glfw) +endif() \ No newline at end of file diff --git a/vendor/libpicasso b/vendor/libpicasso new file mode 160000 index 0000000..a6b1e8d --- /dev/null +++ b/vendor/libpicasso @@ -0,0 +1 @@ +Subproject commit a6b1e8ddbda00335e5e5aac646a6bcc224a084b3