imgui/imgui_macos_main.mm
2024-06-21 17:47:52 +08:00

142 lines
5.1 KiB
Plaintext

// Dear ImGui: standalone example application for GLFW + Metal, using programmable pipeline
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_metal.h"
#include <stdio.h>
#include <thread>
#include "imgui_main.h"
#define GLFW_INCLUDE_NONE
#define GLFW_EXPOSE_NATIVE_COCOA
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
static GLFWwindow* g_main_window = nullptr;
static void glfw_error_callback(int error, const char* description)
{
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}
int init_imgui() {
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
configure_imgui(io);
// Setup window
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
return 1;
// Create window with graphics context
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
g_main_window = glfwCreateWindow(1280, 720, get_window_title().c_str(), nullptr, nullptr);
if (g_main_window == nullptr)
return 1;
return 0;
}
bool imgui_new_frame() {
return true;
}
void render_imgui() {
}
void shutdown_imgui() {
// Cleanup
ImGui_ImplMetal_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(g_main_window);
glfwTerminate();
}
void run_imgui() {
init_imgui();
id <MTLDevice> device = MTLCreateSystemDefaultDevice();
id <MTLCommandQueue> commandQueue = [device newCommandQueue];
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOther(g_main_window, true);
ImGui_ImplMetal_Init(device);
NSWindow* nswin = glfwGetCocoaWindow(g_main_window);
CAMetalLayer* layer = [CAMetalLayer layer];
layer.device = device;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
nswin.contentView.layer = layer;
nswin.contentView.wantsLayer = YES;
float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f};
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor new];
while (!glfwWindowShouldClose(g_main_window)) {
@autoreleasepool {
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
std::this_thread::sleep_for(std::chrono::milliseconds(5));
int width, height;
glfwGetFramebufferSize(g_main_window, &width, &height);
layer.drawableSize = CGSizeMake(width, height);
id<CAMetalDrawable> drawable = [layer nextDrawable];
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]);
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
[renderEncoder pushDebugGroup:@"ImGui demo"];
// Start the Dear ImGui frame
ImGui_ImplMetal_NewFrame(renderPassDescriptor);
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGuiIO& io = ImGui::GetIO();
tick_imgui(io.DeltaTime);
draw_imgui(io.DeltaTime);
// Rendering
ImGui::Render();
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
// Update and Render additional Platform Windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
[renderEncoder popDebugGroup];
[renderEncoder endEncoding];
[commandBuffer presentDrawable:drawable];
[commandBuffer commit];
}
}
shutdown_imgui();
}