10.3 KB、277行 生 Blame 履歴
1// Dear ImGui: standalone example application for OSX + OpenGL2, using legacy fixed pipeline
2
3// Learn about Dear ImGui:
4// - FAQ https://dearimgui.com/faq
5// - Getting Started https://dearimgui.com/getting-started
6// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
7// - Introduction, links and more at the top of imgui.cpp
8
9// FIXME: Multi-viewports is not yet functional in this example. May need backend rework/coordination.
10
11#import <Cocoa/Cocoa.h>
12#import <OpenGL/gl.h>
13#import <OpenGL/glu.h>
14
15#include "imgui.h"
16#include "imgui_impl_opengl2.h"
17#include "imgui_impl_osx.h"
18
19//-----------------------------------------------------------------------------------
20// AppView
21//-----------------------------------------------------------------------------------
22
23@interface AppView : NSOpenGLView
24{
25 NSTimer* animationTimer;
26}
27@end
28
29@implementation AppView
30
31-(void)prepareOpenGL
32{
33 [super prepareOpenGL];
34
35#ifndef DEBUG
36 GLint swapInterval = 1;
37 [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
38 if (swapInterval == 0)
39 NSLog(@"Error: Cannot set swap interval.");
40#endif
41}
42
43-(void)initialize
44{
45 // Setup Dear ImGui context
46 // FIXME: This example doesn't have proper cleanup...
47 IMGUI_CHECKVERSION();
48 ImGui::CreateContext();
49 ImGuiIO& io = ImGui::GetIO(); (void)io;
50 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
51 io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
52 io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
53 io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
54
55 // Setup Dear ImGui style
56 ImGui::StyleColorsDark();
57 //ImGui::StyleColorsLight();
58
59 // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
60 ImGuiStyle& style = ImGui::GetStyle();
61 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
62 {
63 style.WindowRounding = 0.0f;
64 style.Colors[ImGuiCol_WindowBg].w = 1.0f;
65 }
66
67 // Setup Platform/Renderer backends
68 ImGui_ImplOSX_Init(self);
69 ImGui_ImplOpenGL2_Init();
70
71 // Load Fonts
72 // - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
73 // This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
74 // - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
75 // - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
76 // - Read 'docs/FONTS.md' for more instructions and details.
77 // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
78 // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
79 //style.FontSizeBase = 20.0f;
80 //io.Fonts->AddFontDefaultVector();
81 //io.Fonts->AddFontDefaultBitmap();
82 //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
83 //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
84 //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
85 //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
86 //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
87 //IM_ASSERT(font != nullptr);
88}
89
90-(void)updateAndDrawDemoView
91{
92 // Start the Dear ImGui frame
93 ImGuiIO& io = ImGui::GetIO();
94 ImGui_ImplOpenGL2_NewFrame();
95 ImGui_ImplOSX_NewFrame(self);
96 ImGui::NewFrame();
97
98 // Our state (make them static = more or less global) as a convenience to keep the example terse.
99 static bool show_demo_window = true;
100 static bool show_another_window = false;
101 static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
102
103 // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
104 if (show_demo_window)
105 ImGui::ShowDemoWindow(&show_demo_window);
106
107 // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
108 {
109 static float f = 0.0f;
110 static int counter = 0;
111
112 ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
113
114 ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
115 ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
116 ImGui::Checkbox("Another Window", &show_another_window);
117
118 ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
119 ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
120
121 if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
122 counter++;
123 ImGui::SameLine();
124 ImGui::Text("counter = %d", counter);
125
126 ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
127 ImGui::End();
128 }
129
130 // 3. Show another simple window.
131 if (show_another_window)
132 {
133 ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
134 ImGui::Text("Hello from another window!");
135 if (ImGui::Button("Close Me"))
136 show_another_window = false;
137 ImGui::End();
138 }
139
140 // Rendering
141 ImGui::Render();
142 ImDrawData* draw_data = ImGui::GetDrawData();
143
144 [[self openGLContext] makeCurrentContext];
145 GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
146 GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
147 glViewport(0, 0, width, height);
148 glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
149 glClear(GL_COLOR_BUFFER_BIT);
150
151 ImGui_ImplOpenGL2_RenderDrawData(draw_data);
152
153 // Update and Render additional Platform Windows
154 if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
155 {
156 ImGui::UpdatePlatformWindows();
157 ImGui::RenderPlatformWindowsDefault();
158 }
159
160 // Present
161 [[self openGLContext] flushBuffer];
162
163 if (!animationTimer)
164 animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES];
165}
166
167-(void)reshape { [super reshape]; [[self openGLContext] update]; [self updateAndDrawDemoView]; }
168-(void)drawRect:(NSRect)bounds { [self updateAndDrawDemoView]; }
169-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; }
170-(void)dealloc { animationTimer = nil; }
171
172@end
173
174//-----------------------------------------------------------------------------------
175// AppDelegate
176//-----------------------------------------------------------------------------------
177
178@interface AppDelegate : NSObject <NSApplicationDelegate>
179@property (nonatomic, readonly) NSWindow* window;
180@end
181
182@implementation AppDelegate
183@synthesize window = _window;
184
185-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
186{
187 return YES;
188}
189
190-(NSWindow*)window
191{
192 if (_window != nil)
193 return _window;
194
195 NSRect viewRect = NSMakeRect(100.0, 100.0, 100.0 + 1280.0, 100 + 800.0);
196
197 _window = [[NSWindow alloc] initWithContentRect:viewRect styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable|NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:YES];
198 [_window setTitle:@"Dear ImGui OSX+OpenGL2 Example"];
199 [_window setAcceptsMouseMovedEvents:YES];
200 [_window setOpaque:YES];
201 [_window makeKeyAndOrderFront:NSApp];
202
203 return _window;
204}
205
206-(void)setupMenu
207{
208 NSMenu* mainMenuBar = [[NSMenu alloc] init];
209 NSMenu* appMenu;
210 NSMenuItem* menuItem;
211
212 appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+OpenGL2 Example"];
213 menuItem = [appMenu addItemWithTitle:@"Quit Dear ImGui OSX+OpenGL2 Example" action:@selector(terminate:) keyEquivalent:@"q"];
214 [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
215
216 menuItem = [[NSMenuItem alloc] init];
217 [menuItem setSubmenu:appMenu];
218
219 [mainMenuBar addItem:menuItem];
220
221 appMenu = nil;
222 [NSApp setMainMenu:mainMenuBar];
223}
224
225-(void)dealloc
226{
227 _window = nil;
228}
229
230-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
231{
232 // Make the application a foreground application (else it won't receive keyboard events)
233 ProcessSerialNumber psn = {0, kCurrentProcess};
234 TransformProcessType(&psn, kProcessTransformToForegroundApplication);
235
236 // Menu
237 [self setupMenu];
238
239 NSOpenGLPixelFormatAttribute attrs[] =
240 {
241 NSOpenGLPFADoubleBuffer,
242 NSOpenGLPFADepthSize, 32,
243 0
244 };
245
246 NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
247 AppView* view = [[AppView alloc] initWithFrame:self.window.frame pixelFormat:format];
248 format = nil;
249#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
250 if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
251 [view setWantsBestResolutionOpenGLSurface:YES];
252#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
253 [self.window setContentView:view];
254
255 if ([view openGLContext] == nil)
256 NSLog(@"No OpenGL Context!");
257
258 [view initialize];
259}
260
261@end
262
263//-----------------------------------------------------------------------------------
264// Application main() function
265//-----------------------------------------------------------------------------------
266
267int main(int argc, const char* argv[])
268{
269 @autoreleasepool
270 {
271 NSApp = [NSApplication sharedApplication];
272 AppDelegate* delegate = [[AppDelegate alloc] init];
273 [[NSApplication sharedApplication] setDelegate:delegate];
274 [NSApp run];
275 }
276 return NSApplicationMain(argc, argv);
277}