Merge branch 'master' into 2016-02-colorpicker

This commit is contained in:
ocornut 2016-04-09 19:12:03 +02:00
commit 77177c18f0
50 changed files with 3906 additions and 919 deletions

View File

@ -63,9 +63,9 @@ directx11_example/
DirectX11 example, Windows only. DirectX11 example, Windows only.
This is quite long and tedious, because: DirectX11. This is quite long and tedious, because: DirectX11.
ios_example/ apple_example/
iOS example. OSX & iOS example.
Using Synergy to access keyboard/mouse data from server computer. On iOS, Using Synergy to access keyboard/mouse data from server computer.
Synergy keyboard integration is rather hacky. Synergy keyboard integration is rather hacky.
sdl_opengl_example/ sdl_opengl_example/
@ -80,3 +80,7 @@ allegro5_example/
marmalade_example/ marmalade_example/
Marmalade example using IwGx Marmalade example using IwGx
vulkan_example/
Vulkan example.
This is quite long and tedious, because: Vulkan.

View File

@ -1,20 +1,27 @@
# iOS example # iOS / OSX example
## Introduction ## 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. 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" * In Synergy, go to Preferences, and uncheck "Use SSL encryption"
0. Run the example app. * Run the example app.
0. Tap the "servername" button in the corner * Tap the "servername" button in the corner
0. Enter the name or the IP of your synergy host * 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. * 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 ## 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. * Graceful disconnect/reconnect from uSynergy.
* Copy/Paste not well-supported * 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. 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. 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.

View File

