Work at 3ds support and backend upgrades

- Track textures (not sure if this is done tbh)
- Add lithium formatters and move TextureID, TextureFormat and TextureFilter to lithium
- Only include gl-helper if any glDriver is included
- Add Li::Rect for UV stuff
- Add Li::Texture as Info holder (still thinking of making them to ptrs
- Add Check if textures are still loaded on exit
This commit is contained in:
2026-03-18 09:31:47 +01:00
parent d4c59e5b61
commit e04046720b
28 changed files with 791 additions and 243 deletions

5
.clangd Normal file
View File

@@ -0,0 +1,5 @@
CompileFlags:
Add: []
Completion:
HeaderInsertion: Never

3
.gitmodules vendored
View File

@@ -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

View File

@@ -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
$<$<CXX_COMPILER_ID:GNU,Clang>:
PUBLIC $<$<CXX_COMPILER_ID:GNU,Clang>:
-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
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_compile_options(palladium
PRIVATE
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU,Clang>>:-O0 -g>
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU,Clang>>:-O3>
PRIVATE
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU,Clang>>:-O0 -g>
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU,Clang>>:-O3>
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:MSVC>>:/Od /Zi>
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:MSVC>>:/O2>
$<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:MSVC>>:/Od /Zi>
$<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:MSVC>>:/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)

View File

@@ -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
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_compile_options(palladium
PUBLIC
$<$<CXX_COMPILER_ID:GNU,Clang>:
PUBLIC $<$<CXX_COMPILER_ID:GNU,Clang>:
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/source=source
-fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}/include=include
>
)
target_compile_definitions(pd-system
PUBLIC
$<$<BOOL:${PD_ENABLE_OPENGL2}>:PD_ENABLE_OPENGL2>
$<$<BOOL:${PD_ENABLE_OPENGL3}>:PD_ENABLE_OPENGL3>
$<$<BOOL:${PD_ENABLE_VULKAN}>:PD_ENABLE_VULKAN>
$<$<BOOL:${PD_ENABLE_DIRECTX9}>:PD_ENABLE_DIRECTX9>
PUBLIC
$<$<BOOL:${PD_ENABLE_OPENGL2}>:PD_ENABLE_OPENGL2>
$<$<BOOL:${PD_ENABLE_OPENGL3}>:PD_ENABLE_OPENGL3>
$<$<BOOL:${PD_ENABLE_VULKAN}>:PD_ENABLE_VULKAN>
$<$<BOOL:${PD_ENABLE_DIRECTX9}>:PD_ENABLE_DIRECTX9>
$<$<BOOL:${PD_ENABLE_CITRO3D}>: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()

View File

@@ -26,10 +26,11 @@ class GfxCitro3D : public GfxDriverBase<GfxCitro3DConfig> {
void Submit(size_t count, size_t start) override;
void BindTexture(TextureID id) override;
void SysReset() override;
TextureID LoadTexture(const std::vector<PD::u8>& 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<PD::u8>& pixels, int w, int h,
TextureFormat type = TextureFormat::RGBA32,
TextureFilter filter = TextureFilter::Linear) override;
void DeleteTexture(const Li::Texture& tex) override;
private:
struct Impl;

View File

@@ -26,10 +26,11 @@ class GfxDirectX9 : public GfxDriverBase<GfxDirectX9Config> {
void Submit(size_t count, size_t start) override;
void BindTexture(TextureID id) override;
void SysReset() override;
TextureID LoadTexture(const std::vector<PD::u8>& 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<PD::u8>& pixels, int w, int h,
TextureFormat type = TextureFormat::RGBA32,
TextureFilter filter = TextureFilter::Linear) override;
void DeleteTexture(const Li::Texture& tex) override;
private:
struct Impl;

View File

@@ -25,10 +25,11 @@ class GfxOpenGL2 : public GfxDriverBase<GfxOpenGL2Config> {
void Submit(size_t count, size_t start) override;
void BindTexture(TextureID id) override;
void SysReset() override;
TextureID LoadTexture(const std::vector<PD::u8>& 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<PD::u8>& 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);

View File

@@ -25,10 +25,11 @@ class GfxOpenGL3 : public GfxDriverBase<GfxOpenGL3Config> {
void Submit(size_t count, size_t start) override;
void BindTexture(TextureID id) override;
void SysReset() override;
TextureID LoadTexture(const std::vector<PD::u8>& 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<PD::u8>& 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;

View File

@@ -1,25 +1,140 @@
// Well yes, i finally try it
#include <pd/core/core.hpp>
#include <pd/lithium/formatters.hpp>
#include <pd_system/gfx_citro3d.hpp>
#if defined(PD_ENABLE_CITRO3D) // && defined(__3DS__)
#if defined(PD_ENABLE_CITRO3D) && defined(__3DS__)
#include <3ds.h>
#include <citro3d.h>
#include <pd/drivers/drivers.hpp>
#include <pica.hpp>
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<u8> 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<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
if (!impl) return 0;
return 0;
Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& 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<C3D_Tex*>(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<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
Li::Texture GfxCitro3D::LoadTexture(const std::vector<PD::u8>& 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

View File

@@ -1,5 +1,6 @@
// Well yes, i finally try it
#include <pd/lithium/formatters.hpp>
#include <pd_system/gfx_directx9.hpp>
// Sicher ist sicher
@@ -182,9 +183,9 @@ void GfxDirectX9::SysReset() {
impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}
TextureID GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& 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<PD::u8>& 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<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
Li::Texture GfxDirectX9::LoadTexture(const std::vector<PD::u8>& 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

View File

@@ -1,3 +1,4 @@
#include <pd/lithium/formatters.hpp>
#include <pd_system/gfx_opengl2.hpp>
#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<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
Li::Texture GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& 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<PD::u8>& 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<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
Li::Texture GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& 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

View File

@@ -1,4 +1,6 @@
#include <pd/lithium/formatters.hpp>
#include <pd_system/gfx_opengl3.hpp>
#if defined(PD_ENABLE_OPENGL3)
#include <glad/glad.h>
@@ -124,9 +126,9 @@ void GfxOpenGL3::SysReset() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
TextureID GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& 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<PD::u8>& 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<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
Li::Texture GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& 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

View File

@@ -1,3 +1,4 @@
#if defined(PD_ENABLE_OPENGL2) || defined(PD_ENABLE_OPENGL3)
#include <glad/glad.h>
#include <iostream>
@@ -44,3 +45,4 @@ u32 CreateShaderProgram(const char* vert, const char* frag) {
return shaderProgram;
}
} // namespace PD
#endif

View File

@@ -27,12 +27,15 @@ SOFTWARE.
#include <chrono>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <exception>
#include <format>
#include <fstream>
#include <numbers>
#include <pd/pd_p_api.hpp>
#include <string>
#include <unordered_map>
#include <vector>
namespace PD {

View File

@@ -1,6 +1,5 @@
#pragma once
#include <iostream>
#include <memory>
#include <pd/common.hpp>
namespace PD {

View File

@@ -1,5 +1,4 @@
#pragma once
#include <pd/drivers/formatters.hpp>
#include <pd/drivers/gfx.hpp>
#include <pd/drivers/os.hpp>

View File

@@ -1,44 +0,0 @@
#pragma once
#include <pd/drivers/gfx.hpp>
template <>
struct std::formatter<PD::TextureFilter> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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<PD::TextureFormat> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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);
}
};

View File

@@ -3,6 +3,7 @@
#include <pd/core/mat.hpp>
#include <pd/drivers/interface.hpp>
#include <pd/lithium/command.hpp>
#include <pd/lithium/texture.hpp>
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<PD::u8>& pixels, int w, int h,
TextureFormat type = TextureFormat::RGBA32,
TextureFilter filter = TextureFilter::Linear) {
return 0;
virtual Li::Texture LoadTexture(
const std::vector<PD::u8>& 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<Li::Command>& 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<TextureID, Li::Texture> pTextureRegestry;
};
struct DefaultGfxConfig {
@@ -152,11 +146,15 @@ class PD_API Gfx {
static void Draw(const Pool<Li::Command>& commands) {
driver->Draw(commands);
}
static TextureID LoadTexture(const std::vector<PD::u8>& pixels, int w, int h,
TextureFormat type = TextureFormat::RGBA32,
TextureFilter filter = TextureFilter::Linear) {
static Li::Texture LoadTexture(const std::vector<PD::u8>& 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(); }

View File

@@ -0,0 +1,25 @@
#pragma once
#include <pd/core/core.hpp>
#include <pd/lithium/texture.hpp>
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

View File

@@ -0,0 +1,109 @@
#pragma once
#include <pd/lithium/atlas.hpp>
#include <pd/lithium/rect.hpp>
#include <pd/lithium/texture.hpp>
#include <pd/lithium/vertex.hpp>
template <>
struct std::formatter<PD::TextureFilter> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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<PD::TextureFormat> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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<PD::Li::Rect> : std::formatter<std::string> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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<PD::Li::Texture> : std::formatter<std::string> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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<PD::Li::Vertex> : std::formatter<std::string> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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<PD::Li::AtlasState> : std::formatter<std::string> {
constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
template <typename FormatContext>
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);
}
};

149
include/pd/lithium/rect.hpp Normal file
View File

@@ -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 <pd/core/core.hpp>
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

View File

@@ -0,0 +1,46 @@
#pragma once
#include <pd/core/core.hpp>
#include <pd/lithium/rect.hpp>
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

24
source/drivers/gfx.cpp Executable file → Normal file
View File

@@ -1,16 +1,24 @@
#include <pd/drivers/gfx.hpp>
#include <pd/lithium/formatters.hpp>
namespace PD {
PD_API std::unique_ptr<GfxDriver> 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

View File

@@ -1,9 +1,6 @@
#include <pd/core/core.hpp>
#include <pd/lithium/pools.hpp>
#include "pd/common.hpp"
#include "pd/core/pool.hpp"
#include "pd/lithium/vertex.hpp"
namespace PD {
namespace Li {
PD::Pool<Vertex> 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); }

View File

@@ -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()

View File

@@ -1,16 +1,14 @@
#ifndef __3DS__
#include <glad/glad.h>
//////////////////////////
#include <GLFW/glfw3.h>
#endif
#include <format>
#include <iostream>
#include <palladium>
#include <pdsystem>
#include "pd/core/vec2.hpp"
#include "pd/lithium/pools.hpp"
#include "pd/lithium/vertex.hpp"
#ifdef _WIN32
#include <d3d9.h>
#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<PD::u8>(buf, buf + (w * h * 4)), w,
@@ -38,6 +36,7 @@ class App {
public:
App(Driver d = Driver::OpenGL3) : pDriver(d) {
PD::Os::UseDriver<PD::OsDriver>();
#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<PD::GfxCitro3D>();
#endif
PD::Gfx::Init();
PD::Li::InitPools(8192);
#ifdef __3DS__
pTex = LoadTex("sdmc:/icon.png");
#else
pTex = LoadTex("icon.png");
#endif
/*std::vector<PD::u8> 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<PD::Li::Command> pPool;
PD::ptr pTex = 0;
PD::Li::Texture pTex;
Driver pDriver;
#ifdef _WIN32
IDirect3D9* d3d = nullptr;

20
vendor/CMakeLists.txt vendored
View File

@@ -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)
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()

1
vendor/libpicasso vendored Submodule

Submodule vendor/libpicasso added at a6b1e8ddbd