diff --git a/engine/brush.cpp b/engine/brush.cpp index fbc4740..6176fb4 100644 --- a/engine/brush.cpp +++ b/engine/brush.cpp @@ -133,7 +133,9 @@ void CBrushRendering::Init() {"shaders/brush_vert.spv", SHADER_TYPE_VERTEX}, {"shaders/brush_frag.spv", SHADER_TYPE_FRAGMENT}, }, - {}, 64, + {}, 64, + 20, + {{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32Z32}, {12,1,EVertexFormat::VERTEX_FORMAT_X32Y32}}, {EImageFormat::IMAGE_FORMAT_R8G8B8A8} ); }; diff --git a/engine/ml_video.cpp b/engine/ml_video.cpp index 0722080..cecfb9b 100644 --- a/engine/ml_video.cpp +++ b/engine/ml_video.cpp @@ -6,24 +6,55 @@ #include "tier1/utlvector.h" #include "tier0/platform.h" #include "rendering.h" +#include "ml_video.h" mat4 g_cameraView; +class CMlBuffer: public IBuffer +{ +public: + void *Map() override; + void Unmap() override; + MTL::Buffer *m_buffer; +}; + +void *CMlBuffer::Map() +{ + return m_buffer->contents(); +} + +void CMlBuffer::Unmap() +{ + +} + IStorageBuffer *IRenderer::CreateStorageBuffer( uint32_t uSize ) { + CMlBuffer *pBuffer = new CMlBuffer; + pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared); + return pBuffer; } IUniformBuffer *IRenderer::CreateUniformBuffer( uint32_t uSize ) { + CMlBuffer *pBuffer = new CMlBuffer; + pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared); + return pBuffer; } IVertexBuffer *IRenderer::CreateVertexBuffer( uint32_t uSize ) { + CMlBuffer *pBuffer = new CMlBuffer; + pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared); + return pBuffer; } IIndexBuffer *IRenderer::CreateIndexBuffer( uint32_t uSize ) { + CMlBuffer *pBuffer = new CMlBuffer; + pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared); + return pBuffer; } @@ -96,6 +127,8 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline( CUtlVector shaders, CUtlVector inputs, uint32_t nConstantsSize, + uint32_t nVertexSize, + CUtlVector vertexFormat, CUtlVector outputFormats ) { diff --git a/engine/ml_video.h b/engine/ml_video.h new file mode 100644 index 0000000..0e8d7eb --- /dev/null +++ b/engine/ml_video.h @@ -0,0 +1,12 @@ +#ifndef ML_VIDEO_H +#define ML_VIDEO_H + +#include "Metal/Metal.hpp" +#include "QuartzCore/QuartzCore.hpp" + +extern CA::MetalLayer *g_mlLayer; +extern MTL::Device *g_mlDevice; +extern MTL::CommandQueue *g_mlCommandQueue; +extern NS::AutoreleasePool *g_mlPool; + +#endif diff --git a/engine/ml_videosdl.cpp b/engine/ml_videosdl.cpp index 501fe18..e16af3a 100644 --- a/engine/ml_videosdl.cpp +++ b/engine/ml_videosdl.cpp @@ -11,6 +11,7 @@ #define CA_PRIVATE_IMPLEMENTATION #include "tier0/minmax_off.h" +#include "QuartzCore/CAMetalLayer.hpp" #include "Metal/Metal.hpp" #include "SDL3/SDL.h" @@ -19,7 +20,30 @@ #include "SDL3/SDL_events.h" #include "tier0/minmax.h" +char g_bConfigNotify = 0; +uint32_t g_nWindowWidth = 1280; +uint32_t g_nWindowHeight = 720; + SDL_Window *g_window; +SDL_MetalView g_mlView; +CA::MetalLayer *g_mlLayer; +MTL::Device *g_mlDevice; +MTL::CommandQueue *g_mlCommandQueue; +NS::AutoreleasePool *g_mlPool; + +#if defined(__APPLE__) && defined(__MACH__) +#include "TargetConditionals.h" +#if TARGET_OS_IPHONE +// iOS +#define SDL_METAL_VIEW UI::View +#define STBI_NO_THREAD_LOCALS +#else +// macOS +#define SDL_METAL_VIEW NS::View +#endif +#else +// Other platforms +#endif void IInput::SetMouseMode( EMouseMode mode ) { @@ -34,12 +58,131 @@ void IInput::SetMouseMode( EMouseMode mode ) } } +EInputKey ISDL_KeyName(SDL_Keycode key) +{ + switch(key) + { + case SDLK_ESCAPE: return KEY_ESCAPE; + + case SDLK_1: return KEY_1; + case SDLK_2: return KEY_2; + case SDLK_3: return KEY_3; + case SDLK_4: return KEY_4; + case SDLK_5: return KEY_5; + case SDLK_6: return KEY_6; + case SDLK_7: return KEY_7; + case SDLK_8: return KEY_8; + case SDLK_9: return KEY_9; + case SDLK_0: return KEY_0; + + case SDLK_A: return KEY_A; + case SDLK_B: return KEY_B; + case SDLK_C: return KEY_C; + case SDLK_D: return KEY_D; + case SDLK_E: return KEY_E; + case SDLK_F: return KEY_F; + case SDLK_G: return KEY_G; + case SDLK_H: return KEY_H; + case SDLK_I: return KEY_I; + case SDLK_J: return KEY_J; + case SDLK_K: return KEY_K; + case SDLK_L: return KEY_L; + case SDLK_M: return KEY_M; + case SDLK_N: return KEY_N; + case SDLK_O: return KEY_O; + case SDLK_P: return KEY_P; + case SDLK_Q: return KEY_Q; + case SDLK_R: return KEY_R; + case SDLK_S: return KEY_S; + case SDLK_T: return KEY_T; + case SDLK_U: return KEY_U; + case SDLK_V: return KEY_V; + case SDLK_W: return KEY_W; + case SDLK_X: return KEY_X; + case SDLK_Y: return KEY_Y; + case SDLK_Z: return KEY_Z; + } + return KEY_NONE; +}; + +void IVideo_HandleEvents() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) + { + SDL_KeyboardEvent *key = &event.key; + SDL_MouseMotionEvent *motion = &event.motion; + switch (event.type) + { + case SDL_EVENT_WINDOW_RESIZED: + g_nWindowWidth = event.window.data1; + g_nWindowHeight = event.window.data2; + g_bConfigNotify = 2; + break; + case SDL_EVENT_KEY_DOWN: + if (!key->repeat) + IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_DOWN); + break; + case SDL_EVENT_KEY_UP: + key = &event.key; + if (!key->repeat) + IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_UP); + break; + case SDL_EVENT_MOUSE_MOTION: + IInput::AxisEvent(AXIS_MOUSE_X, motion->yrel*0.022); + IInput::AxisEvent(AXIS_MOUSE_Y, -motion->xrel*0.022); + break; + } + }; +}; + void IVideo::Init() { - if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) - V_printf("%s\n",SDL_GetError()); - g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_VULKAN); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); + g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_METAL); + g_mlView = SDL_Metal_CreateView(g_window); + g_mlLayer = (CA::MetalLayer*)SDL_Metal_GetLayer(g_mlView); + + g_mlDevice = MTL::CreateSystemDefaultDevice(); + + g_mlLayer->setDevice(g_mlDevice); + g_mlLayer->setPixelFormat(MTL::PixelFormatBGRA8Unorm); + + g_mlCommandQueue = g_mlDevice->newCommandQueue(); + + g_mlLayer->setDrawableSize(CGSizeMake(1280, 720)); + } void IVideo::Frame( float fDelta ) { + IVideo_HandleEvents(); + + NS::AutoreleasePool *pool = NS::AutoreleasePool::alloc()->init(); + int w, h; + SDL_GetWindowSizeInPixels(g_window, &w, &h); + g_mlLayer->setDrawableSize(CGSizeMake(w, h)); + + CA::MetalDrawable *drawable = g_mlLayer->nextDrawable(); + if (!drawable) + return; + + MTL::CommandBuffer *commandBuffer = g_mlCommandQueue->commandBuffer(); + + MTL::RenderPassDescriptor *renderPass = MTL::RenderPassDescriptor::alloc()->init(); + renderPass->colorAttachments()->object(0)->setTexture(drawable->texture()); + renderPass->colorAttachments()->object(0)->setLoadAction(MTL::LoadActionClear); + renderPass->colorAttachments()->object(0)->setStoreAction(MTL::StoreActionStore); + renderPass->colorAttachments()->object(0)->setClearColor(MTL::ClearColor(0.0, 0, 1.0, 1.0)); + MTL::RenderCommandEncoder *renderEncoder = commandBuffer->renderCommandEncoder(renderPass); + renderEncoder->endEncoding(); + + commandBuffer->presentDrawable(drawable); + commandBuffer->commit(); + pool->release(); } + +void IVideo::Deinit() +{ + g_mlCommandQueue->release(); + g_mlDevice->release(); +}; diff --git a/engine/vk_video.cpp b/engine/vk_video.cpp index 21aa51c..0f11a74 100644 --- a/engine/vk_video.cpp +++ b/engine/vk_video.cpp @@ -65,6 +65,35 @@ VkFormat IRenderer_FormatToVk( EImageFormat format ) } }; +VkFormat IRenderer_VertexToVk( EVertexFormat format ) +{ + switch (format) + { + case VERTEX_FORMAT_X16: return VK_FORMAT_R16_SFLOAT; + case VERTEX_FORMAT_X16Y16: return VK_FORMAT_R16G16_SFLOAT; + case VERTEX_FORMAT_X16Y16Z16: return VK_FORMAT_R16G16B16_SFLOAT; + case VERTEX_FORMAT_X16Y16Z16W16: return VK_FORMAT_R16G16B16A16_SFLOAT; + case VERTEX_FORMAT_X32: return VK_FORMAT_R32_SFLOAT; + case VERTEX_FORMAT_X32Y32: return VK_FORMAT_R32G32_SFLOAT; + case VERTEX_FORMAT_X32Y32Z32: return VK_FORMAT_R32G32B32_SFLOAT; + case VERTEX_FORMAT_X32Y32Z32W32: return VK_FORMAT_R32G32B32A32_SFLOAT; + } +}; +uint32_t IRenderer_VertexToSize( EVertexFormat format ) +{ + switch (format) + { + case VERTEX_FORMAT_X16: return 2; + case VERTEX_FORMAT_X16Y16: return 4; + case VERTEX_FORMAT_X16Y16Z16: return 6; + case VERTEX_FORMAT_X16Y16Z16W16: return 8; + case VERTEX_FORMAT_X32: return 4; + case VERTEX_FORMAT_X32Y32: return 8; + case VERTEX_FORMAT_X32Y32Z32: return 12; + case VERTEX_FORMAT_X32Y32Z32W32: return 16; + } +} + VkAttachmentLoadOp IRenderer_LoadOpVk( EAttachmentLoadMode mode ) { switch (mode) @@ -228,11 +257,13 @@ void vk_shader_t::Destroy( void ) void vk_tripipeline_t::Create( - CUtlVector &shaders, - CUtlVector &bindings, - uint32_t pushConstantSize, - CUtlVector formats - ) + CUtlVector &shaders, + CUtlVector &bindings, + uint32_t pushConstantSize, + uint32_t nVertexSize, + CUtlVector vertexFormat, + CUtlVector formats +) { VkPushConstantRange pushConstantRange = {}; pushConstantRange.stageFlags = VK_SHADER_STAGE_ALL; @@ -295,11 +326,32 @@ void vk_tripipeline_t::Create( VK_DYNAMIC_STATE_BLEND_CONSTANTS, }; + VkVertexInputBindingDescription vibd = { + .binding = 0, + .stride = nVertexSize, + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }; + VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, .dynamicStateCount = sizeof(dynamicStates)/sizeof(VkDynamicState), .pDynamicStates = dynamicStates, }; + CUtlVector viad(vertexFormat.GetSize()); + for ( uint32_t i = 0; i < viad.GetSize(); i++ ) + { + viad[i].location = 0; + viad[i].binding = vertexFormat[i].binding; + viad[i].format = IRenderer_VertexToVk(vertexFormat[i].format); + viad[i].offset = vertexFormat[i].offset; + } + + VkPipelineVertexInputStateCreateInfo pvisci = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = 1, + .pVertexBindingDescriptions = &vibd, + .vertexAttributeDescriptionCount = (uint32_t)vertexFormat.GetSize(), + }; VkPipelineInputAssemblyStateCreateInfo piasci = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, @@ -318,6 +370,7 @@ void vk_tripipeline_t::Create( VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {}; graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + graphicsPipelineCreateInfo.pVertexInputState = &pvisci; graphicsPipelineCreateInfo.pInputAssemblyState = &piasci; graphicsPipelineCreateInfo.layout = m_layout; graphicsPipelineCreateInfo.pDynamicState = &pipelineDynamicStateCreateInfo; @@ -808,6 +861,8 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline( CUtlVector shaders, CUtlVector inputs, uint32_t nConstantsSize, + uint32_t nVertexSize, + CUtlVector vertexFormats, CUtlVector outputFormats ) { @@ -816,6 +871,7 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline( CUtlVector vkshaders(shaders.GetSize()); CUtlVector vkbindings(inputs.GetSize()); CUtlVector vkformats(outputFormats.GetSize()); + CUtlVector vkVertexFormats(vertexFormats.GetSize()); for ( uint32_t i = 0; i < vkshaders.GetSize(); i++ ) { @@ -842,8 +898,9 @@ IGraphicsPipeline *IRenderer::CreateGraphicsPipeline( { vkformats[i] = IRenderer_FormatToVk(outputFormats[i]); } - pipeline->m_pipeline.Create(vkshaders, vkbindings, nConstantsSize, vkformats); - return 0; + + pipeline->m_pipeline.Create(vkshaders, vkbindings, nConstantsSize, nVertexSize, vertexFormats, vkformats); + return pipeline; }; diff --git a/engine/vk_video.h b/engine/vk_video.h index e0dc5b2..94dacbe 100644 --- a/engine/vk_video.h +++ b/engine/vk_video.h @@ -35,6 +35,8 @@ struct vk_tripipeline_t CUtlVector &shaders, CUtlVector &bindings, uint32_t pushConstantsSize, + uint32_t nVertexSize, + CUtlVector vertexFormat, CUtlVector formats /* the rest of the stuff is set by the dynamic state */ /* literally */ diff --git a/engine/vk_videosdl.cpp b/engine/vk_videosdl.cpp index 7080ef0..575c63d 100644 --- a/engine/vk_videosdl.cpp +++ b/engine/vk_videosdl.cpp @@ -232,8 +232,7 @@ EInputKey ISDL_KeyName(SDL_Keycode key) void IVideo::Init() { - if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) - V_printf("%s\n",SDL_GetError()); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_VULKAN); unsigned int nExtensionCount = 0; diff --git a/fpc/library/ld.cpp b/fpc/library/ld.cpp index 821e29a..672570d 100644 --- a/fpc/library/ld.cpp +++ b/fpc/library/ld.cpp @@ -83,6 +83,7 @@ CUtlString CLDProject::Link( void ) args.AppendTail("-fembed-bitcode"); args.AppendTail("-Wl,-rpath,@executable_path"); args.AppendTail("-Wl,-all_load"); + args.AppendTail("-w"); } if (m_target.kernel == TARGET_KERNEL_LINUX) { diff --git a/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/xcuserdata/kotofyt.xcuserdatad/UserInterfaceState.xcuserstate b/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/xcuserdata/kotofyt.xcuserdatad/UserInterfaceState.xcuserstate index b2de044..2cae69e 100644 Binary files a/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/xcuserdata/kotofyt.xcuserdatad/UserInterfaceState.xcuserstate and b/ios_deploy/funnygame/funnygame.xcodeproj/project.xcworkspace/xcuserdata/kotofyt.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 537799b..62c606b 100644 --- a/ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/ios_deploy/funnygame/funnygame.xcodeproj/xcuserdata/kotofyt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -24,7 +24,7 @@ BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/ios_deploy/funnygame/funnygame/Info.plist b/ios_deploy/funnygame/funnygame/Info.plist index 7ddb044..5373b04 100644 --- a/ios_deploy/funnygame/funnygame/Info.plist +++ b/ios_deploy/funnygame/funnygame/Info.plist @@ -4,24 +4,5 @@ CFBundleExecutable funnygame - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - UIWindowSceneSessionRoleApplication - - - UISceneConfigurationName - Default Configuration - UISceneDelegateClassName - SceneDelegate - UISceneStoryboardFile - Main - - - - diff --git a/ios_deploy/funnygame/funnygame/Main.storyboard b/ios_deploy/funnygame/funnygame/Main.storyboard deleted file mode 100644 index dd79351..0000000 --- a/ios_deploy/funnygame/funnygame/Main.storyboard +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/rendering.h b/public/rendering.h index 66c7281..f1d8e3d 100644 --- a/public/rendering.h +++ b/public/rendering.h @@ -144,6 +144,7 @@ interface IVideo { public: static void Init(); + static void Deinit(); static void CreatePipelines( void ); static void Frame( float fDelta ); }; @@ -324,22 +325,24 @@ public: static void End(); static IGraphicsPipeline *CreateGraphicsPipeline( - CUtlVector shaders, - CUtlVector inputs, - uint32_t nConstantsSize, - CUtlVector outputFormats - ); + CUtlVector shaders, + CUtlVector inputs, + uint32_t nConstantsSize, + uint32_t nVertexSize, + CUtlVector vertexFormat, + CUtlVector outputFormats + ); static IComputePipeline *CreateComputePipeline( - Shader_t szShader, - CUtlVector inputs, - uint32_t nConstantsSize - ); + Shader_t szShader, + CUtlVector inputs, + uint32_t nConstantsSize + ); static IRayTracingPipeline *CreateRayTracingPipeline( - CUtlVector shaders, - CUtlVector inputs, - uint32_t nConstantsSize - ); + CUtlVector shaders, + CUtlVector inputs, + uint32_t nConstantsSize + ); }; abstract_class IRenderingPipelineStep