@ -63,6 +63,11 @@
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "icon_imgui_76@2x~ipad.png", "filename" : "icon_imgui_76@2x~ipad.png",
"scale" : "2x" "scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
} }
], ],
"info" : { "info" : {

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,15 @@
//
// AppDelegate.h
// imguiex-osx
//
// Created by James Chen on 4/5/16.
// Copyright © 2016 Joel Davis. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end

View File

@ -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

View File

@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Joel Davis. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -0,0 +1,13 @@
//
// main.m
// imguiex-osx
//
// Created by James Chen on 4/5/16.
// Copyright © 2016 Joel Davis. All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
return NSApplicationMain(argc, argv);
}

View File

@ -9,6 +9,16 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; 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 */; }; 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 */; }; 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; };
6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; };
6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; };
@ -28,9 +38,18 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; }; 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; };
197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = "<group>"; }; 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = "<group>"; };
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 = "<group>"; };
1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = "<group>"; };
1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = "<group>"; };
1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = "<absolute>"; };
6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = "<group>"; }; 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = "<group>"; };
6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = "<group>"; }; 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = "<group>"; };
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 = "<group>"; }; 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@ -54,6 +73,14 @@
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
1A1A0F1C1CB39FB50090F036 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6D2FC5511B2E632000C130BA /* Frameworks */ = { 6D2FC5511B2E632000C130BA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -66,6 +93,38 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup 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 = "<group>";
};
1A1A0F241CB39FB50090F036 /* Supporting Files */ = {
isa = PBXGroup;
children = (
);
name = "Supporting Files";
sourceTree = "<group>";
};
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 = "<group>";
};
6D1E39141B35EEF10017B40F /* usynergy */ = { 6D1E39141B35EEF10017B40F /* usynergy */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -81,7 +140,8 @@
children = ( children = (
6D1E39141B35EEF10017B40F /* usynergy */, 6D1E39141B35EEF10017B40F /* usynergy */,
6D2FC5841B2E648D00C130BA /* imgui */, 6D2FC5841B2E648D00C130BA /* imgui */,
6D2FC5561B2E632000C130BA /* imguiex */, 6D2FC5561B2E632000C130BA /* imguiex-ios */,
1A1A0F201CB39FB50090F036 /* imguiex-osx */,
6D2FC5551B2E632000C130BA /* Products */, 6D2FC5551B2E632000C130BA /* Products */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
@ -89,12 +149,13 @@
6D2FC5551B2E632000C130BA /* Products */ = { 6D2FC5551B2E632000C130BA /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6D2FC5541B2E632000C130BA /* imguiex.app */, 6D2FC5541B2E632000C130BA /* imguiex-ios.app */,
1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
6D2FC5561B2E632000C130BA /* imguiex */ = { 6D2FC5561B2E632000C130BA /* imguiex-ios */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */,
@ -113,7 +174,7 @@
6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */,
6D2FC5571B2E632000C130BA /* Supporting Files */, 6D2FC5571B2E632000C130BA /* Supporting Files */,
); );
path = imguiex; path = "imguiex-ios";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
6D2FC5571B2E632000C130BA /* Supporting Files */ = { 6D2FC5571B2E632000C130BA /* Supporting Files */ = {
@ -141,9 +202,26 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
6D2FC5531B2E632000C130BA /* imguiex */ = { 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = {
isa = PBXNativeTarget; 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 = ( buildPhases = (
6D2FC5501B2E632000C130BA /* Sources */, 6D2FC5501B2E632000C130BA /* Sources */,
6D2FC5511B2E632000C130BA /* Frameworks */, 6D2FC5511B2E632000C130BA /* Frameworks */,
@ -153,9 +231,9 @@
); );
dependencies = ( dependencies = (
); );
name = imguiex; name = "imguiex-ios";
productName = imguiex; productName = imguiex;
productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@ -167,6 +245,9 @@
LastUpgradeCheck = 0630; LastUpgradeCheck = 0630;
ORGANIZATIONNAME = "Joel Davis"; ORGANIZATIONNAME = "Joel Davis";
TargetAttributes = { TargetAttributes = {
1A1A0F1E1CB39FB50090F036 = {
CreatedOnToolsVersion = 7.3;
};
6D2FC5531B2E632000C130BA = { 6D2FC5531B2E632000C130BA = {
CreatedOnToolsVersion = 6.3.2; CreatedOnToolsVersion = 6.3.2;
}; };
@ -185,12 +266,21 @@
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
6D2FC5531B2E632000C130BA /* imguiex */, 6D2FC5531B2E632000C130BA /* imguiex-ios */,
1A1A0F1E1CB39FB50090F036 /* imguiex-osx */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
1A1A0F1D1CB39FB50090F036 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6D2FC5521B2E632000C130BA /* Resources */ = { 6D2FC5521B2E632000C130BA /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -206,6 +296,21 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase 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 */ = { 6D2FC5501B2E632000C130BA /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -244,6 +349,54 @@
/* End PBXVariantGroup section */ /* End PBXVariantGroup section */
/* Begin XCBuildConfiguration 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 */ = { 6D2FC5791B2E632000C130BA /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
@ -280,11 +433,13 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)/../../";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "";
}; };
name = Debug; name = Debug;
}; };
@ -318,10 +473,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)/../../";
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
name = Release; name = Release;
@ -330,7 +487,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = imguiex/Info.plist; INFOPLIST_FILE = "imguiex-ios/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
}; };
@ -340,7 +497,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = imguiex/Info.plist; INFOPLIST_FILE = "imguiex-ios/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
}; };
@ -349,6 +506,15 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList 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" */ = { 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
@ -358,7 +524,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
6D2FC57C1B2E632000C130BA /* Debug */, 6D2FC57C1B2E632000C130BA /* Debug */,

View File

@ -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) // - 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) void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
{ {
ID3D10Device* ctx = g_pd3dDevice;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 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.BindFlags = D3D10_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
desc.MiscFlags = 0; desc.MiscFlags = 0;
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0) if (ctx->CreateBuffer(&desc, NULL, &g_pVB) < 0)
return; return;
} }
@ -66,13 +68,13 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
{ {
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_IndexBufferSize = draw_data->TotalIdxCount + 10000; g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D10_BUFFER_DESC bufferDesc; D3D10_BUFFER_DESC desc;
memset(&bufferDesc, 0, sizeof(D3D10_BUFFER_DESC)); memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
bufferDesc.Usage = D3D10_USAGE_DYNAMIC; desc.Usage = D3D10_USAGE_DYNAMIC;
bufferDesc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
bufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER; desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pIB) < 0) if (ctx->CreateBuffer(&desc, NULL, &g_pIB) < 0)
return; return;
} }
@ -81,7 +83,6 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
ImDrawIdx* idx_dst = NULL; ImDrawIdx* idx_dst = NULL;
g_pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst); g_pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
g_pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst); g_pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[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 // Setup orthographic projection matrix into our constant buffer
{ {
void* mappedResource; void* mapped_resource;
if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return; return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource;
VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource;
const float L = 0.0f; const float L = 0.0f;
const float R = ImGui::GetIO().DisplaySize.x; const float R = ImGui::GetIO().DisplaySize.x;
const float B = ImGui::GetIO().DisplaySize.y; 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 }, { 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.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(); 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
{ {
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; D3D10_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D10_VIEWPORT)); memset(&vp, 0, sizeof(D3D10_VIEWPORT));
vp.Width = (UINT)ImGui::GetIO().DisplaySize.x; vp.Width = (UINT)ImGui::GetIO().DisplaySize.x;
vp.Height = (UINT)ImGui::GetIO().DisplaySize.y; vp.Height = (UINT)ImGui::GetIO().DisplaySize.y;
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = 0; vp.TopLeftX = vp.TopLeftY = 0;
vp.TopLeftY = 0; ctx->RSSetViewports(1, &vp);
g_pd3dDevice->RSSetViewports(1, &vp);
}
// Bind shader and vertex buffers // Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert); unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0; unsigned int offset = 0;
g_pd3dDevice->IASetInputLayout(g_pInputLayout); ctx->IASetInputLayout(g_pInputLayout);
g_pd3dDevice->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
g_pd3dDevice->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pd3dDevice->VSSetShader(g_pVertexShader); ctx->VSSetShader(g_pVertexShader);
g_pd3dDevice->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
g_pd3dDevice->PSSetShader(g_pPixelShader); ctx->PSSetShader(g_pPixelShader);
g_pd3dDevice->PSSetSamplers(0, 1, &g_pFontSampler); ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state // Setup render state
const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
g_pd3dDevice->OMSetBlendState(g_pBlendState, blendFactor, 0xffffffff); ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
g_pd3dDevice->RSSetState(g_pRasterizerState); ctx->RSSetState(g_pRasterizerState);
// Render command lists // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
@ -161,19 +194,29 @@ void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data)
else else
{ {
const D3D10_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; 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); ctx->PSSetShaderResources(0, 1, (ID3D10ShaderResourceView**)&pcmd->TextureId);
g_pd3dDevice->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
g_pd3dDevice->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.size(); vtx_offset += cmd_list->VtxBuffer.size();
} }
// Restore modified state // Restore modified DX state
g_pd3dDevice->IASetInputLayout(NULL); ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
g_pd3dDevice->PSSetShader(NULL); ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
g_pd3dDevice->VSSetShader(NULL); 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) 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 // Create DX10 texture
{ {
D3D10_TEXTURE2D_DESC texDesc; D3D10_TEXTURE2D_DESC desc;
ZeroMemory(&texDesc, sizeof(texDesc)); ZeroMemory(&desc, sizeof(desc));
texDesc.Width = width; desc.Width = width;
texDesc.Height = height; desc.Height = height;
texDesc.MipLevels = 1; desc.MipLevels = 1;
texDesc.ArraySize = 1; desc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
texDesc.Usage = D3D10_USAGE_DEFAULT; desc.Usage = D3D10_USAGE_DEFAULT;
texDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE; desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
ID3D10Texture2D *pTexture = NULL; ID3D10Texture2D *pTexture = NULL;
D3D10_SUBRESOURCE_DATA subResource; D3D10_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels; subResource.pSysMem = pixels;
subResource.SysMemPitch = texDesc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0; subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&texDesc, &subResource, &pTexture); g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view // Create texture view
D3D10_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
ZeroMemory(&srvDesc, sizeof(srvDesc)); ZeroMemory(&srv_desc, sizeof(srv_desc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srv_desc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0; srv_desc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); g_pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &g_pFontTextureView);
pTexture->Release(); pTexture->Release();
} }
@ -269,17 +312,17 @@ static void ImGui_ImplDX10_CreateFontsTexture()
// Create texture sampler // Create texture sampler
{ {
D3D10_SAMPLER_DESC samplerDesc; D3D10_SAMPLER_DESC desc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc)); ZeroMemory(&desc, sizeof(desc));
samplerDesc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.f; desc.MipLODBias = 0.f;
samplerDesc.ComparisonFunc = D3D10_COMPARISON_ALWAYS; desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
samplerDesc.MinLOD = 0.f; desc.MinLOD = 0.f;
samplerDesc.MaxLOD = 0.f; desc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
} }
// Cleanup (don't clear the input data if you want to append new fonts later) // 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; return false;
// Create the input layout // 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 }, { "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 }, { "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 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 },
}; };
if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
return false; return false;
// Create the constant buffer // Create the constant buffer
{ {
D3D10_BUFFER_DESC cbDesc; D3D10_BUFFER_DESC desc;
cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
cbDesc.Usage = D3D10_USAGE_DYNAMIC; desc.Usage = D3D10_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0; desc.MiscFlags = 0;
g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
} }
} }

