Introduced a new Metal renderer implementation and a new example illustrating usage of Metal on macOS and iOS (partially addresses #1873)
parent
deb7aa29cd
commit
d64157e803
@ -0,0 +1,6 @@
|
|||||||
|
# iOS / OSX Metal example
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This example shows how to render ImGui with Metal. It is based on the cross-platform game template provided with Xcode as of Xcode 9.
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#import <TargetConditionals.h>
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||||
|
@property (strong, nonatomic) UIWindow *window;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
#import <MetalKit/MetalKit.h>
|
||||||
|
|
||||||
|
@interface Renderer : NSObject <MTKViewDelegate>
|
||||||
|
|
||||||
|
-(nonnull instancetype)initWithView:(nonnull MTKView *)view;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
#import "Renderer.h"
|
||||||
|
#import <Metal/Metal.h>
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_impl_metal.h"
|
||||||
|
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
#include "imgui_impl_osx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@interface Renderer ()
|
||||||
|
@property (nonatomic, strong) id <MTLDevice> device;
|
||||||
|
@property (nonatomic, strong) id <MTLCommandQueue> commandQueue;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Renderer
|
||||||
|
|
||||||
|
-(nonnull instancetype)initWithView:(nonnull MTKView *)view;
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if(self)
|
||||||
|
{
|
||||||
|
_device = view.device;
|
||||||
|
_commandQueue = [_device newCommandQueue];
|
||||||
|
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ImGui::CreateContext();
|
||||||
|
(void)ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplMetal_Init(_device);
|
||||||
|
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawInMTKView:(MTKView *)view
|
||||||
|
{
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
io.DisplaySize.x = view.bounds.size.width;
|
||||||
|
io.DisplaySize.y = view.bounds.size.height;
|
||||||
|
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
CGFloat framebufferScale = view.window.screen.backingScaleFactor ?: NSScreen.mainScreen.backingScaleFactor;
|
||||||
|
#else
|
||||||
|
CGFloat framebufferScale = view.window.screen.scale ?: UIScreen.mainScreen.scale;
|
||||||
|
#endif
|
||||||
|
io.DisplayFramebufferScale = ImVec2(framebufferScale, framebufferScale);
|
||||||
|
|
||||||
|
io.DeltaTime = 1 / float(view.preferredFramesPerSecond ?: 60);
|
||||||
|
|
||||||
|
id<MTLCommandBuffer> commandBuffer = [self.commandQueue commandBuffer];
|
||||||
|
|
||||||
|
static bool show_demo_window = true;
|
||||||
|
static bool show_another_window = false;
|
||||||
|
static float clear_color[4] = { 0.28f, 0.36f, 0.5f, 1.0f };
|
||||||
|
|
||||||
|
MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
|
||||||
|
if(renderPassDescriptor != nil)
|
||||||
|
{
|
||||||
|
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
|
||||||
|
|
||||||
|
// Here, you could do additional rendering work, including other passes as necessary.
|
||||||
|
|
||||||
|
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
||||||
|
|
||||||
|
[renderEncoder pushDebugGroup:@"Draw ImGui"];
|
||||||
|
|
||||||
|
ImGui_ImplMetal_NewFrame(renderPassDescriptor);
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
ImGui_ImplOSX_NewFrame(view);
|
||||||
|
#endif
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
{
|
||||||
|
static float f = 0.0f;
|
||||||
|
static int counter = 0;
|
||||||
|
ImGui::Text("Hello, world!"); // Display some text (you can use a format string too)
|
||||||
|
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||||
|
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||||
|
|
||||||
|
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our windows open/close state
|
||||||
|
ImGui::Checkbox("Another Window", &show_another_window);
|
||||||
|
|
||||||
|
if (ImGui::Button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated)
|
||||||
|
counter++;
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text("counter = %d", counter);
|
||||||
|
|
||||||
|
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows.
|
||||||
|
if (show_another_window)
|
||||||
|
{
|
||||||
|
ImGui::Begin("Another Window", &show_another_window);
|
||||||
|
ImGui::Text("Hello from another window!");
|
||||||
|
if (ImGui::Button("Close Me"))
|
||||||
|
show_another_window = false;
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). Read its code to learn more about Dear ImGui!
|
||||||
|
if (show_demo_window)
|
||||||
|
{
|
||||||
|
// Normally user code doesn't need/want to call this because positions are saved in .ini file anyway.
|
||||||
|
// Here we just want to make the demo initial state a bit more friendly!
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver);
|
||||||
|
ImGui::ShowDemoWindow(&show_demo_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Render();
|
||||||
|
ImDrawData *drawData = ImGui::GetDrawData();
|
||||||
|
ImGui_ImplMetal_RenderDrawData(drawData, commandBuffer, renderEncoder);
|
||||||
|
|
||||||
|
[renderEncoder popDebugGroup];
|
||||||
|
|
||||||
|
[renderEncoder endEncoding];
|
||||||
|
|
||||||
|
[commandBuffer presentDrawable:view.currentDrawable];
|
||||||
|
}
|
||||||
|
|
||||||
|
[commandBuffer commit];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
#import <Metal/Metal.h>
|
||||||
|
#import <MetalKit/MetalKit.h>
|
||||||
|
#import "Renderer.h"
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface ViewController : UIViewController
|
||||||
|
@end
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface ViewController : NSViewController
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,130 @@
|
|||||||
|
|
||||||
|
#import "ViewController.h"
|
||||||
|
#import "Renderer.h"
|
||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
#include "imgui_impl_osx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@interface ViewController ()
|
||||||
|
@property (nonatomic, readonly) MTKView *mtkView;
|
||||||
|
@property (nonatomic, strong) Renderer *renderer;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ViewController
|
||||||
|
|
||||||
|
- (MTKView *)mtkView {
|
||||||
|
return (MTKView *)self.view;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLoad
|
||||||
|
{
|
||||||
|
[super viewDidLoad];
|
||||||
|
|
||||||
|
self.mtkView.device = MTLCreateSystemDefaultDevice();
|
||||||
|
|
||||||
|
if (!self.mtkView.device) {
|
||||||
|
NSLog(@"Metal is not supported");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.renderer = [[Renderer alloc] initWithView:self.mtkView];
|
||||||
|
|
||||||
|
[self.renderer mtkView:self.mtkView drawableSizeWillChange:self.mtkView.bounds.size];
|
||||||
|
|
||||||
|
self.mtkView.delegate = self.renderer;
|
||||||
|
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
// Add a tracking area in order to receive mouse events whenever the mouse is within the bounds of our view
|
||||||
|
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
|
||||||
|
options:NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
|
||||||
|
owner:self
|
||||||
|
userInfo:nil];
|
||||||
|
[self.view addTrackingArea:trackingArea];
|
||||||
|
|
||||||
|
// If we want to receive key events, we either need to be in the responder chain of the key view,
|
||||||
|
// or else we can install a local monitor. The consequence of this heavy-handed approach is that
|
||||||
|
// we receive events for all controls, not just ImGui widgets. If we had native controls in our
|
||||||
|
// window, we'd want to be much more careful than just ingesting the complete event stream, though
|
||||||
|
// we do make an effort to be good citizens by passing along events when ImGui doesn't want to capture.
|
||||||
|
NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged | NSEventTypeScrollWheel;
|
||||||
|
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event) {
|
||||||
|
BOOL wantsCapture = ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||||
|
if (event.type == NSEventTypeKeyDown && wantsCapture) {
|
||||||
|
return nil;
|
||||||
|
} else {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
}];
|
||||||
|
|
||||||
|
ImGui_ImplOSX_Init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
|
||||||
|
- (void)mouseMoved:(NSEvent *)event {
|
||||||
|
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDown:(NSEvent *)event {
|
||||||
|
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseUp:(NSEvent *)event {
|
||||||
|
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDragged:(NSEvent *)event {
|
||||||
|
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollWheel:(NSEvent *)event {
|
||||||
|
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif TARGET_OS_IOS
|
||||||
|
|
||||||
|
// This touch mapping is super cheesy/hacky. We treat any touch on the screen
|
||||||
|
// as if it were a depressed left mouse button, and we don't bother handling
|
||||||
|
// multitouch correctly at all. This causes the "cursor" to behave very erratically
|
||||||
|
// when there are multiple active touches. But for demo purposes, single-touch
|
||||||
|
// interaction actually works surprisingly well.
|
||||||
|
- (void)updateIOWithTouchEvent:(UIEvent *)event {
|
||||||
|
UITouch *anyTouch = event.allTouches.anyObject;
|
||||||
|
CGPoint touchLocation = [anyTouch locationInView:self.view];
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
io.MousePos = ImVec2(touchLocation.x, touchLocation.y);
|
||||||
|
|
||||||
|
BOOL hasActiveTouch = NO;
|
||||||
|
for (UITouch *touch in event.allTouches) {
|
||||||
|
if (touch.phase != UITouchPhaseEnded && touch.phase != UITouchPhaseCancelled) {
|
||||||
|
hasActiveTouch = YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
io.MouseDown[0] = hasActiveTouch;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||||
|
[self updateIOWithTouchEvent:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||||
|
[self updateIOWithTouchEvent:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||||
|
[self updateIOWithTouchEvent:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||||
|
[self updateIOWithTouchEvent:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#import <TargetConditionals.h>
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
@autoreleasepool {
|
||||||
|
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
int main(int argc, const char * argv[]) {
|
||||||
|
return NSApplicationMain(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,541 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 50;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
8307E7CC20E9F9C900473790 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7CB20E9F9C900473790 /* ViewController.mm */; };
|
||||||
|
8307E7CF20E9F9C900473790 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8307E7CD20E9F9C900473790 /* Main.storyboard */; };
|
||||||
|
8307E7DE20E9F9C900473790 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7DD20E9F9C900473790 /* AppDelegate.m */; };
|
||||||
|
8307E7E420E9F9C900473790 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8307E7E220E9F9C900473790 /* Main.storyboard */; };
|
||||||
|
8307E7E720E9F9C900473790 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7E620E9F9C900473790 /* main.m */; };
|
||||||
|
8307E7E820E9F9C900473790 /* Renderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7BC20E9F9C700473790 /* Renderer.mm */; };
|
||||||
|
8307E7E920E9F9C900473790 /* Renderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7BC20E9F9C700473790 /* Renderer.mm */; };
|
||||||
|
836D2A2E20EE208E0098E909 /* imgui_impl_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 836D2A2D20EE208E0098E909 /* imgui_impl_osx.mm */; };
|
||||||
|
836D2A3020EE4A180098E909 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 836D2A2F20EE4A180098E909 /* Default-568h@2x.png */; };
|
||||||
|
836D2A3220EE4A900098E909 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 836D2A3120EE4A900098E909 /* Launch Screen.storyboard */; };
|
||||||
|
83BBE9DE20EB3FFC00295997 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7E620E9F9C900473790 /* main.m */; };
|
||||||
|
83BBE9DF20EB40AE00295997 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7DD20E9F9C900473790 /* AppDelegate.m */; };
|
||||||
|
83BBE9E020EB42D000295997 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8307E7CB20E9F9C900473790 /* ViewController.mm */; };
|
||||||
|
83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9E420EB46B900295997 /* Metal.framework */; };
|
||||||
|
83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9E620EB46BD00295997 /* MetalKit.framework */; };
|
||||||
|
83BBE9E920EB46C100295997 /* ModelIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9E820EB46C100295997 /* ModelIO.framework */; };
|
||||||
|
83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9EA20EB471700295997 /* MetalKit.framework */; };
|
||||||
|
83BBE9ED20EB471700295997 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9EB20EB471700295997 /* Metal.framework */; };
|
||||||
|
83BBE9EF20EB471C00295997 /* ModelIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83BBE9EE20EB471C00295997 /* ModelIO.framework */; };
|
||||||
|
83BBE9FE20EB54D800295997 /* imgui_impl_metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83BBE9FD20EB54D800295997 /* imgui_impl_metal.mm */; };
|
||||||
|
83BBE9FF20EB54D800295997 /* imgui_impl_metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83BBE9FD20EB54D800295997 /* imgui_impl_metal.mm */; };
|
||||||
|
83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0120EB54E700295997 /* imgui_draw.cpp */; };
|
||||||
|
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0120EB54E700295997 /* imgui_draw.cpp */; };
|
||||||
|
83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0220EB54E700295997 /* imgui_demo.cpp */; };
|
||||||
|
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0220EB54E700295997 /* imgui_demo.cpp */; };
|
||||||
|
83BBEA0920EB54E700295997 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0320EB54E700295997 /* imgui.cpp */; };
|
||||||
|
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BBEA0320EB54E700295997 /* imgui.cpp */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
8307E7BB20E9F9C700473790 /* Renderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Renderer.h; sourceTree = "<group>"; };
|
||||||
|
8307E7BC20E9F9C700473790 /* Renderer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Renderer.mm; sourceTree = "<group>"; };
|
||||||
|
8307E7C420E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
8307E7CA20E9F9C900473790 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
|
||||||
|
8307E7CB20E9F9C900473790 /* ViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewController.mm; sourceTree = "<group>"; };
|
||||||
|
8307E7CE20E9F9C900473790 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
|
8307E7D320E9F9C900473790 /* Info-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = "<group>"; };
|
||||||
|
8307E7DA20E9F9C900473790 /* example_apple_metal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example_apple_metal.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
8307E7DC20E9F9C900473790 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||||
|
8307E7DD20E9F9C900473790 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||||
|
8307E7E320E9F9C900473790 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
|
8307E7E520E9F9C900473790 /* Info-macOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = "<group>"; };
|
||||||
|
8307E7E620E9F9C900473790 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||||
|
836D2A2C20EE208D0098E909 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../../imgui_impl_osx.h; sourceTree = "<group>"; };
|
||||||
|
836D2A2D20EE208E0098E909 /* imgui_impl_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_osx.mm; path = ../../imgui_impl_osx.mm; sourceTree = "<group>"; };
|
||||||
|
836D2A2F20EE4A180098E909 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||||
|
836D2A3120EE4A900098E909 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
|
||||||
|
83BBE9E420EB46B900295997 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.4.sdk/System/Library/Frameworks/Metal.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
|
83BBE9E620EB46BD00295997 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.4.sdk/System/Library/Frameworks/MetalKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
|
83BBE9E820EB46C100295997 /* ModelIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ModelIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.4.sdk/System/Library/Frameworks/ModelIO.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
|
83BBE9EA20EB471700295997 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
|
||||||
|
83BBE9EB20EB471700295997 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
|
||||||
|
83BBE9EE20EB471C00295997 /* ModelIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ModelIO.framework; path = System/Library/Frameworks/ModelIO.framework; sourceTree = SDKROOT; };
|
||||||
|
83BBE9FC20EB54D800295997 /* imgui_impl_metal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_metal.h; path = ../../imgui_impl_metal.h; sourceTree = "<group>"; };
|
||||||
|
83BBE9FD20EB54D800295997 /* imgui_impl_metal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_metal.mm; path = ../../imgui_impl_metal.mm; sourceTree = "<group>"; };
|
||||||
|
83BBEA0020EB54E700295997 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = "<group>"; };
|
||||||
|
83BBEA0120EB54E700295997 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; };
|
||||||
|
83BBEA0220EB54E700295997 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = "<group>"; };
|
||||||
|
83BBEA0320EB54E700295997 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = "<group>"; };
|
||||||
|
83BBEA0420EB54E700295997 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
8307E7C120E9F9C900473790 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
83BBE9E920EB46C100295997 /* ModelIO.framework in Frameworks */,
|
||||||
|
83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */,
|
||||||
|
83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
8307E7D720E9F9C900473790 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
83BBE9EF20EB471C00295997 /* ModelIO.framework in Frameworks */,
|
||||||
|
83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */,
|
||||||
|
83BBE9ED20EB471700295997 /* Metal.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
8307E7B520E9F9C700473790 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
83BBE9F020EB544400295997 /* imgui */,
|
||||||
|
8307E7BA20E9F9C700473790 /* Shared */,
|
||||||
|
8307E7C620E9F9C900473790 /* iOS */,
|
||||||
|
8307E7DB20E9F9C900473790 /* macOS */,
|
||||||
|
8307E7C520E9F9C900473790 /* Products */,
|
||||||
|
83BBE9E320EB46B800295997 /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
8307E7BA20E9F9C700473790 /* Shared */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
83BBE9FC20EB54D800295997 /* imgui_impl_metal.h */,
|
||||||
|
83BBE9FD20EB54D800295997 /* imgui_impl_metal.mm */,
|
||||||
|
836D2A2C20EE208D0098E909 /* imgui_impl_osx.h */,
|
||||||
|
836D2A2D20EE208E0098E909 /* imgui_impl_osx.mm */,
|
||||||
|
8307E7DC20E9F9C900473790 /* AppDelegate.h */,
|
||||||
|
8307E7DD20E9F9C900473790 /* AppDelegate.m */,
|
||||||
|
8307E7BB20E9F9C700473790 /* Renderer.h */,
|
||||||
|
8307E7BC20E9F9C700473790 /* Renderer.mm */,
|
||||||
|
8307E7CA20E9F9C900473790 /* ViewController.h */,
|
||||||
|
8307E7CB20E9F9C900473790 /* ViewController.mm */,
|
||||||
|
8307E7E620E9F9C900473790 /* main.m */,
|
||||||
|
);
|
||||||
|
path = Shared;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
8307E7C520E9F9C900473790 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8307E7C420E9F9C900473790 /* example_apple_metal.app */,
|
||||||
|
8307E7DA20E9F9C900473790 /* example_apple_metal.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
8307E7C620E9F9C900473790 /* iOS */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
836D2A2F20EE4A180098E909 /* Default-568h@2x.png */,
|
||||||
|
8307E7CD20E9F9C900473790 /* Main.storyboard */,
|
||||||
|
8307E7D320E9F9C900473790 /* Info-iOS.plist */,
|
||||||
|
836D2A3120EE4A900098E909 /* Launch Screen.storyboard */,
|
||||||
|
);
|
||||||
|
path = iOS;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
8307E7DB20E9F9C900473790 /* macOS */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8307E7E220E9F9C900473790 /* Main.storyboard */,
|
||||||
|
8307E7E520E9F9C900473790 /* Info-macOS.plist */,
|
||||||
|
);
|
||||||
|
path = macOS;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
83BBE9E320EB46B800295997 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
83BBE9EE20EB471C00295997 /* ModelIO.framework */,
|
||||||
|
83BBE9EB20EB471700295997 /* Metal.framework */,
|
||||||
|
83BBE9EA20EB471700295997 /* MetalKit.framework */,
|
||||||
|
83BBE9E820EB46C100295997 /* ModelIO.framework */,
|
||||||
|
83BBE9E620EB46BD00295997 /* MetalKit.framework */,
|
||||||
|
83BBE9E420EB46B900295997 /* Metal.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
83BBE9F020EB544400295997 /* imgui */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
83BBEA0420EB54E700295997 /* imconfig.h */,
|
||||||
|
83BBEA0020EB54E700295997 /* imgui.h */,
|
||||||
|
83BBEA0220EB54E700295997 /* imgui_demo.cpp */,
|
||||||
|
83BBEA0120EB54E700295997 /* imgui_draw.cpp */,
|
||||||
|
83BBEA0320EB54E700295997 /* imgui.cpp */,
|
||||||
|
);
|
||||||
|
name = imgui;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
8307E7C320E9F9C900473790 /* example_apple_metal_ios */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 8307E7F020E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_ios" */;
|
||||||
|
buildPhases = (
|
||||||
|
8307E7C020E9F9C900473790 /* Sources */,
|
||||||
|
8307E7C120E9F9C900473790 /* Frameworks */,
|
||||||
|
8307E7C220E9F9C900473790 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = example_apple_metal_ios;
|
||||||
|
productName = "imguiex iOS";
|
||||||
|
productReference = 8307E7C420E9F9C900473790 /* example_apple_metal.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
8307E7D920E9F9C900473790 /* example_apple_metal_macos */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 8307E7F320E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_macos" */;
|
||||||
|
buildPhases = (
|
||||||
|
8307E7D620E9F9C900473790 /* Sources */,
|
||||||
|
8307E7D720E9F9C900473790 /* Frameworks */,
|
||||||
|
8307E7D820E9F9C900473790 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = example_apple_metal_macos;
|
||||||
|
productName = "imguiex macOS";
|
||||||
|
productReference = 8307E7DA20E9F9C900473790 /* example_apple_metal.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
8307E7B620E9F9C700473790 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0940;
|
||||||
|
ORGANIZATIONNAME = "Warren Moore";
|
||||||
|
TargetAttributes = {
|
||||||
|
8307E7C320E9F9C900473790 = {
|
||||||
|
CreatedOnToolsVersion = 9.4.1;
|
||||||
|
};
|
||||||
|
8307E7D920E9F9C900473790 = {
|
||||||
|
CreatedOnToolsVersion = 9.4.1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 8307E7B920E9F9C700473790 /* Build configuration list for PBXProject "example_apple_metal" */;
|
||||||
|
compatibilityVersion = "Xcode 9.3";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 8307E7B520E9F9C700473790;
|
||||||
|
productRefGroup = 8307E7C520E9F9C900473790 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
8307E7C320E9F9C900473790 /* example_apple_metal_ios */,
|
||||||
|
8307E7D920E9F9C900473790 /* example_apple_metal_macos */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
8307E7C220E9F9C900473790 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
836D2A3220EE4A900098E909 /* Launch Screen.storyboard in Resources */,
|
||||||
|
8307E7CF20E9F9C900473790 /* Main.storyboard in Resources */,
|
||||||
|
836D2A3020EE4A180098E909 /* Default-568h@2x.png in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
8307E7D820E9F9C900473790 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
8307E7E420E9F9C900473790 /* Main.storyboard in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
8307E7C020E9F9C900473790 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
8307E7E820E9F9C900473790 /* Renderer.mm in Sources */,
|
||||||
|
8307E7CC20E9F9C900473790 /* ViewController.mm in Sources */,
|
||||||
|
83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||||
|
83BBE9DF20EB40AE00295997 /* AppDelegate.m in Sources */,
|
||||||
|
83BBEA0920EB54E700295997 /* imgui.cpp in Sources */,
|
||||||
|
83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||||
|
83BBE9FE20EB54D800295997 /* imgui_impl_metal.mm in Sources */,
|
||||||
|
83BBE9DE20EB3FFC00295997 /* main.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
8307E7D620E9F9C900473790 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
83BBE9E020EB42D000295997 /* ViewController.mm in Sources */,
|
||||||
|
8307E7E920E9F9C900473790 /* Renderer.mm in Sources */,
|
||||||
|
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||||
|
8307E7E720E9F9C900473790 /* main.m in Sources */,
|
||||||
|
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */,
|
||||||
|
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||||
|
83BBE9FF20EB54D800295997 /* imgui_impl_metal.mm in Sources */,
|
||||||
|
836D2A2E20EE208E0098E909 /* imgui_impl_osx.mm in Sources */,
|
||||||
|
8307E7DE20E9F9C900473790 /* AppDelegate.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
8307E7CD20E9F9C900473790 /* Main.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
8307E7CE20E9F9C900473790 /* Base */,
|
||||||
|
);
|
||||||
|
name = Main.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
8307E7E220E9F9C900473790 /* Main.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
8307E7E320E9F9C900473790 /* Base */,
|
||||||
|
);
|
||||||
|
name = Main.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
8307E7EE20E9F9C900473790 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
8307E7EF20E9F9C900473790 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
8307E7F120E9F9C900473790 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
|
||||||
|
PRODUCT_NAME = example_apple_metal;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
8307E7F220E9F9C900473790 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
|
||||||
|
PRODUCT_NAME = example_apple_metal;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
8307E7F420E9F9C900473790 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
|
||||||
|
PRODUCT_NAME = example_apple_metal;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
8307E7F520E9F9C900473790 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
|
||||||
|
PRODUCT_NAME = example_apple_metal;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
8307E7B920E9F9C700473790 /* Build configuration list for PBXProject "example_apple_metal" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
8307E7EE20E9F9C900473790 /* Debug */,
|
||||||
|
8307E7EF20E9F9C900473790 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
8307E7F020E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_ios" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
8307E7F120E9F9C900473790 /* Debug */,
|
||||||
|
8307E7F220E9F9C900473790 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
8307E7F320E9F9C900473790 /* Build configuration list for PBXNativeTarget "example_apple_metal_macos" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
8307E7F420E9F9C900473790 /* Debug */,
|
||||||
|
8307E7F520E9F9C900473790 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 8307E7B620E9F9C700473790 /* Project object */;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BV1-FR-VrT">
|
||||||
|
<device id="retina4_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="tXr-a1-R10">
|
||||||
|
<objects>
|
||||||
|
<viewController id="BV1-FR-VrT" customClass="ViewController" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="3se-qz-xqx" customClass="MTKView">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="BKg-qs-eN0"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="SZV-WD-TEh" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>imgui</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>Launch Screen</string>
|
||||||
|
<key>UIMainStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>armv7</string>
|
||||||
|
<string>metal</string>
|
||||||
|
</array>
|
||||||
|
<key>UIRequiresFullScreen</key>
|
||||||
|
<true/>
|
||||||
|
<key>UIStatusBarHidden</key>
|
||||||
|
<true/>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14269.14" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||||
|
<device id="retina4_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14252.5"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="EHf-IW-A2E">
|
||||||
|
<objects>
|
||||||
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="53" y="375"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
@ -0,0 +1,130 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14269.14" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14269.14"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--Application-->
|
||||||
|
<scene sceneID="JPo-4y-FX3">
|
||||||
|
<objects>
|
||||||
|
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
||||||
|
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||||
|
<items>
|
||||||
|
<menuItem title="ImGui" id="1Xt-HY-uBw">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="ImGui" systemMenu="apple" id="uQy-DD-JDr">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||||
|
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||||
|
<menuItem title="Services" id="NMo-om-nkz">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||||
|
<menuItem title="Hide" keyEquivalent="h" id="Olw-nP-bQN">
|
||||||
|
<connections>
|
||||||
|
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||||
|
<menuItem title="Quit" keyEquivalent="q" id="4sb-4s-VLi">
|
||||||
|
<connections>
|
||||||
|
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="View" id="H8h-7b-M4v">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Window" id="aUF-d1-5bR">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||||
|
<connections>
|
||||||
|
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
||||||
|
</connections>
|
||||||
|
</application>
|
||||||
|
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
|
||||||
|
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||||
|
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="75" y="0.0"/>
|
||||||
|
</scene>
|
||||||
|
<!--Window Controller-->
|
||||||
|
<scene sceneID="R2V-B0-nI4">
|
||||||
|
<objects>
|
||||||
|
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
|
||||||
|
<window key="window" title="ImGui" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" titleVisibility="hidden" id="IQv-IB-iLA">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="B8D-0N-5wS" id="CyC-Pq-WbN"/>
|
||||||
|
</connections>
|
||||||
|
</window>
|
||||||
|
<connections>
|
||||||
|
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
|
||||||
|
</connections>
|
||||||
|
</windowController>
|
||||||
|
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="-128" y="390"/>
|
||||||
|
</scene>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="hIz-AP-VOD">
|
||||||
|
<objects>
|
||||||
|
<viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController">
|
||||||
|
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl" customClass="MTKView">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="1280" height="720"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="205" y="1032"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string></string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>imgui</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>Copyright © 2018 Warren Moore. All rights reserved.</string>
|
||||||
|
<key>NSMainStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,25 @@
|
|||||||
|
// ImGui Renderer for: Metal
|
||||||
|
// This needs to be used along with a Platform Binding (e.g. OSX)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
|
||||||
|
|
||||||
|
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
|
||||||
|
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
|
||||||
|
// https://github.com/ocornut/imgui
|
||||||
|
|
||||||
|
@class MTLRenderPassDescriptor;
|
||||||
|
@protocol MTLDevice, MTLCommandBuffer, MTLRenderCommandEncoder;
|
||||||
|
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplMetal_Init(id<MTLDevice> device);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor *renderPassDescriptor);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data,
|
||||||
|
id<MTLCommandBuffer> commandBuffer,
|
||||||
|
id<MTLRenderCommandEncoder> commandEncoder);
|
||||||
|
|
||||||
|
// Called by Init/NewFrame/Shutdown
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyFontsTexture();
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
@ -0,0 +1,490 @@
|
|||||||
|
// ImGui Renderer for: Metal
|
||||||
|
// This needs to be used along with a Platform Binding (e.g. OSX)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
|
||||||
|
|
||||||
|
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
|
||||||
|
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
|
||||||
|
// https://github.com/ocornut/imgui
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2018-07-05: Metal: Added new Metal backend implementation
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_impl_metal.h"
|
||||||
|
|
||||||
|
#import <Metal/Metal.h>
|
||||||
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
#import <simd/simd.h>
|
||||||
|
|
||||||
|
#pragma mark - Support classes
|
||||||
|
|
||||||
|
// A wrapper around a MTLBuffer object that knows the last time it was reused
|
||||||
|
@interface MetalBuffer : NSObject
|
||||||
|
@property (nonatomic, strong) id<MTLBuffer> buffer;
|
||||||
|
@property (nonatomic, assign) NSTimeInterval lastReuseTime;
|
||||||
|
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
||||||
|
@end
|
||||||
|
|
||||||
|
// An object that encapsulates the data necessary to uniquely identify a
|
||||||
|
// render pipeline state. These are used as cache keys.
|
||||||
|
@interface FramebufferDescriptor : NSObject<NSCopying>
|
||||||
|
@property (nonatomic, assign) unsigned long sampleCount;
|
||||||
|
@property (nonatomic, assign) MTLPixelFormat colorPixelFormat;
|
||||||
|
@property (nonatomic, assign) MTLPixelFormat depthPixelFormat;
|
||||||
|
@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat;
|
||||||
|
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor *)renderPassDescriptor;
|
||||||
|
@end
|
||||||
|
|
||||||
|
// A singleton that stores long-lived objects that are needed by the Metal
|
||||||
|
// renderer backend. Stores the render pipeline state cache and the default
|
||||||
|
// font texture, and manages the reusable buffer cache.
|
||||||
|
@interface MetalContext : NSObject
|
||||||
|
@property (nonatomic, strong) id<MTLDepthStencilState> depthStencilState;
|
||||||
|
@property (nonatomic, strong) FramebufferDescriptor *framebufferDescriptor; // framebuffer descriptor for current frame; transient
|
||||||
|
@property (nonatomic, strong) NSMutableDictionary *renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
|
||||||
|
@property (nonatomic, strong, nullable) id<MTLTexture> fontTexture;
|
||||||
|
@property (nonatomic, strong) NSMutableArray<MetalBuffer *> *bufferCache;
|
||||||
|
@property (nonatomic, assign) NSTimeInterval lastBufferCachePurge;
|
||||||
|
- (void)makeDeviceObjectsWithDevice:(id<MTLDevice>)device;
|
||||||
|
- (void)makeFontTextureWithDevice:(id<MTLDevice>)device;
|
||||||
|
- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device;
|
||||||
|
- (void)enqueueReusableBuffer:(MetalBuffer *)buffer;
|
||||||
|
- (id<MTLRenderPipelineState>)renderPipelineStateForFrameAndDevice:(id<MTLDevice>)device;
|
||||||
|
- (void)emptyRenderPipelineStateCache;
|
||||||
|
- (void)renderDrawData:(ImDrawData *)drawData
|
||||||
|
commandBuffer:(id<MTLCommandBuffer>)commandBuffer
|
||||||
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder;
|
||||||
|
@end
|
||||||
|
|
||||||
|
static MetalContext *g_sharedMetalContext = nil;
|
||||||
|
|
||||||
|
#pragma mark - ImGui API implementation
|
||||||
|
|
||||||
|
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
||||||
|
{
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
g_sharedMetalContext = [[MetalContext alloc] init];
|
||||||
|
});
|
||||||
|
|
||||||
|
ImGui_ImplMetal_CreateDeviceObjects(device);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplMetal_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor *renderPassDescriptor)
|
||||||
|
{
|
||||||
|
IM_ASSERT(g_sharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init?");
|
||||||
|
|
||||||
|
g_sharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metal Render function.
|
||||||
|
void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer> commandBuffer, id<MTLRenderCommandEncoder> commandEncoder)
|
||||||
|
{
|
||||||
|
[g_sharedMetalContext renderDrawData:draw_data commandBuffer:commandBuffer commandEncoder:commandEncoder];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
|
||||||
|
{
|
||||||
|
[g_sharedMetalContext makeFontTextureWithDevice:device];
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.Fonts->TexID = (__bridge void *)g_sharedMetalContext.fontTexture;
|
||||||
|
|
||||||
|
return (g_sharedMetalContext.fontTexture != nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplMetal_DestroyFontsTexture()
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
g_sharedMetalContext.fontTexture = nil;
|
||||||
|
io.Fonts->TexID = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
||||||
|
{
|
||||||
|
[g_sharedMetalContext makeDeviceObjectsWithDevice:device];
|
||||||
|
|
||||||
|
ImGui_ImplMetal_CreateFontsTexture(device);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplMetal_DestroyDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplMetal_DestroyFontsTexture();
|
||||||
|
[g_sharedMetalContext emptyRenderPipelineStateCache];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - MetalBuffer implementation
|
||||||
|
|
||||||
|
@implementation MetalBuffer
|
||||||
|
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer {
|
||||||
|
if ((self = [super init])) {
|
||||||
|
_buffer = buffer;
|
||||||
|
_lastReuseTime = [NSDate date].timeIntervalSince1970;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - FramebufferDescriptor implementation
|
||||||
|
|
||||||
|
@implementation FramebufferDescriptor
|
||||||
|
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor *)renderPassDescriptor {
|
||||||
|
if ((self = [super init])) {
|
||||||
|
_sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount;
|
||||||
|
_colorPixelFormat = renderPassDescriptor.colorAttachments[0].texture.pixelFormat;
|
||||||
|
_depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat;
|
||||||
|
_stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
|
||||||
|
FramebufferDescriptor *copy = [[FramebufferDescriptor allocWithZone:zone] init];
|
||||||
|
copy.sampleCount = self.sampleCount;
|
||||||
|
copy.colorPixelFormat = self.colorPixelFormat;
|
||||||
|
copy.depthPixelFormat = self.depthPixelFormat;
|
||||||
|
copy.stencilPixelFormat = self.stencilPixelFormat;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)hash {
|
||||||
|
NSUInteger sc = _sampleCount & 0x3;
|
||||||
|
NSUInteger cf = _colorPixelFormat & 0x3FF;
|
||||||
|
NSUInteger df = _depthPixelFormat & 0x3FF;
|
||||||
|
NSUInteger sf = _stencilPixelFormat & 0x3FF;
|
||||||
|
NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isEqual:(id)object {
|
||||||
|
FramebufferDescriptor *other = object;
|
||||||
|
if (![other isKindOfClass:[FramebufferDescriptor class]]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return other.sampleCount == self.sampleCount &&
|
||||||
|
other.colorPixelFormat == self.colorPixelFormat &&
|
||||||
|
other.depthPixelFormat == self.depthPixelFormat &&
|
||||||
|
other.stencilPixelFormat == self.stencilPixelFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - MetalContext implementation
|
||||||
|
|
||||||
|
@implementation MetalContext
|
||||||
|
- (instancetype)init {
|
||||||
|
if ((self = [super init])) {
|
||||||
|
_renderPipelineStateCache = [NSMutableDictionary dictionary];
|
||||||
|
_bufferCache = [NSMutableArray array];
|
||||||
|
_lastBufferCachePurge = [NSDate date].timeIntervalSince1970;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)makeDeviceObjectsWithDevice:(id<MTLDevice>)device {
|
||||||
|
MTLDepthStencilDescriptor *depthStencilDescriptor = [[MTLDepthStencilDescriptor alloc] init];
|
||||||
|
depthStencilDescriptor.depthWriteEnabled = NO;
|
||||||
|
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
||||||
|
self.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)makeFontTextureWithDevice:(id<MTLDevice>)device {
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height;
|
||||||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||||
|
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
|
||||||
|
width:width
|
||||||
|
height:height
|
||||||
|
mipmapped:NO];
|
||||||
|
textureDescriptor.usage = MTLTextureUsageShaderRead;
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
textureDescriptor.storageMode = MTLStorageModeManaged;
|
||||||
|
#else
|
||||||
|
textureDescriptor.storageMode = MTLStorageModeShared;
|
||||||
|
#endif
|
||||||
|
id <MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
|
||||||
|
[texture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:pixels bytesPerRow:width * 4];
|
||||||
|
self.fontTexture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MetalBuffer *)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device {
|
||||||
|
NSTimeInterval now = [NSDate date].timeIntervalSince1970;
|
||||||
|
|
||||||
|
// Purge old buffers that haven't been useful for a while
|
||||||
|
if (now - self.lastBufferCachePurge > 1.0) {
|
||||||
|
NSMutableArray *survivors = [NSMutableArray array];
|
||||||
|
for (MetalBuffer *candidate in self.bufferCache) {
|
||||||
|
if (candidate.lastReuseTime > self.lastBufferCachePurge) {
|
||||||
|
[survivors addObject:candidate];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.bufferCache = [survivors mutableCopy];
|
||||||
|
self.lastBufferCachePurge = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if we have a buffer we can reuse
|
||||||
|
MetalBuffer *bestCandidate = nil;
|
||||||
|
for (MetalBuffer *candidate in self.bufferCache) {
|
||||||
|
if (candidate.buffer.length >= length && (bestCandidate == nil || bestCandidate.lastReuseTime > candidate.lastReuseTime)) {
|
||||||
|
bestCandidate = candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestCandidate != nil) {
|
||||||
|
[self.bufferCache removeObject:bestCandidate];
|
||||||
|
bestCandidate.lastReuseTime = now;
|
||||||
|
return bestCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No luck; make a new buffer
|
||||||
|
id<MTLBuffer> backing = [device newBufferWithLength:length options:MTLResourceStorageModeShared];
|
||||||
|
return [[MetalBuffer alloc] initWithBuffer:backing];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)enqueueReusableBuffer:(MetalBuffer *)buffer {
|
||||||
|
[self.bufferCache addObject:buffer];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (_Nullable id<MTLRenderPipelineState>)renderPipelineStateForFrameAndDevice:(id<MTLDevice>)device {
|
||||||
|
// Try to retrieve a render pipeline state that is compatible with the framebuffer config for this frame
|
||||||
|
// Thie hit rate for this cache should be very near 100%.
|
||||||
|
id<MTLRenderPipelineState> renderPipelineState = self.renderPipelineStateCache[self.framebufferDescriptor];
|
||||||
|
|
||||||
|
if (renderPipelineState == nil) {
|
||||||
|
// No luck; make a new render pipeline state
|
||||||
|
renderPipelineState = [self _renderPipelineStateForFramebufferDescriptor:self.framebufferDescriptor device:device];
|
||||||
|
// Cache render pipeline state for later reuse
|
||||||
|
self.renderPipelineStateCache[self.framebufferDescriptor] = renderPipelineState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderPipelineState;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id<MTLRenderPipelineState>)_renderPipelineStateForFramebufferDescriptor:(FramebufferDescriptor *)descriptor device:(id<MTLDevice>)device
|
||||||
|
{
|
||||||
|
NSError *error = nil;
|
||||||
|
|
||||||
|
NSString *shaderSource = @""
|
||||||
|
"#include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
"\n"
|
||||||
|
"struct Uniforms {\n"
|
||||||
|
" float4x4 projectionMatrix;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct VertexIn {\n"
|
||||||
|
" float2 position [[attribute(0)]];\n"
|
||||||
|
" float2 texCoords [[attribute(1)]];\n"
|
||||||
|
" uchar4 color [[attribute(2)]];\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct VertexOut {\n"
|
||||||
|
" float4 position [[position]];\n"
|
||||||
|
" float2 texCoords;\n"
|
||||||
|
" float4 color;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"vertex VertexOut vertex_main(VertexIn in [[stage_in]],\n"
|
||||||
|
" constant Uniforms &uniforms [[buffer(1)]]) {\n"
|
||||||
|
" VertexOut out;\n"
|
||||||
|
" out.position = uniforms.projectionMatrix * float4(in.position, 0, 1);\n"
|
||||||
|
" out.texCoords = in.texCoords;\n"
|
||||||
|
" out.color = float4(in.color) / float4(255.0);\n"
|
||||||
|
" return out;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"fragment half4 fragment_main(VertexOut in [[stage_in]],\n"
|
||||||
|
" texture2d<half, access::sample> texture [[texture(0)]]) {\n"
|
||||||
|
" constexpr sampler linearSampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear);\n"
|
||||||
|
" half4 texColor = texture.sample(linearSampler, in.texCoords);\n"
|
||||||
|
" return half4(in.color) * texColor;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
id<MTLLibrary> library = [device newLibraryWithSource:shaderSource options:nil error:&error];
|
||||||
|
if (library == nil) {
|
||||||
|
NSLog(@"Error: failed to create Metal library: %@", error);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
id<MTLFunction> vertexFunction = [library newFunctionWithName:@"vertex_main"];
|
||||||
|
id<MTLFunction> fragmentFunction = [library newFunctionWithName:@"fragment_main"];
|
||||||
|
|
||||||
|
if (vertexFunction == nil || fragmentFunction == nil) {
|
||||||
|
NSLog(@"Error: failed to find Metal shader functions in library: %@", error);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTLVertexDescriptor *vertexDescriptor = [MTLVertexDescriptor vertexDescriptor];
|
||||||
|
vertexDescriptor.attributes[0].offset = IM_OFFSETOF(ImDrawVert, pos);
|
||||||
|
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position
|
||||||
|
vertexDescriptor.attributes[0].bufferIndex = 0;
|
||||||
|
vertexDescriptor.attributes[1].offset = IM_OFFSETOF(ImDrawVert, uv);
|
||||||
|
vertexDescriptor.attributes[1].format = MTLVertexFormatFloat2; // texCoords
|
||||||
|
vertexDescriptor.attributes[1].bufferIndex = 0;
|
||||||
|
vertexDescriptor.attributes[2].offset = IM_OFFSETOF(ImDrawVert, col);
|
||||||
|
vertexDescriptor.attributes[2].format = MTLVertexFormatUChar4; // color
|
||||||
|
vertexDescriptor.attributes[2].bufferIndex = 0;
|
||||||
|
vertexDescriptor.layouts[0].stepRate = 1;
|
||||||
|
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
||||||
|
vertexDescriptor.layouts[0].stride = sizeof(ImDrawVert);
|
||||||
|
|
||||||
|
MTLRenderPipelineDescriptor *pipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||||
|
pipelineDescriptor.vertexFunction = vertexFunction;
|
||||||
|
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||||
|
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
||||||
|
pipelineDescriptor.sampleCount = self.framebufferDescriptor.sampleCount;
|
||||||
|
pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat;
|
||||||
|
pipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
|
||||||
|
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
|
||||||
|
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
|
||||||
|
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
||||||
|
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
|
||||||
|
pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||||
|
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||||
|
pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat;
|
||||||
|
pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat;
|
||||||
|
|
||||||
|
id<MTLRenderPipelineState> renderPipelineState = [device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error];
|
||||||
|
if (error != nil) {
|
||||||
|
NSLog(@"Error: failed to create Metal pipeline state: %@", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderPipelineState;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)emptyRenderPipelineStateCache {
|
||||||
|
[self.renderPipelineStateCache removeAllObjects];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)renderDrawData:(ImDrawData *)drawData
|
||||||
|
commandBuffer:(id<MTLCommandBuffer>)commandBuffer
|
||||||
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||||
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
int fb_width = (int)(drawData->DisplaySize.x * io.DisplayFramebufferScale.x);
|
||||||
|
int fb_height = (int)(drawData->DisplaySize.y * io.DisplayFramebufferScale.y);
|
||||||
|
if (fb_width <= 0 || fb_height <= 0 || drawData->CmdListsCount == 0)
|
||||||
|
return;
|
||||||
|
drawData->ScaleClipRects(io.DisplayFramebufferScale);
|
||||||
|
|
||||||
|
[commandEncoder setCullMode:MTLCullModeNone];
|
||||||
|
[commandEncoder setDepthStencilState:g_sharedMetalContext.depthStencilState];
|
||||||
|
|
||||||
|
// Setup viewport, orthographic projection matrix
|
||||||
|
// Our visible imgui space lies from draw_data->DisplayPps (top left) to
|
||||||
|
// draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.
|
||||||
|
MTLViewport viewport = { .originX = 0.0,
|
||||||
|
.originY = 0.0,
|
||||||
|
.width = double(fb_width),
|
||||||
|
.height = double(fb_height),
|
||||||
|
.znear = 0.0,
|
||||||
|
.zfar = 1.0 };
|
||||||
|
[commandEncoder setViewport:viewport];
|
||||||
|
float L = drawData->DisplayPos.x;
|
||||||
|
float R = drawData->DisplayPos.x + drawData->DisplaySize.x;
|
||||||
|
float T = drawData->DisplayPos.y;
|
||||||
|
float B = drawData->DisplayPos.y + drawData->DisplaySize.y;
|
||||||
|
float N = viewport.znear;
|
||||||
|
float F = viewport.zfar;
|
||||||
|
const float ortho_projection[4][4] =
|
||||||
|
{
|
||||||
|
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 1/(F-N), 0.0f },
|
||||||
|
{ (R+L)/(L-R), (T+B)/(B-T), N/(F-N), 1.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
[commandEncoder setVertexBytes:&ortho_projection length:sizeof(ortho_projection) atIndex:1];
|
||||||
|
|
||||||
|
size_t vertexBufferLength = 0;
|
||||||
|
size_t indexBufferLength = 0;
|
||||||
|
for (int n = 0; n < drawData->CmdListsCount; n++) {
|
||||||
|
const ImDrawList* cmd_list = drawData->CmdLists[n];
|
||||||
|
vertexBufferLength += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||||
|
indexBufferLength += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetalBuffer *vertexBuffer = [self dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
|
||||||
|
MetalBuffer *indexBuffer = [self dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
|
||||||
|
|
||||||
|
id<MTLRenderPipelineState> renderPipelineState = [self renderPipelineStateForFrameAndDevice:commandBuffer.device];
|
||||||
|
[commandEncoder setRenderPipelineState:renderPipelineState];
|
||||||
|
|
||||||
|
[commandEncoder setVertexBuffer:vertexBuffer.buffer offset:0 atIndex:0];
|
||||||
|
|
||||||
|
size_t vertexBufferOffset = 0;
|
||||||
|
size_t indexBufferOffset = 0;
|
||||||
|
ImVec2 pos = drawData->DisplayPos;
|
||||||
|
for (int n = 0; n < drawData->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = drawData->CmdLists[n];
|
||||||
|
ImDrawIdx idx_buffer_offset = 0;
|
||||||
|
|
||||||
|
memcpy((char *)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy((char *)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
|
||||||
|
[commandEncoder setVertexBufferOffset:vertexBufferOffset atIndex:0];
|
||||||
|
|
||||||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback)
|
||||||
|
{
|
||||||
|
// User callback (registered via ImDrawList::AddCallback)
|
||||||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y);
|
||||||
|
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
||||||
|
{
|
||||||
|
// Apply scissor/clipping rectangle
|
||||||
|
MTLScissorRect scissorRect = { .x = NSUInteger(clip_rect.x),
|
||||||
|
.y = NSUInteger(clip_rect.y),
|
||||||
|
.width = NSUInteger(clip_rect.z - clip_rect.x),
|
||||||
|
.height = NSUInteger(clip_rect.w - clip_rect.y) };
|
||||||
|
[commandEncoder setScissorRect:scissorRect];
|
||||||
|
|
||||||
|
|
||||||
|
// Bind texture, Draw
|
||||||
|
if (pcmd->TextureId != NULL) {
|
||||||
|
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(pcmd->TextureId) atIndex:0];
|
||||||
|
}
|
||||||
|
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
|
indexCount:pcmd->ElemCount
|
||||||
|
indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
|
||||||
|
indexBuffer:indexBuffer.buffer
|
||||||
|
indexBufferOffset:indexBufferOffset + idx_buffer_offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexBufferOffset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||||
|
indexBufferOffset += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak id weakSelf = self;
|
||||||
|
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[weakSelf enqueueReusableBuffer:vertexBuffer];
|
||||||
|
[weakSelf enqueueReusableBuffer:indexBuffer];
|
||||||
|
});
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue