From 7d89ab1c4720081cb7500dbd1ee7242704674e3e Mon Sep 17 00:00:00 2001 From: tobid7 Date: Wed, 18 Mar 2026 15:17:48 +0100 Subject: [PATCH] Add SpirvHelper (Shader cross compilation) - Make OpenGL2 and OpenGL3 use the same base shaders (using SpirvHelper) - Add Transpose func to Mat4 --- .gitmodules | 24 ++- backends/CMakeLists.txt | 85 +++++--- backends/include/pd_system/gfx_opengl2.hpp | 2 - backends/include/pd_system/gfx_opengl3.hpp | 2 - backends/include/pd_system/shaders.hpp | 51 +++++ backends/include/pd_system/spirv-helper.hpp | 36 ++++ backends/source/gfx_opengl2.cpp | 57 ++---- backends/source/gfx_opengl3.cpp | 60 ++---- backends/source/spirv-helper.cpp | 209 ++++++++++++++++++++ include/pd/core/mat.hpp | 10 + vendor/CMakeLists.txt | 25 ++- vendor/glslang | 1 + vendor/spirv-cross | 1 + 13 files changed, 424 insertions(+), 139 deletions(-) create mode 100644 backends/include/pd_system/shaders.hpp create mode 100644 backends/include/pd_system/spirv-helper.hpp create mode 100644 backends/source/spirv-helper.cpp create mode 160000 vendor/glslang create mode 160000 vendor/spirv-cross diff --git a/.gitmodules b/.gitmodules index 777c9cb..7f58658 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,15 @@ -[submodule "vendor/stb"] - path = vendor/stb - url = https://github.com/nothings/stb.git -[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 +[submodule "vendor/stb"] + path = vendor/stb + url = https://github.com/nothings/stb.git +[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 +[submodule "vendor/glslang"] + path = vendor/glslang + url = https://github.com/KhronosGroup/glslang.git +[submodule "vendor/spirv-cross"] + path = vendor/spirv-cross + url = https://github.com/KhronosGroup/SPIRV-Cross.git diff --git a/backends/CMakeLists.txt b/backends/CMakeLists.txt index 95fce20..a1dc6f7 100644 --- a/backends/CMakeLists.txt +++ b/backends/CMakeLists.txt @@ -9,43 +9,45 @@ 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) + 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 + ${CMAKE_CURRENT_SOURCE_DIR}/source/spirv-helper.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> - $<$:PD_ENABLE_CITRO3D> + PUBLIC + $<$:PD_ENABLE_OPENGL2> + $<$:PD_ENABLE_OPENGL3> + $<$:PD_ENABLE_VULKAN> + $<$:PD_ENABLE_DIRECTX9> + $<$:PD_ENABLE_CITRO3D> + $<$,$,$>:PD_ENABLE_SPIRV_HELPER> ) # Palladium @@ -53,20 +55,43 @@ 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 + target_link_libraries(pd-system + PUBLIC + pica::pica + citro3d + ctru + ) +else() + target_link_libraries(pd-system + PUBLIC + spirv-cross-core + spirv-cross-cpp + spirv-cross-glsl + spirv-cross-hlsl + spirv-cross-msl + spirv-cross-reflect + spirv-cross-util + glslang + glslang-default-resource-limits + #OGLCompiler + OSDependent + SPIRV + #SPVRemapper + #HLSL + ) +endif() diff --git a/backends/include/pd_system/gfx_opengl2.hpp b/backends/include/pd_system/gfx_opengl2.hpp index 7423093..c718d2c 100644 --- a/backends/include/pd_system/gfx_opengl2.hpp +++ b/backends/include/pd_system/gfx_opengl2.hpp @@ -39,7 +39,5 @@ class GfxOpenGL2 : public GfxDriverBase { int pLocTex = 0; int pLocAlfa = 0; int pLocProjection = 0; - static const char* pVertCode; - static const char* pFragCode; }; } // namespace PD \ No newline at end of file diff --git a/backends/include/pd_system/gfx_opengl3.hpp b/backends/include/pd_system/gfx_opengl3.hpp index c8f04e3..4639972 100644 --- a/backends/include/pd_system/gfx_opengl3.hpp +++ b/backends/include/pd_system/gfx_opengl3.hpp @@ -39,7 +39,5 @@ class GfxOpenGL3 : public GfxDriverBase { int pLocTex = 0; int pLocAlfa = 0; int pLocProjection = 0; - static const char* pVertCode; - static const char* pFragCode; }; } // namespace PD \ No newline at end of file diff --git a/backends/include/pd_system/shaders.hpp b/backends/include/pd_system/shaders.hpp new file mode 100644 index 0000000..9b1a292 --- /dev/null +++ b/backends/include/pd_system/shaders.hpp @@ -0,0 +1,51 @@ +#pragma once + +namespace PD { +namespace Shaders { +inline static const char* VertCode = R"( + #version 460 + + layout(location = 0) in vec2 pos; + layout(location = 1) in vec2 uv; + layout(location = 2) in vec4 color; + + layout(location = 0) out vec2 oUV; + layout(location = 1) out vec4 oColor; + + // Probably forgot about this matrix and + // searched hours for why the rendering isn't working :/ + layout(set = 0, binding = 0) uniform UBO { + mat4 projection; + } ubo; + + void main() { + gl_Position = ubo.projection*vec4(pos, 0.0, 1.0); + oUV = uv; + oColor = color; + } + )"; + +inline static const char* FragCode = R"( + #version 460 + + layout(location = 0) in vec2 oUV; + layout(location = 1) in vec4 oColor; + + uniform sampler2D tex; + layout(push_constant) uniform PushData { + int alfa; + } push; + + out vec4 FragColor; + + void main() { + vec4 tc = texture(tex, oUV); + if (push.alfa != 0) { + FragColor = vec4(oColor.rgb, tc.a * oColor.a); + } else { + FragColor = tc * oColor; + } + } + )"; +} // namespace Shaders +} // namespace PD \ No newline at end of file diff --git a/backends/include/pd_system/spirv-helper.hpp b/backends/include/pd_system/spirv-helper.hpp new file mode 100644 index 0000000..55ff391 --- /dev/null +++ b/backends/include/pd_system/spirv-helper.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include + +namespace PD { +class SpirvHelper { + public: + enum class Format { + GLSL, + HLSL, + MSL, // Not supported yet + SPIRV, + }; + + enum class Stage { + Vertex = 0, + Geometry = 3, + Fragment = 4, + }; + + SpirvHelper() = default; + ~SpirvHelper() = default; + + static void Init(); + static void Finalize(); + static void SetupResources(TBuiltInResource& resources); + static std::vector GLSL2SPV(Stage stage, const char* code, + bool vulkan_mode = false); + static std::string SPV2GLSL(const std::vector& spirv, int version, + bool es = false); + static std::string SPV2HLSL(const std::vector& spirv, int version); +}; +} // namespace PD \ No newline at end of file diff --git a/backends/source/gfx_opengl2.cpp b/backends/source/gfx_opengl2.cpp index ff5686a..1c2f080 100644 --- a/backends/source/gfx_opengl2.cpp +++ b/backends/source/gfx_opengl2.cpp @@ -6,47 +6,10 @@ #include #include +#include +#include namespace PD { -const char* GfxOpenGL2::pVertCode = R"( - #version 120 - - attribute vec2 pos; - attribute vec2 uv; - attribute vec4 color; - - varying vec2 oUV; - varying vec4 oColor; - - // Probably forgot about this matrix and - // searched hours for why the rendering isn't working :/ - uniform mat4 projection; - - void main() { - gl_Position = projection*vec4(pos, 0.0, 1.0); - oUV = uv; - oColor = color; - } - )"; - -const char* GfxOpenGL2::pFragCode = R"( - #version 120 - - varying vec2 oUV; - varying vec4 oColor; - - uniform sampler2D tex; - uniform bool alfa; - - void main() { - vec4 tc = texture2D(tex, oUV); - if (alfa) { - gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a); - } else { - gl_FragColor = tc * oColor; - } - } - )"; void GfxOpenGL2::pSetupShaderAttribs(u32 shader) { GLint _pos = glGetAttribLocation(shader, "pos"); @@ -67,7 +30,17 @@ void GfxOpenGL2::pSetupShaderAttribs(u32 shader) { } void GfxOpenGL2::SysInit() { - pShader = CreateShaderProgram(pVertCode, pFragCode); + SpirvHelper::Init(); + auto vshader = + SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Vertex, Shaders::VertCode); + auto fshader = + SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Fragment, Shaders::FragCode); + SpirvHelper::Finalize(); + std::string vcode = SpirvHelper::SPV2GLSL(vshader, 110, false); + std::string fcode = SpirvHelper::SPV2GLSL(fshader, 110, false); + PDLOG("Vertex: \n{}", vcode); + PDLOG("Fragment: \n{}", fcode); + pShader = CreateShaderProgram(vcode.c_str(), fcode.c_str()); glUseProgram(pShader); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); @@ -76,8 +49,8 @@ void GfxOpenGL2::SysInit() { pSetupShaderAttribs(pShader); pLocTex = glGetUniformLocation(pShader, "tex"); - pLocAlfa = glGetUniformLocation(pShader, "alfa"); - pLocProjection = glGetUniformLocation(pShader, "projection"); + pLocAlfa = glGetUniformLocation(pShader, "push.alfa"); + pLocProjection = glGetUniformLocation(pShader, "ubo.projection"); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/backends/source/gfx_opengl3.cpp b/backends/source/gfx_opengl3.cpp index 9901030..2e4b812 100644 --- a/backends/source/gfx_opengl3.cpp +++ b/backends/source/gfx_opengl3.cpp @@ -6,52 +6,22 @@ #include #include +#include +#include namespace PD { -const char* GfxOpenGL3::pVertCode = R"( - #version 330 core - - layout(location = 0) in vec2 pos; - layout(location = 1) in vec2 uv; - layout(location = 2) in vec4 color; - - out vec2 oUV; - out vec4 oColor; - - // Probably forgot about this matrix and - // searched hours for why the rendering isn't working :/ - uniform mat4 projection; - - void main() { - gl_Position = projection*vec4(pos, 0.0, 1.0); - oUV = uv; - oColor = color; - } - )"; - -const char* GfxOpenGL3::pFragCode = R"( - #version 330 core - - in vec2 oUV; - in vec4 oColor; - - uniform sampler2D tex; - uniform bool alfa; - - out vec4 FragColor; - - void main() { - vec4 tc = texture(tex, oUV); - if (alfa) { - FragColor = vec4(oColor.rgb, tc.a * oColor.a); - } else { - FragColor = tc * oColor; - } - } - )"; - void GfxOpenGL3::SysInit() { - pShader = CreateShaderProgram(pVertCode, pFragCode); + SpirvHelper::Init(); + auto vshader = + SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Vertex, Shaders::VertCode); + auto fshader = + SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Fragment, Shaders::FragCode); + SpirvHelper::Finalize(); + std::string vcode = SpirvHelper::SPV2GLSL(vshader, 330, false); + std::string fcode = SpirvHelper::SPV2GLSL(fshader, 330, false); + PDLOG("Vertex: \n{}", vcode); + PDLOG("Fragment: \n{}", fcode); + pShader = CreateShaderProgram(vcode.c_str(), fcode.c_str()); glUseProgram(pShader); glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); @@ -72,8 +42,8 @@ void GfxOpenGL3::SysInit() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); pLocTex = glGetUniformLocation(pShader, "tex"); - pLocAlfa = glGetUniformLocation(pShader, "alfa"); - pLocProjection = glGetUniformLocation(pShader, "projection"); + pLocAlfa = glGetUniformLocation(pShader, "push.alfa"); + pLocProjection = glGetUniformLocation(pShader, "ubo.projection"); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/backends/source/spirv-helper.cpp b/backends/source/spirv-helper.cpp new file mode 100644 index 0000000..11ba42f --- /dev/null +++ b/backends/source/spirv-helper.cpp @@ -0,0 +1,209 @@ +#if defined(PD_ENABLE_SPIRV_HELPER) +#include + +#include +#include +#include +#include + +namespace PD { +void SpirvHelper::Init() { glslang::InitializeProcess(); } + +void SpirvHelper::Finalize() { glslang::FinalizeProcess(); } + +void SpirvHelper::SetupResources(TBuiltInResource& resources) { + resources.maxLights = 32; + resources.maxClipPlanes = 6; + resources.maxTextureUnits = 32; + resources.maxTextureCoords = 32; + resources.maxVertexAttribs = 64; + resources.maxVertexUniformComponents = 4096; + resources.maxVaryingFloats = 64; + resources.maxVertexTextureImageUnits = 32; + resources.maxCombinedTextureImageUnits = 80; + resources.maxTextureImageUnits = 32; + resources.maxFragmentUniformComponents = 4096; + resources.maxDrawBuffers = 32; + resources.maxVertexUniformVectors = 128; + resources.maxVaryingVectors = 8; + resources.maxFragmentUniformVectors = 16; + resources.maxVertexOutputVectors = 16; + resources.maxFragmentInputVectors = 15; + resources.minProgramTexelOffset = -8; + resources.maxProgramTexelOffset = 7; + resources.maxClipDistances = 8; + resources.maxComputeWorkGroupCountX = 65535; + resources.maxComputeWorkGroupCountY = 65535; + resources.maxComputeWorkGroupCountZ = 65535; + resources.maxComputeWorkGroupSizeX = 1024; + resources.maxComputeWorkGroupSizeY = 1024; + resources.maxComputeWorkGroupSizeZ = 64; + resources.maxComputeUniformComponents = 1024; + resources.maxComputeTextureImageUnits = 16; + resources.maxComputeImageUniforms = 8; + resources.maxComputeAtomicCounters = 8; + resources.maxComputeAtomicCounterBuffers = 1; + resources.maxVaryingComponents = 60; + resources.maxVertexOutputComponents = 64; + resources.maxGeometryInputComponents = 64; + resources.maxGeometryOutputComponents = 128; + resources.maxFragmentInputComponents = 128; + resources.maxImageUnits = 8; + resources.maxCombinedImageUnitsAndFragmentOutputs = 8; + resources.maxCombinedShaderOutputResources = 8; + resources.maxImageSamples = 0; + resources.maxVertexImageUniforms = 0; + resources.maxTessControlImageUniforms = 0; + resources.maxTessEvaluationImageUniforms = 0; + resources.maxGeometryImageUniforms = 0; + resources.maxFragmentImageUniforms = 8; + resources.maxCombinedImageUniforms = 8; + resources.maxGeometryTextureImageUnits = 16; + resources.maxGeometryOutputVertices = 256; + resources.maxGeometryTotalOutputComponents = 1024; + resources.maxGeometryUniformComponents = 1024; + resources.maxGeometryVaryingComponents = 64; + resources.maxTessControlInputComponents = 128; + resources.maxTessControlOutputComponents = 128; + resources.maxTessControlTextureImageUnits = 16; + resources.maxTessControlUniformComponents = 1024; + resources.maxTessControlTotalOutputComponents = 4096; + resources.maxTessEvaluationInputComponents = 128; + resources.maxTessEvaluationOutputComponents = 128; + resources.maxTessEvaluationTextureImageUnits = 16; + resources.maxTessEvaluationUniformComponents = 1024; + resources.maxTessPatchComponents = 120; + resources.maxPatchVertices = 32; + resources.maxTessGenLevel = 64; + resources.maxViewports = 16; + resources.maxVertexAtomicCounters = 0; + resources.maxTessControlAtomicCounters = 0; + resources.maxTessEvaluationAtomicCounters = 0; + resources.maxGeometryAtomicCounters = 0; + resources.maxFragmentAtomicCounters = 8; + resources.maxCombinedAtomicCounters = 8; + resources.maxAtomicCounterBindings = 1; + resources.maxVertexAtomicCounterBuffers = 0; + resources.maxTessControlAtomicCounterBuffers = 0; + resources.maxTessEvaluationAtomicCounterBuffers = 0; + resources.maxGeometryAtomicCounterBuffers = 0; + resources.maxFragmentAtomicCounterBuffers = 1; + resources.maxCombinedAtomicCounterBuffers = 1; + resources.maxAtomicCounterBufferSize = 16384; + resources.maxTransformFeedbackBuffers = 4; + resources.maxTransformFeedbackInterleavedComponents = 64; + resources.maxCullDistances = 8; + resources.maxCombinedClipAndCullDistances = 8; + resources.maxSamples = 4; + resources.maxMeshOutputVerticesNV = 256; + resources.maxMeshOutputPrimitivesNV = 512; + resources.maxMeshWorkGroupSizeX_NV = 32; + resources.maxMeshWorkGroupSizeY_NV = 1; + resources.maxMeshWorkGroupSizeZ_NV = 1; + resources.maxTaskWorkGroupSizeX_NV = 32; + resources.maxTaskWorkGroupSizeY_NV = 1; + resources.maxTaskWorkGroupSizeZ_NV = 1; + resources.maxMeshViewCountNV = 4; + resources.limits.nonInductiveForLoops = 1; + resources.limits.whileLoops = 1; + resources.limits.doWhileLoops = 1; + resources.limits.generalUniformIndexing = 1; + resources.limits.generalAttributeMatrixVectorIndexing = 1; + resources.limits.generalVaryingIndexing = 1; + resources.limits.generalSamplerIndexing = 1; + resources.limits.generalVariableIndexing = 1; + resources.limits.generalConstantMatrixVectorIndexing = 1; +} + +std::vector SpirvHelper::GLSL2SPV(Stage stage, const char* code, + bool vulkan_mode) { + std::vector spv; + EShLanguage estage = static_cast(stage); + glslang::TShader shader(estage); + glslang::TProgram program; + const char* strings[1]; + TBuiltInResource resources = {}; + SetupResources(resources); + + EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); + + strings[0] = code; + shader.setStrings(strings, 1); + shader.setAutoMapBindings(true); + shader.setAutoMapLocations(true); + + if (!shader.parse(&resources, 100, false, messages)) { + puts(shader.getInfoLog()); + puts(shader.getInfoDebugLog()); + return spv; + } + + program.addShader(&shader); + + if (!program.link(messages)) { + puts(shader.getInfoLog()); + puts(shader.getInfoDebugLog()); + fflush(stdout); + return spv; + } + + glslang::GlslangToSpv(*program.getIntermediate(estage), spv); + return spv; +} + +std::string SpirvHelper::SPV2GLSL(const std::vector& spirv, + int version, bool es) { + std::string ret; + spirv_cross::CompilerGLSL glsl(spirv); + spirv_cross::ShaderResources resources = glsl.get_shader_resources(); + for (auto& resource : resources.stage_inputs) { + glsl.unset_decoration(resource.id, spv::DecorationLocation); + } + for (auto& resource : resources.stage_outputs) { + glsl.unset_decoration(resource.id, spv::DecorationLocation); + } + spirv_cross::CompilerGLSL::Options scoptions; + scoptions.version = version; + scoptions.es = es; + scoptions.emit_uniform_buffer_as_plain_uniforms = true; + scoptions.enable_420pack_extension = false; + glsl.set_common_options(scoptions); + ret = glsl.compile(); + return ret; +} + +std::string SpirvHelper::SPV2HLSL(const std::vector& spirv, + int version) { + std::string ret; + spirv_cross::CompilerHLSL hlsl(spirv); + spirv_cross::CompilerHLSL::Options scoptions; + scoptions.shader_model = version; + scoptions.point_size_compat = false; + scoptions.force_storage_buffer_as_uav = false; + hlsl.set_hlsl_options(scoptions); + ret = hlsl.compile(); + return ret; +} +} // namespace PD +#else +namespace PD { +void SpirvHelper::Init() { glslang::InitializeProcess(); } +void SpirvHelper::Finalize() { glslang::FinalizeProcess(); } +void SpirvHelper::SetupResources(TBuiltInResource& resources) {} +std::vector SpirvHelper::GLSL2SPV(Stage stage, const char* code, + bool vulkan_mode) { + std::vector spv; + return spv; +} +std::string SpirvHelper::SPV2GLSL(const std::vector& spirv, + int version, bool es) { + std::string ret; + return ret; +} +std::string SpirvHelper::SPV2HLSL(const std::vector& spirv, + int version) { + std::string ret; + return ret; +} +} // namespace PD +#endif \ No newline at end of file diff --git a/include/pd/core/mat.hpp b/include/pd/core/mat.hpp index eb87d04..0d59df2 100755 --- a/include/pd/core/mat.hpp +++ b/include/pd/core/mat.hpp @@ -109,6 +109,16 @@ struct PD_API Mat4 { return ret; } + constexpr Mat4 Transpose() const { + Mat4 ret; + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + ret(i, j) = (*this)(j, i); + } + } + return ret; + } + constexpr static Mat4 Ortho(float l, float r, float b, float t, float n, float f) { Mat4 ret; diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index 41e5f4b..f1be3b7 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -1,10 +1,17 @@ cmake_minimum_required(VERSION 3.22) if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libpicasso) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libpicasso) else() - # GLAD - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad) + # GLAD + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad) + # GLSLANG + set(ENABLE_OPT OFF CACHE BOOL "" FORCE) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glslang) + # SPIRV-Cross + set(SPIRV_CROSS_CLI OFF CACHE BOOL "" FORCE) + set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/spirv-cross) endif() # STB @@ -12,9 +19,9 @@ add_library(stb INTERFACE) target_include_directories(stb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/stb) 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 + # 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() diff --git a/vendor/glslang b/vendor/glslang new file mode 160000 index 0000000..09c541e --- /dev/null +++ b/vendor/glslang @@ -0,0 +1 @@ +Subproject commit 09c541ee5b22bbac307987b50d86ec2b4f683d75 diff --git a/vendor/spirv-cross b/vendor/spirv-cross new file mode 160000 index 0000000..a0fba56 --- /dev/null +++ b/vendor/spirv-cross @@ -0,0 +1 @@ +Subproject commit a0fba56c34a6700f1724bf9b751da5b488a3775c