View File

@ -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) // - 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) void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data)
{ {
ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) 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; } if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_IndexBufferSize = draw_data->TotalIdxCount + 10000; g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D11_BUFFER_DESC bufferDesc; D3D11_BUFFER_DESC desc;
memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
bufferDesc.Usage = D3D11_USAGE_DYNAMIC; desc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx); desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pIB) < 0) if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0)
return; return;
} }
// Copy and convert all vertices into a single contiguous buffer // Copy and convert all vertices into a single contiguous buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; 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; 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; return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_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(); vtx_dst += cmd_list->VtxBuffer.size();
idx_dst += cmd_list->IdxBuffer.size(); idx_dst += cmd_list->IdxBuffer.size();
} }
g_pd3dDeviceContext->Unmap(g_pVB, 0); ctx->Unmap(g_pVB, 0);
g_pd3dDeviceContext->Unmap(g_pIB, 0); ctx->Unmap(g_pIB, 0);
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
{ {
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (g_pd3dDeviceContext->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return; return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource.pData; float L = 0.0f;
const float L = 0.0f; float R = ImGui::GetIO().DisplaySize.x;
const float R = ImGui::GetIO().DisplaySize.x; float B = ImGui::GetIO().DisplaySize.y;
const float B = ImGui::GetIO().DisplaySize.y; float T = 0.0f;
const float T = 0.0f; float mvp[4][4] =
const float mvp[4][4] =
{ {
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f }, { 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.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_pd3dDeviceContext->Unmap(g_pVertexConstantBuffer, 0); 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
{ {
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; D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT)); memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = ImGui::GetIO().DisplaySize.x; vp.Width = ImGui::GetIO().DisplaySize.x;
vp.Height = ImGui::GetIO().DisplaySize.y; vp.Height = ImGui::GetIO().DisplaySize.y;
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = 0; vp.TopLeftX = vp.TopLeftY = 0.0f;
vp.TopLeftY = 0; ctx->RSSetViewports(1, &vp);
g_pd3dDeviceContext->RSSetViewports(1, &vp);
}
// Bind shader and vertex buffers // Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert); unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0; unsigned int offset = 0;
g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout); ctx->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
g_pd3dDeviceContext->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
g_pd3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pd3dDeviceContext->VSSetShader(g_pVertexShader, NULL, 0); ctx->VSSetShader(g_pVertexShader, NULL, 0);
g_pd3dDeviceContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
g_pd3dDeviceContext->PSSetShader(g_pPixelShader, NULL, 0); ctx->PSSetShader(g_pPixelShader, NULL, 0);
g_pd3dDeviceContext->PSSetSamplers(0, 1, &g_pFontSampler); ctx->PSSetSamplers(0, 1, &g_pFontSampler);
// Setup render state // Setup render state
const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
g_pd3dDeviceContext->OMSetBlendState(g_pBlendState, blendFactor, 0xffffffff); ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
g_pd3dDeviceContext->RSSetState(g_pRasterizerState); ctx->RSSetState(g_pRasterizerState);
// Render command lists // Render command lists
int vtx_offset = 0; int vtx_offset = 0;
@ -162,19 +199,31 @@ void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data)
else else
{ {
const D3D11_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; 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); ctx->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId);
g_pd3dDeviceContext->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
g_pd3dDeviceContext->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;
} }
vtx_offset += cmd_list->VtxBuffer.size(); vtx_offset += cmd_list->VtxBuffer.size();
} }
// Restore modified state // Restore modified DX state
g_pd3dDeviceContext->IASetInputLayout(NULL); ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
g_pd3dDeviceContext->PSSetShader(NULL, NULL, 0); ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
g_pd3dDeviceContext->VSSetShader(NULL, NULL, 0); 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) 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 // Upload texture to graphics system
{ {
D3D11_TEXTURE2D_DESC texDesc; D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&texDesc, sizeof(texDesc)); ZeroMemory(&desc, sizeof(desc));
texDesc.Width = width; desc.Width = width;
texDesc.Height = height; desc.Height = height;
texDesc.MipLevels = 1; desc.MipLevels = 1;
texDesc.ArraySize = 1; desc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
texDesc.Usage = D3D11_USAGE_DEFAULT; desc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
ID3D11Texture2D *pTexture = NULL; ID3D11Texture2D *pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource; D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels; subResource.pSysMem = pixels;
subResource.SysMemPitch = texDesc.Width * 4; subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0; subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&texDesc, &subResource, &pTexture); g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view // Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc)); ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView); g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
pTexture->Release(); pTexture->Release();
@ -269,17 +318,17 @@ static void ImGui_ImplDX11_CreateFontsTexture()
// Create texture sampler // Create texture sampler
{ {
D3D11_SAMPLER_DESC samplerDesc; D3D11_SAMPLER_DESC desc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc)); ZeroMemory(&desc, sizeof(desc));
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerDesc.MipLODBias = 0.f; desc.MipLODBias = 0.f;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
samplerDesc.MinLOD = 0.f; desc.MinLOD = 0.f;
samplerDesc.MaxLOD = 0.f; desc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
} }
} }
@ -327,24 +376,23 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
return false; return false;
// Create the input layout // 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 }, { "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 }, { "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 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
}; };
if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
return false; return false;
// Create the constant buffer // Create the constant buffer
{ {
D3D11_BUFFER_DESC cbDesc; D3D11_BUFFER_DESC desc;
cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC; desc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0; desc.MiscFlags = 0;
g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/************************************************************************* /*************************************************************************
* GLFW 3.1 - www.glfw.org * GLFW 3.2 - www.glfw.org
* A library for OpenGL, window and input * A library for OpenGL, window and input
*------------------------------------------------------------------------ *------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2002-2006 Marcus Geelnard
@ -38,20 +38,30 @@ extern "C" {
* Doxygen documentation * 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 /*! @defgroup native Native access
* *
* **By using the native access functions you assert that you know what you're * **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 * doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.** * shouldn't be using them.**
* *
* Before the inclusion of @ref glfw3native.h, you must define exactly one * Before the inclusion of @ref glfw3native.h, you may define exactly one
* window system API macro and exactly one context creation API macro. Failure * window system API macro and zero or more context creation API macros.
* to do this will cause a compile-time error. *
* 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: * The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32` * * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA` * * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11` * * `GLFW_EXPOSE_NATIVE_X11`
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
* * `GLFW_EXPOSE_NATIVE_MIR`
* *
* The available context API macros are: * The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL` * * `GLFW_EXPOSE_NATIVE_WGL`
@ -86,20 +96,23 @@ extern "C" {
#elif defined(GLFW_EXPOSE_NATIVE_X11) #elif defined(GLFW_EXPOSE_NATIVE_X11)
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#else #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#error "No window API selected" #include <wayland-client.h>
#elif defined(GLFW_EXPOSE_NATIVE_MIR)
#include <mir_toolkit/mir_client_library.h>
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_WGL) #if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */ /* 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 */ /* NSGL is declared by Cocoa.h */
#elif defined(GLFW_EXPOSE_NATIVE_GLX) #endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
#include <GL/glx.h> #include <GL/glx.h>
#elif defined(GLFW_EXPOSE_NATIVE_EGL) #endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h> #include <EGL/egl.h>
#else
#error "No context API selected"
#endif #endif
@ -114,11 +127,10 @@ extern "C" {
* of the specified monitor, or `NULL` if an [error](@ref error_handling) * of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred. * occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -130,11 +142,10 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -145,11 +156,10 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
* @return The `HWND` of the specified window, or `NULL` if an * @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -162,11 +172,10 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
* @return The `HGLRC` of the specified window, or `NULL` if an * @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -179,11 +188,10 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
* @return The `CGDirectDisplayID` of the specified monitor, or * @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -194,11 +202,10 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
* @return The `NSWindow` of the specified window, or `nil` if an * @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -211,11 +218,10 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
* @return The `NSOpenGLContext` of the specified window, or `nil` if an * @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -228,11 +234,10 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
* @return The `Display` used by GLFW, or `NULL` if an * @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -243,11 +248,10 @@ GLFWAPI Display* glfwGetX11Display(void);
* @return The `RRCrtc` of the specified monitor, or `None` if an * @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -258,11 +262,10 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
* @return The `RROutput` of the specified monitor, or `None` if an * @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.1.
* Added in GLFW 3.1.
* *
* @ingroup native * @ingroup native
*/ */
@ -273,11 +276,10 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @return The `Window` of the specified window, or `None` if an * @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -290,15 +292,116 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
* @return The `GLXContext` of the specified window, or `NULL` if an * @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); 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 #endif
#if defined(GLFW_EXPOSE_NATIVE_EGL) #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 * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -322,11 +424,10 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */
@ -337,11 +438,10 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @thread_safety This function may be called from any thread. Access is not
* This function may be called from any thread. Access is not synchronized. * synchronized.
* *
* @par History * @since Added in version 3.0.
* Added in GLFW 3.0.
* *
* @ingroup native * @ingroup native
*/ */

View File

@ -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})

