diff --git a/examples/README.txt b/examples/README.txt index f8e0c55e..df6fe879 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -63,9 +63,9 @@ directx11_example/ DirectX11 example, Windows only. This is quite long and tedious, because: DirectX11. -ios_example/ - iOS example. - Using Synergy to access keyboard/mouse data from server computer. +apple_example/ + OSX & iOS example. + On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. sdl_opengl_example/ @@ -79,4 +79,8 @@ allegro5_example/ marmalade_example/ Marmalade example using IwGx - + +vulkan_example/ + Vulkan example. + This is quite long and tedious, because: Vulkan. + diff --git a/examples/ios_example/.gitignore b/examples/apple_example/.gitignore similarity index 100% rename from examples/ios_example/.gitignore rename to examples/apple_example/.gitignore diff --git a/examples/ios_example/README.md b/examples/apple_example/README.md similarity index 50% rename from examples/ios_example/README.md rename to examples/apple_example/README.md index a2ada955..339f6bf8 100644 --- a/examples/ios_example/README.md +++ b/examples/apple_example/README.md @@ -1,20 +1,27 @@ -# iOS example +# iOS / OSX example ## Introduction -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/) to share mouse/keyboard on an iOS device. -It is a rather complex example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. +It is a rather complex and messy example because of all of the faff required to get an XCode/iOS application running. Refer to the regular OpenGL examples if you want to learn about integrating ImGui. **The opengl3_example/ should also work on OS X and is much simpler.** This is an integration for iOS with Synergy. Synergy (remote keyboard/mouse) is not required, but it's pretty hard to use ImGui without it. Synergy includes a "uSynergy" library that allows embedding a synergy client, this is what is used here. ImGui supports "TouchPadding", and this is enabled when Synergy is not active. -## How to Use +## How to Use on iOS -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. +* In Synergy, go to Preferences, and uncheck "Use SSL encryption" +* Run the example app. +* Tap the "servername" button in the corner +* Enter the name or the IP of your synergy host +* If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Build on OSX + +* Make sure you have install `brew`, if not, please refer to [Homebrew Website](http://brew.sh) +* Run the command: `brew install glfw3` +* Double click `imguiex.xcodeproj` and select `imguiex-osx` scheme +* Click `Run` button ## Notes and TODOs @@ -25,7 +32,8 @@ Things that would be nice but I didn't get around to doing: * Graceful disconnect/reconnect from uSynergy. * Copy/Paste not well-supported -## C++ on iOS +## C++ on iOS / OSX + ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h similarity index 100% rename from examples/ios_example/imguiex/AppDelegate.h rename to examples/apple_example/imguiex-ios/AppDelegate.h diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m similarity index 100% rename from examples/ios_example/imguiex/AppDelegate.m rename to examples/apple_example/imguiex-ios/AppDelegate.m diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib similarity index 100% rename from examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib rename to examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard similarity index 100% rename from examples/ios_example/imguiex/Base.lproj/Main.storyboard rename to examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h similarity index 100% rename from examples/ios_example/imguiex/GameViewController.h rename to examples/apple_example/imguiex-ios/GameViewController.h diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m similarity index 100% rename from examples/ios_example/imguiex/GameViewController.m rename to examples/apple_example/imguiex-ios/GameViewController.m diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 93% rename from examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json rename to examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json index a05a29bb..06b60d8b 100644 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -63,6 +63,11 @@ "idiom" : "ipad", "filename" : "icon_imgui_76@2x~ipad.png", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" } ], "info" : { diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png similarity index 100% rename from examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png rename to examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png similarity index 100% rename from examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png rename to examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png similarity index 100% rename from examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png rename to examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png similarity index 100% rename from examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png rename to examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png diff --git a/examples/ios_example/imguiex/Info.plist b/examples/apple_example/imguiex-ios/Info.plist similarity index 100% rename from examples/ios_example/imguiex/Info.plist rename to examples/apple_example/imguiex-ios/Info.plist diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh similarity index 100% rename from examples/ios_example/imguiex/Shaders/Shader.fsh rename to examples/apple_example/imguiex-ios/Shaders/Shader.fsh diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh similarity index 100% rename from examples/ios_example/imguiex/Shaders/Shader.vsh rename to examples/apple_example/imguiex-ios/Shaders/Shader.vsh diff --git a/examples/ios_example/imguiex/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp similarity index 100% rename from examples/ios_example/imguiex/debug_hud.cpp rename to examples/apple_example/imguiex-ios/debug_hud.cpp diff --git a/examples/ios_example/imguiex/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h similarity index 100% rename from examples/ios_example/imguiex/debug_hud.h rename to examples/apple_example/imguiex-ios/debug_hud.h diff --git a/examples/ios_example/imguiex/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png similarity index 100% rename from examples/ios_example/imguiex/imgui_ex_icon.png rename to examples/apple_example/imguiex-ios/imgui_ex_icon.png diff --git a/examples/ios_example/imguiex/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h similarity index 100% rename from examples/ios_example/imguiex/imgui_impl_ios.h rename to examples/apple_example/imguiex-ios/imgui_impl_ios.h diff --git a/examples/ios_example/imguiex/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm similarity index 100% rename from examples/ios_example/imguiex/imgui_impl_ios.mm rename to examples/apple_example/imguiex-ios/imgui_impl_ios.mm diff --git a/examples/ios_example/imguiex/main.m b/examples/apple_example/imguiex-ios/main.m similarity index 100% rename from examples/ios_example/imguiex/main.m rename to examples/apple_example/imguiex-ios/main.m diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 00000000..33d199bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 00000000..59e877b3 --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..b13908fc --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 00000000..f48b799d Binary files /dev/null and b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 00000000..ba1c2bb0 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 00000000..20b07313 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj similarity index 66% rename from examples/ios_example/imguiex.xcodeproj/project.pbxproj rename to examples/apple_example/imguiex.xcodeproj/project.pbxproj index 26bcff49..652d15b6 100644 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -9,6 +9,16 @@ /* Begin PBXBuildFile section */ 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; @@ -28,9 +38,18 @@ /* Begin PBXFileReference section */ 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = ""; }; 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -54,6 +73,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6D2FC5511B2E632000C130BA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -66,6 +93,38 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; 6D1E39141B35EEF10017B40F /* usynergy */ = { isa = PBXGroup; children = ( @@ -81,7 +140,8 @@ children = ( 6D1E39141B35EEF10017B40F /* usynergy */, 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, 6D2FC5551B2E632000C130BA /* Products */, ); sourceTree = ""; @@ -89,12 +149,13 @@ 6D2FC5551B2E632000C130BA /* Products */ = { isa = PBXGroup; children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, ); name = Products; sourceTree = ""; }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { isa = PBXGroup; children = ( 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, @@ -113,7 +174,7 @@ 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, 6D2FC5571B2E632000C130BA /* Supporting Files */, ); - path = imguiex; + path = "imguiex-ios"; sourceTree = ""; }; 6D2FC5571B2E632000C130BA /* Supporting Files */ = { @@ -141,9 +202,26 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; buildPhases = ( 6D2FC5501B2E632000C130BA /* Sources */, 6D2FC5511B2E632000C130BA /* Frameworks */, @@ -153,9 +231,9 @@ ); dependencies = ( ); - name = imguiex; + name = "imguiex-ios"; productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -167,6 +245,9 @@ LastUpgradeCheck = 0630; ORGANIZATIONNAME = "Joel Davis"; TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; 6D2FC5531B2E632000C130BA = { CreatedOnToolsVersion = 6.3.2; }; @@ -185,12 +266,21 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6D2FC5521B2E632000C130BA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -206,6 +296,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6D2FC5501B2E632000C130BA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -244,6 +349,54 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; 6D2FC5791B2E632000C130BA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -280,11 +433,13 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; }; @@ -318,10 +473,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; VALIDATE_PRODUCT = YES; }; name = Release; @@ -330,7 +487,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -340,7 +497,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -349,6 +506,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -358,7 +524,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { isa = XCConfigurationList; buildConfigurations = ( 6D2FC57C1B2E632000C130BA /* Debug */, diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 21f86f5d..f0e57f72 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -46,6 +46,8 @@ struct VERTEX_CONSTANT_BUFFER // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) { + ID3D10Device* ctx = g_pd3dDevice; + // Create and grow vertex/index buffers if needed if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) { @@ -58,7 +60,7 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0) + if (ctx->CreateBuffer(&desc, NULL, &g_pVB) < 0) return; } @@ -66,13 +68,13 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) { if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } g_IndexBufferSize = draw_data->TotalIdxCount + 10000; - D3D10_BUFFER_DESC bufferDesc; - memset(&bufferDesc, 0, sizeof(D3D10_BUFFER_DESC)); - bufferDesc.Usage = D3D10_USAGE_DYNAMIC; - bufferDesc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); - bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER; - bufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; - if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pIB) < 0) + D3D10_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D10_BUFFER_DESC)); + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); + desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + if (ctx->CreateBuffer(&desc, NULL, &g_pIB) < 0) return; } @@ -81,7 +83,6 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) ImDrawIdx* idx_dst = NULL; g_pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst); g_pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst); - for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; @@ -95,11 +96,10 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) // Setup orthographic projection matrix into our constant buffer { - void* mappedResource; - if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) + void* mapped_resource; + if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) return; - - VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource; + VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource; const float L = 0.0f; const float R = ImGui::GetIO().DisplaySize.x; const float B = ImGui::GetIO().DisplaySize.y; @@ -111,39 +111,72 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) { 0.0f, 0.0f, 0.5f, 0.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, }; - memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp)); + memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); g_pVertexConstantBuffer->Unmap(); } - // Setup viewport + // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) + struct BACKUP_DX10_STATE { - D3D10_VIEWPORT vp; - memset(&vp, 0, sizeof(D3D10_VIEWPORT)); - vp.Width = (UINT)ImGui::GetIO().DisplaySize.x; - vp.Height = (UINT)ImGui::GetIO().DisplaySize.y; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - vp.TopLeftX = 0; - vp.TopLeftY = 0; - g_pd3dDevice->RSSetViewports(1, &vp); - } + UINT ScissorRectsCount, ViewportsCount; + D3D10_RECT ScissorRects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D10_VIEWPORT Viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D10RasterizerState* RS; + ID3D10BlendState* BlendState; + FLOAT BlendFactor[4]; + UINT SampleMask; + ID3D10ShaderResourceView* PSShaderResource; + ID3D10SamplerState* PSSampler; + ID3D10PixelShader* PS; + ID3D10VertexShader* VS; + D3D10_PRIMITIVE_TOPOLOGY PrimitiveTopology; + ID3D10Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; + UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; + DXGI_FORMAT IndexBufferFormat; + ID3D10InputLayout* InputLayout; + }; + BACKUP_DX10_STATE old; + old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); + ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); + ctx->RSGetState(&old.RS); + ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); + ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); + ctx->PSGetSamplers(0, 1, &old.PSSampler); + ctx->PSGetShader(&old.PS); + ctx->VSGetShader(&old.VS); + ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); + ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); + ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); + ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); + ctx->IAGetInputLayout(&old.InputLayout); + + // Setup viewport + D3D10_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D10_VIEWPORT)); + vp.Width = (UINT)ImGui::GetIO().DisplaySize.x; + vp.Height = (UINT)ImGui::GetIO().DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = vp.TopLeftY = 0; + ctx->RSSetViewports(1, &vp); // Bind shader and vertex buffers unsigned int stride = sizeof(ImDrawVert); unsigned int offset = 0; - g_pd3dDevice->IASetInputLayout(g_pInputLayout); - g_pd3dDevice->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); - g_pd3dDevice->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); - g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - g_pd3dDevice->VSSetShader(g_pVertexShader); - g_pd3dDevice->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); - g_pd3dDevice->PSSetShader(g_pPixelShader); - g_pd3dDevice->PSSetSamplers(0, 1, &g_pFontSampler); + ctx->IASetInputLayout(g_pInputLayout); + ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); + ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); + ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->VSSetShader(g_pVertexShader); + ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); + ctx->PSSetShader(g_pPixelShader); + ctx->PSSetSamplers(0, 1, &g_pFontSampler); // Setup render state - const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; - g_pd3dDevice->OMSetBlendState(g_pBlendState, blendFactor, 0xffffffff); - g_pd3dDevice->RSSetState(g_pRasterizerState); + const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; + ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff); + ctx->RSSetState(g_pRasterizerState); // Render command lists int vtx_offset = 0; @@ -161,19 +194,29 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) else { const D3D10_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; - g_pd3dDevice->PSSetShaderResources(0, 1, (ID3D10ShaderResourceView**)&pcmd->TextureId); - g_pd3dDevice->RSSetScissorRects(1, &r); - g_pd3dDevice->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); + ctx->PSSetShaderResources(0, 1, (ID3D10ShaderResourceView**)&pcmd->TextureId); + ctx->RSSetScissorRects(1, &r); + ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); } idx_offset += pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.size(); } - // Restore modified state - g_pd3dDevice->IASetInputLayout(NULL); - g_pd3dDevice->PSSetShader(NULL); - g_pd3dDevice->VSSetShader(NULL); + // Restore modified DX state + ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); + ctx->RSSetViewports(old.ViewportsCount, old.Viewports); + ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); + ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); + ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); + ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); + ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release(); + ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release(); + ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); + ctx->IASetPrimitiveTopology(old.PrimitiveTopology); + ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); + ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); + ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } IMGUI_API LRESULT ImGui_ImplDX10_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) @@ -234,33 +277,33 @@ static void ImGui_ImplDX10_CreateFontsTexture() // Create DX10 texture { - D3D10_TEXTURE2D_DESC texDesc; - ZeroMemory(&texDesc, sizeof(texDesc)); - texDesc.Width = width; - texDesc.Height = height; - texDesc.MipLevels = 1; - texDesc.ArraySize = 1; - texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - texDesc.SampleDesc.Count = 1; - texDesc.Usage = D3D10_USAGE_DEFAULT; - texDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE; - texDesc.CPUAccessFlags = 0; + D3D10_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D10_USAGE_DEFAULT; + desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; ID3D10Texture2D *pTexture = NULL; D3D10_SUBRESOURCE_DATA subResource; subResource.pSysMem = pixels; - subResource.SysMemPitch = texDesc.Width * 4; + subResource.SysMemPitch = desc.Width * 4; subResource.SysMemSlicePitch = 0; - g_pd3dDevice->CreateTexture2D(&texDesc, &subResource, &pTexture); + g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); // Create texture view - D3D10_SHADER_RESOURCE_VIEW_DESC srvDesc; - ZeroMemory(&srvDesc, sizeof(srvDesc)); - srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - srvDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = texDesc.MipLevels; - srvDesc.Texture2D.MostDetailedMip = 0; - g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); + D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc; + ZeroMemory(&srv_desc, sizeof(srv_desc)); + srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; + srv_desc.Texture2D.MipLevels = desc.MipLevels; + srv_desc.Texture2D.MostDetailedMip = 0; + g_pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &g_pFontTextureView); pTexture->Release(); } @@ -269,17 +312,17 @@ static void ImGui_ImplDX10_CreateFontsTexture() // Create texture sampler { - D3D10_SAMPLER_DESC samplerDesc; - ZeroMemory(&samplerDesc, sizeof(samplerDesc)); - samplerDesc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; - samplerDesc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; - samplerDesc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP; - samplerDesc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP; - samplerDesc.MipLODBias = 0.f; - samplerDesc.ComparisonFunc = D3D10_COMPARISON_ALWAYS; - samplerDesc.MinLOD = 0.f; - samplerDesc.MaxLOD = 0.f; - g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); + D3D10_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; + desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP; + desc.MipLODBias = 0.f; + desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS; + desc.MinLOD = 0.f; + desc.MaxLOD = 0.f; + g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler); } // Cleanup (don't clear the input data if you want to append new fonts later) @@ -331,24 +374,24 @@ bool ImGui_ImplDX10_CreateDeviceObjects() return false; // Create the input layout - D3D10_INPUT_ELEMENT_DESC localLayout[] = { + D3D10_INPUT_ELEMENT_DESC local_layout[] = + { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; - - if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) return false; // Create the constant buffer { - D3D10_BUFFER_DESC cbDesc; - cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); - cbDesc.Usage = D3D10_USAGE_DYNAMIC; - cbDesc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; - cbDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; - cbDesc.MiscFlags = 0; - g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); + D3D10_BUFFER_DESC desc; + desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); + desc.Usage = D3D10_USAGE_DYNAMIC; + desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer); } } diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 8451fb8e..5f209bc0 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -46,6 +46,8 @@ struct VERTEX_CONSTANT_BUFFER // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) { + ID3D11DeviceContext* ctx = g_pd3dDeviceContext; + // Create and grow vertex/index buffers if needed if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) { @@ -65,21 +67,21 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) { if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } g_IndexBufferSize = draw_data->TotalIdxCount + 10000; - D3D11_BUFFER_DESC bufferDesc; - memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); - bufferDesc.Usage = D3D11_USAGE_DYNAMIC; - bufferDesc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); - bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pIB) < 0) + D3D11_BUFFER_DESC desc; + memset(&desc, 0, sizeof(D3D11_BUFFER_DESC)); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); + desc.BindFlags = D3D11_BIND_INDEX_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0) return; } // Copy and convert all vertices into a single contiguous buffer D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; - if (g_pd3dDeviceContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) + if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) return; - if (g_pd3dDeviceContext->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) + if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) return; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; @@ -91,60 +93,95 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) vtx_dst += cmd_list->VtxBuffer.size(); idx_dst += cmd_list->IdxBuffer.size(); } - g_pd3dDeviceContext->Unmap(g_pVB, 0); - g_pd3dDeviceContext->Unmap(g_pIB, 0); + ctx->Unmap(g_pVB, 0); + ctx->Unmap(g_pIB, 0); // Setup orthographic projection matrix into our constant buffer { - D3D11_MAPPED_SUBRESOURCE mappedResource; - if (g_pd3dDeviceContext->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) + D3D11_MAPPED_SUBRESOURCE mapped_resource; + if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) return; - - VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource.pData; - const float L = 0.0f; - const float R = ImGui::GetIO().DisplaySize.x; - const float B = ImGui::GetIO().DisplaySize.y; - const float T = 0.0f; - const float mvp[4][4] = + VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData; + float L = 0.0f; + float R = ImGui::GetIO().DisplaySize.x; + float B = ImGui::GetIO().DisplaySize.y; + float T = 0.0f; + float mvp[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, 0.5f, 0.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, }; - memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp)); - g_pd3dDeviceContext->Unmap(g_pVertexConstantBuffer, 0); + memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); + ctx->Unmap(g_pVertexConstantBuffer, 0); } - // Setup viewport + // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!) + struct BACKUP_DX11_STATE { - D3D11_VIEWPORT vp; - memset(&vp, 0, sizeof(D3D11_VIEWPORT)); - vp.Width = ImGui::GetIO().DisplaySize.x; - vp.Height = ImGui::GetIO().DisplaySize.y; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - vp.TopLeftX = 0; - vp.TopLeftY = 0; - g_pd3dDeviceContext->RSSetViewports(1, &vp); - } + UINT ScissorRectsCount, ViewportsCount; + D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D11RasterizerState* RS; + ID3D11BlendState* BlendState; + FLOAT BlendFactor[4]; + UINT SampleMask; + ID3D11ShaderResourceView* PSShaderResource; + ID3D11SamplerState* PSSampler; + ID3D11PixelShader* PS; + ID3D11VertexShader* VS; + UINT PSInstancesCount, VSInstancesCount; + ID3D11ClassInstance* PSInstances[256], *VSInstances[256]; // 256 is max according to PSSetShader documentation + D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology; + ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer; + UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset; + DXGI_FORMAT IndexBufferFormat; + ID3D11InputLayout* InputLayout; + }; + BACKUP_DX11_STATE old; + old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); + ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); + ctx->RSGetState(&old.RS); + ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); + ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); + ctx->PSGetSamplers(0, 1, &old.PSSampler); + old.PSInstancesCount = old.VSInstancesCount = 256; + ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount); + ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount); + ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); + ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); + ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); + ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); + ctx->IAGetInputLayout(&old.InputLayout); + + // Setup viewport + D3D11_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D11_VIEWPORT)); + vp.Width = ImGui::GetIO().DisplaySize.x; + vp.Height = ImGui::GetIO().DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = vp.TopLeftY = 0.0f; + ctx->RSSetViewports(1, &vp); // Bind shader and vertex buffers unsigned int stride = sizeof(ImDrawVert); unsigned int offset = 0; - g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout); - g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); - g_pd3dDeviceContext->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); - g_pd3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - g_pd3dDeviceContext->VSSetShader(g_pVertexShader, NULL, 0); - g_pd3dDeviceContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); - g_pd3dDeviceContext->PSSetShader(g_pPixelShader, NULL, 0); - g_pd3dDeviceContext->PSSetSamplers(0, 1, &g_pFontSampler); + ctx->IASetInputLayout(g_pInputLayout); + ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); + ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); + ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ctx->VSSetShader(g_pVertexShader, NULL, 0); + ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); + ctx->PSSetShader(g_pPixelShader, NULL, 0); + ctx->PSSetSamplers(0, 1, &g_pFontSampler); // Setup render state - const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; - g_pd3dDeviceContext->OMSetBlendState(g_pBlendState, blendFactor, 0xffffffff); - g_pd3dDeviceContext->RSSetState(g_pRasterizerState); + const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; + ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff); + ctx->RSSetState(g_pRasterizerState); // Render command lists int vtx_offset = 0; @@ -162,19 +199,31 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) else { const D3D11_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; - g_pd3dDeviceContext->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId); - g_pd3dDeviceContext->RSSetScissorRects(1, &r); - g_pd3dDeviceContext->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); + ctx->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId); + ctx->RSSetScissorRects(1, &r); + ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); } idx_offset += pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.size(); } - // Restore modified state - g_pd3dDeviceContext->IASetInputLayout(NULL); - g_pd3dDeviceContext->PSSetShader(NULL, NULL, 0); - g_pd3dDeviceContext->VSSetShader(NULL, NULL, 0); + // Restore modified DX state + ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); + ctx->RSSetViewports(old.ViewportsCount, old.Viewports); + ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); + ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); + ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); + ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); + ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); + for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); + ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); + ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); + for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); + ctx->IASetPrimitiveTopology(old.PrimitiveTopology); + ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); + ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); + ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } IMGUI_API LRESULT ImGui_ImplDX11_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) @@ -234,31 +283,31 @@ static void ImGui_ImplDX11_CreateFontsTexture() // Upload texture to graphics system { - D3D11_TEXTURE2D_DESC texDesc; - ZeroMemory(&texDesc, sizeof(texDesc)); - texDesc.Width = width; - texDesc.Height = height; - texDesc.MipLevels = 1; - texDesc.ArraySize = 1; - texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - texDesc.SampleDesc.Count = 1; - texDesc.Usage = D3D11_USAGE_DEFAULT; - texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - texDesc.CPUAccessFlags = 0; + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; ID3D11Texture2D *pTexture = NULL; D3D11_SUBRESOURCE_DATA subResource; subResource.pSysMem = pixels; - subResource.SysMemPitch = texDesc.Width * 4; + subResource.SysMemPitch = desc.Width * 4; subResource.SysMemSlicePitch = 0; - g_pd3dDevice->CreateTexture2D(&texDesc, &subResource, &pTexture); + g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); // Create texture view D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory(&srvDesc, sizeof(srvDesc)); srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = texDesc.MipLevels; + srvDesc.Texture2D.MipLevels = desc.MipLevels; srvDesc.Texture2D.MostDetailedMip = 0; g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); pTexture->Release(); @@ -269,17 +318,17 @@ static void ImGui_ImplDX11_CreateFontsTexture() // Create texture sampler { - D3D11_SAMPLER_DESC samplerDesc; - ZeroMemory(&samplerDesc, sizeof(samplerDesc)); - samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - samplerDesc.MipLODBias = 0.f; - samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - samplerDesc.MinLOD = 0.f; - samplerDesc.MaxLOD = 0.f; - g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); + D3D11_SAMPLER_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + desc.MipLODBias = 0.f; + desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + desc.MinLOD = 0.f; + desc.MaxLOD = 0.f; + g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler); } } @@ -327,24 +376,23 @@ bool ImGui_ImplDX11_CreateDeviceObjects() return false; // Create the input layout - D3D11_INPUT_ELEMENT_DESC localLayout[] = { + D3D11_INPUT_ELEMENT_DESC local_layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - - if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) return false; // Create the constant buffer { - D3D11_BUFFER_DESC cbDesc; - cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); - cbDesc.Usage = D3D11_USAGE_DYNAMIC; - cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - cbDesc.MiscFlags = 0; - g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); + D3D11_BUFFER_DESC desc; + desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer); } } diff --git a/examples/libs/glfw/include/GLFW/glfw3.h b/examples/libs/glfw/include/GLFW/glfw3.h index 89414491..f8ca3d61 100644 --- a/examples/libs/glfw/include/GLFW/glfw3.h +++ b/examples/libs/glfw/include/GLFW/glfw3.h @@ -1,5 +1,5 @@ /************************************************************************* - * GLFW 3.1 - www.glfw.org + * GLFW 3.2 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard @@ -38,58 +38,60 @@ extern "C" { * Doxygen documentation *************************************************************************/ -/*! @defgroup context Context handling +/*! @file glfw3.h + * @brief The header of the GLFW 3 API. * - * This is the reference documentation for context related functions. For more - * information, see the @ref context. + * This is the header file of the GLFW 3 API. It defines all its types and + * declares all its functions. + * + * For more information about how to use this file, see @ref build_include. + */ +/*! @defgroup context Context reference + * + * This is the reference documentation for OpenGL and OpenGL ES context related + * functions. For more task-oriented information, see the @ref context_guide. + */ +/*! @defgroup vulkan Vulkan reference + * + * This is the reference documentation for Vulkan related functions and types. + * For more task-oriented information, see the @ref vulkan_guide. */ -/*! @defgroup init Initialization, version and errors +/*! @defgroup init Initialization, version and error reference * * This is the reference documentation for initialization and termination of - * the library, version management and error handling. For more information, - * see the @ref intro. + * the library, version management and error handling. For more task-oriented + * information, see the @ref intro_guide. */ -/*! @defgroup input Input handling +/*! @defgroup input Input reference * * This is the reference documentation for input related functions and types. - * For more information, see the @ref input. + * For more task-oriented information, see the @ref input_guide. */ -/*! @defgroup monitor Monitor handling +/*! @defgroup monitor Monitor reference * * This is the reference documentation for monitor related functions and types. - * For more information, see the @ref monitor. + * For more task-oriented information, see the @ref monitor_guide. */ -/*! @defgroup window Window handling +/*! @defgroup window Window reference * * This is the reference documentation for window related functions and types, - * including creation, deletion and event polling. For more information, see - * the @ref window. + * including creation, deletion and event polling. For more task-oriented + * information, see the @ref window_guide. */ /************************************************************************* - * Global definitions + * Compiler- and platform-specific preprocessor work *************************************************************************/ -/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ - -/* Please report any problems that you find with your compiler, which may - * be solved in this section! There are several compilers that I have not - * been able to test this file with yet. - * - * First: If we are we on Windows, we want a single define for it (_WIN32) - * (Note: For Cygwin the compiler flag -mwin32 should be used, but to - * make sure that things run smoothly for Cygwin users, we add __CYGWIN__ - * to the list of "valid Win32 identifiers", which removes the need for - * -mwin32) +/* If we are we on Windows, we want a single define for it. */ -#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)) +#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) #define _WIN32 #endif /* _WIN32 */ -/* In order for extension support to be portable, we need to define an - * OpenGL function call method. We use the keyword APIENTRY, which is - * defined for Win32. (Note: Windows also needs this for ) +/* It is customary to use APIENTRY for OpenGL function pointer declarations on + * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. */ #ifndef APIENTRY #ifdef _WIN32 @@ -99,51 +101,30 @@ extern "C" { #endif #endif /* APIENTRY */ -/* The following three defines are here solely to make some Windows-based - * files happy. Theoretically we could include , but - * it has the major drawback of severely polluting our namespace. +/* Some Windows OpenGL headers need this. */ - -/* Under Windows, we need WINGDIAPI defined */ #if !defined(WINGDIAPI) && defined(_WIN32) - #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__POCC__) - /* Microsoft Visual C++, Borland C++ Builder and Pelles C */ - #define WINGDIAPI __declspec(dllimport) - #elif defined(__LCC__) - /* LCC-Win32 */ - #define WINGDIAPI __stdcall - #else - /* Others (e.g. MinGW, Cygwin) */ - #define WINGDIAPI extern - #endif + #define WINGDIAPI __declspec(dllimport) #define GLFW_WINGDIAPI_DEFINED #endif /* WINGDIAPI */ -/* Some files also need CALLBACK defined */ +/* Some Windows GLU headers need this. + */ #if !defined(CALLBACK) && defined(_WIN32) - #if defined(_MSC_VER) - /* Microsoft Visual C++ */ - #if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) - #define CALLBACK __stdcall - #else - #define CALLBACK - #endif - #else - /* Other Windows compilers */ - #define CALLBACK __stdcall - #endif + #define CALLBACK __stdcall #define GLFW_CALLBACK_DEFINED #endif /* CALLBACK */ -/* Most GL/glu.h variants on Windows need wchar_t - * OpenGL/gl.h blocks the definition of ptrdiff_t by glext.h on OS X */ -#if !defined(GLFW_INCLUDE_NONE) - #include -#endif +/* Most Windows GLU headers need wchar_t. + * The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h. + * Include it unconditionally to avoid surprising side-effects. + */ +#include +#include /* Include the chosen client API headers. */ -#if defined(__APPLE_CC__) +#if defined(__APPLE__) #if defined(GLFW_INCLUDE_GLCOREARB) #include #if defined(GLFW_INCLUDE_GLEXT) @@ -174,13 +155,15 @@ extern "C" { #elif defined(GLFW_INCLUDE_ES3) #include #if defined(GLFW_INCLUDE_GLEXT) - #include + #include #endif #elif defined(GLFW_INCLUDE_ES31) #include #if defined(GLFW_INCLUDE_GLEXT) - #include + #include #endif + #elif defined(GLFW_INCLUDE_VULKAN) + #include #elif !defined(GLFW_INCLUDE_NONE) #include #if defined(GLFW_INCLUDE_GLEXT) @@ -208,11 +191,7 @@ extern "C" { #define GLFWAPI __declspec(dllexport) #elif defined(_WIN32) && defined(GLFW_DLL) /* We are calling GLFW as a Win32 DLL */ - #if defined(__LCC__) - #define GLFWAPI extern - #else - #define GLFWAPI __declspec(dllimport) - #endif + #define GLFWAPI __declspec(dllimport) #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) /* We are building GLFW as a shared / dynamic library */ #define GLFWAPI __attribute__((visibility("default"))) @@ -221,8 +200,6 @@ extern "C" { #define GLFWAPI #endif -/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ - /************************************************************************* * GLFW API tokens @@ -242,7 +219,7 @@ extern "C" { * backward-compatible. * @ingroup init */ -#define GLFW_VERSION_MINOR 1 +#define GLFW_VERSION_MINOR 2 /*! @brief The revision number of the GLFW library. * * This is incremented when a bug fix release is made that does not contain any @@ -252,6 +229,24 @@ extern "C" { #define GLFW_VERSION_REVISION 0 /*! @} */ +/*! @name Boolean values + * @{ */ +/*! @brief One. + * + * One. Seriously. You don't _need_ to use this symbol in your code. It's + * just semantic sugar for the number 1. You can use `1` or `true` or `_True` + * or `GL_TRUE` or whatever you want. + */ +#define GLFW_TRUE 1 +/*! @brief Zero. + * + * Zero. Seriously. You don't _need_ to use this symbol in your code. It's + * just just semantic sugar for the number 0. You can use `0` or `false` or + * `_False` or `GL_FALSE` or whatever you want. + */ +#define GLFW_FALSE 0 +/*! @} */ + /*! @name Key and button actions * @{ */ /*! @brief The key or mouse button was released. @@ -426,6 +421,7 @@ extern "C" { #define GLFW_KEY_RIGHT_ALT 346 #define GLFW_KEY_RIGHT_SUPER 347 #define GLFW_KEY_MENU 348 + #define GLFW_KEY_LAST GLFW_KEY_MENU /*! @} */ @@ -505,12 +501,11 @@ extern "C" { * @{ */ /*! @brief GLFW has not been initialized. * - * This occurs if a GLFW function was called that may not be called unless the + * This occurs if a GLFW function was called that must not be called unless the * library is [initialized](@ref intro_init). * - * @par Analysis - * Application programmer error. Initialize GLFW before calling any function - * that requires initialization. + * @analysis Application programmer error. Initialize GLFW before calling any + * function that requires initialization. */ #define GLFW_NOT_INITIALIZED 0x00010001 /*! @brief No context is current for this thread. @@ -519,9 +514,8 @@ extern "C" { * current OpenGL or OpenGL ES context but no context is current on the calling * thread. One such function is @ref glfwSwapInterval. * - * @par Analysis - * Application programmer error. Ensure a context is current before calling - * functions that require a current context. + * @analysis Application programmer error. Ensure a context is current before + * calling functions that require a current context. */ #define GLFW_NO_CURRENT_CONTEXT 0x00010002 /*! @brief One of the arguments to the function was an invalid enum value. @@ -530,8 +524,7 @@ extern "C" { * requesting [GLFW_RED_BITS](@ref window_hints_fb) with @ref * glfwGetWindowAttrib. * - * @par Analysis - * Application programmer error. Fix the offending call. + * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_ENUM 0x00010003 /*! @brief One of the arguments to the function was an invalid value. @@ -542,46 +535,41 @@ extern "C" { * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead * result in a @ref GLFW_VERSION_UNAVAILABLE error. * - * @par Analysis - * Application programmer error. Fix the offending call. + * @analysis Application programmer error. Fix the offending call. */ #define GLFW_INVALID_VALUE 0x00010004 /*! @brief A memory allocation failed. * * A memory allocation failed. * - * @par Analysis - * A bug in GLFW or the underlying operating system. Report the bug to our - * [issue tracker](https://github.com/glfw/glfw/issues). + * @analysis A bug in GLFW or the underlying operating system. Report the bug + * to our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_OUT_OF_MEMORY 0x00010005 -/*! @brief GLFW could not find support for the requested client API on the - * system. +/*! @brief GLFW could not find support for the requested API on the system. * - * GLFW could not find support for the requested client API on the system. + * GLFW could not find support for the requested API on the system. * - * @par Analysis - * The installed graphics driver does not support the requested client API, or - * does not support it via the chosen context creation backend. Below are - * a few examples. + * @analysis The installed graphics driver does not support the requested + * API, or does not support it via the chosen context creation backend. + * Below are a few examples. * * @par * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only - * supports OpenGL ES via EGL, while Nvidia and Intel only supports it via + * supports OpenGL ES via EGL, while Nvidia and Intel only support it via * a WGL or GLX extension. OS X does not provide OpenGL ES at all. The Mesa * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary - * driver. + * driver. Older graphics drivers do not support Vulkan. */ #define GLFW_API_UNAVAILABLE 0x00010006 /*! @brief The requested OpenGL or OpenGL ES version is not available. * - * The requested OpenGL or OpenGL ES version (including any requested profile - * or context option) is not available on this machine. + * The requested OpenGL or OpenGL ES version (including any requested context + * or framebuffer hints) is not available on this machine. * - * @par Analysis - * The machine does not support your requirements. If your application is - * sufficiently flexible, downgrade your requirements and try again. - * Otherwise, inform the user that their machine does not match your + * @analysis The machine does not support your requirements. If your + * application is sufficiently flexible, downgrade your requirements and try + * again. Otherwise, inform the user that their machine does not match your * requirements. * * @par @@ -597,9 +585,9 @@ extern "C" { * A platform-specific error occurred that does not match any of the more * specific categories. * - * @par Analysis - * A bug in GLFW or the underlying operating system. Report the bug to our - * [issue tracker](https://github.com/glfw/glfw/issues). + * @analysis A bug or configuration error in GLFW, the underlying operating + * system or its drivers, or a lack of required resources. Report the issue to + * our [issue tracker](https://github.com/glfw/glfw/issues). */ #define GLFW_PLATFORM_ERROR 0x00010008 /*! @brief The requested format is not supported or available. @@ -610,8 +598,7 @@ extern "C" { * If emitted when querying the clipboard, the contents of the clipboard could * not be converted to the requested format. * - * @par Analysis - * If emitted during window creation, one or more + * @analysis If emitted during window creation, one or more * [hard constraints](@ref window_hints_hard) did not match any of the * available pixel formats. If your application is sufficiently flexible, * downgrade your requirements and try again. Otherwise, inform the user that @@ -622,6 +609,14 @@ extern "C" { * the user, as appropriate. */ #define GLFW_FORMAT_UNAVAILABLE 0x00010009 +/*! @brief The specified window does not have an OpenGL or OpenGL ES context. + * + * A window that does not have an OpenGL or OpenGL ES context was passed to + * a function that requires it to have one. + * + * @analysis Application programmer error. Fix the offending call. + */ +#define GLFW_NO_WINDOW_CONTEXT 0x0001000A /*! @} */ #define GLFW_FOCUSED 0x00020001 @@ -631,6 +626,7 @@ extern "C" { #define GLFW_DECORATED 0x00020005 #define GLFW_AUTO_ICONIFY 0x00020006 #define GLFW_FLOATING 0x00020007 +#define GLFW_MAXIMIZED 0x00020008 #define GLFW_RED_BITS 0x00021001 #define GLFW_GREEN_BITS 0x00021002 @@ -658,7 +654,9 @@ extern "C" { #define GLFW_OPENGL_DEBUG_CONTEXT 0x00022007 #define GLFW_OPENGL_PROFILE 0x00022008 #define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 +#define GLFW_CONTEXT_NO_ERROR 0x0002200A +#define GLFW_NO_API 0 #define GLFW_OPENGL_API 0x00030001 #define GLFW_OPENGL_ES_API 0x00030002 @@ -736,14 +734,37 @@ extern "C" { * Generic function pointer used for returning client API function pointers * without forcing a cast from a regular pointer. * + * @sa @ref context_glext + * @sa glfwGetProcAddress + * + * @since Added in version 3.0. + * @ingroup context */ typedef void (*GLFWglproc)(void); +/*! @brief Vulkan API function pointer type. + * + * Generic function pointer used for returning Vulkan API function pointers + * without forcing a cast from a regular pointer. + * + * @sa @ref vulkan_proc + * @sa glfwGetInstanceProcAddress + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +typedef void (*GLFWvkproc)(void); + /*! @brief Opaque monitor object. * * Opaque monitor object. * + * @see @ref monitor_object + * + * @since Added in version 3.0. + * * @ingroup monitor */ typedef struct GLFWmonitor GLFWmonitor; @@ -752,6 +773,10 @@ typedef struct GLFWmonitor GLFWmonitor; * * Opaque window object. * + * @see @ref window_object + * + * @since Added in version 3.0. + * * @ingroup window */ typedef struct GLFWwindow GLFWwindow; @@ -760,6 +785,10 @@ typedef struct GLFWwindow GLFWwindow; * * Opaque cursor object. * + * @see @ref cursor_object + * + * @since Added in version 3.1. + * * @ingroup cursor */ typedef struct GLFWcursor GLFWcursor; @@ -771,8 +800,11 @@ typedef struct GLFWcursor GLFWcursor; * @param[in] error An [error code](@ref errors). * @param[in] description A UTF-8 encoded string describing the error. * + * @sa @ref error_handling * @sa glfwSetErrorCallback * + * @since Added in version 3.0. + * * @ingroup init */ typedef void (* GLFWerrorfun)(int,const char*); @@ -787,8 +819,11 @@ typedef void (* GLFWerrorfun)(int,const char*); * @param[in] ypos The new y-coordinate, in screen coordinates, of the * upper-left corner of the client area of the window. * + * @sa @ref window_pos * @sa glfwSetWindowPosCallback * + * @since Added in version 3.0. + * * @ingroup window */ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); @@ -801,8 +836,12 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); * @param[in] width The new width, in screen coordinates, of the window. * @param[in] height The new height, in screen coordinates, of the window. * + * @sa @ref window_size * @sa glfwSetWindowSizeCallback * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. + * * @ingroup window */ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); @@ -813,8 +852,12 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); * * @param[in] window The window that the user attempted to close. * + * @sa @ref window_close * @sa glfwSetWindowCloseCallback * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * * @ingroup window */ typedef void (* GLFWwindowclosefun)(GLFWwindow*); @@ -825,8 +868,12 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*); * * @param[in] window The window whose content needs to be refreshed. * + * @sa @ref window_refresh * @sa glfwSetWindowRefreshCallback * + * @since Added in version 2.5. + * @glfw3 Added window handle parameter. + * * @ingroup window */ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); @@ -836,11 +883,14 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); * This is the function signature for window focus callback functions. * * @param[in] window The window that gained or lost input focus. - * @param[in] focused `GL_TRUE` if the window was given input focus, or - * `GL_FALSE` if it lost it. + * @param[in] focused `GLFW_TRUE` if the window was given input focus, or + * `GLFW_FALSE` if it lost it. * + * @sa @ref window_focus * @sa glfwSetWindowFocusCallback * + * @since Added in version 3.0. + * * @ingroup window */ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); @@ -851,11 +901,14 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); * functions. * * @param[in] window The window that was iconified or restored. - * @param[in] iconified `GL_TRUE` if the window was iconified, or `GL_FALSE` - * if it was restored. + * @param[in] iconified `GLFW_TRUE` if the window was iconified, or + * `GLFW_FALSE` if it was restored. * + * @sa @ref window_iconify * @sa glfwSetWindowIconifyCallback * + * @since Added in version 3.0. + * * @ingroup window */ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); @@ -869,8 +922,11 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); * @param[in] width The new width, in pixels, of the framebuffer. * @param[in] height The new height, in pixels, of the framebuffer. * + * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * + * @since Added in version 3.0. + * * @ingroup window */ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); @@ -886,8 +942,12 @@ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * + * @sa @ref input_mouse_button * @sa glfwSetMouseButtonCallback * + * @since Added in version 1.0. + * @glfw3 Added window handle and modifier mask parameters. + * * @ingroup input */ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); @@ -897,11 +957,16 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); * This is the function signature for cursor position callback functions. * * @param[in] window The window that received the event. - * @param[in] xpos The new x-coordinate, in screen coordinates, of the cursor. - * @param[in] ypos The new y-coordinate, in screen coordinates, of the cursor. + * @param[in] xpos The new cursor x-coordinate, relative to the left edge of + * the client area. + * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the + * client area. * + * @sa @ref cursor_pos * @sa glfwSetCursorPosCallback * + * @since Added in version 3.0. Replaces `GLFWmouseposfun`. + * * @ingroup input */ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); @@ -911,11 +976,14 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); * This is the function signature for cursor enter/leave callback functions. * * @param[in] window The window that received the event. - * @param[in] entered `GL_TRUE` if the cursor entered the window's client - * area, or `GL_FALSE` if it left it. + * @param[in] entered `GLFW_TRUE` if the cursor entered the window's client + * area, or `GLFW_FALSE` if it left it. * + * @sa @ref cursor_enter * @sa glfwSetCursorEnterCallback * + * @since Added in version 3.0. + * * @ingroup input */ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); @@ -928,8 +996,11 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); * @param[in] xoffset The scroll offset along the x-axis. * @param[in] yoffset The scroll offset along the y-axis. * + * @sa @ref scrolling * @sa glfwSetScrollCallback * + * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. + * * @ingroup input */ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); @@ -945,8 +1016,12 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * + * @sa @ref input_key * @sa glfwSetKeyCallback * + * @since Added in version 1.0. + * @glfw3 Added window handle, scancode and modifier mask parameters. + * * @ingroup input */ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); @@ -958,8 +1033,12 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); * @param[in] window The window that received the event. * @param[in] codepoint The Unicode code point of the character. * + * @sa @ref input_char * @sa glfwSetCharCallback * + * @since Added in version 2.4. + * @glfw3 Added window handle parameter. + * * @ingroup input */ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); @@ -976,8 +1055,11 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); * @param[in] mods Bit field describing which [modifier keys](@ref mods) were * held down. * + * @sa @ref input_char * @sa glfwSetCharModsCallback * + * @since Added in version 3.1. + * * @ingroup input */ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); @@ -988,10 +1070,13 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); * * @param[in] window The window that received the event. * @param[in] count The number of dropped files. - * @param[in] names The UTF-8 encoded path names of the dropped files. + * @param[in] paths The UTF-8 encoded file and/or directory path names. * + * @sa @ref path_drop * @sa glfwSetDropCallback * + * @since Added in version 3.1. + * * @ingroup input */ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); @@ -1003,16 +1088,42 @@ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); * @param[in] monitor The monitor that was connected or disconnected. * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. * + * @sa @ref monitor_event * @sa glfwSetMonitorCallback * + * @since Added in version 3.0. + * * @ingroup monitor */ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); +/*! @brief The function signature for joystick configuration callbacks. + * + * This is the function signature for joystick configuration callback + * functions. + * + * @param[in] joy The joystick that was connected or disconnected. + * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. + * + * @sa @ref joystick_event + * @sa glfwSetJoystickCallback + * + * @since Added in version 3.2. + * + * @ingroup input + */ +typedef void (* GLFWjoystickfun)(int,int); + /*! @brief Video mode type. * * This describes a single video mode. * + * @sa @ref monitor_modes + * @sa glfwGetVideoMode glfwGetVideoModes + * + * @since Added in version 1.0. + * @glfw3 Added refresh rate member. + * * @ingroup monitor */ typedef struct GLFWvidmode @@ -1041,8 +1152,11 @@ typedef struct GLFWvidmode * * This describes the gamma ramp for a monitor. * + * @sa @ref monitor_gamma * @sa glfwGetGammaRamp glfwSetGammaRamp * + * @since Added in version 3.0. + * * @ingroup monitor */ typedef struct GLFWgammaramp @@ -1062,6 +1176,11 @@ typedef struct GLFWgammaramp } GLFWgammaramp; /*! @brief Image data. + * + * @sa @ref cursor_custom + * + * @since Added in version 2.1. + * @glfw3 Removed format and bytes-per-pixel members. */ typedef struct GLFWimage { @@ -1092,29 +1211,24 @@ typedef struct GLFWimage * succeeds, you should call @ref glfwTerminate before the application exits. * * Additional calls to this function after successful initialization but before - * termination will return `GL_TRUE` immediately. + * termination will return `GLFW_TRUE` immediately. * - * @return `GL_TRUE` if successful, or `GL_FALSE` if an + * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * [error](@ref error_handling) occurred. * - * @remarks __OS X:__ This function will change the current directory of the + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. + * + * @remark @osx This function will change the current directory of the * application to the `Contents/Resources` subdirectory of the application's * bundle, if present. This can be disabled with a * [compile-time option](@ref compile_options_osx). * - * @remarks __X11:__ If the `LC_CTYPE` category of the current locale is set to - * `"C"` then the environment's locale will be applied to that category. This - * is done because character input will not function when `LC_CTYPE` is set to - * `"C"`. If another locale was set before this function was called, it will - * be left untouched. - * - * @par Thread Safety - * This function may only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwTerminate * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup init */ @@ -1132,21 +1246,21 @@ GLFWAPI int glfwInit(void); * call this function, as it is called by @ref glfwInit before it returns * failure. * - * @remarks This function may be called before @ref glfwInit. + * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * - * @warning No window's context may be current on another thread when this - * function is called. + * @remark This function may be called before @ref glfwInit. * - * @par Reentrancy - * This function may not be called from a callback. + * @warning The contexts of any remaining windows must not be current on any + * other thread when this function is called. * - * @par Thread Safety - * This function may only be called from the main thread. + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref intro_init * @sa glfwInit * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup init */ @@ -1158,22 +1272,22 @@ GLFWAPI void glfwTerminate(void); * library. It is intended for when you are using GLFW as a shared library and * want to ensure that you are using the minimum required version. * - * Any or all of the version arguments may be `NULL`. This function always - * succeeds. + * Any or all of the version arguments may be `NULL`. * * @param[out] major Where to store the major version number, or `NULL`. * @param[out] minor Where to store the minor version number, or `NULL`. * @param[out] rev Where to store the revision number, or `NULL`. * - * @remarks This function may be called before @ref glfwInit. + * @errors None. * - * @par Thread Safety - * This function may be called from any thread. + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersionString * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup init */ @@ -1184,28 +1298,27 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); * This function returns the compile-time generated * [version string](@ref intro_version_string) of the GLFW library binary. It * describes the version, platform, compiler and any platform-specific - * compile-time options. + * compile-time options. It should not be confused with the OpenGL or OpenGL + * ES version string, queried with `glGetString`. * * __Do not use the version string__ to parse the GLFW library version. The - * @ref glfwGetVersion function already provides the version of the running - * library binary. + * @ref glfwGetVersion function provides the version of the running library + * binary in numerical format. * - * This function always succeeds. + * @return The ASCII encoded GLFW version string. * - * @return The GLFW version string. + * @errors None. * - * @remarks This function may be called before @ref glfwInit. + * @remark This function may be called before @ref glfwInit. * - * @par Pointer Lifetime - * The returned string is static and compile-time generated. + * @pointer_lifetime The returned string is static and compile-time generated. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref intro_version * @sa glfwGetVersion * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup init */ @@ -1231,14 +1344,15 @@ GLFWAPI const char* glfwGetVersionString(void); * callback. * @return The previously set callback, or `NULL` if no callback was set. * - * @remarks This function may be called before @ref glfwInit. + * @errors None. * - * @par Thread Safety - * This function may only be called from the main thread. + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref error_handling * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup init */ @@ -1247,26 +1361,27 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun); /*! @brief Returns the currently connected monitors. * * This function returns an array of handles for all currently connected - * monitors. + * monitors. The primary monitor is always first in the returned array. If no + * monitors were found, this function returns `NULL`. * * @param[out] count Where to store the number of monitors in the returned * array. This is set to zero if an error occurred. - * @return An array of monitor handles, or `NULL` if an - * [error](@ref error_handling) occurred. + * @return An array of monitor handles, or `NULL` if no monitors were found or + * if an [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is guaranteed to be valid only until the monitor configuration - * changes or the library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * monitor configuration changes or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_monitors * @sa @ref monitor_event * @sa glfwGetPrimaryMonitor * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1275,18 +1390,22 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); /*! @brief Returns the primary monitor. * * This function returns the primary monitor. This is usually the monitor - * where elements like the Windows task bar or the OS X menu bar is located. + * where elements like the task bar or global menu bar are located. * - * @return The primary monitor, or `NULL` if an [error](@ref error_handling) - * occurred. + * @return The primary monitor, or `NULL` if no monitors were found or if an + * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @remark The primary monitor is always first in the array returned by @ref + * glfwGetMonitors. * * @sa @ref monitor_monitors * @sa glfwGetMonitors * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1304,12 +1423,14 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1334,15 +1455,16 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); * @param[out] heightMM Where to store the height, in millimetres, of the * monitor's display area, or `NULL`. * - * @remarks __Windows:__ The OS calculates the returned physical size from the + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @remark @win32 calculates the returned physical size from the * current resolution and system DPI instead of querying the monitor EDID data. * - * @par Thread Safety - * This function may only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1358,17 +1480,17 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* * @return The UTF-8 encoded name of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected or the - * library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_properties * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1385,15 +1507,13 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @bug __X11:__ This callback is not yet called on monitor configuration - * changes. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @par Thread Safety - * This function may only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_event * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1412,21 +1532,21 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun); * @return An array of video modes, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected, this - * function is called again for that monitor or the library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected, this function is called again for that monitor or the library + * is terminated. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoMode * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Changed to return an array of modes for a specific monitor. + * @since Added in version 1.0. + * @glfw3 Changed to return an array of modes for a specific monitor. * * @ingroup monitor */ @@ -1442,18 +1562,19 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); * @return The current mode of the monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified monitor is disconnected or the - * library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified monitor is + * disconnected or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_modes * @sa glfwGetVideoModes * - * @since Added in GLFW 3.0. Replaces `glfwGetDesktopMode`. + * @since Added in version 3.0. Replaces `glfwGetDesktopMode`. * * @ingroup monitor */ @@ -1462,17 +1583,20 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); /*! @brief Generates a gamma ramp and sets it for the specified monitor. * * This function generates a 256-element gamma ramp from the specified exponent - * and then calls @ref glfwSetGammaRamp with it. + * and then calls @ref glfwSetGammaRamp with it. The value must be a finite + * number greater than zero. * * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] gamma The desired exponent. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1486,18 +1610,19 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * @return The current gamma ramp, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned structure and its arrays are allocated and freed by GLFW. You - * should not free them yourself. They are valid until the specified monitor - * is disconnected, this function is called again for that monitor or the - * library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned structure and its arrays are allocated and + * freed by GLFW. You should not free them yourself. They are valid until the + * specified monitor is disconnected, this function is called again for that + * monitor or the library is terminated. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1512,17 +1637,22 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @param[in] monitor The monitor whose gamma ramp to set. * @param[in] ramp The gamma ramp to use. * - * @note Gamma ramp sizes other than 256 are not supported by all hardware. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Pointer Lifetime - * The specified gamma ramp is copied before this function returns. + * @remark Gamma ramp sizes other than 256 are not supported by all platforms + * or graphics hardware. * - * @par Thread Safety - * This function may only be called from the main thread. + * @remark @win32 The gamma ramp size must be 256. + * + * @pointer_lifetime The specified gamma ramp is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref monitor_gamma * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup monitor */ @@ -1533,13 +1663,14 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); * This function resets all window hints to their * [default values](@ref window_hints_values). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwWindowHint * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1552,20 +1683,26 @@ GLFWAPI void glfwDefaultWindowHints(void); * glfwWindowHint or @ref glfwDefaultWindowHints, or until the library is * terminated. * - * @param[in] target The [window hint](@ref window_hints) to set. - * @param[in] hint The new value of the window hint. + * This function does not check whether the specified hint values are valid. + * If you set hints to invalid values this will instead be reported by the next + * call to @ref glfwCreateWindow. * - * @par Thread Safety - * This function may only be called from the main thread. + * @param[in] hint The [window hint](@ref window_hints) to set. + * @param[in] value The new value of the window hint. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hints * @sa glfwDefaultWindowHints * - * @since Added in GLFW 3.0. Replaces `glfwOpenWindowHint`. + * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. * * @ingroup window */ -GLFWAPI void glfwWindowHint(int target, int hint); +GLFWAPI void glfwWindowHint(int hint, int value); /*! @brief Creates a window and its associated context. * @@ -1582,21 +1719,21 @@ GLFWAPI void glfwWindowHint(int target, int hint); * requested, as not all parameters and hints are * [hard constraints](@ref window_hints_hard). This includes the size of the * window, especially for full screen windows. To query the actual attributes - * of the created window, framebuffer and context, use queries like @ref - * glfwGetWindowAttrib and @ref glfwGetWindowSize. + * of the created window, framebuffer and context, see @ref + * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. * * To create a full screen window, you need to specify the monitor the window - * will cover. If no monitor is specified, windowed mode will be used. Unless - * you have a way for the user to choose a specific monitor, it is recommended - * that you pick the primary monitor. For more information on how to query - * connected monitors, see @ref monitor_monitors. + * will cover. If no monitor is specified, the window will be windowed mode. + * Unless you have a way for the user to choose a specific monitor, it is + * recommended that you pick the primary monitor. For more information on how + * to query connected monitors, see @ref monitor_monitors. * * For full screen windows, the specified size becomes the resolution of the - * window's _desired video mode_. As long as a full screen window has input - * focus, the supported video mode most closely matching the desired video mode - * is set for the specified monitor. For more information about full screen - * windows, including the creation of so called _windowed full screen_ or - * _borderless full screen_ windows, see @ref window_windowed_full_screen. + * window's _desired video mode_. As long as a full screen window is not + * iconified, the supported video mode most closely matching the desired video + * mode is set for the specified monitor. For more information about full + * screen windows, including the creation of so called _windowed full screen_ + * or _borderless full screen_ windows, see @ref window_windowed_full_screen. * * By default, newly created windows use the placement recommended by the * window system. To create the window at a specific position, make it @@ -1604,8 +1741,8 @@ GLFWAPI void glfwWindowHint(int target, int hint); * hint, set its [position](@ref window_pos) and then [show](@ref window_hide) * it. * - * If a full screen window has input focus, the screensaver is prohibited from - * starting. + * As long as at least one full screen window is not iconified, the screensaver + * is prohibited from starting. * * Window systems put limits on window sizes. Very large or very small window * dimensions may be overridden by the window system on creation. Check the @@ -1619,50 +1756,67 @@ GLFWAPI void glfwWindowHint(int target, int hint); * @param[in] height The desired height, in screen coordinates, of the window. * This must be greater than zero. * @param[in] title The initial, UTF-8 encoded window title. - * @param[in] monitor The monitor to use for full screen mode, or `NULL` to use + * @param[in] monitor The monitor to use for full screen mode, or `NULL` for * windowed mode. * @param[in] share The window whose context to share resources with, or `NULL` * to not share resources. * @return The handle of the created window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @remarks __Windows:__ Window creation will fail if the Microsoft GDI - * software OpenGL implementation is the only one available. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref + * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark @win32 Window creation will fail if the Microsoft GDI software + * OpenGL implementation is the only one available. * - * @remarks __Windows:__ If the executable has an icon resource named - * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is - * present, the `IDI_WINLOGO` icon will be used instead. + * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` + * it will be set as the icon for the window. If no such icon is present, the + * `IDI_WINLOGO` icon will be used instead. * - * @remarks __Windows:__ The context to share resources with may not be current - * on any other thread. + * @remark @win32 The context to share resources with must not be current on + * any other thread. * - * @remarks __OS X:__ The GLFW window has no icon, as it is not a document + * @remark @osx The GLFW window has no icon, as it is not a document * window, but the dock icon will be the same as the application bundle's icon. * For more information on bundles, see the * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * in the Mac Developer Library. * - * @remarks __OS X:__ The first time a window is created the menu bar is - * populated with common commands like Hide, Quit and About. The About entry - * opens a minimal about dialog with information from the application's bundle. - * The menu bar can be disabled with a + * @remark @osx The first time a window is created the menu bar is populated + * with common commands like Hide, Quit and About. The About entry opens + * a minimal about dialog with information from the application's bundle. The + * menu bar can be disabled with a * [compile-time option](@ref compile_options_osx). * - * @remarks __X11:__ There is no mechanism for setting the window icon yet. + * @remark @osx On OS X 10.10 and later the window frame will not be rendered + * at full resolution on Retina displays unless the `NSHighResolutionCapable` + * key is enabled in the application bundle's `Info.plist`. For more + * information, see + * [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html) + * in the Mac Developer Library. The GLFW test and example programs use + * a custom `Info.plist` template for this, which can be found as + * `CMake/MacOSXBundleInfo.plist.in` in the source tree. * - * @remarks __X11:__ Some window managers will not respect the placement of + * @remark @x11 There is no mechanism for setting the window icon yet. + * + * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. * - * @par Reentrancy - * This function may not be called from a callback. + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * a window to reach its requested state. This means you may not be able to + * query the final size, position or other attributes directly after window + * creation. * - * @par Thread Safety - * This function may only be called from the main thread. + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwDestroyWindow * - * @since Added in GLFW 3.0. Replaces `glfwOpenWindow`. + * @since Added in version 3.0. Replaces `glfwOpenWindow`. * * @ingroup window */ @@ -1678,19 +1832,20 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G * * @param[in] window The window to destroy. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * * @note The context of the specified window must not be current on any other * thread when this function is called. * - * @par Reentrancy - * This function may not be called from a callback. + * @reentrancy This function must not be called from a callback. * - * @par Thread Safety - * This function may only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_creation * @sa glfwCreateWindow * - * @since Added in GLFW 3.0. Replaces `glfwCloseWindow`. + * @since Added in version 3.0. Replaces `glfwCloseWindow`. * * @ingroup window */ @@ -1703,12 +1858,14 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* window); * @param[in] window The window to query. * @return The value of the close flag. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_close * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1723,12 +1880,14 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); * @param[in] window The window whose flag to change. * @param[in] value The new value. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_close * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1742,20 +1901,62 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); * @param[in] window The window whose title to change. * @param[in] title The UTF-8 encoded window title. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @sa @ref window_title + * @remark @osx The window title will not be updated until the next time you + * process events. * - * @since Added in GLFW 1.0. + * @thread_safety This function must only be called from the main thread. * - * @par - * __GLFW 3:__ Added window handle parameter. + * @sa @ref window_title + * + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); +/*! @brief Sets the icon for the specified window. + * + * This function sets the icon of the specified window. If passed an array of + * candidate images, those of or closest to the sizes desired by the system are + * selected. If no images are specified, the window reverts to its default + * icon. + * + * The desired image sizes varies depending on platform and system settings. + * The selected images will be rescaled as needed. Good sizes include 16x16, + * 32x32 and 48x48. + * + * @param[in] window The window whose icon to set. + * @param[in] count The number of images in the specified array, or zero to + * revert to the default window icon. + * @param[in] images The images to create the icon from. This is ignored if + * count is zero. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The specified image data is copied before this function + * returns. + * + * @remark @osx The GLFW window has no icon, as it is not a document + * window, but the dock icon will be the same as the application bundle's icon. + * For more information on bundles, see the + * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) + * in the Mac Developer Library. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_icon + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); + /*! @brief Retrieves the position of the client area of the specified window. * * This function retrieves the position, in screen coordinates, of the @@ -1770,13 +1971,15 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); * @param[out] ypos Where to store the y-coordinate of the upper-left corner of * the client area, or `NULL`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwSetWindowPos * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1798,16 +2001,16 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); * @param[in] xpos The x-coordinate of the upper-left corner of the client area. * @param[in] ypos The y-coordinate of the upper-left corner of the client area. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * @sa glfwGetWindowPos * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -1828,48 +2031,131 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); * @param[out] height Where to store the height, in screen coordinates, of the * client area, or `NULL`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwSetWindowSize * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup window */ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); +/*! @brief Sets the size limits of the specified window. + * + * This function sets the size limits of the client area of the specified + * window. If the window is full screen, the size limits only take effect if + * once it is made windowed. If the window is not resizable, this function + * does nothing. + * + * The size limits are applied immediately to a windowed mode window and may + * cause it to be resized. + * + * @param[in] window The window to set limits for. + * @param[in] minwidth The minimum width, in screen coordinates, of the client + * area, or `GLFW_DONT_CARE`. + * @param[in] minheight The minimum height, in screen coordinates, of the + * client area, or `GLFW_DONT_CARE`. + * @param[in] maxwidth The maximum width, in screen coordinates, of the client + * area, or `GLFW_DONT_CARE`. + * @param[in] maxheight The maximum height, in screen coordinates, of the + * client area, or `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa glfwSetWindowAspectRatio + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); + +/*! @brief Sets the aspect ratio of the specified window. + * + * This function sets the required aspect ratio of the client area of the + * specified window. If the window is full screen, the aspect ratio only takes + * effect once it is made windowed. If the window is not resizable, this + * function does nothing. + * + * The aspect ratio is specified as a numerator and a denominator and both + * values must be greater than zero. For example, the common 16:9 aspect ratio + * is specified as 16 and 9, respectively. + * + * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect + * ratio limit is disabled. + * + * The aspect ratio is applied immediately to a windowed mode window and may + * cause it to be resized. + * + * @param[in] window The window to set limits for. + * @param[in] numer The numerator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * @param[in] denom The denominator of the desired aspect ratio, or + * `GLFW_DONT_CARE`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * + * @remark If you set size limits and an aspect ratio that conflict, the + * results are undefined. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_sizelimits + * @sa glfwSetWindowSizeLimits + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); + /*! @brief Sets the size of the client area of the specified window. * * This function sets the size, in screen coordinates, of the client area of * the specified window. * - * For full screen windows, this function selects and switches to the resolution - * closest to the specified size, without affecting the window's context. As - * the context is unaffected, the bit depths of the framebuffer remain - * unchanged. + * For full screen windows, this function updates the resolution of its desired + * video mode and switches to the video mode closest to it, without affecting + * the window's context. As the context is unaffected, the bit depths of the + * framebuffer remain unchanged. + * + * If you wish to update the refresh rate of the desired video mode in addition + * to its resolution, see @ref glfwSetWindowMonitor. * * The window manager may put limits on what sizes are allowed. GLFW cannot * and should not override these limits. * * @param[in] window The window to resize. - * @param[in] width The desired width of the specified window. - * @param[in] height The desired height of the specified window. + * @param[in] width The desired width, in screen coordinates, of the window + * client area. + * @param[in] height The desired height, in screen coordinates, of the window + * client area. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * @sa glfwGetWindowSize + * @sa glfwSetWindowMonitor * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -1890,13 +2176,15 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); * @param[out] height Where to store the height, in pixels, of the framebuffer, * or `NULL`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * @sa glfwSetFramebufferSizeCallback * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -1926,12 +2214,14 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height) * @param[out] bottom Where to store the size, in screen coordinates, of the * bottom edge of the window frame, or `NULL`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_size * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup window */ @@ -1948,16 +2238,17 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int * * @param[in] window The window to iconify. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * @sa glfwRestoreWindow + * @sa glfwMaximizeWindow * - * @since Added in GLFW 2.1. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in version 2.1. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -1966,27 +2257,51 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window); /*! @brief Restores the specified window. * * This function restores the specified window if it was previously iconified - * (minimized). If the window is already restored, this function does nothing. + * (minimized) or maximized. If the window is already restored, this function + * does nothing. * * If the specified window is a full screen window, the resolution chosen for * the window is restored on the selected monitor. * * @param[in] window The window to restore. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_iconify + * @sa glfwIconifyWindow + * @sa glfwMaximizeWindow + * + * @since Added in version 2.1. + * @glfw3 Added window handle parameter. + * + * @ingroup window + */ +GLFWAPI void glfwRestoreWindow(GLFWwindow* window); + +/*! @brief Maximizes the specified window. + * + * This function maximizes the specified window if it was previously not + * maximized. If the window is already maximized, this function does nothing. + * + * If the specified window is a full screen window, this function does nothing. + * + * @param[in] window The window to maximize. + * * @par Thread Safety * This function may only be called from the main thread. * * @sa @ref window_iconify * @sa glfwIconifyWindow + * @sa glfwRestoreWindow * - * @since Added in GLFW 2.1. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in GLFW 3.2. * * @ingroup window */ -GLFWAPI void glfwRestoreWindow(GLFWwindow* window); +GLFWAPI void glfwMaximizeWindow(GLFWwindow* window); /*! @brief Makes the specified window visible. * @@ -1996,13 +2311,15 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* window); * * @param[in] window The window to make visible. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwHideWindow * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2016,18 +2333,48 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window); * * @param[in] window The window to hide. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide * @sa glfwShowWindow * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ GLFWAPI void glfwHideWindow(GLFWwindow* window); +/*! @brief Brings the specified window to front and sets input focus. + * + * This function brings the specified window to front and sets input focus. + * The window should already be visible and not iconified. + * + * By default, both windowed and full screen mode windows are focused when + * initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable + * this behavior. + * + * __Do not use this function__ to steal focus from other applications unless + * you are certain that is what the user wants. Focus stealing can be + * extremely disruptive. + * + * @param[in] window The window to give input focus. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_focus + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwFocusWindow(GLFWwindow* window); + /*! @brief Returns the monitor that the window uses for full screen mode. * * This function returns the handle of the monitor that the specified window is @@ -2037,17 +2384,67 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * @return The monitor, or `NULL` if the window is in windowed mode or an error * occurred. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_monitor + * @sa glfwSetWindowMonitor * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); +/*! @brief Sets the mode, monitor, video mode and placement of a window. + * + * This function sets the monitor that the window uses for full screen mode or, + * if the monitor is `NULL`, makes it windowed mode. + * + * When setting a monitor, this function updates the width, height and refresh + * rate of the desired video mode and switches to the video mode closest to it. + * The window position is ignored when setting a monitor. + * + * When the monitor is `NULL`, the position, width and height are used to + * place the window client area. The refresh rate is ignored when no monitor + * is specified. + * + * If you only wish to update the resolution of a full screen window or the + * size of a windowed mode window, see @ref glfwSetWindowSize. + * + * When a window transitions from full screen to windowed mode, this function + * restores any previous window settings such as whether it is decorated, + * floating, resizable, has size or aspect ratio limits, etc.. + * + * @param[in] window The window whose monitor, size or video mode to set. + * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. + * @param[in] xpos The desired x-coordinate of the upper-left corner of the + * client area. + * @param[in] ypos The desired y-coordinate of the upper-left corner of the + * client area. + * @param[in] width The desired with, in screen coordinates, of the client area + * or video mode. + * @param[in] height The desired height, in screen coordinates, of the client + * area or video mode. + * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref window_monitor + * @sa @ref window_full_screen + * @sa glfwGetWindowMonitor + * @sa glfwSetWindowSize + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); + /*! @brief Returns an attribute of the specified window. * * This function returns the value of an attribute of the specified window or @@ -2059,12 +2456,22 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); * @return The value of the attribute, or zero if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @remark Framebuffer related hints are not window attributes. See @ref + * window_attribs_fb for more information. + * + * @remark Zero is a valid value for many window and context related + * attributes so you cannot use a return value of zero as an indication of + * errors. However, this function should not fail as long as it is passed + * valid arguments and the library has been [initialized](@ref intro_init). + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_attribs * - * @since Added in GLFW 3.0. Replaces `glfwGetWindowParam` and + * @since Added in version 3.0. Replaces `glfwGetWindowParam` and * `glfwGetGLVersion`. * * @ingroup window @@ -2080,13 +2487,15 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); * @param[in] window The window whose pointer to set. * @param[in] pointer The new value. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_userptr * @sa glfwGetWindowUserPointer * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2099,13 +2508,15 @@ GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); * * @param[in] window The window whose pointer to return. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * * @sa @ref window_userptr * @sa glfwSetWindowUserPointer * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2123,12 +2534,13 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_pos * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2146,15 +2558,14 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @sa @ref window_size + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 1.0. + * @sa @ref window_size * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. * * @ingroup window */ @@ -2177,18 +2588,17 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @remarks __OS X:__ Selecting Quit from the application menu will - * trigger the close callback for all windows. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @par Thread Safety - * This function may only be called from the main thread. + * @remark @osx Selecting Quit from the application menu will trigger the close + * callback for all windows. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_close * - * @since Added in GLFW 2.5. - * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. * * @ingroup window */ @@ -2210,15 +2620,14 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @sa @ref window_refresh + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 2.5. + * @sa @ref window_refresh * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @since Added in version 2.5. + * @glfw3 Added window handle parameter and return value. * * @ingroup window */ @@ -2240,12 +2649,13 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2262,12 +2672,13 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_iconify * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2284,12 +2695,13 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref window_fbsize * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup window */ @@ -2313,16 +2725,18 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window * * Event processing is not required for joystick input to work. * - * @par Reentrancy - * This function may not be called from a callback. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwWaitEvents + * @sa glfwWaitEventsTimeout * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup window */ @@ -2356,21 +2770,69 @@ GLFWAPI void glfwPollEvents(void); * * Event processing is not required for joystick input to work. * - * @par Reentrancy - * This function may not be called from a callback. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref events * @sa glfwPollEvents + * @sa glfwWaitEventsTimeout * - * @since Added in GLFW 2.5. + * @since Added in version 2.5. * * @ingroup window */ GLFWAPI void glfwWaitEvents(void); +/*! @brief Waits with timeout until events are queued and processes them. + * + * This function puts the calling thread to sleep until at least one event is + * available in the event queue, or until the specified timeout is reached. If + * one or more events are available, it behaves exactly like @ref + * glfwPollEvents, i.e. the events in the queue are processed and the function + * then returns immediately. Processing events will cause the window and input + * callbacks associated with those events to be called. + * + * The timeout value must be a positive finite number. + * + * Since not all events are associated with callbacks, this function may return + * without a callback having been called even if you are monitoring all + * callbacks. + * + * On some platforms, a window move, resize or menu operation will cause event + * processing to block. This is due to how event processing is designed on + * those platforms. You can use the + * [window refresh callback](@ref window_refresh) to redraw the contents of + * your window when necessary during such operations. + * + * On some platforms, certain callbacks may be called outside of a call to one + * of the event processing functions. + * + * If no windows exist, this function returns immediately. For synchronization + * of threads in applications that do not create windows, use your threading + * library of choice. + * + * Event processing is not required for joystick input to work. + * + * @param[in] timeout The maximum amount of time, in seconds, to wait. + * + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref events + * @sa glfwPollEvents + * @sa glfwWaitEvents + * + * @since Added in version 3.2. + * + * @ingroup window + */ +GLFWAPI void glfwWaitEventsTimeout(double timeout); + /*! @brief Posts an empty event to the event queue. * * This function posts an empty event from the current thread to the event @@ -2380,13 +2842,15 @@ GLFWAPI void glfwWaitEvents(void); * of threads in applications that do not create windows, use your threading * library of choice. * - * @par Thread Safety - * This function may be called from any thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. * * @sa @ref events * @sa glfwWaitEvents * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup window */ @@ -2402,12 +2866,14 @@ GLFWAPI void glfwPostEmptyEvent(void); * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. + * + * @thread_safety This function must only be called from the main thread. * * @sa glfwSetInputMode * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -2428,37 +2894,96 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * and unlimited cursor movement. This is useful for implementing for * example 3D camera controls. * - * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GL_TRUE` to - * enable sticky keys, or `GL_FALSE` to disable it. If sticky keys are + * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to + * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` * the next time it is called even if the key had been released before the * call. This is useful when you are only interested in whether keys have been * pressed but not when or in which order. * * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either - * `GL_TRUE` to enable sticky mouse buttons, or `GL_FALSE` to disable it. If - * sticky mouse buttons are enabled, a mouse button press will ensure that @ref - * glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even if - * the mouse button had been released before the call. This is useful when you - * are only interested in whether mouse buttons have been pressed but not when - * or in which order. + * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it. + * If sticky mouse buttons are enabled, a mouse button press will ensure that + * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even + * if the mouse button had been released before the call. This is useful when + * you are only interested in whether mouse buttons have been pressed but not + * when or in which order. * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS` or * `GLFW_STICKY_MOUSE_BUTTONS`. * @param[in] value The new value of the specified input mode. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa glfwGetInputMode * - * @since Added in GLFW 3.0. Replaces `glfwEnable` and `glfwDisable`. + * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. * * @ingroup input */ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); +/*! @brief Returns the localized name of the specified printable key. + * + * This function returns the localized name of the specified printable key. + * This is intended for displaying key bindings to the user. + * + * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used instead, otherwise + * the scancode is ignored. If a non-printable key or (if the key is + * `GLFW_KEY_UNKNOWN`) a scancode that maps to a non-printable key is + * specified, this function returns `NULL`. + * + * This behavior allows you to pass in the arguments passed to the + * [key callback](@ref input_key) without modification. + * + * The printable keys are: + * - `GLFW_KEY_APOSTROPHE` + * - `GLFW_KEY_COMMA` + * - `GLFW_KEY_MINUS` + * - `GLFW_KEY_PERIOD` + * - `GLFW_KEY_SLASH` + * - `GLFW_KEY_SEMICOLON` + * - `GLFW_KEY_EQUAL` + * - `GLFW_KEY_LEFT_BRACKET` + * - `GLFW_KEY_RIGHT_BRACKET` + * - `GLFW_KEY_BACKSLASH` + * - `GLFW_KEY_WORLD_1` + * - `GLFW_KEY_WORLD_2` + * - `GLFW_KEY_0` to `GLFW_KEY_9` + * - `GLFW_KEY_A` to `GLFW_KEY_Z` + * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9` + * - `GLFW_KEY_KP_DECIMAL` + * - `GLFW_KEY_KP_DIVIDE` + * - `GLFW_KEY_KP_MULTIPLY` + * - `GLFW_KEY_KP_SUBTRACT` + * - `GLFW_KEY_KP_ADD` + * - `GLFW_KEY_KP_EQUAL` + * + * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. + * @param[in] scancode The scancode of the key to query. + * @return The localized name of the key, or `NULL`. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref + * glfwGetKeyName, or until the library is terminated. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref input_key_name + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI const char* glfwGetKeyName(int key, int scancode); + /*! @brief Returns the last reported state of a keyboard key for the specified * window. * @@ -2478,20 +3003,22 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); * The [modifier key bit masks](@ref mods) are not key tokens and cannot be * used with this function. * + * __Do not use this function__ to implement [text input](@ref input_char). + * * @param[in] window The desired window. * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is * not a valid key for this function. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. * - * @sa @ref input_key + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 1.0. + * @sa @ref input_key * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup input */ @@ -2512,15 +3039,15 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key); * @param[in] button The desired [mouse button](@ref buttons). * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_ENUM. * - * @sa @ref input_mouse_button + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 1.0. + * @sa @ref input_mouse_button * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup input */ @@ -2550,13 +3077,15 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); * @param[out] ypos Where to store the cursor y-coordinate, relative to the to * top edge of the client area, or `NULL`. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwSetCursorPos * - * @since Added in GLFW 3.0. Replaces `glfwGetMousePos`. + * @since Added in version 3.0. Replaces `glfwGetMousePos`. * * @ingroup input */ @@ -2585,17 +3114,19 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); * @param[in] ypos The desired y-coordinate, relative to the top edge of the * client area. * - * @remarks __X11:__ Due to the asynchronous nature of a modern X desktop, it - * may take a moment for the window focus event to arrive. This means you will - * not be able to set the cursor position directly after window creation. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for + * the window focus event to arrive. This means you may not be able to set the + * cursor position directly after window creation. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * @sa glfwGetCursorPos * - * @since Added in GLFW 3.0. Replaces `glfwSetMousePos`. + * @since Added in version 3.0. Replaces `glfwSetMousePos`. * * @ingroup input */ @@ -2607,9 +3138,9 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor. * Any remaining cursors are destroyed by @ref glfwTerminate. * - * The pixels are 32-bit little-endian RGBA, i.e. eight bits per channel. They - * are arranged canonically as packed sequential rows, starting from the - * top-left corner. + * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight + * bits per channel. They are arranged canonically as packed sequential rows, + * starting from the top-left corner. * * The cursor hotspot is specified in pixels, relative to the upper-left corner * of the cursor image. Like all other coordinate systems in GLFW, the X-axis @@ -2618,24 +3149,24 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); * @param[in] image The desired cursor image. * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. - * * @return The handle of the created cursor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The specified image data is copied before this function returns. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Reentrancy - * This function may not be called from a callback. + * @pointer_lifetime The specified image data is copied before this function + * returns. * - * @par Thread Safety - * This function may only be called from the main thread. + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwDestroyCursor * @sa glfwCreateStandardCursor * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2647,20 +3178,20 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) * a window with @ref glfwSetCursor. * * @param[in] shape One of the [standard shapes](@ref shapes). - * * @return A new cursor ready to use or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Reentrancy - * This function may not be called from a callback. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2674,16 +3205,17 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); * * @param[in] cursor The cursor object to destroy. * - * @par Reentrancy - * This function may not be called from a callback. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @reentrancy This function must not be called from a callback. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * @sa glfwCreateCursor * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2703,12 +3235,14 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); * @param[in] cursor The cursor to set, or `NULL` to switch back to the default * arrow cursor. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_object * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2744,15 +3278,14 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @sa @ref input_key + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 1.0. + * @sa @ref input_key * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. * * @ingroup input */ @@ -2783,15 +3316,14 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @sa @ref input_char + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 2.4. + * @sa @ref input_char * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @since Added in version 2.4. + * @glfw3 Added window handle parameter and return value. * * @ingroup input */ @@ -2818,12 +3350,13 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun); * @return The previously set callback, or `NULL` if no callback was set or an * error occurred. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref input_char * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2846,15 +3379,14 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * - * @sa @ref input_mouse_button + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 1.0. + * @sa @ref input_mouse_button * - * @par - * __GLFW 3:__ Added window handle parameter. Updated callback signature. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter and return value. * * @ingroup input */ @@ -2873,12 +3405,13 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_pos * - * @since Added in GLFW 3.0. Replaces `glfwSetMousePosCallback`. + * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`. * * @ingroup input */ @@ -2896,12 +3429,13 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref cursor_enter * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -2922,12 +3456,13 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref scrolling * - * @since Added in GLFW 3.0. Replaces `glfwSetMouseWheelCallback`. + * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`. * * @ingroup input */ @@ -2949,12 +3484,13 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref path_drop * - * @since Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup input */ @@ -2965,14 +3501,16 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun); * This function returns whether the specified joystick is present. * * @param[in] joy The [joystick](@ref joysticks) to query. - * @return `GL_TRUE` if the joystick is present, or `GL_FALSE` otherwise. + * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick * - * @since Added in GLFW 3.0. Replaces `glfwGetJoystickParam`. + * @since Added in version 3.0. Replaces `glfwGetJoystickParam`. * * @ingroup input */ @@ -2983,22 +3521,28 @@ GLFWAPI int glfwJoystickPresent(int joy); * This function returns the values of all axes of the specified joystick. * Each element in the array is a value between -1.0 and 1.0. * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of axis values in the returned * array. This is set to zero if an error occurred. * @return An array of axis values, or `NULL` if the joystick is not present. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, this function is called again for that joystick or the library + * is terminated. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_axis * - * @since Added in GLFW 3.0. Replaces `glfwGetJoystickPos`. + * @since Added in version 3.0. Replaces `glfwGetJoystickPos`. * * @ingroup input */ @@ -3009,25 +3553,29 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count); * This function returns the state of all buttons of the specified joystick. * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * * @param[in] joy The [joystick](@ref joysticks) to query. * @param[out] count Where to store the number of button states in the returned * array. This is set to zero if an error occurred. * @return An array of button states, or `NULL` if the joystick is not present. * - * @par Pointer Lifetime - * The returned array is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, this function is called again for that joystick or the library + * is terminated. * - * @sa @ref joystick_button + * @thread_safety This function must only be called from the main thread. * - * @since Added in GLFW 2.2. + * @sa @ref joystick_button * - * @par - * __GLFW 3:__ Changed to return a dynamic array. + * @since Added in version 2.2. + * @glfw3 Changed to return a dynamic array. * * @ingroup input */ @@ -3039,26 +3587,55 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count); * The returned string is allocated and freed by GLFW. You should not free it * yourself. * + * Querying a joystick slot with no device present is not an error, but will + * cause this function to return `NULL`. Call @ref glfwJoystickPresent to + * check device presence. + * * @param[in] joy The [joystick](@ref joysticks) to query. * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick * is not present. * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the specified joystick is disconnected, this - * function is called again for that joystick or the library is terminated. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the specified joystick is + * disconnected, this function is called again for that joystick or the library + * is terminated. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref joystick_name * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ GLFWAPI const char* glfwGetJoystickName(int joy); +/*! @brief Sets the joystick configuration callback. + * + * This function sets the joystick configuration callback, or removes the + * currently set callback. This is called when a joystick is connected to or + * disconnected from the system. + * + * @param[in] cbfun The new callback, or `NULL` to remove the currently set + * callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref joystick_event + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun); + /*! @brief Sets the clipboard to the specified string. * * This function sets the system clipboard to the specified, UTF-8 encoded @@ -3067,16 +3644,18 @@ GLFWAPI const char* glfwGetJoystickName(int joy); * @param[in] window The window that will own the clipboard contents. * @param[in] string A UTF-8 encoded string. * - * @par Pointer Lifetime - * The specified string is copied before this function returns. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @par Thread Safety - * This function may only be called from the main thread. + * @pointer_lifetime The specified string is copied before this function + * returns. + * + * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwGetClipboardString * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -3085,25 +3664,28 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); /*! @brief Returns the contents of the clipboard as a string. * * This function returns the contents of the system clipboard, if it contains - * or is convertible to a UTF-8 encoded string. + * or is convertible to a UTF-8 encoded string. If the clipboard is empty or + * if its contents cannot be converted, `NULL` is returned and a @ref + * GLFW_FORMAT_UNAVAILABLE error is generated. * * @param[in] window The window that will request the clipboard contents. * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * - * @par Pointer Lifetime - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. It is valid until the next call to @ref + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. + * + * @pointer_lifetime The returned string is allocated and freed by GLFW. You + * should not free it yourself. It is valid until the next call to @ref * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library * is terminated. * - * @par Thread Safety - * This function may only be called from the main thread. + * @thread_safety This function must only be called from the main thread. * * @sa @ref clipboard * @sa glfwSetClipboardString * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup input */ @@ -3122,12 +3704,14 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); * @return The current value, in seconds, or zero if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. Reading of the + * internal timer offset is not atomic. * * @sa @ref time * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup input */ @@ -3136,21 +3720,71 @@ GLFWAPI double glfwGetTime(void); /*! @brief Sets the GLFW timer. * * This function sets the value of the GLFW timer. It then continues to count - * up from that value. + * up from that value. The value must be a positive finite number less than + * or equal to 18446744073.0, which is approximately 584.5 years. * * @param[in] time The new value, in seconds. * - * @par Thread Safety - * This function may only be called from the main thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_INVALID_VALUE. + * + * @remark The upper limit of the timer is calculated as + * floor((264 - 1) / 109) and is due to implementations + * storing nanoseconds in 64 bits. The limit may be increased in the future. + * + * @thread_safety This function may be called from any thread. Writing of the + * internal timer offset is not atomic. * * @sa @ref time * - * @since Added in GLFW 2.2. + * @since Added in version 2.2. * * @ingroup input */ GLFWAPI void glfwSetTime(double time); +/*! @brief Returns the current value of the raw timer. + * + * This function returns the current value of the raw timer, measured in + * 1 / frequency seconds. To get the frequency, call @ref + * glfwGetTimerFrequency. + * + * @return The value of the timer, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa glfwGetTimerFrequency + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerValue(void); + +/*! @brief Returns the frequency, in Hz, of the raw timer. + * + * This function returns the frequency, in Hz, of the raw timer. + * + * @return The frequency of the timer, in Hz, or zero if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref time + * @sa glfwGetTimerValue + * + * @since Added in version 3.2. + * + * @ingroup input + */ +GLFWAPI uint64_t glfwGetTimerFrequency(void); + /*! @brief Makes the context of the specified window current for the calling * thread. * @@ -3164,16 +3798,22 @@ GLFWAPI void glfwSetTime(double time); * whether a context performs this flush by setting the * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref window_hints_ctx) window hint. * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * * @param[in] window The window whose context to make current, or `NULL` to * detach the current context. * - * @par Thread Safety - * This function may be called from any thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwGetCurrentContext * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup context */ @@ -3187,13 +3827,14 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); * @return The window whose context is current, or `NULL` if no window's * context is current. * - * @par Thread Safety - * This function may be called from any thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. * * @sa @ref context_current * @sa glfwMakeContextCurrent * - * @since Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup context */ @@ -3201,22 +3842,33 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void); /*! @brief Swaps the front and back buffers of the specified window. * - * This function swaps the front and back buffers of the specified window. If - * the swap interval is greater than zero, the GPU driver waits the specified - * number of screen updates before swapping the buffers. + * This function swaps the front and back buffers of the specified window when + * rendering with OpenGL or OpenGL ES. If the swap interval is greater than + * zero, the GPU driver waits the specified number of screen updates before + * swapping the buffers. + * + * The specified window must have an OpenGL or OpenGL ES context. Specifying + * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT + * error. + * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see `vkQueuePresentKHR` instead. * * @param[in] window The window whose buffers to swap. * - * @par Thread Safety - * This function may be called from any thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark __EGL:__ The context of the specified window must be current on the + * calling thread. + * + * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapInterval * - * @since Added in GLFW 1.0. - * - * @par - * __GLFW 3:__ Added window handle parameter. + * @since Added in version 1.0. + * @glfw3 Added window handle parameter. * * @ingroup window */ @@ -3224,11 +3876,11 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); /*! @brief Sets the swap interval for the current context. * - * This function sets the swap interval for the current context, i.e. the - * number of screen updates to wait from the time @ref glfwSwapBuffers was - * called before swapping the buffers and returning. This is sometimes called - * _vertical synchronization_, _vertical retrace synchronization_ or just - * _vsync_. + * This function sets the swap interval for the current OpenGL or OpenGL ES + * context, i.e. the number of screen updates to wait from the time @ref + * glfwSwapBuffers was called before swapping the buffers and returning. This + * is sometimes called _vertical synchronization_, _vertical retrace + * synchronization_ or just _vsync_. * * Contexts that support either of the `WGL_EXT_swap_control_tear` and * `GLX_EXT_swap_control_tear` extensions also accept negative swap intervals, @@ -3240,25 +3892,30 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window); * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see the present mode of your swapchain instead. + * * @param[in] interval The minimum number of screen updates to wait for * until the buffers are swapped by @ref glfwSwapBuffers. * - * @note This function is not called during window creation, leaving the swap - * interval set to whatever is the default on that platform. This is done + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. + * + * @remark This function is not called during context creation, leaving the + * swap interval set to whatever is the default on that platform. This is done * because some swap interval extensions used by GLFW do not allow the swap * interval to be reset to zero once it has been set to a non-zero value. * - * @note Some GPU drivers do not honor the requested swap interval, either - * because of user settings that override the request or due to bugs in the - * driver. + * @remark Some GPU drivers do not honor the requested swap interval, either + * because of a user setting that overrides the application's request or due to + * bugs in the driver. * - * @par Thread Safety - * This function may be called from any thread. + * @thread_safety This function may be called from any thread. * * @sa @ref buffer_swap * @sa glfwSwapBuffers * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup context */ @@ -3268,8 +3925,8 @@ GLFWAPI void glfwSwapInterval(int interval); * * This function returns whether the specified * [API extension](@ref context_glext) is supported by the current OpenGL or - * OpenGL ES context. It searches both for OpenGL and OpenGL ES extension and - * platform-specific context creation API extensions. + * OpenGL ES context. It searches both for client API extension and context + * creation API extensions. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. @@ -3279,16 +3936,24 @@ GLFWAPI void glfwSwapInterval(int interval); * frequently. The extension strings will not change during the lifetime of * a context, so there is no danger in doing this. * + * This function does not apply to Vulkan. If you are using Vulkan, see @ref + * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties` + * and `vkEnumerateDeviceExtensionProperties` instead. + * * @param[in] extension The ASCII encoded name of the extension. - * @return `GL_TRUE` if the extension is available, or `GL_FALSE` otherwise. + * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` + * otherwise. * - * @par Thread Safety - * This function may be called from any thread. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref + * GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwGetProcAddress * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup context */ @@ -3297,36 +3962,243 @@ GLFWAPI int glfwExtensionSupported(const char* extension); /*! @brief Returns the address of the specified function for the current * context. * - * This function returns the address of the specified - * [client API or extension function](@ref context_glext), if it is supported + * This function returns the address of the specified OpenGL or OpenGL ES + * [core or extension function](@ref context_glext), if it is supported * by the current context. * * A context must be current on the calling thread. Calling this function * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. * + * This function does not apply to Vulkan. If you are rendering with Vulkan, + * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and + * `vkGetDeviceProcAddr` instead. + * * @param[in] procname The ASCII encoded name of the function. - * @return The address of the function, or `NULL` if the function is - * unavailable or an [error](@ref error_handling) occurred. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. * - * @note The addresses of a given function is not guaranteed to be the same + * @remark The address of a given function is not guaranteed to be the same * between contexts. * - * @par Pointer Lifetime - * The returned function pointer is valid until the context is destroyed or the - * library is terminated. + * @remark This function may return a non-`NULL` address despite the + * associated version or extension not being available. Always check the + * context version or extension string first. * - * @par Thread Safety - * This function may be called from any thread. + * @pointer_lifetime The returned function pointer is valid until the context + * is destroyed or the library is terminated. + * + * @thread_safety This function may be called from any thread. * * @sa @ref context_glext * @sa glfwExtensionSupported * - * @since Added in GLFW 1.0. + * @since Added in version 1.0. * * @ingroup context */ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); +/*! @brief Returns whether the Vulkan loader has been found. + * + * This function returns whether the Vulkan loader has been found. This check + * is performed by @ref glfwInit. + * + * The availability of a Vulkan loader does not by itself guarantee that window + * surface creation or even device creation is possible. Call @ref + * glfwGetRequiredInstanceExtensions to check whether the extensions necessary + * for Vulkan surface creation are available and @ref + * glfwGetPhysicalDevicePresentationSupport to check whether a queue family of + * a physical device supports image presentation. + * + * @return `GLFW_TRUE` if Vulkan is available, or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_support + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwVulkanSupported(void); + +/*! @brief Returns the Vulkan instance extensions required by GLFW. + * + * This function returns an array of names of Vulkan instance extensions required + * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the + * list will always contains `VK_KHR_surface`, so if you don't require any + * additional extensions you can pass this list directly to the + * `VkInstanceCreateInfo` struct. + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available. + * + * If Vulkan is available but no set of extensions allowing window surface + * creation was found, this function returns `NULL`. You may still use Vulkan + * for off-screen rendering and compute work. + * + * @param[out] count Where to store the number of extensions in the returned + * array. This is set to zero if an error occurred. + * @return An array of ASCII encoded extension names, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @remarks Additional extensions may be required by future versions of GLFW. + * You should check if any extensions you wish to enable are already in the + * returned array, as it is an error to specify an extension more than once in + * the `VkInstanceCreateInfo` struct. + * + * @pointer_lifetime The returned array is allocated and freed by GLFW. You + * should not free it yourself. It is guaranteed to be valid only until the + * library is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_ext + * @sa glfwCreateWindowSurface + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count); + +#if defined(VK_VERSION_1_0) + +/*! @brief Returns the address of the specified Vulkan instance function. + * + * This function returns the address of the specified Vulkan core or extension + * function for the specified instance. If instance is set to `NULL` it can + * return any function exported from the Vulkan loader, including at least the + * following functions: + * + * - `vkEnumerateInstanceExtensionProperties` + * - `vkEnumerateInstanceLayerProperties` + * - `vkCreateInstance` + * - `vkGetInstanceProcAddr` + * + * If Vulkan is not available on the machine, this function returns `NULL` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available. + * + * This function is equivalent to calling `vkGetInstanceProcAddr` with + * a platform-specific query of the Vulkan loader as a fallback. + * + * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve + * functions related to instance creation. + * @param[in] procname The ASCII encoded name of the function. + * @return The address of the function, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_API_UNAVAILABLE. + * + * @pointer_lifetime The returned function pointer is valid until the library + * is terminated. + * + * @thread_safety This function may be called from any thread. + * + * @sa @ref vulkan_proc + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); + +/*! @brief Returns whether the specified queue family can present images. + * + * This function returns whether the specified queue family of the specified + * physical device supports presentation to the platform GLFW was built for. + * + * If Vulkan or the required window surface creation instance extensions are + * not available on the machine, or if the specified instance was not created + * with the required extensions, this function returns `GLFW_FALSE` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported + * to check whether Vulkan is available and @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * @param[in] instance The instance that the physical device belongs to. + * @param[in] device The physical device that the queue family belongs to. + * @param[in] queuefamily The index of the queue family to query. + * @return `GLFW_TRUE` if the queue family supports presentation, or + * `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_present + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); + +/*! @brief Creates a Vulkan surface for the specified window. + * + * This function creates a Vulkan surface for the specified window. + * + * If the Vulkan loader was not found at initialization, this function returns + * `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref GLFW_API_UNAVAILABLE + * error. Call @ref glfwVulkanSupported to check whether the Vulkan loader was + * found. + * + * If the required window surface creation instance extensions are not + * available or if the specified instance was not created with these extensions + * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and + * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref + * glfwGetRequiredInstanceExtensions to check what instance extensions are + * required. + * + * The window surface must be destroyed before the specified Vulkan instance. + * It is the responsibility of the caller to destroy the window surface. GLFW + * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the + * surface. + * + * @param[in] instance The Vulkan instance to create the surface in. + * @param[in] window The window to create the surface for. + * @param[in] allocator The allocator to use, or `NULL` to use the default + * allocator. + * @param[out] surface Where to store the handle of the surface. This is set + * to `VK_NULL_HANDLE` if an error occurred. + * @return `VK_SUCCESS` if successful, or a Vulkan error code if an + * [error](@ref error_handling) occurred. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * + * @remarks If an error occurs before the creation call is made, GLFW returns + * the Vulkan error code most appropriate for the error. Appropriate use of + * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should + * eliminate almost all occurrences of these errors. + * + * @thread_safety This function may be called from any thread. For + * synchronization details of Vulkan objects, see the Vulkan specification. + * + * @sa @ref vulkan_surface + * @sa glfwGetRequiredInstanceExtensions + * + * @since Added in version 3.2. + * + * @ingroup vulkan + */ +GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); + +#endif /*VK_VERSION_1_0*/ + /************************************************************************* * Global definition cleanup diff --git a/examples/libs/glfw/include/GLFW/glfw3native.h b/examples/libs/glfw/include/GLFW/glfw3native.h index b3ce7482..9fa955e9 100644 --- a/examples/libs/glfw/include/GLFW/glfw3native.h +++ b/examples/libs/glfw/include/GLFW/glfw3native.h @@ -1,5 +1,5 @@ /************************************************************************* - * GLFW 3.1 - www.glfw.org + * GLFW 3.2 - www.glfw.org * A library for OpenGL, window and input *------------------------------------------------------------------------ * Copyright (c) 2002-2006 Marcus Geelnard @@ -38,20 +38,30 @@ extern "C" { * Doxygen documentation *************************************************************************/ +/*! @file glfw3native.h + * @brief The header of the native access functions. + * + * This is the header file of the native access functions. See @ref native for + * more information. + */ /*! @defgroup native Native access * * **By using the native access functions you assert that you know what you're * doing and how to fix problems caused by using them. If you don't, you * shouldn't be using them.** * - * Before the inclusion of @ref glfw3native.h, you must define exactly one - * window system API macro and exactly one context creation API macro. Failure - * to do this will cause a compile-time error. + * Before the inclusion of @ref glfw3native.h, you may define exactly one + * window system API macro and zero or more context creation API macros. + * + * The chosen backends must match those the library was compiled for. Failure + * to do this will cause a link-time error. * * The available window API macros are: * * `GLFW_EXPOSE_NATIVE_WIN32` * * `GLFW_EXPOSE_NATIVE_COCOA` * * `GLFW_EXPOSE_NATIVE_X11` + * * `GLFW_EXPOSE_NATIVE_WAYLAND` + * * `GLFW_EXPOSE_NATIVE_MIR` * * The available context API macros are: * * `GLFW_EXPOSE_NATIVE_WGL` @@ -86,20 +96,23 @@ extern "C" { #elif defined(GLFW_EXPOSE_NATIVE_X11) #include #include -#else - #error "No window API selected" +#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) + #include +#elif defined(GLFW_EXPOSE_NATIVE_MIR) + #include #endif #if defined(GLFW_EXPOSE_NATIVE_WGL) /* WGL is declared by windows.h */ -#elif defined(GLFW_EXPOSE_NATIVE_NSGL) +#endif +#if defined(GLFW_EXPOSE_NATIVE_NSGL) /* NSGL is declared by Cocoa.h */ -#elif defined(GLFW_EXPOSE_NATIVE_GLX) +#endif +#if defined(GLFW_EXPOSE_NATIVE_GLX) #include -#elif defined(GLFW_EXPOSE_NATIVE_EGL) +#endif +#if defined(GLFW_EXPOSE_NATIVE_EGL) #include -#else - #error "No context API selected" #endif @@ -114,11 +127,10 @@ extern "C" { * of the specified monitor, or `NULL` if an [error](@ref error_handling) * occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -130,11 +142,10 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -145,11 +156,10 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); * @return The `HWND` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -162,11 +172,10 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); * @return The `HGLRC` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -179,11 +188,10 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); * @return The `CGDirectDisplayID` of the specified monitor, or * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -194,11 +202,10 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); * @return The `NSWindow` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -211,11 +218,10 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); * @return The `NSOpenGLContext` of the specified window, or `nil` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -228,11 +234,10 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); * @return The `Display` used by GLFW, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -243,11 +248,10 @@ GLFWAPI Display* glfwGetX11Display(void); * @return The `RRCrtc` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -258,11 +262,10 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); * @return The `RROutput` of the specified monitor, or `None` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.1. + * @since Added in version 3.1. * * @ingroup native */ @@ -273,11 +276,10 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); * @return The `Window` of the specified window, or `None` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -290,15 +292,116 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window); * @return The `GLXContext` of the specified window, or `NULL` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); + +/*! @brief Returns the `GLXWindow` of the specified window. + * + * @return The `GLXWindow` of the specified window, or `None` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_WAYLAND) +/*! @brief Returns the `struct wl_display*` used by GLFW. + * + * @return The `struct wl_display*` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); + +/*! @brief Returns the `struct wl_output*` of the specified monitor. + * + * @return The `struct wl_output*` of the specified monitor, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the main `struct wl_surface*` of the specified window. + * + * @return The main `struct wl_surface*` of the specified window, or `NULL` if + * an [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); +#endif + +#if defined(GLFW_EXPOSE_NATIVE_MIR) +/*! @brief Returns the `MirConnection*` used by GLFW. + * + * @return The `MirConnection*` used by GLFW, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI MirConnection* glfwGetMirDisplay(void); + +/*! @brief Returns the Mir output ID of the specified monitor. + * + * @return The Mir output ID of the specified monitor, or zero if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor); + +/*! @brief Returns the `MirSurface*` of the specified window. + * + * @return The `MirSurface*` of the specified window, or `NULL` if an + * [error](@ref error_handling) occurred. + * + * @thread_safety This function may be called from any thread. Access is not + * synchronized. + * + * @since Added in version 3.2. + * + * @ingroup native + */ +GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window); #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) @@ -307,11 +410,10 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -322,11 +424,10 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void); * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ @@ -337,11 +438,10 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * [error](@ref error_handling) occurred. * - * @par Thread Safety - * This function may be called from any thread. Access is not synchronized. + * @thread_safety This function may be called from any thread. Access is not + * synchronized. * - * @par History - * Added in GLFW 3.0. + * @since Added in version 3.0. * * @ingroup native */ diff --git a/examples/libs/glfw/lib-vc2010-32/glfw3.lib b/examples/libs/glfw/lib-vc2010-32/glfw3.lib index 014458ef..348abecf 100644 Binary files a/examples/libs/glfw/lib-vc2010-32/glfw3.lib and b/examples/libs/glfw/lib-vc2010-32/glfw3.lib differ diff --git a/examples/libs/glfw/lib-vc2010-64/glfw3.lib b/examples/libs/glfw/lib-vc2010-64/glfw3.lib index 8cdda399..768f3083 100644 Binary files a/examples/libs/glfw/lib-vc2010-64/glfw3.lib and b/examples/libs/glfw/lib-vc2010-64/glfw3.lib differ diff --git a/examples/vulkan_example/CMakeLists.txt b/examples/vulkan_example/CMakeLists.txt new file mode 100644 index 00000000..3657c829 --- /dev/null +++ b/examples/vulkan_example/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 2.8) +project(ImGuiGLFWVulkanExample C CXX) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) +endif() + +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES") +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES") + +# GLFW +set(GLFW_DIR ../../../glfw) # Set this to point to a up-to-date GLFW repo +option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF) +option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF) +option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF) +option(GLFW_INSTALL "Generate installation target" OFF) +option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) +add_subdirectory(${GLFW_DIR} binary_dir EXCLUDE_FROM_ALL) +include_directories(${GLFW_DIR}/include) + +# ImGui +set(IMGUI_DIR ../../) +include_directories(${IMGUI_DIR}) + +# Libraries +find_library(VULKAN_LIBRARY + NAMES vulkan vulkan-1) +set(LIBRARIES "glfw;${VULKAN_LIBRARY}") + +# Use vulkan headers from glfw: +include_directories(${GLFW_DIR}/deps) + +file(GLOB sources *.cpp) + +add_executable(vulkan_example ${sources} ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp) +target_link_libraries(vulkan_example ${LIBRARIES}) diff --git a/examples/vulkan_example/build_win32.bat b/examples/vulkan_example/build_win32.bat new file mode 100644 index 00000000..e8b5a6c7 --- /dev/null +++ b/examples/vulkan_example/build_win32.bat @@ -0,0 +1,4 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include /I %VULKAN_SDK%\include *.cpp ..\..\*.cpp /FeDebug/vulkan_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\bin32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib + diff --git a/examples/vulkan_example/gen_spv.sh b/examples/vulkan_example/gen_spv.sh new file mode 100755 index 00000000..f95f8fa8 --- /dev/null +++ b/examples/vulkan_example/gen_spv.sh @@ -0,0 +1,4 @@ +#!/bin/bash +glslangValidator -V -o glsl_shader.frag.spv glsl_shader.frag +glslangValidator -V -o glsl_shader.vert.spv glsl_shader.vert +spirv-remap --map all --dce all --strip-all --input glsl_shader.frag.spv glsl_shader.vert.spv --output ./ diff --git a/examples/vulkan_example/glsl_shader.frag b/examples/vulkan_example/glsl_shader.frag new file mode 100644 index 00000000..8205b673 --- /dev/null +++ b/examples/vulkan_example/glsl_shader.frag @@ -0,0 +1,14 @@ +#version 450 core +layout(location = 0, index = 0) out vec4 fColor; + +layout(set=0, binding=0) uniform sampler2D sTexture; + +in block{ + vec4 Color; + vec2 UV; +} In; + +void main() +{ + fColor = In.Color * texture(sTexture, In.UV.st); +} diff --git a/examples/vulkan_example/glsl_shader.vert b/examples/vulkan_example/glsl_shader.vert new file mode 100644 index 00000000..55098fec --- /dev/null +++ b/examples/vulkan_example/glsl_shader.vert @@ -0,0 +1,21 @@ +#version 450 core +layout(location = 0) in vec2 aPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec4 aColor; + +layout(push_constant) uniform uPushConstant{ + vec2 uScale; + vec2 uTranslate; +} pc; + +out block{ + vec4 Color; + vec2 UV; +} Out; + +void main() +{ + Out.Color = aColor; + Out.UV = aUV; + gl_Position = vec4(aPos*pc.uScale+pc.uTranslate, 0, 1); +} diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp new file mode 100644 index 00000000..33d8e997 --- /dev/null +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -0,0 +1,935 @@ +// ImGui GLFW binding with Vulkan + shaders +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 5 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXX_CreateFontsTexture(), ImGui_ImplXXXX_NewFrame(), ImGui_ImplXXXX_Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include + +// GLFW +#define GLFW_INCLUDE_NONE +#define GLFW_INCLUDE_VULKAN +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +#include "imgui_impl_glfw_vulkan.h" + +// GLFW Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; + +// Vulkan Data +static VkAllocationCallbacks* g_Allocator = NULL; +static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; +static VkDevice g_Device = VK_NULL_HANDLE; +static VkRenderPass g_RenderPass = VK_NULL_HANDLE; +static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; +static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; +static void (*g_CheckVkResult)(VkResult err) = NULL; + +static VkCommandBuffer g_CommandBuffer = VK_NULL_HANDLE; +static size_t g_BufferMemoryAlignment = 256; +static VkPipelineCreateFlags g_PipelineCreateFlags = 0; +static int g_FrameIndex = 0; + +static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE; +static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE; +static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE; +static VkPipeline g_Pipeline = VK_NULL_HANDLE; + +static VkSampler g_FontSampler = VK_NULL_HANDLE; +static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE; +static VkImage g_FontImage = VK_NULL_HANDLE; +static VkImageView g_FontView = VK_NULL_HANDLE; + +static VkDeviceMemory g_VertexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {}; +static VkDeviceMemory g_IndexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {}; +static size_t g_VertexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {}; +static size_t g_IndexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {}; +static VkBuffer g_VertexBuffer[IMGUI_VK_QUEUED_FRAMES] = {}; +static VkBuffer g_IndexBuffer[IMGUI_VK_QUEUED_FRAMES] = {}; + +static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; +static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; + +static unsigned char __glsl_shader_vert_spv[] = +{ + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x6c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, + 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x16, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x41, 0x14, 0x00, 0x00, + 0x6a, 0x16, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, + 0x47, 0x00, 0x03, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x41, 0x14, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x6a, 0x16, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0xb1, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xb1, 0x02, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0xb1, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0xb1, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0xb1, 0x02, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x80, 0x14, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x06, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x03, 0x00, 0x06, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0xfa, 0x16, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x03, 0x00, 0x02, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, + 0x1a, 0x04, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1a, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00, + 0x47, 0x11, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x9a, 0x02, 0x00, 0x00, 0x41, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x9b, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0e, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x90, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, 0x6a, 0x16, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x91, 0x02, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x7f, 0x02, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, + 0xb1, 0x02, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x7f, 0x02, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x2e, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, + 0x80, 0x14, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, + 0x06, 0x04, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x83, 0x06, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x06, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x83, 0x06, 0x00, 0x00, + 0xfa, 0x16, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x92, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x05, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x1f, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x05, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x6b, 0x60, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x71, 0x4e, 0x00, 0x00, + 0x41, 0x14, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x9b, 0x02, 0x00, 0x00, + 0xaa, 0x26, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xaa, 0x26, 0x00, 0x00, 0x71, 0x4e, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xda, 0x35, 0x00, 0x00, + 0x6a, 0x16, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x91, 0x02, 0x00, 0x00, + 0xea, 0x50, 0x00, 0x00, 0x47, 0x11, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xea, 0x50, 0x00, 0x00, 0xda, 0x35, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xc7, 0x35, 0x00, 0x00, + 0x80, 0x14, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x92, 0x02, 0x00, 0x00, + 0xef, 0x56, 0x00, 0x00, 0xfa, 0x16, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xe0, 0x29, 0x00, 0x00, + 0xef, 0x56, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, + 0xa0, 0x22, 0x00, 0x00, 0xc7, 0x35, 0x00, 0x00, 0xe0, 0x29, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x92, 0x02, 0x00, 0x00, 0x42, 0x2c, 0x00, 0x00, + 0xfa, 0x16, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x09, 0x60, 0x00, 0x00, 0x42, 0x2c, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00, + 0xa0, 0x22, 0x00, 0x00, 0x09, 0x60, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0xa1, 0x41, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x84, 0x36, 0x00, 0x00, 0xd1, 0x4e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x07, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x54, 0x47, 0x00, 0x00, + 0xa1, 0x41, 0x00, 0x00, 0x84, 0x36, 0x00, 0x00, 0x0c, 0x0a, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x9b, 0x02, 0x00, 0x00, + 0x17, 0x2f, 0x00, 0x00, 0x42, 0x13, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x17, 0x2f, 0x00, 0x00, 0x54, 0x47, 0x00, 0x00, + 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 +}; +static unsigned int __glsl_shader_vert_spv_len = 1172; + +static unsigned char __glsl_shader_frag_spv[] = +{ + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x6c, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1f, 0x16, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x7a, 0x0c, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x1f, 0x16, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x7a, 0x0c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x7a, 0x0c, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x1a, 0x04, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xec, 0x14, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0xec, 0x14, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, + 0x02, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x9a, 0x02, 0x00, 0x00, + 0x7a, 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x04, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x97, 0x06, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x97, 0x06, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x9b, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x09, 0x00, 0x96, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x03, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x7b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x7b, 0x04, 0x00, 0x00, + 0xec, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x90, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x1f, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x6b, 0x5d, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x9b, 0x02, 0x00, 0x00, 0x8d, 0x1b, 0x00, 0x00, 0x35, 0x16, 0x00, 0x00, + 0x0b, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x0b, 0x40, 0x00, 0x00, 0x8d, 0x1b, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0xfe, 0x01, 0x00, 0x00, 0xc0, 0x36, 0x00, 0x00, 0xec, 0x14, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x90, 0x02, 0x00, 0x00, 0xc2, 0x43, 0x00, 0x00, + 0x35, 0x16, 0x00, 0x00, 0x0e, 0x0a, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x02, 0x4e, 0x00, 0x00, 0xc2, 0x43, 0x00, 0x00, + 0x57, 0x00, 0x05, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xb9, 0x46, 0x00, 0x00, + 0xc0, 0x36, 0x00, 0x00, 0x02, 0x4e, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0xe4, 0x23, 0x00, 0x00, 0x0b, 0x40, 0x00, 0x00, + 0xb9, 0x46, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7a, 0x0c, 0x00, 0x00, + 0xe4, 0x23, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 +}; +static unsigned int __glsl_shader_frag_spv_len = 660; + +static uint32_t ImGui_ImplGlfwVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits) +{ + VkPhysicalDeviceMemoryProperties prop; + vkGetPhysicalDeviceMemoryProperties(g_Gpu, &prop); + for (uint32_t i = 0; i < prop.memoryTypeCount; i++) + if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<TotalVtxCount * sizeof(ImDrawVert); + if (!g_VertexBuffer[g_FrameIndex] || g_VertexBufferSize[g_FrameIndex] < vertex_size) + { + if (g_VertexBuffer[g_FrameIndex]) + vkDestroyBuffer(g_Device, g_VertexBuffer[g_FrameIndex], g_Allocator); + if (g_VertexBufferMemory[g_FrameIndex]) + vkFreeMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], g_Allocator); + size_t vertex_buffer_size = ((vertex_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment; + VkBufferCreateInfo buffer_info = {}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = vertex_buffer_size; + buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_VertexBuffer[g_FrameIndex]); + ImGui_ImplGlfwVulkan_VkResult(err); + VkMemoryRequirements req; + vkGetBufferMemoryRequirements(g_Device, g_VertexBuffer[g_FrameIndex], &req); + g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = req.size; + alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); + err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_VertexBufferMemory[g_FrameIndex]); + ImGui_ImplGlfwVulkan_VkResult(err); + err = vkBindBufferMemory(g_Device, g_VertexBuffer[g_FrameIndex], g_VertexBufferMemory[g_FrameIndex], 0); + ImGui_ImplGlfwVulkan_VkResult(err); + g_VertexBufferSize[g_FrameIndex] = vertex_buffer_size; + } + + // Create the Index Buffer: + size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); + if (!g_IndexBuffer[g_FrameIndex] || g_IndexBufferSize[g_FrameIndex] < index_size) + { + if (g_IndexBuffer[g_FrameIndex]) + vkDestroyBuffer(g_Device, g_IndexBuffer[g_FrameIndex], g_Allocator); + if (g_IndexBufferMemory[g_FrameIndex]) + vkFreeMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], g_Allocator); + size_t index_buffer_size = ((index_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment; + VkBufferCreateInfo buffer_info = {}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = index_buffer_size; + buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_IndexBuffer[g_FrameIndex]); + ImGui_ImplGlfwVulkan_VkResult(err); + VkMemoryRequirements req; + vkGetBufferMemoryRequirements(g_Device, g_IndexBuffer[g_FrameIndex], &req); + g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = req.size; + alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); + err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_IndexBufferMemory[g_FrameIndex]); + ImGui_ImplGlfwVulkan_VkResult(err); + err = vkBindBufferMemory(g_Device, g_IndexBuffer[g_FrameIndex], g_IndexBufferMemory[g_FrameIndex], 0); + ImGui_ImplGlfwVulkan_VkResult(err); + g_IndexBufferSize[g_FrameIndex] = index_buffer_size; + } + + // Upload Vertex and index Data: + { + ImDrawVert* vtx_dst; + ImDrawIdx* idx_dst; + err = vkMapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], 0, vertex_size, 0, (void**)(&vtx_dst)); + ImGui_ImplGlfwVulkan_VkResult(err); + err = vkMapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], 0, index_size, 0, (void**)(&idx_dst)); + ImGui_ImplGlfwVulkan_VkResult(err); + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + memcpy(idx_dst, &cmd_list->IdxBuffer[0], cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.size(); + idx_dst += cmd_list->IdxBuffer.size(); + } + VkMappedMemoryRange range[2] = {}; + range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + range[0].memory = g_VertexBufferMemory[g_FrameIndex]; + range[0].size = vertex_size; + range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + range[1].memory = g_IndexBufferMemory[g_FrameIndex]; + range[1].size = index_size; + err = vkFlushMappedMemoryRanges(g_Device, 2, range); + ImGui_ImplGlfwVulkan_VkResult(err); + vkUnmapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex]); + vkUnmapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex]); + } + + // Bind pipeline and descriptor sets: + { + vkCmdBindPipeline(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline); + VkDescriptorSet desc_set[1] = {g_DescriptorSet}; + vkCmdBindDescriptorSets(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL); + } + + // Bind Vertex And Index Buffer: + { + VkBuffer vertex_buffers[1] = {g_VertexBuffer[g_FrameIndex]}; + VkDeviceSize vertex_offset[1] = {0}; + vkCmdBindVertexBuffers(g_CommandBuffer, 0, 1, vertex_buffers, vertex_offset); + vkCmdBindIndexBuffer(g_CommandBuffer, g_IndexBuffer[g_FrameIndex], 0, VK_INDEX_TYPE_UINT16); + } + + // Setup viewport: + { + VkViewport viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = ImGui::GetIO().DisplaySize.x; + viewport.height = ImGui::GetIO().DisplaySize.y; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + vkCmdSetViewport(g_CommandBuffer, 0, 1, &viewport); + } + + // Setup scale and translation: + { + float scale[2]; + scale[0] = 2.0f/io.DisplaySize.x; + scale[1] = 2.0f/io.DisplaySize.y; + float translate[2]; + translate[0] = -1.0f; + translate[1] = -1.0f; + vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale); + vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate); + } + + // Render the command lists: + int vtx_offset = 0; + int idx_offset = 0; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + 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 + { + VkRect2D scissor; + scissor.offset.x = static_cast(pcmd->ClipRect.x); + scissor.offset.y = static_cast(pcmd->ClipRect.y); + scissor.extent.width = static_cast(pcmd->ClipRect.z - pcmd->ClipRect.x); + scissor.extent.height = static_cast(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // TODO: + 1?????? + vkCmdSetScissor(g_CommandBuffer, 0, 1, &scissor); + vkCmdDrawIndexed(g_CommandBuffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0); + } + idx_offset += pcmd->ElemCount; + } + vtx_offset += cmd_list->VtxBuffer.size(); + } +} + +static const char* ImGui_ImplGlfwVulkan_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfwVulkan_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) +{ + ImGuiIO& io = ImGui::GetIO(); + + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + size_t upload_size = width*height*4*sizeof(char); + + VkResult err; + + // Create the Image: + { + VkImageCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + info.imageType = VK_IMAGE_TYPE_2D; + info.format = VK_FORMAT_R8G8B8A8_UNORM; + info.extent.width = width; + info.extent.height = height; + info.extent.depth = 1; + info.mipLevels = 1; + info.arrayLayers = 1; + info.samples = VK_SAMPLE_COUNT_1_BIT; + info.tiling = VK_IMAGE_TILING_OPTIMAL; + info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + err = vkCreateImage(g_Device, &info, g_Allocator, &g_FontImage); + ImGui_ImplGlfwVulkan_VkResult(err); + VkMemoryRequirements req; + vkGetImageMemoryRequirements(g_Device, g_FontImage, &req); + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = req.size; + alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits); + err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_FontMemory); + ImGui_ImplGlfwVulkan_VkResult(err); + err = vkBindImageMemory(g_Device, g_FontImage, g_FontMemory, 0); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + // Create the Image View: + { + VkResult err; + VkImageViewCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + info.image = g_FontImage; + info.viewType = VK_IMAGE_VIEW_TYPE_2D; + info.format = VK_FORMAT_R8G8B8A8_UNORM; + info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + info.subresourceRange.levelCount = 1; + info.subresourceRange.layerCount = 1; + err = vkCreateImageView(g_Device, &info, g_Allocator, &g_FontView); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + // Update the Descriptor Set: + { + VkDescriptorImageInfo desc_image[1] = {}; + desc_image[0].sampler = g_FontSampler; + desc_image[0].imageView = g_FontView; + desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + VkWriteDescriptorSet write_desc[1] = {}; + write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_desc[0].dstSet = g_DescriptorSet; + write_desc[0].descriptorCount = 1; + write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write_desc[0].pImageInfo = desc_image; + vkUpdateDescriptorSets(g_Device, 1, write_desc, 0, NULL); + } + + // Create the Upload Buffer: + { + VkBufferCreateInfo buffer_info = {}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = upload_size; + buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_UploadBuffer); + ImGui_ImplGlfwVulkan_VkResult(err); + VkMemoryRequirements req; + vkGetBufferMemoryRequirements(g_Device, g_UploadBuffer, &req); + g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment; + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = req.size; + alloc_info.memoryTypeIndex = ImGui_ImplGlfwVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); + err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_UploadBufferMemory); + ImGui_ImplGlfwVulkan_VkResult(err); + err = vkBindBufferMemory(g_Device, g_UploadBuffer, g_UploadBufferMemory, 0); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + // Upload to Buffer: + { + char* map = NULL; + err = vkMapMemory(g_Device, g_UploadBufferMemory, 0, upload_size, 0, (void**)(&map)); + ImGui_ImplGlfwVulkan_VkResult(err); + memcpy(map, pixels, upload_size); + VkMappedMemoryRange range[1] = {}; + range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + range[0].memory = g_UploadBufferMemory; + range[0].size = upload_size; + err = vkFlushMappedMemoryRanges(g_Device, 1, range); + ImGui_ImplGlfwVulkan_VkResult(err); + vkUnmapMemory(g_Device, g_UploadBufferMemory); + } + // Copy to Image: + { + VkImageMemoryBarrier copy_barrier[1] = {}; + copy_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + copy_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + copy_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + copy_barrier[0].image = g_FontImage; + copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy_barrier[0].subresourceRange.levelCount = 1; + copy_barrier[0].subresourceRange.layerCount = 1; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, copy_barrier); + + VkBufferImageCopy region = {}; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.layerCount = 1; + region.imageExtent.width = width; + region.imageExtent.height = height; + vkCmdCopyBufferToImage(command_buffer, g_UploadBuffer, g_FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + VkImageMemoryBarrier use_barrier[1] = {}; + use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + use_barrier[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + use_barrier[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + use_barrier[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + use_barrier[0].image = g_FontImage; + use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + use_barrier[0].subresourceRange.levelCount = 1; + use_barrier[0].subresourceRange.layerCount = 1; + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, use_barrier); + } + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontImage; + + return true; +} + +bool ImGui_ImplGlfwVulkan_CreateDeviceObjects() +{ + VkResult err; + VkShaderModule vert_module; + VkShaderModule frag_module; + + // Create The Shader Modules: + { + VkShaderModuleCreateInfo vert_info = {}; + vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + vert_info.codeSize = __glsl_shader_vert_spv_len; + vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv; + err = vkCreateShaderModule(g_Device, &vert_info, g_Allocator, &vert_module); + ImGui_ImplGlfwVulkan_VkResult(err); + VkShaderModuleCreateInfo frag_info = {}; + frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + frag_info.codeSize = __glsl_shader_frag_spv_len; + frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv; + err = vkCreateShaderModule(g_Device, &frag_info, g_Allocator, &frag_module); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + if (!g_FontSampler) + { + VkSamplerCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + info.magFilter = VK_FILTER_LINEAR; + info.minFilter = VK_FILTER_LINEAR; + info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + info.minLod = -1000; + info.maxLod = 1000; + err = vkCreateSampler(g_Device, &info, g_Allocator, &g_FontSampler); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + if (!g_DescriptorSetLayout) + { + VkSampler sampler[1] = {g_FontSampler}; + VkDescriptorSetLayoutBinding binding[1] = {}; + binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + binding[0].descriptorCount = 1; + binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + binding[0].pImmutableSamplers = sampler; + VkDescriptorSetLayoutCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + info.bindingCount = 1; + info.pBindings = binding; + err = vkCreateDescriptorSetLayout(g_Device, &info, g_Allocator, &g_DescriptorSetLayout); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + // Create Descriptor Set: + { + VkDescriptorSetAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + alloc_info.descriptorPool = g_DescriptorPool; + alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = &g_DescriptorSetLayout; + err = vkAllocateDescriptorSets(g_Device, &alloc_info, &g_DescriptorSet); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + if (!g_PipelineLayout) + { + VkPushConstantRange push_constants[2] = {}; + push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constants[0].offset = sizeof(float) * 0; + push_constants[0].size = sizeof(float) * 2; + push_constants[1].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constants[1].offset = sizeof(float) * 2; + push_constants[1].size = sizeof(float) * 2; + VkDescriptorSetLayout set_layout[1] = {g_DescriptorSetLayout}; + VkPipelineLayoutCreateInfo layout_info = {}; + layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layout_info.setLayoutCount = 1; + layout_info.pSetLayouts = set_layout; + layout_info.pushConstantRangeCount = 2; + layout_info.pPushConstantRanges = push_constants; + err = vkCreatePipelineLayout(g_Device, &layout_info, g_Allocator, &g_PipelineLayout); + ImGui_ImplGlfwVulkan_VkResult(err); + } + + VkPipelineShaderStageCreateInfo stage[2] = {}; + stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + stage[0].module = vert_module; + stage[0].pName = "main"; + stage[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stage[1].module = frag_module; + stage[1].pName = "main"; + + VkVertexInputBindingDescription binding_desc[1] = {}; + binding_desc[0].stride = sizeof(ImDrawVert); + binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + VkVertexInputAttributeDescription attribute_desc[3] = {}; + attribute_desc[0].location = 0; + attribute_desc[0].binding = binding_desc[0].binding; + attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT; + attribute_desc[0].offset = (size_t)(&((ImDrawVert*)0)->pos); + attribute_desc[1].location = 1; + attribute_desc[1].binding = binding_desc[0].binding; + attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT; + attribute_desc[1].offset = (size_t)(&((ImDrawVert*)0)->uv); + attribute_desc[2].location = 2; + attribute_desc[2].binding = binding_desc[0].binding; + attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM; + attribute_desc[2].offset = (size_t)(&((ImDrawVert*)0)->col); + + VkPipelineVertexInputStateCreateInfo vertex_info = {}; + vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_info.vertexBindingDescriptionCount = 1; + vertex_info.pVertexBindingDescriptions = binding_desc; + vertex_info.vertexAttributeDescriptionCount = 3; + vertex_info.pVertexAttributeDescriptions = attribute_desc; + + VkPipelineInputAssemblyStateCreateInfo ia_info = {}; + ia_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + ia_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + VkPipelineViewportStateCreateInfo viewport_info = {}; + viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_info.viewportCount = 1; + viewport_info.scissorCount = 1; + + VkPipelineRasterizationStateCreateInfo raster_info = {}; + raster_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + raster_info.polygonMode = VK_POLYGON_MODE_FILL; + raster_info.cullMode = VK_CULL_MODE_NONE; + raster_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + + VkPipelineMultisampleStateCreateInfo ms_info = {}; + ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + ms_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState color_attachment[1] = {}; + color_attachment[0].blendEnable = VK_TRUE; + color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_attachment[0].colorBlendOp = VK_BLEND_OP_ADD; + color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + color_attachment[0].alphaBlendOp = VK_BLEND_OP_ADD; + color_attachment[0].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + VkPipelineColorBlendStateCreateInfo blend_info = {}; + blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + blend_info.attachmentCount = 1; + blend_info.pAttachments = color_attachment; + + VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkPipelineDynamicStateCreateInfo dynamic_state = {}; + dynamic_state.dynamicStateCount = 2; + dynamic_state.pDynamicStates = dynamic_states; + + VkGraphicsPipelineCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + info.flags = g_PipelineCreateFlags; + info.stageCount = 2; + info.pStages = stage; + info.pVertexInputState = &vertex_info; + info.pInputAssemblyState = &ia_info; + info.pViewportState = &viewport_info; + info.pRasterizationState = &raster_info; + info.pMultisampleState = &ms_info; + info.pColorBlendState = &blend_info; + info.pDynamicState = &dynamic_state; + info.layout = g_PipelineLayout; + info.renderPass = g_RenderPass; + err = vkCreateGraphicsPipelines(g_Device, g_PipelineCache, 1, &info, g_Allocator, &g_Pipeline); + ImGui_ImplGlfwVulkan_VkResult(err); + + vkDestroyShaderModule(g_Device, vert_module, g_Allocator); + vkDestroyShaderModule(g_Device, frag_module, g_Allocator); + + return true; +} + +void ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects() +{ + if (g_UploadBuffer) + { + vkDestroyBuffer(g_Device, g_UploadBuffer, g_Allocator); + g_UploadBuffer = VK_NULL_HANDLE; + } + if (g_UploadBufferMemory) + { + vkFreeMemory(g_Device, g_UploadBufferMemory, g_Allocator); + g_UploadBufferMemory = VK_NULL_HANDLE; + } +} + +void ImGui_ImplGlfwVulkan_InvalidateDeviceObjects() +{ + ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); + for (int i=0; iallocator; + g_Gpu = init_data->gpu; + g_Device = init_data->device; + g_RenderPass = init_data->render_pass; + g_PipelineCache = init_data->pipeline_cache; + g_DescriptorPool = init_data->descriptor_pool; + g_CheckVkResult = init_data->check_vk_result; + + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfwVulkan_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfwVulkan_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfwVulkan_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfwVulkan_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfwVulkan_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlfwVulkan_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfwVulkan_CharCallback); + } + + ImGui_ImplGlfwVulkan_CreateDeviceObjects(); + + return true; +} + +void ImGui_ImplGlfwVulkan_Shutdown() +{ + ImGui_ImplGlfwVulkan_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfwVulkan_NewFrame() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} +void ImGui_ImplGlfwVulkan_Render(VkCommandBuffer command_buffer) +{ + g_CommandBuffer = command_buffer; + ImGui::Render(); + g_CommandBuffer = VK_NULL_HANDLE; + g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; +} diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.h b/examples/vulkan_example/imgui_impl_glfw_vulkan.h new file mode 100644 index 00000000..74d35a2d --- /dev/null +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.h @@ -0,0 +1,40 @@ +// ImGui GLFW binding with Vulkan + shaders +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 5 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXX_CreateFontsTexture(), ImGui_ImplXXXX_NewFrame(), ImGui_ImplXXXX_Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +#define IMGUI_VK_QUEUED_FRAMES 2 + +struct ImGui_ImplGlfwVulkan_Init_Data +{ + VkAllocationCallbacks* allocator; + VkPhysicalDevice gpu; + VkDevice device; + VkRenderPass render_pass; + VkPipelineCache pipeline_cache; + VkDescriptorPool descriptor_pool; + void (*check_vk_result)(VkResult err); +}; + +IMGUI_API bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, ImGui_ImplGlfwVulkan_Init_Data *init_data); +IMGUI_API void ImGui_ImplGlfwVulkan_Shutdown(); +IMGUI_API void ImGui_ImplGlfwVulkan_NewFrame(); +IMGUI_API void ImGui_ImplGlfwVulkan_Render(VkCommandBuffer command_buffer); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); +IMGUI_API void ImGui_ImplGlfwVulkan_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfwVulkan_CreateFontsTexture(VkCommandBuffer command_buffer); +IMGUI_API bool ImGui_ImplGlfwVulkan_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow* window, unsigned int c); + diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp new file mode 100644 index 00000000..130fd870 --- /dev/null +++ b/examples/vulkan_example/main.cpp @@ -0,0 +1,539 @@ +// ImGui - standalone example application for Glfw + Vulkan, using programmable pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include + +#include // printf, fprintf +#include // abort +#define GLFW_INCLUDE_NONE +#define GLFW_INCLUDE_VULKAN +#include + +#include "imgui_impl_glfw_vulkan.h" + +#define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16 + +static VkAllocationCallbacks* g_Allocator = NULL; +static VkInstance g_Instance = VK_NULL_HANDLE; +static VkSurfaceKHR g_Surface = VK_NULL_HANDLE; +static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; +static VkDevice g_Device = VK_NULL_HANDLE; +static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE; +static VkRenderPass g_RenderPass = VK_NULL_HANDLE; +static uint32_t g_QueueFamily = 0; +static VkQueue g_Queue = VK_NULL_HANDLE; + +static VkFormat g_Format = VK_FORMAT_B8G8R8A8_UNORM; +static VkColorSpaceKHR g_ColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; +static VkImageSubresourceRange g_ImageRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + +static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; +static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; + +static int fb_width, fb_height; +static uint32_t g_BackBufferIndex = 0; +static uint32_t g_BackBufferCount = 0; +static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; +static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; +static VkFramebuffer g_Framebuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {}; + +static uint32_t g_FrameIndex = 0; +static VkCommandPool g_CommandPool[IMGUI_VK_QUEUED_FRAMES]; +static VkCommandBuffer g_CommandBuffer[IMGUI_VK_QUEUED_FRAMES]; +static VkFence g_Fence[IMGUI_VK_QUEUED_FRAMES]; +static VkSemaphore g_Semaphore[IMGUI_VK_QUEUED_FRAMES]; + +static VkClearValue g_ClearValue = {}; + +static void check_vk_result(VkResult err) +{ + if (err == 0) return; + printf("VkResult %d\n", err); + if (err < 0) + abort(); +} + +static void resize_vulkan(GLFWwindow* /*window*/, int w, int h) +{ + VkResult err; + VkSwapchainKHR old_swapchain = g_Swapchain; + err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + + // Destroy old Framebuffer: + for (uint32_t i=0; iAddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + // Upload Fonts + { + VkResult err; + err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0); + check_vk_result(err); + VkCommandBufferBeginInfo begin_info = {}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &begin_info); + check_vk_result(err); + + ImGui_ImplGlfwVulkan_CreateFontsTexture(g_CommandBuffer[g_FrameIndex]); + + VkSubmitInfo end_info = {}; + end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + end_info.commandBufferCount = 1; + end_info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex]; + err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]); + check_vk_result(err); + err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); + check_vk_result(err); + + err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + ImGui_ImplGlfwVulkan_InvalidateFontUploadObjects(); + } + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfwVulkan_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + 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::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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); + } + + g_ClearValue.color.float32[0] = clear_color.x; + g_ClearValue.color.float32[1] = clear_color.y; + g_ClearValue.color.float32[2] = clear_color.z; + g_ClearValue.color.float32[3] = clear_color.w; + + frame_begin(); + ImGui_ImplGlfwVulkan_Render(g_CommandBuffer[g_FrameIndex]); + frame_end(); + } + + // Cleanup + VkResult err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + ImGui_ImplGlfwVulkan_Shutdown(); + cleanup_vulkan(); + glfwTerminate(); + + return 0; +} diff --git a/imgui.cpp b/imgui.cpp index 8f2b87ff..316dea54 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. @@ -152,6 +152,8 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337). + - 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337) - 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). - 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert. - 2016/02/21 (1.48) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to ColorEdit*() functions @@ -506,6 +508,7 @@ - color: add a better color picker (#346) - node/graph editor (#306) - pie menus patterns (#434) + - drag'n drop, dragging helpers (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479) - plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals) - plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots) - plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value) @@ -694,13 +697,12 @@ ImGuiStyle::ImGuiStyle() WindowMinSize = ImVec2(32,32); // Minimum window size WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows WindowTitleAlign = ImGuiAlign_Left; // Alignment for title bar text - ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows + ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! - WindowFillAlphaDefault = 0.70f; // Default alpha of window background, if not specified in ImGui::Begin() IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar @@ -715,8 +717,9 @@ ImGuiStyle::ImGuiStyle() Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.65f); Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input @@ -754,7 +757,6 @@ ImGuiStyle::ImGuiStyle() Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); - Colors[ImGuiCol_TooltipBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f); Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); } @@ -1652,7 +1654,7 @@ ImGuiWindow* ImGui::GetParentWindow() { ImGuiState& g = *GImGui; IM_ASSERT(g.CurrentWindowStack.Size >= 2); - return g.CurrentWindowStack[g.CurrentWindowStack.Size - 2]; + return g.CurrentWindowStack[(unsigned int)g.CurrentWindowStack.Size - 2]; } void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window = NULL) @@ -2339,9 +2341,9 @@ static void AddDrawListToRenderList(ImVector& out_render_list, ImDr // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices) // If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly. - IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); // Sanity check. Bug or mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. - IM_ASSERT((unsigned long long int)draw_list->_VtxCurrentIdx <= ((unsigned long long int)1L << (sizeof(ImDrawIdx)*8))); // Too many vertices in same ImDrawList. See comment above. - + IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); // Sanity check. Bug or mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. + IM_ASSERT((int64_t)draw_list->_VtxCurrentIdx <= ((int64_t)1L << (sizeof(ImDrawIdx)*8))); // Too many vertices in same ImDrawList. See comment above. + out_render_list.push_back(draw_list); GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size; @@ -3139,9 +3141,8 @@ static ImRect GetVisibleRect() void ImGui::BeginTooltip() { - ImGuiState& g = *GImGui; ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; - ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), g.Style.Colors[ImGuiCol_TooltipBg].w, flags); + ImGui::Begin("##Tooltip", NULL, flags); } void ImGui::EndTooltip() @@ -3279,9 +3280,8 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags) ImFormatString(name, 20, "##menu_%d", g.CurrentPopupStack.Size); // Recycle windows based on depth else ImFormatString(name, 20, "##popup_%08x", id); // Not recycling, so we can close/open during the same frame - float alpha = 1.0f; - bool opened = ImGui::Begin(name, NULL, ImVec2(0.0f, 0.0f), alpha, flags); + bool opened = ImGui::Begin(name, NULL, flags); if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; if (!opened) // opened can be 'false' when the popup is completely clipped (e.g. zero size display) @@ -3312,7 +3312,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_opened, ImGuiWindowFlags e } ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; - bool opened = ImGui::Begin(name, p_opened, ImVec2(0.0f, 0.0f), -1.0f, flags); + bool opened = ImGui::Begin(name, p_opened, flags); if (!opened || (p_opened && !*p_opened)) // Opened can be 'false' when the popup is completely clipped (e.g. zero size display) { ImGui::EndPopup(); @@ -3392,8 +3392,7 @@ bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, char title[256]; ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id); - const float alpha = 1.0f; - bool ret = ImGui::Begin(title, NULL, size, alpha, flags); + bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags); if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) GetCurrentWindow()->Flags &= ~ImGuiWindowFlags_ShowBorders; @@ -3443,13 +3442,14 @@ bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags ext const ImGuiStyle& style = g.Style; ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); - return ImGui::BeginChild(id, size, false, ImGuiWindowFlags_NoMove | extra_flags); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + return ImGui::BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } void ImGui::EndChildFrame() { ImGui::EndChild(); - ImGui::PopStyleVar(); + ImGui::PopStyleVar(2); ImGui::PopStyleColor(); } @@ -3692,10 +3692,6 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ window->RootWindow = g.CurrentWindowStack[root_idx]; window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // This is merely for displaying the TitleBgActive color. - // Default alpha - if (bg_alpha < 0.0f) - bg_alpha = style.WindowFillAlphaDefault; - // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame) { @@ -3767,7 +3763,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ } // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. - window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding; + window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding; // Calculate auto-fit size ImVec2 size_auto_fit; @@ -3981,27 +3977,26 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ } // Scrollbars - window->ScrollbarY = (flags & ImGuiWindowFlags_ForceVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_ForceHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; // Window background - if (bg_alpha > 0.0f) - { - ImGuiCol col_idx; - if ((flags & ImGuiWindowFlags_ComboBox) != 0) - col_idx = ImGuiCol_ComboBg; - else if ((flags & ImGuiWindowFlags_Tooltip) != 0) - col_idx = ImGuiCol_TooltipBg; - else if ((flags & ImGuiWindowFlags_Popup) != 0) - col_idx = ImGuiCol_WindowBg; - else if ((flags & ImGuiWindowFlags_ChildWindow) != 0) - col_idx = ImGuiCol_ChildWindowBg; - else - col_idx = ImGuiCol_WindowBg; - window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, GetColorU32(col_idx, bg_alpha), window_rounding); - } + // Default alpha + ImGuiCol bg_color_idx = ImGuiCol_WindowBg; + if ((flags & ImGuiWindowFlags_ComboBox) != 0) + bg_color_idx = ImGuiCol_ComboBg; + else if ((flags & ImGuiWindowFlags_Tooltip) != 0 || (flags & ImGuiWindowFlags_Popup) != 0) + bg_color_idx = ImGuiCol_PopupBg; + else if ((flags & ImGuiWindowFlags_ChildWindow) != 0) + bg_color_idx = ImGuiCol_ChildWindowBg; + ImVec4 bg_color = style.Colors[bg_color_idx]; + if (bg_alpha >= 0.0f) + bg_color.w = bg_alpha; + bg_color.w *= style.Alpha; + if (bg_color.w > 0.0f) + window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding); // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) @@ -4521,6 +4516,7 @@ const char* ImGui::GetStyleColName(ImGuiCol idx) case ImGuiCol_TextDisabled: return "TextDisabled"; case ImGuiCol_WindowBg: return "WindowBg"; case ImGuiCol_ChildWindowBg: return "ChildWindowBg"; + case ImGuiCol_PopupBg: return "PopupBg"; case ImGuiCol_Border: return "Border"; case ImGuiCol_BorderShadow: return "BorderShadow"; case ImGuiCol_FrameBg: return "FrameBg"; @@ -4558,7 +4554,6 @@ const char* ImGui::GetStyleColName(ImGuiCol idx) case ImGuiCol_PlotHistogram: return "PlotHistogram"; case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; - case ImGuiCol_TooltipBg: return "TooltipBg"; case ImGuiCol_ModalWindowDarkening: return "ModalWindowDarkening"; } IM_ASSERT(0); @@ -7104,9 +7099,9 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* ob static bool is_separator(unsigned int c) { return ImCharIsSpace(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; } -static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; } static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } #ifdef __APPLE__ // FIXME: Move setting to IO structure +static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; } static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } #else static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } @@ -7310,7 +7305,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 return false; } draw_window = GetCurrentWindow(); - draw_window->DC.CursorPos += style.FramePadding; size.x -= draw_window->ScrollbarSizes.x; } else @@ -8501,7 +8495,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) bool want_open = false, want_close = false; if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) { - // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers so menus feel more reactive. + // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. bool moving_within_opened_triangle = false; if (g.HoveredWindow == window && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentWindow == window) { diff --git a/imgui.h b/imgui.h index c7eaa1b6..36418244 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (headers) // See imgui.cpp file for documentation. @@ -16,7 +16,7 @@ #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.48 WIP" +#define IMGUI_VERSION "1.49 WIP" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API @@ -114,7 +114,7 @@ namespace ImGui // Window IMGUI_API bool Begin(const char* name, bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false). - IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // ". this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually. + IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE. this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually. IMGUI_API void End(); // finish appending to current window, pop it off the window stack. IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " @@ -316,7 +316,7 @@ namespace ImGui IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose IMGUI_API void TreePush(const void* ptr_id = NULL); // " IMGUI_API void TreePop(); - IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node to be opened. + IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node/collapsing header to be opened. // Widgets: Selectable / Lists IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height @@ -467,11 +467,12 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar - ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You need to use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. + ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus) - ImGuiWindowFlags_ForceVerticalScrollbar = 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) - ImGuiWindowFlags_ForceHorizontalScrollbar=1 << 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) + ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) + ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) + ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) // [Internal] ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // Don't use! For internal use by BeginChild() @@ -546,8 +547,9 @@ enum ImGuiCol_ { ImGuiCol_Text, ImGuiCol_TextDisabled, - ImGuiCol_WindowBg, - ImGuiCol_ChildWindowBg, + ImGuiCol_WindowBg, // Background of normal windows + ImGuiCol_ChildWindowBg, // Background of child windows + ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows ImGuiCol_Border, ImGuiCol_BorderShadow, ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input @@ -585,7 +587,6 @@ enum ImGuiCol_ ImGuiCol_PlotHistogram, ImGuiCol_PlotHistogramHovered, ImGuiCol_TextSelectedBg, - ImGuiCol_TooltipBg, ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active ImGuiCol_COUNT }; @@ -667,7 +668,6 @@ struct ImGuiStyle ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! - float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin() float IndentSpacing; // Horizontal indentation when e.g. entering a tree node float ColumnsMinSpacing; // Minimum horizontal spacing between two columns float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar @@ -895,6 +895,7 @@ struct ImGuiTextFilter int CountGrep; ImGuiTextFilter(const char* default_filter = ""); + ~ImGuiTextFilter() {} void Clear() { InputBuf[0] = 0; Build(); } bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build bool PassFilter(const char* text, const char* text_end = NULL) const; @@ -1157,7 +1158,7 @@ struct ImDrawList // Stateful path API, add points then finish with PathFill() or PathStroke() inline void PathClear() { _Path.resize(0); } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } - inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || _Path[_Path.Size-1].x != pos.x || _Path[_Path.Size-1].y != pos.y) _Path.push_back(pos); } + inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } inline void PathFill(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); } inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); } IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 132e8e7f..fdf2d8ea 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (demo code) // Don't remove this file from your project! It is useful reference code that you can execute. @@ -139,7 +139,6 @@ void ImGui::ShowTestWindow(bool* p_opened) static bool no_scrollbar = false; static bool no_collapse = false; static bool no_menu = false; - static float bg_alpha = -0.01f; // <0: default // Demonstrate the various window flags. Typically you would just use the default. ImGuiWindowFlags window_flags = 0; @@ -150,7 +149,8 @@ void ImGui::ShowTestWindow(bool* p_opened) if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; - if (!ImGui::Begin("ImGui Demo", p_opened, ImVec2(550,680), bg_alpha, window_flags)) + ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiSetCond_FirstUseEver); + if (!ImGui::Begin("ImGui Demo", p_opened, window_flags)) { // Early out if the window is collapsed, as an optimization. ImGui::End(); @@ -211,10 +211,6 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::Checkbox("No collapse", &no_collapse); ImGui::Checkbox("No menu", &no_menu); - ImGui::PushItemWidth(100); - ImGui::DragFloat("Window Fill Alpha", &bg_alpha, 0.005f, -0.01f, 1.0f, bg_alpha < 0.0f ? "(default)" : "%.3f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. - ImGui::PopItemWidth(); - if (ImGui::TreeNode("Style")) { ImGui::ShowStyleEditor(); @@ -1500,7 +1496,7 @@ void ImGui::ShowTestWindow(bool* p_opened) ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); } ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } - ImGui::Text("KeyMods: %s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); + ImGui::Text("KeyMods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); ImGui::Text("WantCaptureMouse: %s", io.WantCaptureMouse ? "true" : "false"); ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "true" : "false"); @@ -1561,7 +1557,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f; ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. - ImGui::DragFloat("Window Fill Alpha Default", &style.WindowFillAlphaDefault, 0.005f, 0.0f, 1.0f, "%.2f"); ImGui::PopItemWidth(); ImGui::TreePop(); } @@ -1618,7 +1613,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) static ImGuiTextFilter filter; filter.Draw("Filter colors", 200); - ImGui::BeginChild("#colors", ImVec2(0, 300), true); + ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar); ImGui::PushItemWidth(-160); for (int i = 0; i < ImGuiCol_COUNT; i++) { @@ -2299,12 +2294,12 @@ static void ShowExampleAppPropertyEditor(bool* opened) { ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. - bool opened = ImGui::TreeNode("Object", "%s_%u", prefix, uid); + bool is_opened = ImGui::TreeNode("Object", "%s_%u", prefix, uid); ImGui::NextColumn(); ImGui::AlignFirstTextHeightToWidgets(); ImGui::Text("my sailor is rich"); ImGui::NextColumn(); - if (opened) + if (is_opened) { static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; for (int i = 0; i < 8; i++) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 95871b60..1d268561 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (drawing and font code) // Contains implementation for diff --git a/imgui_internal.h b/imgui_internal.h index 384a8467..65d766c8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.48 WIP +// dear imgui, v1.49 WIP // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!