From 752076d2ccad1c19dfc37174f437cf03f89d3127 Mon Sep 17 00:00:00 2001 From: xszAzy <3486170277@qq.com> Date: Thu, 2 Oct 2025 01:24:12 +0800 Subject: [PATCH] backing --- .gitmodules | 5 +- MEL.xcworkspace/contents.xcworkspacedata | 17 +- .../xcdebugger/Breakpoints_v2.xcbkptlist | 6 - MetalLearning/Core.h | 2 + MetalLearning/MEL.h | 2 + .../MetalLearning.xcodeproj/project.pbxproj | 637 ++++++------------ MetalLearning/Window.h | 3 + MetalLearning/src/MEL/Application.h | 14 +- MetalLearning/src/MEL/Application.mm | 46 +- MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.h | 24 + .../src/MEL/ImGuiLayer/ImGuiLayer.mm | 15 + MetalLearning/src/MEL/Input/Input.cpp | 1 - MetalLearning/src/MEL/Input/Input.h | 71 ++ MetalLearning/src/MEL/Input/MacInput.h | 29 + MetalLearning/src/MEL/Input/MacInput.mm | 132 ++++ MetalLearning/src/MEL/Layer/Layer.cpp | 6 +- MetalLearning/src/MEL/Layer/Layer.h | 1 + MetalLearning/src/MEL/Layer/LayerStack.cpp | 35 + MetalLearning/src/MEL/Layer/LayerStack.h | 25 + MetalLearning/src/MEL/Renderer/AppDelegate.mm | 1 + .../src/MEL/Renderer/MetalRenderer.h | 5 + .../src/MEL/Renderer/MetalRenderer.mm | 70 +- .../src/MEL/Renderer/ViewController.mm | 10 +- MetalLearning/src/MEL/Window/CocoaWindow.mm | 7 + MetalLearning/src/MEL/Window/MacWindow.h | 6 +- MetalLearning/src/MEL/Window/MacWindow.mm | 2 + MetalLearning/src/Sandbox/Sandbox.mm | 23 +- MetalLearning/src/melpch.h | 1 + MetalLearning/vendor/imgui | 1 + premake5.lua | 39 +- 30 files changed, 754 insertions(+), 482 deletions(-) delete mode 100644 MEL.xcworkspace/xcuserdata/xudianhuan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.h create mode 100644 MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.mm delete mode 100644 MetalLearning/src/MEL/Input/Input.cpp create mode 100644 MetalLearning/src/MEL/Input/MacInput.h create mode 100644 MetalLearning/src/MEL/Input/MacInput.mm create mode 100644 MetalLearning/src/MEL/Layer/LayerStack.cpp create mode 100644 MetalLearning/src/MEL/Layer/LayerStack.h create mode 160000 MetalLearning/vendor/imgui diff --git a/.gitmodules b/.gitmodules index 6edecff..37b183c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ -[submodule "MetalLearning/src/vendor"] +[submodule "MetalLearning/vendor/imgui"] + path=MetalLearning/vendor/imgui + url=https://github.com/TheCherno/imgui.git +[submodule "MetalLearning/vendor/spdlog"] path = MetalLearning/vendor/spdlog url = https://github.com/gabime/spdlog.git diff --git a/MEL.xcworkspace/contents.xcworkspacedata b/MEL.xcworkspace/contents.xcworkspacedata index 4b9edc7..41f72cd 100644 --- a/MEL.xcworkspace/contents.xcworkspacedata +++ b/MEL.xcworkspace/contents.xcworkspacedata @@ -1,11 +1,10 @@ - - - - - + version = "1.0"> + + + + + \ No newline at end of file diff --git a/MEL.xcworkspace/xcuserdata/xudianhuan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/MEL.xcworkspace/xcuserdata/xudianhuan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index 018b591..0000000 --- a/MEL.xcworkspace/xcuserdata/xudianhuan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/MetalLearning/Core.h b/MetalLearning/Core.h index 621758f..957aec7 100644 --- a/MetalLearning/Core.h +++ b/MetalLearning/Core.h @@ -2,3 +2,5 @@ #define BIT(x)(1< m_Window; bool m_Running=true; + LayerStack m_LayerStack; + + static Application* s_Instance; }; Application* CreateApplication(); } diff --git a/MetalLearning/src/MEL/Application.mm b/MetalLearning/src/MEL/Application.mm index ac421e0..e09c046 100644 --- a/MetalLearning/src/MEL/Application.mm +++ b/MetalLearning/src/MEL/Application.mm @@ -1,10 +1,11 @@ #import "melpch.h" #import "Renderer/AppDelegate.h" -#include "Log.h" #include "Application.h" -#include "Events/ApplicationEvent.h" + namespace MEL{ + Application* Application::s_Instance=nullptr; + Application::Application(){ m_Window=std::unique_ptr(Window::Create()); m_Window->SetEventCallback([this](MEL::Event& e){ @@ -21,23 +22,50 @@ namespace MEL{ dispathcher.Dispatch(MEL_BIND_EVENT_FN(Application::OnWindowClose)); MEL_CORE_INFO("{0}",e.ToString()); + + for(auto it=m_LayerStack.end();it!=m_LayerStack.begin();){ + (*--it)->OnEvent(e); + if(e.m_Handled) + break; + } + } + + bool Application::OnWindowClose(WindowCloseEvent& event){ + m_Running=false; + return true; } void Application::Run() { - m_Window->Show(); NSApplication* application=[NSApplication sharedApplication]; AppDelegate* appDelegate=[[AppDelegate alloc] init]; [application setDelegate:appDelegate]; - [application run]; + [application finishLaunching]; + [application activateIgnoringOtherApps:YES]; while (m_Running){ - - m_Window->OnUpdate(); + @autoreleasepool { + NSEvent* event; + while ((event=[application nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES])){ + [application sendEvent:event]; + } + + m_Window->OnUpdate(); + + [NSThread sleepForTimeInterval:0.001]; + m_Window->Show(); + } } + [application stop:nil]; } - bool Application::OnWindowClose(WindowCloseEvent& event){ - m_Running=false; - return true; + void Application::PushLayer(Layer *layer){ + m_LayerStack.PushLayer(layer); + } + + void Application::PushOverlay(Layer *overlay){ + m_LayerStack.PushOverLay(overlay); } } diff --git a/MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.h b/MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.h new file mode 100644 index 0000000..7841fc9 --- /dev/null +++ b/MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.h @@ -0,0 +1,24 @@ +#pragma once +#include "Layer/Layer.h" +#include "Layer/LayerStack.h" + +namespace MEL{ + class ImGuiLayer:public Layer{ + public: + ImGuiLayer(NSWindow* window); + ~ImGuiLayer(); + + virtual void OnAttach()override; + virtual void OnDetach()override; + virtual void OnUpdate()override; + virtual void OnImGuiRender()override; + virtual void OnEvent(Event& event)override; + + void Begin(); + void End(); + + private: + NSWindow* m_NativeWindow; + }; +} + diff --git a/MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.mm b/MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.mm new file mode 100644 index 0000000..7eed071 --- /dev/null +++ b/MetalLearning/src/MEL/ImGuiLayer/ImGuiLayer.mm @@ -0,0 +1,15 @@ +#include "ImGuiLayer.h" + +#import "imgui.h" +#import "imgui_impl_metal.h" +#import "imgui_impl_osx.h" + +namespace MEL{ + ImGuiLayer::ImGuiLayer(NSWindow* window):m_NativeWindow(window){ + + } + + void ImGuiLayer::OnAttach(){ + + } +} diff --git a/MetalLearning/src/MEL/Input/Input.cpp b/MetalLearning/src/MEL/Input/Input.cpp deleted file mode 100644 index 0da0418..0000000 --- a/MetalLearning/src/MEL/Input/Input.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Input.h" diff --git a/MetalLearning/src/MEL/Input/Input.h b/MetalLearning/src/MEL/Input/Input.h index 8b13789..1343e44 100644 --- a/MetalLearning/src/MEL/Input/Input.h +++ b/MetalLearning/src/MEL/Input/Input.h @@ -1 +1,72 @@ +#pragma once +#include "melpch.h" +#include +namespace MEL { + using Keycode =uint16_t; + namespace Key{ + enum: Keycode{ + D1 =18, + D2 =19, + D3 =20, + D4 =21, + D5 =23, + D6 =22, + D7 =26, + D8 =28, + D9 =25, + D0 =29, + S1 =50,//` + S2 =33,//[ + S3 =30,//] + S4 =42,//| + S6 =41,//; + S7 =39,//' + S8 =27,//- + S9 =24,//= + S10 =43,//, + S11 =47,//. + S12 =44,//? + N =45, + M =46, + Q =12, + W =13, + E =14, + R =15, + T =17, + Y =16, + U =32, + I =34, + O =31, + P =35, + A =0, + S =1, + D =2, + F =3, + G =5, + H =4, + J =38, + K =40, + L =37, + Z =6, + X =7, + C =8, + V =9, + B =11, + enter =76 + }; + } + class Input{ + static bool IsKeypressed(Keycode keycode){return IsKeyPressedImpl(keycode);} + static bool IsMouseButtonPressed(int button){return IsMouseButtonPressedImpl(button);} + static float GetMouseX(){return GetMouseXImpl();} + static float GetMouseY(){return GetMouseYImpl();} + static std::pair GetMousePosition(){return GetMousePositionImpl();} + private: + static bool IsKeyPressedImpl(Keycode keycode); + static bool IsMouseButtonPressedImpl(int button); + static float GetMouseXImpl(); + static float GetMouseYImpl(); + static std::pair GetMousePositionImpl(); + }; +} diff --git a/MetalLearning/src/MEL/Input/MacInput.h b/MetalLearning/src/MEL/Input/MacInput.h new file mode 100644 index 0000000..ccfaea9 --- /dev/null +++ b/MetalLearning/src/MEL/Input/MacInput.h @@ -0,0 +1,29 @@ +#pragma once +#include "Input.h" +#include + +namespace MEL{ + class MacInput:public Input{ + public: + static void Init(); + + static void OnKeyEvent(NSEvent* event,bool pressed); + static void OnMouseEvent(NSEvent* event); + static void OnMouseMovedEvent(NSEvent* event); + + static bool IsKeyPressedImpl(Keycode keycode); + static bool IsMouseButtonPressedImpl(int button); + static float GetMouseXImpl(){return MouseX;} + static float GetMouseYImpl(){return MouseY;} + static std::pair GetMousePositionImpl(); + + private: + static std::unordered_map s_KeyState; + static std::unordered_map s_MouseState; + static float MouseX,MouseY; + + static std::unordered_map s_KeyMap; + + static int CocoaToEngineMouseButton(NSEvent* event); + }; +} diff --git a/MetalLearning/src/MEL/Input/MacInput.mm b/MetalLearning/src/MEL/Input/MacInput.mm new file mode 100644 index 0000000..73b9437 --- /dev/null +++ b/MetalLearning/src/MEL/Input/MacInput.mm @@ -0,0 +1,132 @@ +#include "MacInput.h" +#include "Application.h" +namespace MEL{ + std::unordered_map MacInput::s_KeyMap; + std::unordered_map MacInput::s_KeyState; + std::unordered_map MacInput::s_MouseState; + float MacInput::MouseX=.0f; + float MacInput::MouseY=.0f; + + void MacInput::Init(){ + s_KeyState[Key::D1 ]=false; + s_KeyState[Key::D2 ]=false; + s_KeyState[Key::D3 ]=false; + s_KeyState[Key::D4 ]=false; + s_KeyState[Key::D5 ]=false; + s_KeyState[Key::D6 ]=false; + s_KeyState[Key::D7 ]=false; + s_KeyState[Key::D8 ]=false; + s_KeyState[Key::D9 ]=false; + s_KeyState[Key::D0 ]=false; + s_KeyState[Key::S1 ]=false; + s_KeyState[Key::S2 ]=false; + s_KeyState[Key::S3 ]=false; + s_KeyState[Key::S4 ]=false; + s_KeyState[Key::S6 ]=false; + s_KeyState[Key::S7 ]=false; + s_KeyState[Key::S8 ]=false; + s_KeyState[Key::S9 ]=false; + s_KeyState[Key::S10 ]=false; + s_KeyState[Key::S11 ]=false; + s_KeyState[Key::S12 ]=false; + s_KeyState[Key::N ]=false; + s_KeyState[Key::M ]=false; + s_KeyState[Key::Q ]=false; + s_KeyState[Key::W ]=false; + s_KeyState[Key::E ]=false; + s_KeyState[Key::R ]=false; + s_KeyState[Key::T ]=false; + s_KeyState[Key::Y ]=false; + s_KeyState[Key::U ]=false; + s_KeyState[Key::I ]=false; + s_KeyState[Key::O ]=false; + s_KeyState[Key::P ]=false; + s_KeyState[Key::A ]=false; + s_KeyState[Key::S ]=false; + s_KeyState[Key::D ]=false; + s_KeyState[Key::F ]=false; + s_KeyState[Key::G ]=false; + s_KeyState[Key::H ]=false; + s_KeyState[Key::J ]=false; + s_KeyState[Key::K ]=false; + s_KeyState[Key::L ]=false; + s_KeyState[Key::Z ]=false; + s_KeyState[Key::X ]=false; + s_KeyState[Key::C ]=false; + s_KeyState[Key::V ]=false; + s_KeyState[Key::B ]=false; + s_KeyState[Key::enter ]=false; + + s_MouseState[0]=false; + s_MouseState[1]=false; + s_MouseState[2]=false; + } + + void MacInput::OnKeyEvent(NSEvent *event, bool pressed){ + Keycode keycode=[event keyCode]; + s_KeyState[keycode]=pressed; + } + + void MacInput::OnMouseEvent(NSEvent *event){ + int button=CocoaToEngineMouseButton(event); + NSEventType type=[event type]; + + switch (type) { + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseUp: + s_MouseState[button]=false; + break; + case NSEventTypeLeftMouseDown: + case NSEventTypeRightMouseDown: + case NSEventTypeOtherMouseDown: + s_MouseState[button]=true; + break; + default: + break; + } + } + + void MacInput::OnMouseMovedEvent(NSEvent *event){ + NSPoint location=[event locationInWindow]; + MouseX=location.x; + MouseY=location.y; + } + + int MacInput::CocoaToEngineMouseButton(NSEvent *event){ + switch ([event type]) { + case NSEventTypeLeftMouseDown: + case NSEventTypeLeftMouseUp: + case NSEventTypeLeftMouseDragged: + return 0; + break; + case NSEventTypeRightMouseUp: + case NSEventTypeRightMouseDown: + case NSEventTypeRightMouseDragged: + return 1; + break; + case NSEventTypeOtherMouseUp: + case NSEventTypeOtherMouseDown: + case NSEventTypeOtherMouseDragged: + return 2; + break; + default: + return -1; + break; + } + } + + bool MacInput::IsKeyPressedImpl(Keycode keycode){ + auto it=s_KeyState.find(keycode); + return (it != s_KeyState.end())?it->second:false; + } + + bool MacInput::IsMouseButtonPressedImpl(int button){ + auto it=s_MouseState.find(button); + return (it != s_MouseState.end())?it->second:false; + } + + std::pair MacInput::GetMousePositionImpl(){ + return {MouseX,MouseY}; + } +} diff --git a/MetalLearning/src/MEL/Layer/Layer.cpp b/MetalLearning/src/MEL/Layer/Layer.cpp index a062ed6..2430c16 100644 --- a/MetalLearning/src/MEL/Layer/Layer.cpp +++ b/MetalLearning/src/MEL/Layer/Layer.cpp @@ -1,4 +1,8 @@ #include "melpch.h" #include "Layer.h" - +namespace MEL { + Layer::Layer(const std::string& debugName) + :m_DebugName(debugName){} + Layer::~Layer(){} +} diff --git a/MetalLearning/src/MEL/Layer/Layer.h b/MetalLearning/src/MEL/Layer/Layer.h index 55b1689..aafd0aa 100644 --- a/MetalLearning/src/MEL/Layer/Layer.h +++ b/MetalLearning/src/MEL/Layer/Layer.h @@ -11,6 +11,7 @@ namespace MEL { virtual void OnAttach(){} virtual void OnDetach(){} virtual void OnUpdate(){} + virtual void OnImGuiRender(){} virtual void OnEvent(Event& event){} inline const std::string& GetName()const{return m_DebugName;} protected: diff --git a/MetalLearning/src/MEL/Layer/LayerStack.cpp b/MetalLearning/src/MEL/Layer/LayerStack.cpp new file mode 100644 index 0000000..846f808 --- /dev/null +++ b/MetalLearning/src/MEL/Layer/LayerStack.cpp @@ -0,0 +1,35 @@ +#include "melpch.h" +#include "LayerStack.h" + +namespace MEL{ + LayerStack::LayerStack(){ + m_LayerInsert=m_Layers.begin(); + } + + LayerStack::~LayerStack(){ + for (Layer* layer : m_Layers) + delete layer; + } + + void LayerStack::PushLayer(Layer *layer){ + m_LayerInsert=m_Layers.emplace(m_LayerInsert, layer); + } + + void LayerStack::PushOverLay(Layer *overlay){ + m_Layers.emplace_back(overlay); + } + + void LayerStack::PopLayer(Layer *layer){ + auto it=std::find(m_Layers.begin(),m_Layers.end(),layer); + if(it != m_Layers.end()){ + m_Layers.erase(it); + m_LayerInsert--; + } + } + + void LayerStack::PopOverLay(Layer *overlay){ + auto it=std::find(m_Layers.begin(),m_Layers.end(),overlay); + if(it != m_Layers.end()) + m_Layers.erase(it); + } +} diff --git a/MetalLearning/src/MEL/Layer/LayerStack.h b/MetalLearning/src/MEL/Layer/LayerStack.h new file mode 100644 index 0000000..f5fdea6 --- /dev/null +++ b/MetalLearning/src/MEL/Layer/LayerStack.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Core.h" +#include "Layer.h" +#include + +namespace MEL{ + class LayerStack{ + public: + LayerStack(); + ~LayerStack(); + + void PushLayer(Layer* layer); + void PushOverLay(Layer* overlay); + void PopLayer(Layer* layer); + void PopOverLay(Layer* overlay); + + std::vector::iterator begin() {return m_Layers.begin();} + std::vector::iterator end() {return m_Layers.end();} + + private: + std::vectorm_Layers; + std::vector::iterator m_LayerInsert; + }; +} diff --git a/MetalLearning/src/MEL/Renderer/AppDelegate.mm b/MetalLearning/src/MEL/Renderer/AppDelegate.mm index d0ba4fd..36a6beb 100644 --- a/MetalLearning/src/MEL/Renderer/AppDelegate.mm +++ b/MetalLearning/src/MEL/Renderer/AppDelegate.mm @@ -4,6 +4,7 @@ @implementation AppDelegate -(void)applicationDidFinishLaunching:(NSNotification *)notification{ + NSLog(@"finished launching application"); } -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender{ diff --git a/MetalLearning/src/MEL/Renderer/MetalRenderer.h b/MetalLearning/src/MEL/Renderer/MetalRenderer.h index e8f27c0..70c4f6b 100644 --- a/MetalLearning/src/MEL/Renderer/MetalRenderer.h +++ b/MetalLearning/src/MEL/Renderer/MetalRenderer.h @@ -5,4 +5,9 @@ -(nonnull instancetype)initWithMetalKitView: (nonnull MTKView*)mtkView; +-(void)setupImGui; +-(void)cleanup; + +@property (readonly)uint64_t windowID; + @end diff --git a/MetalLearning/src/MEL/Renderer/MetalRenderer.mm b/MetalLearning/src/MEL/Renderer/MetalRenderer.mm index b3123a6..948afbb 100644 --- a/MetalLearning/src/MEL/Renderer/MetalRenderer.mm +++ b/MetalLearning/src/MEL/Renderer/MetalRenderer.mm @@ -1,28 +1,43 @@ #import "MetalRenderer.h" +#import "imgui.h" +#import "imgui_impl_metal.h" +#import "imgui_impl_osx.h" + @implementation MetalRenderer{ id _device; id _pipelineState; id _commandQueue; vector_uint2 _viewportSize; + MTKView* _mtkView; } -(nonnull instancetype)initWithMetalKitView:(MTKView *)mtkView{ self=[super init]; if(self){ _device=mtkView.device; - [self _setupPipeline]; + _mtkView=mtkView; _commandQueue=[_device newCommandQueue]; - _viewportSize=(vector_uint2) { (uint32_t)mtkView.drawableSize.width, (uint32_t)mtkView.drawableSize.height }; + [self _setupPipeline]; } return self; } +-(void)setupImGui{ + ImGui::CreateContext(); + ImGui_ImplMetal_Init(_device); + ImGui_ImplOSX_Init(_mtkView); + ImGui::StyleColorsDark(); + + ImGuiIO& io=ImGui::GetIO(); + io.Fonts->AddFontDefault(); +} + -(void)_setupPipeline{ id defaultLibrary=[_device newDefaultLibrary]; @@ -42,6 +57,11 @@ id vertexFunction=[defaultLibrary newFunctionWithName:@"vertexShader"]; id fragmentFunction=[defaultLibrary newFunctionWithName:@"fragmentShader"]; + if(!vertexFunction || !fragmentFunction){ + NSLog(@"Note:Custom shaders not found,only ImGui rendering will be available!"); + return; + } + MTLRenderPipelineDescriptor* pipeLineDescriptor=[[MTLRenderPipelineDescriptor alloc] init]; pipeLineDescriptor.label=@"Simple Pipeline"; @@ -69,21 +89,49 @@ [commandBuffer commit]; return; } + //begin imgui render + ImGui_ImplMetal_NewFrame(renderPassDescriptor); + ImGui_ImplOSX_NewFrame(view); + ImGui::NewFrame(); + //draw imgui (that's imguilayer::end() in hazel) + [self _drawImGui]; - //renderPassDescriptor.colorAttachments[0].clearColor=MTLClearColorMake(0.1, 0.1, 0.1, 1.0); + ImGui::Render(); id renderEncoder=[commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; renderEncoder.label=@"MyRenderEncoder"; - [renderEncoder setRenderPipelineState:_pipelineState]; + if(_pipelineState){ + + [renderEncoder setRenderPipelineState:_pipelineState]; + + [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:3]; + } - [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle - vertexStart:0 - vertexCount:3]; + ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder); [renderEncoder endEncoding]; [commandBuffer presentDrawable:view.currentDrawable]; [commandBuffer commit]; + + if(ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable){ + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } +} + +-(void)_drawImGui{ + //render ImGui things here,it's really clear!! + ImGui::Begin("MEL Engine - Metal Implementation"); + ImGui::Text("Hello, Metal! This is your engine"); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",1000.0f/ImGui::GetIO().Framerate,ImGui::GetIO().Framerate); + + ImGui::ShowDemoWindow(); + + ImGui::End(); } -(void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size{ @@ -91,4 +139,12 @@ _viewportSize.y=(uint32_t)size.height; } +-(void)cleanup{ + ImGui_ImplOSX_Shutdown(); + ImGui_ImplMetal_Shutdown(); + ImGui::DestroyContext(); +} + @end +#pragma mark - TODO: +//I'll add multi-window later,not now. :P diff --git a/MetalLearning/src/MEL/Renderer/ViewController.mm b/MetalLearning/src/MEL/Renderer/ViewController.mm index 5a8e29a..eff4a2e 100644 --- a/MetalLearning/src/MEL/Renderer/ViewController.mm +++ b/MetalLearning/src/MEL/Renderer/ViewController.mm @@ -5,6 +5,7 @@ @property (nonatomic,strong)MTKView* metalView; @property (nonatomic,strong)MetalRenderer* renderer; +@property (nonatomic,strong)id commandQueue; @end; @@ -21,6 +22,9 @@ [self.view addSubview:self.metalView]; self.renderer=[[MetalRenderer alloc] initWithMetalKitView:self.metalView]; + + [self.renderer setupImGui]; + self.metalView.delegate=self.renderer; } @@ -32,7 +36,11 @@ -(void)loadView{ self.view=[[NSView alloc] init]; self.view.wantsLayer=YES; - //self.view.layer.backgroundColor=[[NSColor blueColor] CGColor]; +} + +-(void)viewWillDisappear{ + [super viewWillDisappear]; + [self.renderer cleanup]; } @end diff --git a/MetalLearning/src/MEL/Window/CocoaWindow.mm b/MetalLearning/src/MEL/Window/CocoaWindow.mm index 7bb9e5d..4822ce8 100644 --- a/MetalLearning/src/MEL/Window/CocoaWindow.mm +++ b/MetalLearning/src/MEL/Window/CocoaWindow.mm @@ -3,6 +3,8 @@ #import "Events/KeyEvent.h" #import "Events/MouseEvent.h" #import "Events/ApplicationEvent.h" +#include "imgui_impl_osx.h" +#include "MacInput.h" @implementation CocoaWindow @@ -22,6 +24,7 @@ //Key Events -(void)keyDown:(NSEvent *)event{ + //MEL::MacInput::OnKeyEvent(event, true); int action; action=[event isARepeat]?1:0; MEL::KeyPressedEvent keyPressedEvent((int)[event keyCode],action); @@ -32,22 +35,26 @@ } -(void)keyUp:(NSEvent *)event{ + MEL::MacInput::OnKeyEvent(event, false); MEL::KeyReleasedEvent keyReleasedEvent((int)[event keyCode]); [self dispatchEvent:keyReleasedEvent]; } //Mouse Events -(void)mouseDown:(NSEvent *)event{ + MEL::MacInput::OnMouseEvent(event); MEL::MouseButtonPressedEvent mousePressed(1); [self dispatchEvent:mousePressed]; } -(void)mouseUp:(NSEvent *)event{ + MEL::MacInput::OnMouseEvent(event); MEL::MouseButtonReleasedEvent mouseReleased(0); [self dispatchEvent:mouseReleased]; } -(void)mouseMoved:(NSEvent *)event{ + MEL::MacInput::OnMouseMovedEvent(event); NSPoint location=[event locationInWindow]; MEL::MouseMovedEvent mouseMovedEvent(location.x,location.y); [self dispatchEvent:mouseMovedEvent]; diff --git a/MetalLearning/src/MEL/Window/MacWindow.h b/MetalLearning/src/MEL/Window/MacWindow.h index e600fef..86b55f1 100644 --- a/MetalLearning/src/MEL/Window/MacWindow.h +++ b/MetalLearning/src/MEL/Window/MacWindow.h @@ -1,8 +1,9 @@ #pragma once - #include "melpch.h" #include "MEL.h" #include "Window.h" +#include "ImGuiLayer/ImGuiLayer.h" + namespace MEL { class MacWindow:public Window{ public: @@ -24,7 +25,6 @@ namespace MEL { static Window* Create(const WindowProps& props=WindowProps()); void Show()override; - private: virtual void Init(const WindowProps& props); virtual void ShutDown(); @@ -37,6 +37,8 @@ namespace MEL { EventCallbackFn EventCallback; }; WindowData m_Data; + private: + ImGuiLayer* m_ImGuiLayer; }; } diff --git a/MetalLearning/src/MEL/Window/MacWindow.mm b/MetalLearning/src/MEL/Window/MacWindow.mm index d45ba41..9ec7d5a 100644 --- a/MetalLearning/src/MEL/Window/MacWindow.mm +++ b/MetalLearning/src/MEL/Window/MacWindow.mm @@ -52,6 +52,8 @@ namespace MEL { m_Data.EventCallback(event); }; } + m_ImGuiLayer=new ImGuiLayer(m_Window); + LayerStack::PushOverLay(m_ImGuiLayer); } void MacWindow::ShutDown(){ diff --git a/MetalLearning/src/Sandbox/Sandbox.mm b/MetalLearning/src/Sandbox/Sandbox.mm index 0d80fa0..3791d8f 100644 --- a/MetalLearning/src/Sandbox/Sandbox.mm +++ b/MetalLearning/src/Sandbox/Sandbox.mm @@ -1,8 +1,29 @@ #include "MEL.h" +#include + +class ExampleLayer:public MEL::Layer{ +public: + ExampleLayer() + :Layer("Example"){ + + } + + void OnUpdate() override{ + MEL_INFO("testing update"); + } + + void OnEvent(MEL::Event& e) override{ + MEL_INFO("testing event{0}",e.ToString()); + } + +private: + +}; + class Sandbox:public MEL::Application{ public: Sandbox(){ - + PushLayer(new ExampleLayer()); } ~Sandbox(){ diff --git a/MetalLearning/src/melpch.h b/MetalLearning/src/melpch.h index 9167772..ea9db0b 100644 --- a/MetalLearning/src/melpch.h +++ b/MetalLearning/src/melpch.h @@ -10,3 +10,4 @@ #include + diff --git a/MetalLearning/vendor/imgui b/MetalLearning/vendor/imgui new file mode 160000 index 0000000..781a4ff --- /dev/null +++ b/MetalLearning/vendor/imgui @@ -0,0 +1 @@ +Subproject commit 781a4ffc674d98dfd2b4d42747e1cd27887fac36 diff --git a/premake5.lua b/premake5.lua index 0444355..a046a14 100644 --- a/premake5.lua +++ b/premake5.lua @@ -6,7 +6,10 @@ workspace "MEL" outputdir= "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" -- Include directories relative to root folder (solution directory) IncludeDir={} -IncludeDir["spdlog"]="MEL/vendor/spdlog/include" +IncludeDir["spdlog"]="MetalLearning/vendor/spdlog/include" +IncludeDir["ImGui"]="MetalLearning/vendor/imgui" + +include "MetalLearning/vendor/imgui" project "MetalLearning" location "MetalLearning" @@ -23,7 +26,10 @@ project "MetalLearning" "%{prj.name}/src/**.cpp", "%{prj.name}/src/**.mm", "%{prj.name}/src/**.m", - "%{prj.name}/ShaderSrc/**.metal" + "%{prj.name}/*.h", + "%{prj.name}/ShaderSrc/**.metal", + "%{prj.name}/vendor/imgui/backends/imgui_impl_osx.mm", + "%{prj.name}/vendor/imgui/backends/imgui_impl_metal.mm" } includedirs @@ -31,12 +37,13 @@ project "MetalLearning" "**", "%{prj.name}/ShaderSrc", "%{IncludeDir.spdlog}", + "%{IncludeDir.ImGui}", } links { -- link directories here - + "ImGui", } filter "system:macosx" @@ -53,19 +60,10 @@ project "MetalLearning" "QuartzCore.framework", "CoreFoundation.framework", "CoreGraphics.framework", - "MetalKit.framework" + "MetalKit.framework", + "GameController.framework" } - - filter "configurations:Debug" - defines"MEL_DEBUG" - runtime "Debug" - symbols "on" - - filter "configurations:Release" - defines "MEL_RELEASE" - runtime "Release" - optimize "on" - + xcodebuildsettings{ ["MACOSX_DEPLOYMENT_TARGET"]="10.15", ["GCC_PRECOMPILE_PREFIX_HEADER"]="NO", @@ -79,3 +77,14 @@ project "MetalLearning" ["GENERATE_INFOPLIST_FILE"]="YES" } + + filter "configurations:Debug" + defines"MEL_DEBUG" + runtime "Debug" + symbols "on" + + filter "configurations:Release" + defines "MEL_RELEASE" + runtime "Release" + optimize "on" +