View File

@ -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

View File

@ -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 ./

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 <imgui.h>
// GLFW
#define GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#ifdef _WIN32
#undef APIENTRY
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#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<<i))
return i;
return 0xffffffff; // Unable to find memoryType
}
static void ImGui_ImplGlfwVulkan_VkResult(VkResult err)
{
if (g_CheckVkResult)
g_CheckVkResult(err);
}
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
void ImGui_ImplGlfwVulkan_RenderDrawLists(ImDrawData* draw_data)
{
VkResult err;
ImGuiIO& io = ImGui::GetIO();
// Create the Vertex Buffer:
size_t vertex_size = draw_data->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<int32_t>(pcmd->ClipRect.x);
scissor.offset.y = static_cast<int32_t>(pcmd->ClipRect.y);
scissor.extent.width = static_cast<uint32_t>(pcmd->ClipRect.z - pcmd->ClipRect.x);
scissor.extent.height = static_cast<uint32_t>(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, &region);
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; i<IMGUI_VK_QUEUED_FRAMES; i++)
{
if (g_VertexBuffer[i])
vkDestroyBuffer(g_Device, g_VertexBuffer[i], g_Allocator);
if (g_VertexBufferMemory[i])
vkFreeMemory(g_Device, g_VertexBufferMemory[i], g_Allocator);
if (g_IndexBuffer[i])
vkDestroyBuffer(g_Device, g_IndexBuffer[i], g_Allocator);
if (g_IndexBufferMemory[i])
vkFreeMemory(g_Device, g_IndexBufferMemory[i], g_Allocator);
}
if (g_FontView)
vkDestroyImageView(g_Device, g_FontView, g_Allocator);
if (g_FontImage)
vkDestroyImage(g_Device, g_FontImage, g_Allocator);
if (g_FontMemory)
vkFreeMemory(g_Device, g_FontMemory, g_Allocator);
if (g_FontSampler)
vkDestroySampler(g_Device, g_FontSampler, g_Allocator);
if (g_DescriptorSetLayout)
vkDestroyDescriptorSetLayout(g_Device, g_DescriptorSetLayout, g_Allocator);
if (g_PipelineLayout)
vkDestroyPipelineLayout(g_Device, g_PipelineLayout, g_Allocator);
if (g_Pipeline)
vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator);
}
bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, ImGui_ImplGlfwVulkan_Init_Data *init_data)
{
g_Allocator = init_data->allocator;
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;
}

