147 lines
5.2 KiB
Plaintext
147 lines
5.2 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();
|
|
}
|
|
|
|
float get_dpi_scale() {
|
|
return 1.0f;
|
|
}
|
|
|
|
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];
|
|
std::this_thread::yield();
|
|
}
|
|
}
|
|
shutdown_imgui();
|
|
}
|