diff --git a/examples/opengl_example/Info.plist b/examples/opengl_example/Info.plist new file mode 100644 index 000000000000..9fc503ad2614 --- /dev/null +++ b/examples/opengl_example/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + com.imgui.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2015 IMGUI. All rights reserved. + NSPrincipalClass + NSApplication + + diff --git a/examples/opengl_example/main.mm b/examples/opengl_example/main.mm new file mode 100644 index 000000000000..087716580bef --- /dev/null +++ b/examples/opengl_example/main.mm @@ -0,0 +1,598 @@ +#import +#import +#import +#include "../../imgui.h" + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) +static float highDpiScale = 1.0; +static bool g_mousePressed[2] = { false, false }; +static float g_mouseCoords[2] {0,0}; +static clock_t g_lastClock; +static unsigned int g_windowWidth, g_windowHeight; +static unsigned int g_backingWidth, g_backingHeight; + +void ImImpl_RenderDrawLists(ImDrawData* draw_data) +{ + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((GLint)(pcmd->ClipRect.x*highDpiScale), + (GLint)((height - pcmd->ClipRect.w)*highDpiScale), + (GLint)((pcmd->ClipRect.z - pcmd->ClipRect.x)*highDpiScale), + (GLint)((pcmd->ClipRect.w - pcmd->ClipRect.y)*highDpiScale)); + + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } +#undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, 0); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); +} + +void LoadFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + GLuint tex_id; + glGenTextures(1, &tex_id); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)tex_id; +} + +void IMGUIExample_InitImGui() +{ + ImGuiIO& io = ImGui::GetIO(); + // Time elapsed since last frame, in seconds + // (in this sample app we'll override this every frame because our time step is variable) + // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_Tab] = 9; + io.KeyMap[ImGuiKey_LeftArrow] = ImGuiKey_LeftArrow; + io.KeyMap[ImGuiKey_RightArrow] = ImGuiKey_RightArrow; + io.KeyMap[ImGuiKey_UpArrow] = ImGuiKey_UpArrow; + io.KeyMap[ImGuiKey_DownArrow] = ImGuiKey_DownArrow; + io.KeyMap[ImGuiKey_Home] = ImGuiKey_Home; + io.KeyMap[ImGuiKey_End] = ImGuiKey_End; + io.KeyMap[ImGuiKey_Delete] = ImGuiKey_Delete; + io.KeyMap[ImGuiKey_Backspace] = 127; + io.KeyMap[ImGuiKey_Enter] = 13; + io.KeyMap[ImGuiKey_Escape] = 27; + io.KeyMap[ImGuiKey_A] = 'a'; + io.KeyMap[ImGuiKey_C] = 'c'; + io.KeyMap[ImGuiKey_V] = 'v'; + io.KeyMap[ImGuiKey_X] = 'x'; + io.KeyMap[ImGuiKey_Y] = 'y'; + io.KeyMap[ImGuiKey_Z] = 'z'; + + io.DeltaTime = 1.0f/60.0f; + + io.RenderDrawListsFn = ImImpl_RenderDrawLists; + + LoadFontsTexture(); +} + +void IMGUIExample_Draw(double elapsedMilliseconds) +{ + ImGuiIO& io = ImGui::GetIO(); + // Setup resolution (every frame to accommodate for window resizing) + int w,h; + int display_w, display_h; + display_w = g_backingWidth; + display_h = g_backingHeight; + w = g_windowWidth; + h = g_windowHeight; + highDpiScale = g_backingWidth / g_windowWidth; + // Display size, in pixels. For clamping windows positions. + io.DisplaySize = ImVec2((float)g_windowWidth, (float)g_windowHeight); + + io.DeltaTime = elapsedMilliseconds/100.0; //convert in seconds + + // Setup inputs + double mouse_x = 0, mouse_y = 0; + mouse_x = g_mouseCoords[0]; + mouse_y = g_mouseCoords[1]; + // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); + io.MouseDown[0] = g_mousePressed[0]; + + // If a mouse press event came, always pass it as "mouse held this frame", + // so we don't miss click-release events that are shorter than 1 frame. + + io.MouseDown[1] = g_mousePressed[1]; + + // Start the frame + ImGui::NewFrame(); + static bool show_test_window = true; + static bool show_another_window = false; + static ImVec4 clear_col = ImColor(114, 144, 154); + + // 1. Show a simple window + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + { + static float f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_col); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::Text("Mouse X=%.1f, Y=%.1f", mouse_x, mouse_y); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); + ImGui::Text("Hello"); + ImGui::End(); + } + + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + if (show_test_window) + { + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + GLsizei width = (GLsizei)(io.DisplaySize.x * highDpiScale); + GLsizei height = (GLsizei)(io.DisplaySize.y * highDpiScale); + glViewport(0, 0, width, height); + glClearColor(clear_col.x, clear_col.y, clear_col.z, clear_col.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); +} + +//------------------------------------------------------------------ +// IMGUIExampleView +//------------------------------------------------------------------ + +@interface IMGUIExampleView : NSOpenGLView +{ + NSTimer *animationTimer; +} +@end + +@implementation IMGUIExampleView + +-(void)animationTimerFired:(NSTimer*)timer +{ + [self setNeedsDisplay:YES]; +} + +-(id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format +{ + self = [super initWithFrame:frameRect pixelFormat:format]; + if (self) + { + g_lastClock = clock(); + } + return(self); +} + +- (void)prepareOpenGL +{ + [super prepareOpenGL]; + +#ifndef DEBUG + GLint swapInterval = 1; + [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; + if (swapInterval == 0) + { + NSLog(@"Error: Cannot set swap interval."); + } +#endif +} + +- (void)drawView +{ + NSWindow *mainWindow = [self window]; + NSPoint mousePosition = [mainWindow mouseLocationOutsideOfEventStream]; + + //convert to View + mousePosition = [self convertPoint:mousePosition fromView:nil]; + + g_mouseCoords[0] = mousePosition.x; + g_mouseCoords[1] = mousePosition.y - 1.0f; + + clock_t thisclock = clock(); + unsigned long clock_delay = thisclock - g_lastClock; + double milliseconds = clock_delay * 1000.0f / CLOCKS_PER_SEC; + + IMGUIExample_Draw(milliseconds); + + g_lastClock = thisclock; + + [[self openGLContext] flushBuffer]; + + if (!animationTimer) + { + animationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES] retain]; + } +} + +-(void)setViewportRect:(NSRect)bounds +{ + glViewport(0, 0, bounds.size.width, bounds.size.height); + g_windowWidth = bounds.size.width; + g_windowHeight = bounds.size.height; + + if (g_windowHeight == 0) + { + g_windowHeight = 1; + } + + + ImGui::GetIO().DisplaySize = ImVec2((float)bounds.size.width, (float)bounds.size.height); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + { + NSRect backing = [self convertRectToBacking:bounds]; + g_backingWidth = backing.size.width; + g_backingHeight= backing.size.height; + if (g_backingHeight == 0) + { + g_backingHeight = g_windowHeight * 2; + } + } + else +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + { + g_backingWidth = g_windowWidth; + g_backingHeight= g_windowHeight; + } +} + +-(void)reshape +{ + [self setViewportRect:self.bounds]; + [[self openGLContext] update]; + [self drawView]; +} + +-(void)drawRect:(NSRect)bounds +{ + [self drawView]; +} + +#pragma mark - + +-(BOOL)acceptsFirstResponder +{ + return(YES); +} + +-(BOOL)becomeFirstResponder +{ + return(YES); +} + +-(BOOL)resignFirstResponder +{ + return(YES); +} + +// Flips coordinate system upside down on Y +-(BOOL)isFlipped +{ + return(YES); +} + +#pragma mark Mouse and Key Events. + +static bool mapKeymap(int* keymap) +{ + if(*keymap == NSUpArrowFunctionKey) + *keymap = ImGuiKey_LeftArrow; + else if(*keymap == NSDownArrowFunctionKey) + *keymap = ImGuiKey_DownArrow; + else if(*keymap == NSLeftArrowFunctionKey) + *keymap = ImGuiKey_LeftArrow; + else if(*keymap == NSRightArrowFunctionKey) + *keymap = ImGuiKey_RightArrow; + else if(*keymap == NSHomeFunctionKey) + *keymap = ImGuiKey_Home; + else if(*keymap == NSEndFunctionKey) + *keymap = ImGuiKey_End; + else if(*keymap == NSDeleteFunctionKey) + *keymap = ImGuiKey_Delete; + else if(*keymap == 25) // SHIFT + TAB + *keymap = 9; // TAB + else + return true; + + return false; +} + +static void resetKeys() +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[io.KeyMap[ImGuiKey_A]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_C]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_V]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_X]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_Y]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_Z]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_LeftArrow]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_RightArrow]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_Tab]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_UpArrow]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_DownArrow]] = false; + io.KeysDown[io.KeyMap[ImGuiKey_Tab]] = false; +} + +-(void)keyUp:(NSEvent *)theEvent +{ + NSString *str = [theEvent characters]; + ImGuiIO& io = ImGui::GetIO(); + int len = (int)[str length]; + for(int i = 0; i < len; i++) + { + int keymap = [str characterAtIndex:i]; + mapKeymap(&keymap); + if(keymap < 512) + { + io.KeysDown[keymap] = false; + } + } +} + +-(void)keyDown:(NSEvent *)theEvent +{ + NSString *str = [theEvent characters]; + ImGuiIO& io = ImGui::GetIO(); + int len = (int)[str length]; + for(int i = 0; i < len; i++) + { + int keymap = [str characterAtIndex:i]; + if(mapKeymap(&keymap) && !io.KeyCtrl) + io.AddInputCharacter(keymap); + if(keymap < 512) + { + if(io.KeyCtrl) + { + // we must reset in case we're pressing a sequence + // of special keys while keeping the command pressed + resetKeys(); + } + io.KeysDown[keymap] = true; + } + } +} + +- (void)flagsChanged:(NSEvent *)event +{ + unsigned int flags; + flags = [event modifierFlags] & NSDeviceIndependentModifierFlagsMask; + ImGuiIO& io = ImGui::GetIO(); + bool wasKeyShift= io.KeyShift; + bool wasKeyCtrl = io.KeyCtrl; + io.KeyShift = flags & NSShiftKeyMask; + io.KeyCtrl = flags & NSCommandKeyMask; + bool keyShiftReleased = wasKeyShift && !io.KeyShift; + bool keyCtrlReleased = wasKeyCtrl && !io.KeyCtrl; + if(keyShiftReleased || keyCtrlReleased) + { + // we must reset them as we will not receive any + // keyUp event if they where pressed during shift or command + resetKeys(); + } +} + +-(void)mouseDown:(NSEvent *)theEvent +{ + int button = (int)[theEvent buttonNumber]; + g_mousePressed[button] = true; +} + +-(void)mouseUp:(NSEvent *)theEvent +{ + int button = (int)[theEvent buttonNumber]; + g_mousePressed[button] = false; +} + +- (void)scrollWheel:(NSEvent *)event +{ + double deltaX, deltaY; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + { + deltaX = [event scrollingDeltaX]; + deltaY = [event scrollingDeltaY]; + + if ([event hasPreciseScrollingDeltas]) + { + deltaX *= 0.1; + deltaY *= 0.1; + } + } + else +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + { + deltaX = [event deltaX]; + deltaY = [event deltaY]; + } + + if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0) + { + ImGuiIO& io = ImGui::GetIO(); + io.MouseWheel += deltaY * 0.1f; + } +} + +-(void)dealloc +{ + [animationTimer release]; + [super dealloc]; +} + +@end + +//------------------------------------------------------------------ +// IMGUIExampleAppDelegate +//------------------------------------------------------------------ +@interface IMGUIExampleAppDelegate : NSObject + +@property (nonatomic, readonly) NSWindow *window; + +@end + +@implementation IMGUIExampleAppDelegate + +@synthesize window = _window; + +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication +{ + return YES; +} + +- (NSWindow*)window +{ + if (_window != nil) + return(_window); + + NSRect viewRect = NSMakeRect(100.0, 100.0, 1300.0, 800.0); + + _window = [[NSWindow alloc] initWithContentRect:viewRect styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:YES]; + [_window setTitle:@"IMGUI OSX Sample"]; + [_window setOpaque:YES]; + + [_window makeKeyAndOrderFront:NSApp]; + + return(_window); +} + +- (void)setupMenu +{ + NSMenu *mainMenuBar; + NSMenu *appMenu; + NSMenuItem *menuItem; + + mainMenuBar = [[NSMenu alloc] init]; + + appMenu = [[NSMenu alloc] initWithTitle:@"IMGUI OSX Sample"]; + menuItem = [appMenu addItemWithTitle:@"Quit IMGUI OSX Sample" action:@selector(terminate:) keyEquivalent:@"q"]; + [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; + + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:appMenu]; + + [mainMenuBar addItem:menuItem]; + + [appMenu release]; + [NSApp setMainMenu:mainMenuBar]; +} + +- (void)dealloc +{ + [_window dealloc]; + [super dealloc]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + [self setupMenu]; + + NSOpenGLPixelFormatAttribute attrs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 32, + 0 + }; + + NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + IMGUIExampleView *view = [[IMGUIExampleView alloc] initWithFrame:self.window.frame pixelFormat:format]; + [format release]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + [view setWantsBestResolutionOpenGLSurface:YES]; +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + + [self.window setContentView:view]; + + if ([view openGLContext] == nil) + { + NSLog(@"No OpenGL Context!"); + } + IMGUIExample_InitImGui(); +} + +@end + +//------------------------------------------------------------------ +// main +//------------------------------------------------------------------ + +int main(int argc, const char * argv[]) +{ + [[NSAutoreleasePool alloc] init]; + NSApp = [NSApplication sharedApplication]; + + IMGUIExampleAppDelegate *delegate = [[IMGUIExampleAppDelegate alloc] init]; + + [[NSApplication sharedApplication] setDelegate:delegate]; + [NSApp run]; + return NSApplicationMain(argc, argv); +} diff --git a/examples/opengl_example/main_without_deps.cpp b/examples/opengl_example/main_without_deps.cpp new file mode 100644 index 000000000000..bc34ee9658ed --- /dev/null +++ b/examples/opengl_example/main_without_deps.cpp @@ -0,0 +1,741 @@ +// Basic windows/OGL boilerplate code taken from nehe.gamedev.net with IMGUI integration + +/* + * This Code Was Created By Jeff Molofee 2000 + * A HUGE Thanks To Fredric Echols For Cleaning Up + * And Optimizing This Code, Making It More Flexible! + * If You've Found This Code Useful, Please Let Me Know. + * Visit My Site At nehe.gamedev.net + */ + +#include // Header File For Windows +#include // Header File For The OpenGL32 Library +#include "..\..\imgui.h" +#pragma warning(disable:4244 4100 4505 4706 4701 4706) +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) +double highDpiScale = 1.0f; +HDC hDC=NULL; // Private GDI Device Context +HGLRC hRC=NULL; // Permanent Rendering Context +HWND hWnd=NULL; // Holds Our Window Handle +HINSTANCE hInstance; // Holds The Instance Of The Application + +bool keys[256]; // Array Used For The Keyboard Routine +bool active=TRUE; // Window Active Flag Set To TRUE By Default +bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default + +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc +static bool mousePressed[2] = { false, false }; + +void ImImpl_RenderDrawLists(ImDrawData* draw_data) +{ + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x / highDpiScale; + const float height = ImGui::GetIO().DisplaySize.y / highDpiScale; + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((GLint)(pcmd->ClipRect.x*highDpiScale), + (GLint)((height - pcmd->ClipRect.w)*highDpiScale), + (GLint)((pcmd->ClipRect.z - pcmd->ClipRect.x)*highDpiScale), + (GLint)((pcmd->ClipRect.w - pcmd->ClipRect.y)*highDpiScale)); + + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } +#undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, 0); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); +} + +void LoadFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + //ImFont* my_font1 = io.Fonts->AddFontDefault(); + //ImFont* my_font2 = io.Fonts->AddFontFromFileTTF("extra_fonts/Karla-Regular.ttf", 15.0f); + //ImFont* my_font3 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyClean.ttf", 13.0f); my_font3->DisplayOffset.y += 1; + //ImFont* my_font4 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyTiny.ttf", 10.0f); my_font4->DisplayOffset.y += 1; + //ImFont* my_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 20.0f, io.Fonts->GetGlyphRangesJapanese()); + + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + GLuint tex_id; + glGenTextures(1, &tex_id); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)tex_id; +} + + +void InitImGui() +{ + RECT rect; + GetClientRect(hWnd, &rect); + int display_w = (int)(rect.right - rect.left); + int display_h = (int)(rect.bottom - rect.top); + + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions. + io.DeltaTime = 1.0f / 60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable) + io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. + io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = VK_UP; + io.KeyMap[ImGuiKey_DownArrow] = VK_UP; + io.KeyMap[ImGuiKey_Home] = VK_HOME; + io.KeyMap[ImGuiKey_End] = VK_END; + io.KeyMap[ImGuiKey_Delete] = VK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = VK_BACK; + io.KeyMap[ImGuiKey_Enter] = VK_RETURN; + io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; + io.KeyMap[ImGuiKey_A] = 'A'; + io.KeyMap[ImGuiKey_C] = 'C'; + io.KeyMap[ImGuiKey_V] = 'V'; + io.KeyMap[ImGuiKey_X] = 'X'; + io.KeyMap[ImGuiKey_Y] = 'Y'; + io.KeyMap[ImGuiKey_Z] = 'Z'; + + io.RenderDrawListsFn = ImImpl_RenderDrawLists; + + LoadFontsTexture(); +} +INT64 ticks_per_second = 0; +INT64 last_time = 0; + +void UpdateImGui() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Setup time step + INT64 current_time; + QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); + io.DeltaTime = (float)(current_time - last_time) / ticks_per_second; + last_time = current_time; + + // Setup inputs + // (we already got mouse position, buttons, wheel from the window message callback) + BYTE keystate[256]; + GetKeyboardState(keystate); + for (int i = 0; i < 256; i++) + io.KeysDown[i] = (keystate[i] & 0x80) != 0; + io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0; + io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0; + // io.MousePos : filled by WM_MOUSEMOVE event + // io.MouseDown : filled by WM_*BUTTON* events + // io.MouseWheel : filled by WM_MOUSEWHEEL events + + // Start the frame + ImGui::NewFrame(); +} + +GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window +{ + if (height==0) // Prevent A Divide By Zero By + { + height=1; // Making Height Equal One + } + ImGuiIO& io = ImGui::GetIO(); + glViewport(0,0,width,height); // Reset The Current Viewport + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glLoadIdentity(); // Reset The Projection Matrix + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glLoadIdentity(); // Reset The Modelview Matrix + io.DisplaySize = ImVec2((float)width, (float)height); // Display size, in pixels. For clamping windows positions. +} + +int InitGL(GLvoid) // All Setup For OpenGL Goes Here +{ + InitImGui(); + glShadeModel(GL_SMOOTH); // Enable Smooth Shading + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background + glClearDepth(1.0f); // Depth Buffer Setup + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations + return TRUE; // Initialization Went OK +} +bool show_test_window = true; +bool show_another_window = false; +ImVec4 clear_col = ImColor(114, 144, 154); +int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing +{ + glClearColor(clear_col.x, clear_col.y, clear_col.z, clear_col.w); + glClear(GL_COLOR_BUFFER_BIT); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer + glLoadIdentity(); // Reset The Current Modelview Matrix + UpdateImGui(); + + // 1. Show a simple window + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + { + static float f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_col); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window, ImVec2(200, 100)); + ImGui::Text("Hello"); + ImGui::End(); + } + + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + if (show_test_window) + { + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + ImGui::Render(); + return TRUE; // Everything Went OK +} + +GLvoid KillGLWindow(const char* className) // Properly Kill The Window +{ + ImGui::Shutdown(); + if (fullscreen) // Are We In Fullscreen Mode? + { + ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop + ShowCursor(TRUE); // Show Mouse Pointer + } + + if (hRC) // Do We Have A Rendering Context? + { + if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts? + { + MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + } + + if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? + { + MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + } + hRC=NULL; // Set RC To NULL + } + + if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC + { + MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hDC=NULL; // Set DC To NULL + } + + if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window? + { + MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hWnd=NULL; // Set hWnd To NULL + } + + if (!UnregisterClass(className, hInstance)) // Are We Able To Unregister Class + { + MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hInstance=NULL; // Set hInstance To NULL + } +} + +/* This Code Creates Our OpenGL Window. Parameters Are: * + * title - Title To Appear At The Top Of The Window * + * width - Width Of The GL Window Or Fullscreen Mode * + * height - Height Of The GL Window Or Fullscreen Mode * + * bits - Number Of Bits To Use For Color (8/16/24/32) * + * fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */ + +BOOL CreateGLWindow(const char* title, const char* windowClass, int width, int height, int bits, bool fullscreenflag) +{ + GLuint PixelFormat; // Holds The Results After Searching For A Match + WNDCLASS wc; // Windows Class Structure + DWORD dwExStyle; // Window Extended Style + DWORD dwStyle; // Window Style + RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values + WindowRect.left=(long)0; // Set Left Value To 0 + WindowRect.right=(long)width; // Set Right Value To Requested Width + WindowRect.top=(long)0; // Set Top Value To 0 + WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height + + fullscreen=fullscreenflag; // Set The Global Fullscreen Flag + + hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window. + wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages + wc.cbClsExtra = 0; // No Extra Window Data + wc.cbWndExtra = 0; // No Extra Window Data + wc.hInstance = hInstance; // Set The Instance + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon + wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer + wc.hbrBackground = NULL; // No Background Required For GL + wc.lpszMenuName = NULL; // We Don't Want A Menu + wc.lpszClassName = windowClass; // Set The Class Name + + if (!RegisterClass(&wc)) // Attempt To Register The Window Class + { + MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (fullscreen) // Attempt Fullscreen Mode? + { + DEVMODE dmScreenSettings; // Device Mode + memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared + dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure + dmScreenSettings.dmPelsWidth = width; // Selected Screen Width + dmScreenSettings.dmPelsHeight = height; // Selected Screen Height + dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel + dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; + + // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. + if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) + { + // If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode. + if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) + { + fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE + } + else + { + // Pop Up A Message Box Letting User Know The Program Is Closing. + MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP); + return FALSE; // Return FALSE + } + } + } + + if (fullscreen) // Are We Still In Fullscreen Mode? + { + dwExStyle=WS_EX_APPWINDOW; // Window Extended Style + dwStyle=WS_POPUP; // Windows Style + ShowCursor(FALSE); // Hide Mouse Pointer + } + else + { + dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style + dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style + } + + AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size + + // Create The Window + if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window + windowClass, // Class Name + title, // Window Title + dwStyle | // Defined Window Style + WS_CLIPSIBLINGS | // Required Window Style + WS_CLIPCHILDREN, // Required Window Style + 0, 0, // Window Position + WindowRect.right-WindowRect.left, // Calculate Window Width + WindowRect.bottom-WindowRect.top, // Calculate Window Height + NULL, // No Parent Window + NULL, // No Menu + hInstance, // Instance + NULL))) // Dont Pass Anything To WM_CREATE + { + KillGLWindow(windowClass); // Reset The Display + MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + bits, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 16, // 16Bit Z-Buffer (Depth Buffer) + 0, // No Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context? + { + KillGLWindow(windowClass); // Reset The Display + MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format? + { + KillGLWindow(windowClass); // Reset The Display + MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format? + { + KillGLWindow(windowClass); // Reset The Display + MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context? + { + KillGLWindow(windowClass); // Reset The Display + MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context + { + KillGLWindow(windowClass); // Reset The Display + MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + ShowWindow(hWnd,SW_SHOW); // Show The Window + SetForegroundWindow(hWnd); // Slightly Higher Priority + SetFocus(hWnd); // Sets Keyboard Focus To The Window + ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen + + if (!InitGL()) // Initialize Our Newly Created GL Window + { + KillGLWindow(windowClass); // Reset The Display + MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + return TRUE; // Success +} + +LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window + UINT uMsg, // Message For This Window + WPARAM wParam, // Additional Message Information + LPARAM lParam) // Additional Message Information +{ + ImGuiIO& io = ImGui::GetIO(); + switch (uMsg) // Check For Windows Messages + { + case WM_ACTIVATE: // Watch For Window Activate Message + { + if (!HIWORD(wParam)) // Check Minimization State + { + active=TRUE; // Program Is Active + } + else + { + active=FALSE; // Program Is No Longer Active + } + + return 0; // Return To The Message Loop + } + + case WM_SYSCOMMAND: // Intercept System Commands + { + switch (wParam) // Check System Calls + { + case SC_SCREENSAVE: // Screensaver Trying To Start? + case SC_MONITORPOWER: // Monitor Trying To Enter Powersave? + return 0; // Prevent From Happening + } + break; // Exit + } + + case WM_CLOSE: // Did We Receive A Close Message? + { + PostQuitMessage(0); // Send A Quit Message + return 0; // Jump Back + } + + case WM_KEYDOWN: // Is A Key Being Held Down? + { + keys[wParam] = TRUE; // If So, Mark It As TRUE + return 0; // Jump Back + } + + case WM_KEYUP: // Has A Key Been Released? + { + keys[wParam] = FALSE; // If So, Mark It As FALSE + return 0; // Jump Back + } + + case WM_SIZE: // Resize The OpenGL Window + { + ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord=Width, HiWord=Height + return 0; // Jump Back + } + case WM_ENTERSIZEMOVE: + { + SetTimer(hWnd, 1, ImGui::GetIO().DeltaTime*1000, (TIMERPROC)NULL); + return 0; + } + + case WM_EXITSIZEMOVE: + { + KillTimer(hWnd, 1); + return 0; + } + case WM_TIMER : + { + switch (wParam) + { + case 1: + { + DrawGLScene(); + SwapBuffers(hDC); + } + } + } + case WM_LBUTTONDOWN: + io.MouseDown[0] = true; + return true; + case WM_LBUTTONUP: + io.MouseDown[0] = false; + return true; + case WM_RBUTTONDOWN: + io.MouseDown[1] = true; + return true; + case WM_RBUTTONUP: + io.MouseDown[1] = false; + return true; + case WM_MOUSEWHEEL: + io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) / 100.0f;// > 0 ? +0.1f : -0.1f; + return true; + case WM_MOUSEMOVE: + // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + io.MousePos.x = (signed short)(lParam); + io.MousePos.y = (signed short)(lParam >> 16); + io.MousePos.x /= highDpiScale; + io.MousePos.y /= highDpiScale; + return true; + case WM_CHAR: + // You can also use ToAscii()+GetKeyboardState() to retrieve characters. + if (wParam > 0 && wParam < 0x10000) + io.AddInputCharacter((unsigned short)wParam); + return true; + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + } + + // Pass All Unhandled Messages To DefWindowProc + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} +// Get the horizontal and vertical screen sizes in pixel +void GetDesktopResolution(int& horizontal, int& vertical) +{ + RECT desktop; + // Get a handle to the desktop window + const HWND hDesktop = GetDesktopWindow(); + // Get the size of screen to the variable desktop + GetWindowRect(hDesktop, &desktop); + // The top left corner will have coordinates (0,0) + // and the bottom right corner will have coordinates + // (horizontal, vertical) + horizontal = desktop.right; + vertical = desktop.bottom; +} + +void* getUser32Function(const char* functionName) +{ + HMODULE module = GetModuleHandleA("user32.dll"); + assert(module != 0); + return (void*)GetProcAddress(module, functionName); +} + +#ifndef MONITOR_DPI_TYPE +enum Monitor_DPI_Type +{ + MDT_Effective_DPI = 0, + MDT_Angular_DPI = 1, + MDT_Raw_DPI = 2, + MDT_Default = MDT_Effective_DPI +}; + +enum Process_DPI_Awareness +{ + Process_DPI_Unaware = 0, + Process_System_DPI_Aware = 1, + Process_Per_Monitor_DPI_Aware = 2 +}; +#endif + +typedef BOOL(WINAPI* SetProcessDPIAwareFunc)(); +typedef BOOL(WINAPI* SetProcessDPIAwarenessFunc) (Process_DPI_Awareness); +typedef HRESULT(WINAPI* GetDPIForMonitorFunc) (HMONITOR, Monitor_DPI_Type, UINT*, UINT*); + +static SetProcessDPIAwareFunc setProcessDPIAware = nullptr; +static SetProcessDPIAwarenessFunc setProcessDPIAwareness = nullptr; +static GetDPIForMonitorFunc getDPIForMonitor = nullptr; + +//============================================================================== +static void setDPIAwareness() +{ + if (setProcessDPIAwareness == nullptr) + { + HMODULE shcoreModule = GetModuleHandleA("SHCore.dll"); + + if (shcoreModule != 0) + { + setProcessDPIAwareness = (SetProcessDPIAwarenessFunc)GetProcAddress(shcoreModule, "SetProcessDpiAwareness"); + getDPIForMonitor = (GetDPIForMonitorFunc)GetProcAddress(shcoreModule, "GetDpiForMonitor"); + + if (setProcessDPIAwareness != nullptr && getDPIForMonitor != nullptr + // && SUCCEEDED (setProcessDPIAwareness (Process_Per_Monitor_DPI_Aware))) + && SUCCEEDED(setProcessDPIAwareness(Process_System_DPI_Aware))) // (keep using this mode temporarily..) + return; + } + + if (setProcessDPIAware == nullptr) + { + setProcessDPIAware = (SetProcessDPIAwareFunc)getUser32Function("SetProcessDPIAware"); + + if (setProcessDPIAware != nullptr) + setProcessDPIAware(); + } + } +} + +static double getGlobalDPI() +{ + setDPIAwareness(); + + HDC dc = GetDC(0); + const double dpi = (GetDeviceCaps(dc, LOGPIXELSX) + + GetDeviceCaps(dc, LOGPIXELSY)) / 2.0; + ReleaseDC(0, dc); + return dpi; +} + +double getDefaultMasterScale() +{ + return getGlobalDPI() / 96.0; +} + +int WINAPI WinMain( HINSTANCE hInstance, // Instance + HINSTANCE hPrevInstance, // Previous Instance + LPSTR lpCmdLine, // Command Line Parameters + int nCmdShow) // Window Show State +{ + setDPIAwareness(); + highDpiScale = getDefaultMasterScale(); + const char* window_name = "rrGui"; + const char* class_name = "rrGui"; + MSG msg; // Windows Message Structure + BOOL done=FALSE; // Bool Variable To Exit Loop + if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second)) + return 1; + if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time)) + return 1; + int width = 1024 * highDpiScale; + int height = 768 * highDpiScale; + fullscreen=FALSE; // Windowed Mode + + // Create Our OpenGL Window + if (!CreateGLWindow(window_name, class_name, width, height, 32, fullscreen)) + { + return 0; // Quit If Window Was Not Created + } + + while(!done) // Loop That Runs While done=FALSE + { + if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? + { + if (msg.message==WM_QUIT) // Have We Received A Quit Message? + { + done=TRUE; // If So done=TRUE + } + else // If Not, Deal With Window Messages + { + TranslateMessage(&msg); // Translate The Message + DispatchMessage(&msg); // Dispatch The Message + } + } + else // If There Are No Messages + { + // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() + if (active) // Program Active? + { + if (keys[VK_ESCAPE]) // Was ESC Pressed? + { + int res = MessageBox(NULL, "Do you really want to quit the application?", + "Quit?", MB_YESNO | MB_ICONEXCLAMATION); + if (res == IDYES) + { + done = TRUE; // ESC Signalled A Quit + } + } + else // Not Time To Quit, Update Screen + { + DrawGLScene(); // Draw The Scene + SwapBuffers(hDC); // Swap Buffers (Double Buffering) + } + } + } + } + + // Shutdown + KillGLWindow(class_name); // Kill The Window + return (msg.wParam); // Exit The Program +} diff --git a/examples/opengl_example/opengl_example_without_deps.vcxproj b/examples/opengl_example/opengl_example_without_deps.vcxproj new file mode 100644 index 000000000000..6553dc3ba617 --- /dev/null +++ b/examples/opengl_example/opengl_example_without_deps.vcxproj @@ -0,0 +1,96 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + + Level3 + Disabled + + + + + true + + + opengl32.lib;%(AdditionalDependencies) + Windows + + + + + + + Level3 + MaxSpeed + true + true + + + + + true + true + true + + + opengl32.lib;%(AdditionalDependencies) + Windows + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.pbxproj b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..7c36c3a11829 --- /dev/null +++ b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.pbxproj @@ -0,0 +1,266 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 7BDE201B1A9235A500766EFE /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B2310C11A92346A0028144F /* imgui.cpp */; }; + 7BDE201C1A9235A500766EFE /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7B2310BB1A92342C0028144F /* main.mm */; }; + 7BDE201D1A9235AB00766EFE /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B2310BD1A9234540028144F /* OpenGL.framework */; }; + 7BDE201E1A9235B000766EFE /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B2310BF1A92345A0028144F /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 7B2310BA1A92342C0028144F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7B2310BB1A92342C0028144F /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; + 7B2310BD1A9234540028144F /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 7B2310BF1A92345A0028144F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 7B2310C11A92346A0028144F /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 7B2310C31A92347B0028144F /* imgui.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 7B2310C41A9234810028144F /* imconfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 7BDE1FFB1A92357F00766EFE /* opengl_sample_without_deps.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = opengl_sample_without_deps.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7BDE1FF81A92357F00766EFE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDE201E1A9235B000766EFE /* Cocoa.framework in Frameworks */, + 7BDE201D1A9235AB00766EFE /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7BE9E7FA1A9233C7009BE5BF = { + isa = PBXGroup; + children = ( + 7B2310BF1A92345A0028144F /* Cocoa.framework */, + 7B2310BD1A9234540028144F /* OpenGL.framework */, + 7B2310BA1A92342C0028144F /* Info.plist */, + 7B2310C41A9234810028144F /* imconfig.h */, + 7B2310C11A92346A0028144F /* imgui.cpp */, + 7B2310C31A92347B0028144F /* imgui.h */, + 7B2310BB1A92342C0028144F /* main.mm */, + 7BE9E8041A9233C7009BE5BF /* Products */, + ); + sourceTree = ""; + }; + 7BE9E8041A9233C7009BE5BF /* Products */ = { + isa = PBXGroup; + children = ( + 7BDE1FFB1A92357F00766EFE /* opengl_sample_without_deps.app */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7BDE1FFA1A92357F00766EFE /* opengl_sample_without_deps */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7BDE20151A92357F00766EFE /* Build configuration list for PBXNativeTarget "opengl_sample_without_deps" */; + buildPhases = ( + 7BDE1FF71A92357F00766EFE /* Sources */, + 7BDE1FF81A92357F00766EFE /* Frameworks */, + 7BDE1FF91A92357F00766EFE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = opengl_sample_without_deps; + productName = opengl_sample; + productReference = 7BDE1FFB1A92357F00766EFE /* opengl_sample_without_deps.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7BE9E7FB1A9233C7009BE5BF /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "Stefano Cristiano"; + TargetAttributes = { + 7BDE1FFA1A92357F00766EFE = { + CreatedOnToolsVersion = 6.1.1; + }; + }; + }; + buildConfigurationList = 7BE9E7FE1A9233C7009BE5BF /* Build configuration list for PBXProject "opengl_example_without_deps" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7BE9E7FA1A9233C7009BE5BF; + productRefGroup = 7BE9E8041A9233C7009BE5BF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7BDE1FFA1A92357F00766EFE /* opengl_sample_without_deps */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7BDE1FF91A92357F00766EFE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7BDE1FF71A92357F00766EFE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BDE201B1A9235A500766EFE /* imgui.cpp in Sources */, + 7BDE201C1A9235A500766EFE /* main.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 7BDE20161A92357F00766EFE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_OBJC_ARC = NO; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 7BDE20171A92357F00766EFE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_OBJC_ARC = NO; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 7BE9E8081A9233C7009BE5BF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + 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; + MACOSX_DEPLOYMENT_TARGET = 10.7; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx10.9; + }; + name = Debug; + }; + 7BE9E8091A9233C7009BE5BF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + 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; + MACOSX_DEPLOYMENT_TARGET = 10.7; + MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx10.9; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7BDE20151A92357F00766EFE /* Build configuration list for PBXNativeTarget "opengl_sample_without_deps" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BDE20161A92357F00766EFE /* Debug */, + 7BDE20171A92357F00766EFE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7BE9E7FE1A9233C7009BE5BF /* Build configuration list for PBXProject "opengl_example_without_deps" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BE9E8081A9233C7009BE5BF /* Debug */, + 7BE9E8091A9233C7009BE5BF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7BE9E7FB1A9233C7009BE5BF /* Project object */; +} diff --git a/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..d30a9c651ff1 --- /dev/null +++ b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcshareddata/opengl_example.xccheckout b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcshareddata/opengl_example.xccheckout new file mode 100644 index 000000000000..01fe6dc390dc --- /dev/null +++ b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcshareddata/opengl_example.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 07C3FA46-F2EB-47E8-B956-B926A9C85BE5 + IDESourceControlProjectName + opengl_example + IDESourceControlProjectOriginsDictionary + + 0C95EEA8FF0C0E695973CB8EA4E7E70E385D606F + https://github.com/Pagghiu/imgui.git + + IDESourceControlProjectPath + examples/opengl_example/opengl_example.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + 0C95EEA8FF0C0E695973CB8EA4E7E70E385D606F + ../../../.. + + IDESourceControlProjectURL + https://github.com/Pagghiu/imgui.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 0C95EEA8FF0C0E695973CB8EA4E7E70E385D606F + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 0C95EEA8FF0C0E695973CB8EA4E7E70E385D606F + IDESourceControlWCCName + imgui-pagghiu + + + + diff --git a/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcuserdata/stefano.xcuserdatad/UserInterfaceState.xcuserstate b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcuserdata/stefano.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 000000000000..88271e8acc1a Binary files /dev/null and b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcuserdata/stefano.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcuserdata/stefano.xcuserdatad/WorkspaceSettings.xcsettings b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcuserdata/stefano.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..bfffcfe01a44 --- /dev/null +++ b/examples/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/xcuserdata/stefano.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + SnapshotAutomaticallyBeforeSignificantChanges + + +