View File

@ -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);

View File

@ -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 <imgui.h>
#include <stdio.h> // printf, fprintf
#include <stdlib.h> // abort
#define GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#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; i<g_BackBufferCount; i++)
if (g_BackBufferView[i])
vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
for(uint32_t i=0; i<g_BackBufferCount; i++)
if (g_Framebuffer[i])
vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
if (g_RenderPass)
vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
// Create Swapchain:
{
VkSwapchainCreateInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
info.surface = g_Surface;
info.imageFormat = g_Format;
info.imageColorSpace = g_ColorSpace;
info.imageArrayLayers = 1;
info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
info.clipped = VK_TRUE;
info.oldSwapchain = old_swapchain;
VkSurfaceCapabilitiesKHR cap;
err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_Gpu, g_Surface, &cap);
check_vk_result(err);
info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount;
if (cap.currentExtent.width == 0xffffffff)
{
fb_width = w;
fb_height = h;
info.imageExtent.width = fb_width;
info.imageExtent.height = fb_height;
}
else
{
fb_width = cap.currentExtent.width;
fb_height = cap.currentExtent.height;
info.imageExtent.width = fb_width;
info.imageExtent.height = fb_height;
}
err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain);
check_vk_result(err);
err = vkGetSwapchainImagesKHR(g_Device, g_Swapchain, &g_BackBufferCount, NULL);
check_vk_result(err);
err = vkGetSwapchainImagesKHR(g_Device, g_Swapchain, &g_BackBufferCount, g_BackBuffer);
check_vk_result(err);
}
if (old_swapchain)
vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator);
// Create the Render Pass:
{
VkAttachmentDescription attachment = {};
attachment.format = g_Format;
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference color_attachment = {};
color_attachment.attachment = 0;
color_attachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &color_attachment;
VkRenderPassCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
info.attachmentCount = 1;
info.pAttachments = &attachment;
info.subpassCount = 1;
info.pSubpasses = &subpass;
err = vkCreateRenderPass(g_Device, &info, g_Allocator, &g_RenderPass);
check_vk_result(err);
}
// Create The Image Views
{
VkImageViewCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
info.viewType = VK_IMAGE_VIEW_TYPE_2D;
info.format = g_Format;
info.components.r = VK_COMPONENT_SWIZZLE_R;
info.components.g = VK_COMPONENT_SWIZZLE_G;
info.components.b = VK_COMPONENT_SWIZZLE_B;
info.components.a = VK_COMPONENT_SWIZZLE_A;
info.subresourceRange = g_ImageRange;
for (uint32_t i = 0; i<g_BackBufferCount; i++)
{
info.image = g_BackBuffer[i];
err = vkCreateImageView(g_Device, &info, g_Allocator, &g_BackBufferView[i]);
check_vk_result(err);
}
}
// Create Framebuffer:
{
VkImageView attachment[1];
VkFramebufferCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
info.renderPass = g_RenderPass;
info.attachmentCount = 1;
info.pAttachments = attachment;
info.width = fb_width;
info.height = fb_height;
info.layers = 1;
for (uint32_t i = 0; i<g_BackBufferCount; i++)
{
attachment[0] = g_BackBufferView[i];
err = vkCreateFramebuffer(g_Device, &info, g_Allocator, &g_Framebuffer[i]);
check_vk_result(err);
}
}
}
static void setup_vulkan(GLFWwindow* window)
{
VkResult err;
// Create Vulkan Instance
{
uint32_t glfw_extensions_count;
const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extensions_count);
VkInstanceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.enabledExtensionCount = glfw_extensions_count;
create_info.ppEnabledExtensionNames = glfw_extensions;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err);
}
// Create Window Surface
{
err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &g_Surface);
check_vk_result(err);
}
// Get GPU
{
uint32_t count = 1;
err = vkEnumeratePhysicalDevices(g_Instance, &count, &g_Gpu);
check_vk_result(err);
}
// Create Logical Device
{
int device_extension_count = 1;
const char* device_extensions[] = {"VK_KHR_swapchain"};
const uint32_t queue_index = 0;
const uint32_t queue_count = 1;
const float queue_priority[] = {1.0f};
VkDeviceQueueCreateInfo queue_info[1] = {};
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_info[0].queueFamilyIndex = g_QueueFamily;
queue_info[0].queueCount = queue_count;
queue_info[0].pQueuePriorities = queue_priority;
VkDeviceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.queueCreateInfoCount = sizeof(queue_info)/sizeof(queue_info[0]);
create_info.pQueueCreateInfos = queue_info;
create_info.enabledExtensionCount = device_extension_count;
create_info.ppEnabledExtensionNames = device_extensions;
err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device);
check_vk_result(err);
vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue);
}
// Create Framebuffers
{
int w, h;
glfwGetFramebufferSize(window, &w, &h);
resize_vulkan(window, w, h);
glfwSetFramebufferSizeCallback(window, resize_vulkan);
}
// Create Command Buffers
for (int i=0; i<IMGUI_VK_QUEUED_FRAMES; i++)
{
{
VkCommandPoolCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
info.queueFamilyIndex = g_QueueFamily;
err = vkCreateCommandPool(g_Device, &info, g_Allocator, &g_CommandPool[i]);
check_vk_result(err);
}
{
VkCommandBufferAllocateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
info.commandPool = g_CommandPool[i];
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
info.commandBufferCount = 1;
err = vkAllocateCommandBuffers(g_Device, &info, &g_CommandBuffer[i]);
check_vk_result(err);
}
{
VkFenceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
err = vkCreateFence(g_Device, &info, g_Allocator, &g_Fence[i]);
check_vk_result(err);
}
{
VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_Semaphore[i]);
check_vk_result(err);
}
}
// Create Descriptor Pool
{
VkDescriptorPoolSize pool_size[11] =
{
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1000 * 11;
pool_info.poolSizeCount = 11;
pool_info.pPoolSizes = pool_size;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
check_vk_result(err);
}
}
static void cleanup_vulkan()
{
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
{
vkDestroyFence(g_Device, g_Fence[i], g_Allocator);
vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]);
vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator);
vkDestroySemaphore(g_Device, g_Semaphore[i], g_Allocator);
}
for (uint32_t i = 0; i < g_BackBufferCount; i++)
{
vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
}
vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
vkDestroySwapchainKHR(g_Device, g_Swapchain, g_Allocator);
vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator);
vkDestroyDevice(g_Device, g_Allocator);
vkDestroyInstance(g_Instance, g_Allocator);
}
static void frame_begin()
{
VkResult err;
while (true)
{
err = vkWaitForFences(g_Device, 1, &g_Fence[g_FrameIndex], VK_TRUE, 100);
if (err == VK_SUCCESS) break;
if (err == VK_TIMEOUT) continue;
check_vk_result(err);
}
{
err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_Semaphore[g_FrameIndex], VK_NULL_HANDLE, &g_BackBufferIndex);
check_vk_result(err);
}
{
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0);
check_vk_result(err);
VkCommandBufferBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &info);
check_vk_result(err);
}
{
VkRenderPassBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = g_RenderPass;
info.framebuffer = g_Framebuffer[g_BackBufferIndex];
info.renderArea.extent.width = fb_width;
info.renderArea.extent.height = fb_height;
info.clearValueCount = 1;
info.pClearValues = &g_ClearValue;
vkCmdBeginRenderPass(g_CommandBuffer[g_FrameIndex], &info, VK_SUBPASS_CONTENTS_INLINE);
}
}
static void frame_end()
{
VkResult err;
vkCmdEndRenderPass(g_CommandBuffer[g_FrameIndex]);
{
VkImageMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = g_BackBuffer[g_BackBufferIndex];
barrier.subresourceRange = g_ImageRange;
vkCmdPipelineBarrier(g_CommandBuffer[g_FrameIndex], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &barrier);
}
{
VkSubmitInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &g_Semaphore[g_FrameIndex];
info.commandBufferCount = 1;
info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex];
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]);
check_vk_result(err);
err = vkResetFences(g_Device, 1, &g_Fence[g_FrameIndex]);
check_vk_result(err);
err = vkQueueSubmit(g_Queue, 1, &info, g_Fence[g_FrameIndex]);
check_vk_result(err);
}
{
VkResult res;
VkSwapchainKHR swapchains[1] = {g_Swapchain};
uint32_t indices[1] = {g_BackBufferIndex};
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.swapchainCount = 1;
info.pSwapchains = swapchains;
info.pImageIndices = indices;
info.pResults = &res;
err = vkQueuePresentKHR(g_Queue, &info);
check_vk_result(err);
check_vk_result(res);
}
g_FrameIndex = (g_FrameIndex) % IMGUI_VK_QUEUED_FRAMES;
}
static void error_callback(int error, const char* description)
{
fprintf(stderr, "Error %d: %s\n", error, description);
}
int main(int, char**)
{
// Setup window
glfwSetErrorCallback(error_callback);
if (!glfwInit())
return 1;
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui Vulkan example", NULL, NULL);
// Setup Vulkan
if (!glfwVulkanSupported())
{
printf("GLFW: Vulkan Not Supported\n");
return 1;
}
setup_vulkan(window);
// Setup ImGui binding
ImGui_ImplGlfwVulkan_Init_Data init_data = {};
init_data.allocator = g_Allocator;
init_data.gpu = g_Gpu;
init_data.device = g_Device;
init_data.render_pass = g_RenderPass;
init_data.pipeline_cache = g_PipelineCache;
init_data.descriptor_pool = g_DescriptorPool;
init_data.check_vk_result = check_vk_result;
ImGui_ImplGlfwVulkan_Init(window, true, &init_data);
// Load Fonts
// (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details)
//ImGuiIO& io = ImGui::GetIO();
//io.Fonts->AddFontDefault();
//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;
}

View File

@ -1,4 +1,4 @@
// dear imgui, v1.48 WIP // dear imgui, v1.49 WIP
// (main code and documentation) // (main code and documentation)
// See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. // 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. 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. 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/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/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 - 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) - color: add a better color picker (#346)
- node/graph editor (#306) - node/graph editor (#306)
- pie menus patterns (#434) - 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: 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: 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) - 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 WindowMinSize = ImVec2(32,32); // Minimum window size
WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows
WindowTitleAlign = ImGuiAlign_Left; // Alignment for title bar text 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) 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). 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 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) 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! 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 IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns
ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar 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_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 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_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_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.65f);
Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); 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 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_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 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_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); Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
} }
@ -1652,7 +1654,7 @@ ImGuiWindow* ImGui::GetParentWindow()
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
IM_ASSERT(g.CurrentWindowStack.Size >= 2); 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) void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window = NULL)
@ -2340,7 +2342,7 @@ static void AddDrawListToRenderList(ImVector<ImDrawList*>& out_render_list, ImDr
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = 2 bytes = 64K vertices) // 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. // 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((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((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); out_render_list.push_back(draw_list);
GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size; GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size;
@ -3139,9 +3141,8 @@ static ImRect GetVisibleRect()
void ImGui::BeginTooltip() void ImGui::BeginTooltip()
{ {
ImGuiState& g = *GImGui;
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; 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() 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 ImFormatString(name, 20, "##menu_%d", g.CurrentPopupStack.Size); // Recycle windows based on depth
else else
ImFormatString(name, 20, "##popup_%08x", id); // Not recycling, so we can close/open during the same frame 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)) if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
g.CurrentWindow->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) 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; 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) if (!opened || (p_opened && !*p_opened)) // Opened can be 'false' when the popup is completely clipped (e.g. zero size display)
{ {
ImGui::EndPopup(); ImGui::EndPopup();
@ -3392,8 +3392,7 @@ bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border,
char title[256]; char title[256];
ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id); ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id);
const float alpha = 1.0f; bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags);
bool ret = ImGui::Begin(title, NULL, size, alpha, flags);
if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
GetCurrentWindow()->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; const ImGuiStyle& style = g.Style;
ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]); ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]);
ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding); 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() void ImGui::EndChildFrame()
{ {
ImGui::EndChild(); ImGui::EndChild();
ImGui::PopStyleVar(); ImGui::PopStyleVar(2);
ImGui::PopStyleColor(); 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->RootWindow = g.CurrentWindowStack[root_idx];
window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // This is merely for displaying the TitleBgActive color. 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) // When reusing window again multiple times a frame, just append content (don't need to setup again)
if (first_begin_of_the_frame) 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. // 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 // Calculate auto-fit size
ImVec2 size_auto_fit; ImVec2 size_auto_fit;
@ -3981,27 +3977,26 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
} }
// Scrollbars // Scrollbars
window->ScrollbarY = (flags & ImGuiWindowFlags_ForceVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((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->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->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
// Window background // Window background
if (bg_alpha > 0.0f) // Default alpha
{ ImGuiCol bg_color_idx = ImGuiCol_WindowBg;
ImGuiCol col_idx;
if ((flags & ImGuiWindowFlags_ComboBox) != 0) if ((flags & ImGuiWindowFlags_ComboBox) != 0)
col_idx = ImGuiCol_ComboBg; bg_color_idx = ImGuiCol_ComboBg;
else if ((flags & ImGuiWindowFlags_Tooltip) != 0) else if ((flags & ImGuiWindowFlags_Tooltip) != 0 || (flags & ImGuiWindowFlags_Popup) != 0)
col_idx = ImGuiCol_TooltipBg; bg_color_idx = ImGuiCol_PopupBg;
else if ((flags & ImGuiWindowFlags_Popup) != 0)
col_idx = ImGuiCol_WindowBg;
else if ((flags & ImGuiWindowFlags_ChildWindow) != 0) else if ((flags & ImGuiWindowFlags_ChildWindow) != 0)
col_idx = ImGuiCol_ChildWindowBg; bg_color_idx = ImGuiCol_ChildWindowBg;
else ImVec4 bg_color = style.Colors[bg_color_idx];
col_idx = ImGuiCol_WindowBg; if (bg_alpha >= 0.0f)
window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, GetColorU32(col_idx, bg_alpha), window_rounding); 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 // Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar)) if (!(flags & ImGuiWindowFlags_NoTitleBar))
@ -4521,6 +4516,7 @@ const char* ImGui::GetStyleColName(ImGuiCol idx)
case ImGuiCol_TextDisabled: return "TextDisabled"; case ImGuiCol_TextDisabled: return "TextDisabled";
case ImGuiCol_WindowBg: return "WindowBg"; case ImGuiCol_WindowBg: return "WindowBg";
case ImGuiCol_ChildWindowBg: return "ChildWindowBg"; case ImGuiCol_ChildWindowBg: return "ChildWindowBg";
case ImGuiCol_PopupBg: return "PopupBg";
case ImGuiCol_Border: return "Border"; case ImGuiCol_Border: return "Border";
case ImGuiCol_BorderShadow: return "BorderShadow"; case ImGuiCol_BorderShadow: return "BorderShadow";
case ImGuiCol_FrameBg: return "FrameBg"; case ImGuiCol_FrameBg: return "FrameBg";
@ -4558,7 +4554,6 @@ const char* ImGui::GetStyleColName(ImGuiCol idx)
case ImGuiCol_PlotHistogram: return "PlotHistogram"; case ImGuiCol_PlotHistogram: return "PlotHistogram";
case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered";
case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
case ImGuiCol_TooltipBg: return "TooltipBg";
case ImGuiCol_ModalWindowDarkening: return "ModalWindowDarkening"; case ImGuiCol_ModalWindowDarkening: return "ModalWindowDarkening";
} }
IM_ASSERT(0); 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 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_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; } 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 #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; } 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 #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; } 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; return false;
} }
draw_window = GetCurrentWindow(); draw_window = GetCurrentWindow();
draw_window->DC.CursorPos += style.FramePadding;
size.x -= draw_window->ScrollbarSizes.x; size.x -= draw_window->ScrollbarSizes.x;
} }
else else
@ -8501,7 +8495,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
bool want_open = false, want_close = false; bool want_open = false, want_close = false;
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) 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; bool moving_within_opened_triangle = false;
if (g.HoveredWindow == window && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentWindow == window) if (g.HoveredWindow == window && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentWindow == window)
{ {

25
imgui.h
View File

@ -1,4 +1,4 @@
// dear imgui, v1.48 WIP // dear imgui, v1.49 WIP
// (headers) // (headers)
// See imgui.cpp file for documentation. // See imgui.cpp file for documentation.
@ -16,7 +16,7 @@
#include <stddef.h> // ptrdiff_t, NULL #include <stddef.h> // ptrdiff_t, NULL
#include <string.h> // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp #include <string.h> // 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. // Define attributes of all API symbols declarations, e.g. for DLL under Windows.
#ifndef IMGUI_API #ifndef IMGUI_API
@ -114,7 +114,7 @@ namespace ImGui
// Window // 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 = 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 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(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); // " 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 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 TreePush(const void* ptr_id = NULL); // "
IMGUI_API void TreePop(); 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 // 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 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_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file
ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs
ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar 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_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_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_AlwaysVerticalScrollbar= 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_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] // [Internal]
ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // 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_Text,
ImGuiCol_TextDisabled, ImGuiCol_TextDisabled,
ImGuiCol_WindowBg, ImGuiCol_WindowBg, // Background of normal windows
ImGuiCol_ChildWindowBg, ImGuiCol_ChildWindowBg, // Background of child windows
ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows
ImGuiCol_Border, ImGuiCol_Border,
ImGuiCol_BorderShadow, ImGuiCol_BorderShadow,
ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input
@ -585,7 +587,6 @@ enum ImGuiCol_
ImGuiCol_PlotHistogram, ImGuiCol_PlotHistogram,
ImGuiCol_PlotHistogramHovered, ImGuiCol_PlotHistogramHovered,
ImGuiCol_TextSelectedBg, ImGuiCol_TextSelectedBg,
ImGuiCol_TooltipBg,
ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active
ImGuiCol_COUNT ImGuiCol_COUNT
}; };
@ -667,7 +668,6 @@ struct ImGuiStyle
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines 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 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! 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 IndentSpacing; // Horizontal indentation when e.g. entering a tree node
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns float ColumnsMinSpacing; // Minimum horizontal spacing between two columns
float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar
@ -895,6 +895,7 @@ struct ImGuiTextFilter
int CountGrep; int CountGrep;
ImGuiTextFilter(const char* default_filter = ""); ImGuiTextFilter(const char* default_filter = "");
~ImGuiTextFilter() {}
void Clear() { InputBuf[0] = 0; Build(); } void Clear() { InputBuf[0] = 0; Build(); }
bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+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; 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() // Stateful path API, add points then finish with PathFill() or PathStroke()
inline void PathClear() { _Path.resize(0); } inline void PathClear() { _Path.resize(0); }
inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } 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 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(); } 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); IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.48 WIP // dear imgui, v1.49 WIP
// (demo code) // (demo code)
// Don't remove this file from your project! It is useful reference code that you can execute. // 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_scrollbar = false;
static bool no_collapse = false; static bool no_collapse = false;
static bool no_menu = 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. // Demonstrate the various window flags. Typically you would just use the default.
ImGuiWindowFlags window_flags = 0; ImGuiWindowFlags window_flags = 0;
@ -150,7 +149,8 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar;
if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse;
if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; 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. // Early out if the window is collapsed, as an optimization.
ImGui::End(); ImGui::End();
@ -211,10 +211,6 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::Checkbox("No collapse", &no_collapse); ImGui::Checkbox("No collapse", &no_collapse);
ImGui::Checkbox("No menu", &no_menu); 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")) if (ImGui::TreeNode("Style"))
{ {
ImGui::ShowStyleEditor(); 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 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 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("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("WantCaptureMouse: %s", io.WantCaptureMouse ? "true" : "false");
ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "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); 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; 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("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::PopItemWidth();
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1618,7 +1613,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
static ImGuiTextFilter filter; static ImGuiTextFilter filter;
filter.Draw("Filter colors", 200); filter.Draw("Filter colors", 200);
ImGui::BeginChild("#colors", ImVec2(0, 300), true); ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
ImGui::PushItemWidth(-160); ImGui::PushItemWidth(-160);
for (int i = 0; i < ImGuiCol_COUNT; i++) 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::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. 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::NextColumn();
ImGui::AlignFirstTextHeightToWidgets(); ImGui::AlignFirstTextHeightToWidgets();
ImGui::Text("my sailor is rich"); ImGui::Text("my sailor is rich");
ImGui::NextColumn(); ImGui::NextColumn();
if (opened) if (is_opened)
{ {
static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f };
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.48 WIP // dear imgui, v1.49 WIP
// (drawing and font code) // (drawing and font code)
// Contains implementation for // Contains implementation for

View File

@ -1,4 +1,4 @@
// dear imgui, v1.48 WIP // dear imgui, v1.49 WIP
// (internals) // (internals)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!