diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/ios_example/imguiex/Shaders/Shader.vsh deleted file mode 100644 index 313c3d7..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.vsh +++ /dev/null @@ -1,25 +0,0 @@ -// -// Shader.vsh -// imguiex - -attribute vec4 position; -attribute vec3 normal; - -varying lowp vec4 colorVarying; - -uniform vec3 diffuseColor; -uniform mat4 modelViewProjectionMatrix; -uniform mat3 normalMatrix; - -void main() -{ - vec3 eyeNormal = normalize(normalMatrix * normal); - vec3 lightPosition = vec3(0.0, 0.0, 1.0); - - float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); - - vec3 colorLit = diffuseColor * nDotVP; - colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); - - gl_Position = modelViewProjectionMatrix * position; -} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/ios_example/imguiex/Shaders/Shader.vsh deleted file mode 100644 index 313c3d7..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.vsh +++ /dev/null @@ -1,25 +0,0 @@ -// -// Shader.vsh -// imguiex - -attribute vec4 position; -attribute vec3 normal; - -varying lowp vec4 colorVarying; - -uniform vec3 diffuseColor; -uniform mat4 modelViewProjectionMatrix; -uniform mat3 normalMatrix; - -void main() -{ - vec3 eyeNormal = normalize(normalMatrix * normal); - vec3 lightPosition = vec3(0.0, 0.0, 1.0); - - float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); - - vec3 colorLit = diffuseColor * nDotVP; - colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); - - gl_Position = modelViewProjectionMatrix * position; -} diff --git a/examples/ios_example/imguiex/debug_hud.cpp b/examples/ios_example/imguiex/debug_hud.cpp deleted file mode 100644 index c75938a..0000000 --- a/examples/ios_example/imguiex/debug_hud.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// debug_hud.cpp -// imguiex - -#include - -#include "debug_hud.h" -#include "imgui.h" - -void DebugHUD_InitDefaults( DebugHUD *hud ) -{ - hud->show_test_window = true; - hud->show_example_window = true; - hud->rotation_speed = 15.0f; - - hud->cubeColor1[0] = 0.4f; - hud->cubeColor1[1] = 0.4f; - hud->cubeColor1[2] = 1.0f; - hud->cubeColor1[3] = 1.0f; - - hud->cubeColor2[0] = 1.0f; - hud->cubeColor2[1] = 0.4f; - hud->cubeColor2[2] = 0.4f; - hud->cubeColor2[3] = 1.0f; -} - -void DebugHUD_DoInterface( DebugHUD *hud ) -{ - if (hud->show_test_window) - { - ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::ShowTestWindow( &hud->show_test_window ); - } - - if (hud->show_example_window) - { - ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); - ImGui::Begin("Another Window", &hud->show_example_window); - ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); - ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); - ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); - ImGui::End(); - } -} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/ios_example/imguiex/Shaders/Shader.vsh deleted file mode 100644 index 313c3d7..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.vsh +++ /dev/null @@ -1,25 +0,0 @@ -// -// Shader.vsh -// imguiex - -attribute vec4 position; -attribute vec3 normal; - -varying lowp vec4 colorVarying; - -uniform vec3 diffuseColor; -uniform mat4 modelViewProjectionMatrix; -uniform mat3 normalMatrix; - -void main() -{ - vec3 eyeNormal = normalize(normalMatrix * normal); - vec3 lightPosition = vec3(0.0, 0.0, 1.0); - - float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); - - vec3 colorLit = diffuseColor * nDotVP; - colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); - - gl_Position = modelViewProjectionMatrix * position; -} diff --git a/examples/ios_example/imguiex/debug_hud.cpp b/examples/ios_example/imguiex/debug_hud.cpp deleted file mode 100644 index c75938a..0000000 --- a/examples/ios_example/imguiex/debug_hud.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// debug_hud.cpp -// imguiex - -#include - -#include "debug_hud.h" -#include "imgui.h" - -void DebugHUD_InitDefaults( DebugHUD *hud ) -{ - hud->show_test_window = true; - hud->show_example_window = true; - hud->rotation_speed = 15.0f; - - hud->cubeColor1[0] = 0.4f; - hud->cubeColor1[1] = 0.4f; - hud->cubeColor1[2] = 1.0f; - hud->cubeColor1[3] = 1.0f; - - hud->cubeColor2[0] = 1.0f; - hud->cubeColor2[1] = 0.4f; - hud->cubeColor2[2] = 0.4f; - hud->cubeColor2[3] = 1.0f; -} - -void DebugHUD_DoInterface( DebugHUD *hud ) -{ - if (hud->show_test_window) - { - ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::ShowTestWindow( &hud->show_test_window ); - } - - if (hud->show_example_window) - { - ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); - ImGui::Begin("Another Window", &hud->show_example_window); - ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); - ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); - ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); - ImGui::End(); - } -} diff --git a/examples/ios_example/imguiex/debug_hud.h b/examples/ios_example/imguiex/debug_hud.h deleted file mode 100644 index 17122f5..0000000 --- a/examples/ios_example/imguiex/debug_hud.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// debug_hud.h -// imguiex - -#pragma once - -typedef struct DebugHUD -{ - bool show_test_window; - bool show_example_window; - float rotation_speed; - float cubeColor1[4]; - float cubeColor2[4]; -} DebugHUD; - -#if __cplusplus -extern "C" { -#endif - -void DebugHUD_InitDefaults( DebugHUD *hud ); -void DebugHUD_DoInterface( DebugHUD *hud ); - -#if __cplusplus -} -#endif diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/ios_example/imguiex/Shaders/Shader.vsh deleted file mode 100644 index 313c3d7..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.vsh +++ /dev/null @@ -1,25 +0,0 @@ -// -// Shader.vsh -// imguiex - -attribute vec4 position; -attribute vec3 normal; - -varying lowp vec4 colorVarying; - -uniform vec3 diffuseColor; -uniform mat4 modelViewProjectionMatrix; -uniform mat3 normalMatrix; - -void main() -{ - vec3 eyeNormal = normalize(normalMatrix * normal); - vec3 lightPosition = vec3(0.0, 0.0, 1.0); - - float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); - - vec3 colorLit = diffuseColor * nDotVP; - colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); - - gl_Position = modelViewProjectionMatrix * position; -} diff --git a/examples/ios_example/imguiex/debug_hud.cpp b/examples/ios_example/imguiex/debug_hud.cpp deleted file mode 100644 index c75938a..0000000 --- a/examples/ios_example/imguiex/debug_hud.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// debug_hud.cpp -// imguiex - -#include - -#include "debug_hud.h" -#include "imgui.h" - -void DebugHUD_InitDefaults( DebugHUD *hud ) -{ - hud->show_test_window = true; - hud->show_example_window = true; - hud->rotation_speed = 15.0f; - - hud->cubeColor1[0] = 0.4f; - hud->cubeColor1[1] = 0.4f; - hud->cubeColor1[2] = 1.0f; - hud->cubeColor1[3] = 1.0f; - - hud->cubeColor2[0] = 1.0f; - hud->cubeColor2[1] = 0.4f; - hud->cubeColor2[2] = 0.4f; - hud->cubeColor2[3] = 1.0f; -} - -void DebugHUD_DoInterface( DebugHUD *hud ) -{ - if (hud->show_test_window) - { - ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::ShowTestWindow( &hud->show_test_window ); - } - - if (hud->show_example_window) - { - ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); - ImGui::Begin("Another Window", &hud->show_example_window); - ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); - ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); - ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); - ImGui::End(); - } -} diff --git a/examples/ios_example/imguiex/debug_hud.h b/examples/ios_example/imguiex/debug_hud.h deleted file mode 100644 index 17122f5..0000000 --- a/examples/ios_example/imguiex/debug_hud.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// debug_hud.h -// imguiex - -#pragma once - -typedef struct DebugHUD -{ - bool show_test_window; - bool show_example_window; - float rotation_speed; - float cubeColor1[4]; - float cubeColor2[4]; -} DebugHUD; - -#if __cplusplus -extern "C" { -#endif - -void DebugHUD_InitDefaults( DebugHUD *hud ); -void DebugHUD_DoInterface( DebugHUD *hud ); - -#if __cplusplus -} -#endif diff --git a/examples/ios_example/imguiex/imgui_ex_icon.png b/examples/ios_example/imguiex/imgui_ex_icon.png deleted file mode 100644 index 820e4d7..0000000 --- a/examples/ios_example/imguiex/imgui_ex_icon.png +++ /dev/null Binary files differ diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/ios_example/imguiex/Shaders/Shader.vsh deleted file mode 100644 index 313c3d7..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.vsh +++ /dev/null @@ -1,25 +0,0 @@ -// -// Shader.vsh -// imguiex - -attribute vec4 position; -attribute vec3 normal; - -varying lowp vec4 colorVarying; - -uniform vec3 diffuseColor; -uniform mat4 modelViewProjectionMatrix; -uniform mat3 normalMatrix; - -void main() -{ - vec3 eyeNormal = normalize(normalMatrix * normal); - vec3 lightPosition = vec3(0.0, 0.0, 1.0); - - float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); - - vec3 colorLit = diffuseColor * nDotVP; - colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); - - gl_Position = modelViewProjectionMatrix * position; -} diff --git a/examples/ios_example/imguiex/debug_hud.cpp b/examples/ios_example/imguiex/debug_hud.cpp deleted file mode 100644 index c75938a..0000000 --- a/examples/ios_example/imguiex/debug_hud.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// debug_hud.cpp -// imguiex - -#include - -#include "debug_hud.h" -#include "imgui.h" - -void DebugHUD_InitDefaults( DebugHUD *hud ) -{ - hud->show_test_window = true; - hud->show_example_window = true; - hud->rotation_speed = 15.0f; - - hud->cubeColor1[0] = 0.4f; - hud->cubeColor1[1] = 0.4f; - hud->cubeColor1[2] = 1.0f; - hud->cubeColor1[3] = 1.0f; - - hud->cubeColor2[0] = 1.0f; - hud->cubeColor2[1] = 0.4f; - hud->cubeColor2[2] = 0.4f; - hud->cubeColor2[3] = 1.0f; -} - -void DebugHUD_DoInterface( DebugHUD *hud ) -{ - if (hud->show_test_window) - { - ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::ShowTestWindow( &hud->show_test_window ); - } - - if (hud->show_example_window) - { - ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); - ImGui::Begin("Another Window", &hud->show_example_window); - ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); - ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); - ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); - ImGui::End(); - } -} diff --git a/examples/ios_example/imguiex/debug_hud.h b/examples/ios_example/imguiex/debug_hud.h deleted file mode 100644 index 17122f5..0000000 --- a/examples/ios_example/imguiex/debug_hud.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// debug_hud.h -// imguiex - -#pragma once - -typedef struct DebugHUD -{ - bool show_test_window; - bool show_example_window; - float rotation_speed; - float cubeColor1[4]; - float cubeColor2[4]; -} DebugHUD; - -#if __cplusplus -extern "C" { -#endif - -void DebugHUD_InitDefaults( DebugHUD *hud ); -void DebugHUD_DoInterface( DebugHUD *hud ); - -#if __cplusplus -} -#endif diff --git a/examples/ios_example/imguiex/imgui_ex_icon.png b/examples/ios_example/imguiex/imgui_ex_icon.png deleted file mode 100644 index 820e4d7..0000000 --- a/examples/ios_example/imguiex/imgui_ex_icon.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/imgui_impl_ios.h b/examples/ios_example/imguiex/imgui_impl_ios.h deleted file mode 100644 index 9b01dd3..0000000 --- a/examples/ios_example/imguiex/imgui_impl_ios.h +++ /dev/null @@ -1,22 +0,0 @@ -// ImGui iOS+OpenGL+Synergy binding -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. -// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. - -// by Joel Davis (joeld42@gmail.com) - -#pragma once - -#include -#include - -@interface ImGuiHelper : NSObject - -- (id) initWithView: (UIView *)view; - -- (void)connectServer: (NSString*)serverName; - -- (void)render; -- (void)newFrame; - -@end diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/ios_example/imguiex/Shaders/Shader.vsh deleted file mode 100644 index 313c3d7..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.vsh +++ /dev/null @@ -1,25 +0,0 @@ -// -// Shader.vsh -// imguiex - -attribute vec4 position; -attribute vec3 normal; - -varying lowp vec4 colorVarying; - -uniform vec3 diffuseColor; -uniform mat4 modelViewProjectionMatrix; -uniform mat3 normalMatrix; - -void main() -{ - vec3 eyeNormal = normalize(normalMatrix * normal); - vec3 lightPosition = vec3(0.0, 0.0, 1.0); - - float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); - - vec3 colorLit = diffuseColor * nDotVP; - colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); - - gl_Position = modelViewProjectionMatrix * position; -} diff --git a/examples/ios_example/imguiex/debug_hud.cpp b/examples/ios_example/imguiex/debug_hud.cpp deleted file mode 100644 index c75938a..0000000 --- a/examples/ios_example/imguiex/debug_hud.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// debug_hud.cpp -// imguiex - -#include - -#include "debug_hud.h" -#include "imgui.h" - -void DebugHUD_InitDefaults( DebugHUD *hud ) -{ - hud->show_test_window = true; - hud->show_example_window = true; - hud->rotation_speed = 15.0f; - - hud->cubeColor1[0] = 0.4f; - hud->cubeColor1[1] = 0.4f; - hud->cubeColor1[2] = 1.0f; - hud->cubeColor1[3] = 1.0f; - - hud->cubeColor2[0] = 1.0f; - hud->cubeColor2[1] = 0.4f; - hud->cubeColor2[2] = 0.4f; - hud->cubeColor2[3] = 1.0f; -} - -void DebugHUD_DoInterface( DebugHUD *hud ) -{ - if (hud->show_test_window) - { - ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::ShowTestWindow( &hud->show_test_window ); - } - - if (hud->show_example_window) - { - ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); - ImGui::Begin("Another Window", &hud->show_example_window); - ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); - ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); - ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); - ImGui::End(); - } -} diff --git a/examples/ios_example/imguiex/debug_hud.h b/examples/ios_example/imguiex/debug_hud.h deleted file mode 100644 index 17122f5..0000000 --- a/examples/ios_example/imguiex/debug_hud.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// debug_hud.h -// imguiex - -#pragma once - -typedef struct DebugHUD -{ - bool show_test_window; - bool show_example_window; - float rotation_speed; - float cubeColor1[4]; - float cubeColor2[4]; -} DebugHUD; - -#if __cplusplus -extern "C" { -#endif - -void DebugHUD_InitDefaults( DebugHUD *hud ); -void DebugHUD_DoInterface( DebugHUD *hud ); - -#if __cplusplus -} -#endif diff --git a/examples/ios_example/imguiex/imgui_ex_icon.png b/examples/ios_example/imguiex/imgui_ex_icon.png deleted file mode 100644 index 820e4d7..0000000 --- a/examples/ios_example/imguiex/imgui_ex_icon.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/imgui_impl_ios.h b/examples/ios_example/imguiex/imgui_impl_ios.h deleted file mode 100644 index 9b01dd3..0000000 --- a/examples/ios_example/imguiex/imgui_impl_ios.h +++ /dev/null @@ -1,22 +0,0 @@ -// ImGui iOS+OpenGL+Synergy binding -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. -// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. - -// by Joel Davis (joeld42@gmail.com) - -#pragma once - -#include -#include - -@interface ImGuiHelper : NSObject - -- (id) initWithView: (UIView *)view; - -- (void)connectServer: (NSString*)serverName; - -- (void)render; -- (void)newFrame; - -@end diff --git a/examples/ios_example/imguiex/imgui_impl_ios.mm b/examples/ios_example/imguiex/imgui_impl_ios.mm deleted file mode 100644 index b286c4d..0000000 --- a/examples/ios_example/imguiex/imgui_impl_ios.mm +++ /dev/null @@ -1,803 +0,0 @@ -// ImGui iOS+OpenGL+Synergy binding -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. -// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. - -#import -#import - -#include -#include -#include -#include - -#include "imgui_impl_ios.h" -#include "imgui.h" - -#include "uSynergy.h" - -// From Carbon HIToolbox/Events.h -// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 -enum { - kVK_ANSI_A = 0x00, - kVK_ANSI_S = 0x01, - kVK_ANSI_D = 0x02, - kVK_ANSI_F = 0x03, - kVK_ANSI_H = 0x04, - kVK_ANSI_G = 0x05, - kVK_ANSI_Z = 0x06, - kVK_ANSI_X = 0x07, - kVK_ANSI_C = 0x08, - kVK_ANSI_V = 0x09, - kVK_ANSI_B = 0x0B, - kVK_ANSI_Q = 0x0C, - kVK_ANSI_W = 0x0D, - kVK_ANSI_E = 0x0E, - kVK_ANSI_R = 0x0F, - kVK_ANSI_Y = 0x10, - kVK_ANSI_T = 0x11, - kVK_ANSI_1 = 0x12, - kVK_ANSI_2 = 0x13, - kVK_ANSI_3 = 0x14, - kVK_ANSI_4 = 0x15, - kVK_ANSI_6 = 0x16, - kVK_ANSI_5 = 0x17, - kVK_ANSI_Equal = 0x18, - kVK_ANSI_9 = 0x19, - kVK_ANSI_7 = 0x1A, - kVK_ANSI_Minus = 0x1B, - kVK_ANSI_8 = 0x1C, - kVK_ANSI_0 = 0x1D, - kVK_ANSI_RightBracket = 0x1E, - kVK_ANSI_O = 0x1F, - kVK_ANSI_U = 0x20, - kVK_ANSI_LeftBracket = 0x21, - kVK_ANSI_I = 0x22, - kVK_ANSI_P = 0x23, - kVK_ANSI_L = 0x25, - kVK_ANSI_J = 0x26, - kVK_ANSI_Quote = 0x27, - kVK_ANSI_K = 0x28, - kVK_ANSI_Semicolon = 0x29, - kVK_ANSI_Backslash = 0x2A, - kVK_ANSI_Comma = 0x2B, - kVK_ANSI_Slash = 0x2C, - kVK_ANSI_N = 0x2D, - kVK_ANSI_M = 0x2E, - kVK_ANSI_Period = 0x2F, - kVK_ANSI_Grave = 0x32, - kVK_ANSI_KeypadDecimal = 0x41, - kVK_ANSI_KeypadMultiply = 0x43, - kVK_ANSI_KeypadPlus = 0x45, - kVK_ANSI_KeypadClear = 0x47, - kVK_ANSI_KeypadDivide = 0x4B, - kVK_ANSI_KeypadEnter = 0x4C, - kVK_ANSI_KeypadMinus = 0x4E, - kVK_ANSI_KeypadEquals = 0x51, - kVK_ANSI_Keypad0 = 0x52, - kVK_ANSI_Keypad1 = 0x53, - kVK_ANSI_Keypad2 = 0x54, - kVK_ANSI_Keypad3 = 0x55, - kVK_ANSI_Keypad4 = 0x56, - kVK_ANSI_Keypad5 = 0x57, - kVK_ANSI_Keypad6 = 0x58, - kVK_ANSI_Keypad7 = 0x59, - kVK_ANSI_Keypad8 = 0x5B, - kVK_ANSI_Keypad9 = 0x5C -}; - -/* keycodes for keys that are independent of keyboard layout*/ -enum { - kVK_Return = 0x24, - kVK_Tab = 0x30, - kVK_Space = 0x31, - kVK_Delete = 0x33, - kVK_Escape = 0x35, - kVK_Command = 0x37, - kVK_Shift = 0x38, - kVK_CapsLock = 0x39, - kVK_Option = 0x3A, - kVK_Control = 0x3B, - kVK_RightShift = 0x3C, - kVK_RightOption = 0x3D, - kVK_RightControl = 0x3E, - kVK_Function = 0x3F, - kVK_F17 = 0x40, - kVK_VolumeUp = 0x48, - kVK_VolumeDown = 0x49, - kVK_Mute = 0x4A, - kVK_F18 = 0x4F, - kVK_F19 = 0x50, - kVK_F20 = 0x5A, - kVK_F5 = 0x60, - kVK_F6 = 0x61, - kVK_F7 = 0x62, - kVK_F3 = 0x63, - kVK_F8 = 0x64, - kVK_F9 = 0x65, - kVK_F11 = 0x67, - kVK_F13 = 0x69, - kVK_F16 = 0x6A, - kVK_F14 = 0x6B, - kVK_F10 = 0x6D, - kVK_F12 = 0x6F, - kVK_F15 = 0x71, - kVK_Help = 0x72, - kVK_Home = 0x73, - kVK_PageUp = 0x74, - kVK_ForwardDelete = 0x75, - kVK_F4 = 0x76, - kVK_End = 0x77, - kVK_F2 = 0x78, - kVK_PageDown = 0x79, - kVK_F1 = 0x7A, - kVK_LeftArrow = 0x7B, - kVK_RightArrow = 0x7C, - kVK_DownArrow = 0x7D, - kVK_UpArrow = 0x7E -}; - -static char g_keycodeCharUnshifted[256] = {}; -static char g_keycodeCharShifted[256] = {}; - -//static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_mouseWheelX = 0.0f; -static float g_mouseWheelY = 0.0f; - -static GLuint g_FontTexture = 0; -static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; -static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; -static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; -static size_t g_VboSize = 0; -static unsigned int g_VboHandle = 0, g_VaoHandle = 0; -static float g_displayScale; - -static int usynergy_sockfd; -static bool g_synergyPtrActive = false; -static uint16_t g_mousePosX = 0; -static uint16_t g_mousePosY = 0; - -static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); -bool ImGui_ImplIOS_CreateDeviceObjects(); - -static NSString *g_serverName; - -uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) -{ - // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since - // uSynergy does not support SSL. - - NSLog( @"Connect Func!"); - struct addrinfo hints, *res; - - // first, load up address structs with getaddrinfo(): - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever - hints.ai_socktype = SOCK_STREAM; - - // get server address - getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); - - if (!res) - { - NSLog( @"Could not find server: %@", g_serverName ); - return USYNERGY_FALSE; - } - - // make a socket: - usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - - // connect it to the address and port we passed in to getaddrinfo(): - int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); - if (!ret) { - NSLog( @"Connect suceeded..."); - } else { - NSLog( @"Connect failed, %d", ret ); - } - - - return USYNERGY_TRUE; -} - -uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) -{ -// NSLog( @"Send Func" ); - send( usynergy_sockfd, buffer, length, 0 ); - - return USYNERGY_TRUE; -} - -uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) -{ - *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); - - return USYNERGY_TRUE; -} - -void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) -{ - usleep( timeMs * 1000 ); -} - -uint32_t ImGui_GetTimeFunc() -{ - struct timeval tv; - gettimeofday(&tv, NULL); - - return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); -} - -void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) -{ - puts(text); -} - -void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) -{ - g_synergyPtrActive = active; -// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); -} - -void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, - uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) -{ -// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); - uSynergyContext *ctx = (uSynergyContext*)cookie; - g_mousePosX = x; - g_mousePosY = y; - g_mouseWheelX = wheelX; - g_mouseWheelY = wheelY; - g_MousePressed[0] = buttonLeft; - g_MousePressed[1] = buttonMiddle; - g_MousePressed[2] = buttonRight; - - ctx->m_mouseWheelX = 0; - ctx->m_mouseWheelY = 0; -} - -void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, - uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) -{ - int scanCode = key-1; -// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); - ImGuiIO& io = ImGui::GetIO(); - io.KeysDown[key] = down; - io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); - io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); - io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); - io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); - - // Add this as keyboard input - if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) - { - // If this key maps to a character input, apply it - int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; - io.AddInputCharacter((unsigned short)charForKeycode); - } - -} - -void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) -{ - printf("Synergy: joystick callback TODO\n"); -} - -void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) -{ - printf("Synergy: clipboard callback TODO\n" ); -} - - -@interface ImGuiHelper () -{ - BOOL _mouseDown; - BOOL _mouseTapped; - CGPoint _touchPos; - - uSynergyContext _synergyCtx; - dispatch_queue_t _synergyQueue; -} -@property (nonatomic, weak) UIView *view; -@property (nonatomic, strong) NSString *serverName; - -@end - -@implementation ImGuiHelper - -- (id) initWithView: (UIView *)view -{ - self = [super init]; - if (self) - { - self.view = view; - - [self setupImGuiHooks]; - } - return self; -} - -- (void)setupKeymaps -{ - // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, - // but this was the best I could come up with. There are some device independent API's available - // to convert scan codes to unicode characters, but these are only available on mac and not - // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do - // this or any way to get the character codes out of usynergy. - g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; - g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; - g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; - g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; - g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; - g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; - g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; - g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; - g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; - g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; - g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; - g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; - g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; - g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; - g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; - g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; - g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; - g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; - g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; - g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; - g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; - g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; - g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; - g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; - g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; - g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; - g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; - g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; - g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; - g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; - g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; - g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; - g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; - g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; - g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; - g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; - g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; - g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; - g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; - g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; - g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; - g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; - g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; - g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; - g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; - g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; - g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; - g_keycodeCharUnshifted[ kVK_Space ]=' '; - - g_keycodeCharShifted[ kVK_ANSI_A ]='A'; - g_keycodeCharShifted[ kVK_ANSI_S ]='S'; - g_keycodeCharShifted[ kVK_ANSI_D ]='D'; - g_keycodeCharShifted[ kVK_ANSI_F ]='F'; - g_keycodeCharShifted[ kVK_ANSI_H ]='H'; - g_keycodeCharShifted[ kVK_ANSI_G ]='G'; - g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; - g_keycodeCharShifted[ kVK_ANSI_X ]='X'; - g_keycodeCharShifted[ kVK_ANSI_C ]='C'; - g_keycodeCharShifted[ kVK_ANSI_V ]='V'; - g_keycodeCharShifted[ kVK_ANSI_B ]='B'; - g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; - g_keycodeCharShifted[ kVK_ANSI_W ]='W'; - g_keycodeCharShifted[ kVK_ANSI_E ]='E'; - g_keycodeCharShifted[ kVK_ANSI_R ]='R'; - g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; - g_keycodeCharShifted[ kVK_ANSI_T ]='T'; - g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; - g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; - g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; - g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; - g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; - g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; - g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; - g_keycodeCharShifted[ kVK_ANSI_9 ]='('; - g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; - g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; - g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; - g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; - g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; - g_keycodeCharShifted[ kVK_ANSI_O ]='O'; - g_keycodeCharShifted[ kVK_ANSI_U ]='U'; - g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; - g_keycodeCharShifted[ kVK_ANSI_I ]='I'; - g_keycodeCharShifted[ kVK_ANSI_P ]='P'; - g_keycodeCharShifted[ kVK_ANSI_L ]='L'; - g_keycodeCharShifted[ kVK_ANSI_J ]='J'; - g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; - g_keycodeCharShifted[ kVK_ANSI_K ]='K'; - g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; - g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; - g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; - g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; - g_keycodeCharShifted[ kVK_ANSI_N ]='N'; - g_keycodeCharShifted[ kVK_ANSI_M ]='M'; - g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; - g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; - g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; - g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; - g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; - g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; - g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; - g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; - g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; - g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; - g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; - g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; - g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; - g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; - g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; - g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; - g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; - g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; - g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; - g_keycodeCharShifted[ kVK_Space ]=' '; -} - -- (void)setupImGuiHooks -{ - ImGuiIO &io = ImGui::GetIO(); - - [self setupKeymaps]; - - // Account for retina display for glScissor - g_displayScale = [[UIScreen mainScreen] scale]; - - ImGuiStyle &style = ImGui::GetStyle(); - style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); - - io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; - - UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; - [self.view addGestureRecognizer:panRecognizer]; - - UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; - [self.view addGestureRecognizer:tapRecoginzer]; - - // Fill out the Synergy key map - // (for some reason synergy scan codes are off by 1) - io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; - io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; - io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; - io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; - io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; - io.KeyMap[ImGuiKey_Home] = kVK_Home+1; - io.KeyMap[ImGuiKey_End] = kVK_End+1; - io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; - io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; - io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; - io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; - io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; - io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; - io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; - io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; - io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; - io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; -} - -- (void)connectServer: (NSString*)serverName -{ - self.serverName = serverName; - g_serverName = serverName; - - // Init synergy - NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; - - uSynergyInit( &_synergyCtx ); - _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); - _synergyCtx.m_clientWidth = self.view.bounds.size.width; - _synergyCtx.m_clientHeight = self.view.bounds.size.height; - - _synergyCtx.m_connectFunc = ImGui_ConnectFunc; - _synergyCtx.m_sendFunc = ImGui_SendFunc; - _synergyCtx.m_receiveFunc = ImGui_RecvFunc; - _synergyCtx.m_sleepFunc = ImGui_SleepFunc; - _synergyCtx.m_traceFunc = ImGui_TraceFunc; - _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; - - _synergyCtx.m_traceFunc = ImGui_TraceFunc; - _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; - _synergyCtx.m_mouseCallback = ImGui_MouseCallback; - _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; - - _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; - - // Create a background thread for synergy - _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); - dispatch_async( _synergyQueue, ^{ - while (1) { - uSynergyUpdate( &_synergyCtx ); - } - }); -} - - -- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer -{ - - if ((recognizer.state == UIGestureRecognizerStateBegan) || - (recognizer.state == UIGestureRecognizerStateChanged)) - { - _mouseDown = YES; - _touchPos = [recognizer locationInView:self.view]; - } - else - { - _mouseDown = NO; - _touchPos = CGPointMake( -1, -1 ); - } -} - -- (void)viewDidTap: (UITapGestureRecognizer*)recognizer -{ - _touchPos = [recognizer locationInView:self.view]; - _mouseTapped = YES; -} - -- (void)render -{ - ImGui::Render(); -} - -- (void)newFrame -{ - ImGuiIO& io = ImGui::GetIO(); - ImGuiStyle &style = ImGui::GetStyle(); - - if (!g_FontTexture) - { - ImGui_ImplIOS_CreateDeviceObjects(); - } - - io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); - - io.MouseDrawCursor = g_synergyPtrActive; - if (g_synergyPtrActive) - { - style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); - io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); - for (int i=0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i]; - } - - // This is an arbitrary scaling factor that works for me. Not sure what units these - // mousewheel values from synergy are supposed to be in - io.MouseWheel = g_mouseWheelY / 500.0; - } - else - { - // Synergy not active, use touch events - style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); - io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); - if ((_mouseDown) || (_mouseTapped)) - { - io.MouseDown[0] = true; - _mouseTapped = NO; - } - else - { - io.MouseDown[0] = false; - } - } - - ImGui::NewFrame(); -} -@end - -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES -static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) -{ - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled - GLint last_program, last_texture; - glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - // Setup orthographic projection matrix - const float width = ImGui::GetIO().DisplaySize.x; - const float height = ImGui::GetIO().DisplaySize.y; - const float ortho_projection[4][4] = - { - { 2.0f/width, 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f/-height, 0.0f, 0.0f }, - { 0.0f, 0.0f, -1.0f, 0.0f }, - { -1.0f, 1.0f, 0.0f, 1.0f }, - }; - glUseProgram(g_ShaderHandle); - glUniform1i(g_AttribLocationTex, 0); - glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - glBindVertexArray(g_VaoHandle); - - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - ImDrawList* cmd_list = draw_data->CmdLists[n]; - ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); - if (g_VboSize < needed_vtx_size) - { - // Grow our buffer if needed - g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); - } - - unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - if (!vtx_data) - continue; - memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); - glUnmapBuffer(GL_ARRAY_BUFFER); - - for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) - { - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)(pcmd->ClipRect.x * g_displayScale), - (int)((height - pcmd->ClipRect.w) * g_displayScale), - (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), - (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); - glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); - } - idx_buffer += pcmd->ElemCount; - } - } - - // Restore modified state - glBindVertexArray(0); - glBindBuffer( GL_ARRAY_BUFFER, 0); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - glUseProgram(last_program); - glDisable(GL_SCISSOR_TEST); - glBindTexture(GL_TEXTURE_2D, last_texture); -} - -void ImGui_ImplIOS_CreateFontsTexture() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); -} - -bool ImGui_ImplIOS_CreateDeviceObjects() -{ - const GLchar *vertex_shader = - "uniform mat4 ProjMtx;\n" - "attribute highp vec2 Position;\n" - "attribute highp vec2 UV;\n" - "attribute highp vec4 Color;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar* fragment_shader = - "uniform sampler2D Texture;\n" - "varying highp vec2 Frag_UV;\n" - "varying highp vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" - "}\n"; - - g_ShaderHandle = glCreateProgram(); - g_VertHandle = glCreateShader(GL_VERTEX_SHADER); - g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_VertHandle, 1, &vertex_shader, 0); - glShaderSource(g_FragHandle, 1, &fragment_shader, 0); - glCompileShader(g_VertHandle); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); - NSLog(@"VERTEX Shader compile log:\n%s", log); - free(log); - } -#endif - - glCompileShader(g_FragHandle); - -#if defined(DEBUG) - glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); - NSLog(@"FRAGMENT Shader compile log:\n%s", log); - free(log); - } -#endif - - glAttachShader(g_ShaderHandle, g_VertHandle); - glAttachShader(g_ShaderHandle, g_FragHandle); - glLinkProgram(g_ShaderHandle); - - g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); - g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); - g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); - g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); - g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); - - glGenBuffers(1, &g_VboHandle); - - glGenVertexArrays(1, &g_VaoHandle); - glBindVertexArray(g_VaoHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); - -#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); -#undef OFFSETOF - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - ImGui_ImplIOS_CreateFontsTexture(); - - return true; -} diff --git a/examples/apple_example/.gitignore b/examples/apple_example/.gitignore new file mode 100644 index 0000000..8feda89 --- /dev/null +++ b/examples/apple_example/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +imguiex.xcodeproj/project.xcworkspace/ +imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/apple_example/README.md b/examples/apple_example/README.md new file mode 100644 index 0000000..c847f1a --- /dev/null +++ b/examples/apple_example/README.md @@ -0,0 +1,40 @@ +# iOS / OSX example + +## Introduction + +This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). + +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. + +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 + +0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" +0. Run the example app. +0. Tap the "servername" button in the corner +0. Enter the name or the IP of your synergy host +0. If you had previously connected to a server, you may need to kill and re-start the app. + +## How to Run 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 + +Things that would be nice but I didn't get around to doing: + +* iOS software keyboard not supported for text inputs +* iOS hardware (bluetooth) keyboards not supported +* Graceful disconnect/reconnect from uSynergy. +* Copy/Paste not well-supported + +## C++ on iOS / OSX +ImGui is a c++ library. If you want to include it directly, rename your Obj-C file to have the ".mm" extension. + +Alternatively, you can wrap your debug code in a C interface, this is what I am demonstrating here with the "debug_hud.h" interface. Either approach works, use whatever you prefer. + +In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/apple_example/imguiex-ios/AppDelegate.h b/examples/apple_example/imguiex-ios/AppDelegate.h new file mode 100644 index 0000000..82f1542 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.h @@ -0,0 +1,13 @@ +// +// AppDelegate.h +// imguiex + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/examples/apple_example/imguiex-ios/AppDelegate.m b/examples/apple_example/imguiex-ios/AppDelegate.m new file mode 100644 index 0000000..ab83101 --- /dev/null +++ b/examples/apple_example/imguiex-ios/AppDelegate.m @@ -0,0 +1,41 @@ +// +// AppDelegate.m +// imguiex + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..5717c00 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/LaunchScreen.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard new file mode 100644 index 0000000..90dfb2e --- /dev/null +++ b/examples/apple_example/imguiex-ios/Base.lproj/Main.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/apple_example/imguiex-ios/GameViewController.h b/examples/apple_example/imguiex-ios/GameViewController.h new file mode 100644 index 0000000..3323cfd --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.h @@ -0,0 +1,12 @@ +// +// GameViewController.h +// imguiex + +// This is the OpenGL Example template from XCode, modified to support ImGui + +#import +#import + +@interface GameViewController : GLKViewController + +@end diff --git a/examples/apple_example/imguiex-ios/GameViewController.m b/examples/apple_example/imguiex-ios/GameViewController.m new file mode 100644 index 0000000..e902f7a --- /dev/null +++ b/examples/apple_example/imguiex-ios/GameViewController.m @@ -0,0 +1,481 @@ +// +// GameViewController.m +// imguiex +// +#import "GameViewController.h" +#import + +#import "imgui_impl_ios.h" +#import "debug_hud.h" + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +#define SERVERNAME_KEY @"ServerName" + +#define SERVERNAME_ALERT_TAG (10) + +// Uniform index. +enum +{ + UNIFORM_MODELVIEWPROJECTION_MATRIX, + UNIFORM_NORMAL_MATRIX, + UNIFORM_DIFFUSE_COLOR, + + NUM_UNIFORMS +}; +GLint uniforms[NUM_UNIFORMS]; + +// Attribute index. +enum +{ + ATTRIB_VERTEX, + ATTRIB_NORMAL, + NUM_ATTRIBUTES +}; + +GLfloat gCubeVertexData[216] = +{ + // Data layout for each line below is: + // positionX, positionY, positionZ, normalX, normalY, normalZ, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f +}; + +@interface GameViewController () +{ + GLuint _program; + + GLKMatrix4 _modelViewProjectionMatrix; + GLKMatrix3 _normalMatrix; + float _rotation; + + GLuint _vertexArray; + GLuint _vertexBuffer; + + DebugHUD _hud; +} +@property (strong, nonatomic) EAGLContext *context; +@property (strong, nonatomic) GLKBaseEffect *effect; +@property (strong, nonatomic) ImGuiHelper *imgui; +@property (weak, nonatomic) IBOutlet UIButton *btnServername; + +@property (strong, nonatomic) NSString *serverName; + +- (IBAction)onServernameTapped:(id)sender; + +- (void)setupGL; +- (void)tearDownGL; + +- (BOOL)loadShaders; +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; +- (BOOL)linkProgram:(GLuint)prog; +- (BOOL)validateProgram:(GLuint)prog; +@end + +@implementation GameViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + if (!self.context) { + NSLog(@"Failed to create ES context"); + } + + GLKView *view = (GLKView *)self.view; + view.context = self.context; + view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + + [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + + [self setupGL]; + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; + self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; + if (self.serverName) + { + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + [self.imgui connectServer: self.serverName ]; + } + + DebugHUD_InitDefaults( &_hud ); +} + +- (void)dealloc +{ + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + + if ([self isViewLoaded] && ([[self view] window] == nil)) { + self.view = nil; + + [self tearDownGL]; + + if ([EAGLContext currentContext] == self.context) { + [EAGLContext setCurrentContext:nil]; + } + self.context = nil; + } + + // Dispose of any resources that can be recreated. +} + + +- (BOOL)prefersStatusBarHidden { + return YES; +} + +- (IBAction)onServernameTapped:(id)sender +{ + UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; + alert.alertViewStyle = UIAlertViewStylePlainTextInput; + alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to + [alert show]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) + { + // This is really janky. I usually just hardcode the servername since I'm building it anyway. + // If you want to properly handle updating the server, you'll want to tear down and recreate + // the usynergy stuff in connectServer + BOOL serverNameWasSet = self.serverName.length > 0; + NSString *serverName = [[alertView textFieldAtIndex:0] text]; + + if ([serverName length] > 0) { + self.serverName = serverName; + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; + [userDefaults synchronize]; + + [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; + + // If we hadn't previously connected, try now + if (!serverNameWasSet) { + [self.imgui connectServer:self.serverName]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" + message:@"Restart the app to connect the server" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; + [alert show]; + } + } + } +} + +- (void)setupGL +{ + [EAGLContext setCurrentContext:self.context]; + + [self loadShaders]; + + self.effect = [[GLKBaseEffect alloc] init]; + self.effect.light0.enabled = GL_TRUE; + self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); + + glEnable(GL_DEPTH_TEST); + + glGenVertexArraysOES(1, &_vertexArray); + glBindVertexArrayOES(_vertexArray); + + glGenBuffers(1, &_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(GLKVertexAttribPosition); + glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(GLKVertexAttribNormal); + glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); + + glBindVertexArrayOES(0); + + +} + +- (void)tearDownGL +{ + [EAGLContext setCurrentContext:self.context]; + + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArraysOES(1, &_vertexArray); + + self.effect = nil; + + if (_program) { + glDeleteProgram(_program); + _program = 0; + } +} + +#pragma mark - GLKView and GLKViewController delegate methods + +- (void)update +{ + float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); + GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); + + self.effect.transform.projectionMatrix = projectionMatrix; + + GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); + baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); + + // Compute the model view matrix for the object rendered with GLKit + GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + self.effect.transform.modelviewMatrix = modelViewMatrix; + + // Compute the model view matrix for the object rendered with ES2 + modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); + modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); + modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); + + _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); + + _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); + + _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); +} + + +- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect +{ + glClearColor(0.65f, 0.65f, 0.65f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArrayOES(_vertexArray); + + // Render the object with GLKit + [self.effect prepareToDraw]; + + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Render the object again with ES2 + glUseProgram(_program); + + glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); + glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); + glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); + + glDrawArrays(GL_TRIANGLES, 0, 36); + + [self.imgui newFrame]; + + // Now do our ImGUI UI + DebugHUD_DoInterface( &_hud ); + + self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); + + // Now render Imgui + [self.imgui render]; + +} + +#pragma mark - OpenGL ES 2 shader compilation + +- (BOOL)loadShaders +{ + GLuint vertShader, fragShader; + NSString *vertShaderPathname, *fragShaderPathname; + + // Create shader program. + _program = glCreateProgram(); + + // Create and compile vertex shader. + vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; + if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { + NSLog(@"Failed to compile vertex shader"); + return NO; + } + + // Create and compile fragment shader. + fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; + if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { + NSLog(@"Failed to compile fragment shader"); + return NO; + } + + // Attach vertex shader to program. + glAttachShader(_program, vertShader); + + // Attach fragment shader to program. + glAttachShader(_program, fragShader); + + // Bind attribute locations. + // This needs to be done prior to linking. + glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); + glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); + + // Link program. + if (![self linkProgram:_program]) { + NSLog(@"Failed to link program: %d", _program); + + if (vertShader) { + glDeleteShader(vertShader); + vertShader = 0; + } + if (fragShader) { + glDeleteShader(fragShader); + fragShader = 0; + } + if (_program) { + glDeleteProgram(_program); + _program = 0; + } + + return NO; + } + + // Get uniform locations. + uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); + uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); + uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); + + // Release vertex and fragment shaders. + if (vertShader) { + glDetachShader(_program, vertShader); + glDeleteShader(vertShader); + } + if (fragShader) { + glDetachShader(_program, fragShader); + glDeleteShader(fragShader); + } + + return YES; +} + +- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file +{ + GLint status; + const GLchar *source; + + source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; + if (!source) { + NSLog(@"Failed to load vertex shader"); + return NO; + } + + *shader = glCreateShader(type); + glShaderSource(*shader, 1, &source, NULL); + glCompileShader(*shader); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + NSLog(@"Shader compile log:\n%s", log); + free(log); + } +#endif + + glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + if (status == 0) { + glDeleteShader(*shader); + return NO; + } + + return YES; +} + +- (BOOL)linkProgram:(GLuint)prog +{ + GLint status; + glLinkProgram(prog); + +#if defined(DEBUG) + GLint logLength; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program link log:\n%s", log); + free(log); + } +#endif + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +- (BOOL)validateProgram:(GLuint)prog +{ + GLint logLength, status; + + glValidateProgram(prog); + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetProgramInfoLog(prog, logLength, &logLength, log); + NSLog(@"Program validate log:\n%s", log); + free(log); + } + + glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); + if (status == 0) { + return NO; + } + + return YES; +} + +@end diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..06b60d8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,77 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@2x~iphone.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_imgui_60@3x~iphone.png", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76~ipad.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_imgui_76@2x~ipad.png", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png new file mode 100644 index 0000000..d728bc3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png new file mode 100644 index 0000000..67b08b8 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png new file mode 100644 index 0000000..ae88e04 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/Info.plist b/examples/apple_example/imguiex-ios/Info.plist new file mode 100644 index 0000000..bc6f548 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.fsh b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh new file mode 100644 index 0000000..4000524 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.fsh @@ -0,0 +1,10 @@ +// +// Shader.fsh +// imguiex + +varying lowp vec4 colorVarying; + +void main() +{ + gl_FragColor = colorVarying; +} diff --git a/examples/apple_example/imguiex-ios/Shaders/Shader.vsh b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh new file mode 100644 index 0000000..313c3d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/Shaders/Shader.vsh @@ -0,0 +1,25 @@ +// +// Shader.vsh +// imguiex + +attribute vec4 position; +attribute vec3 normal; + +varying lowp vec4 colorVarying; + +uniform vec3 diffuseColor; +uniform mat4 modelViewProjectionMatrix; +uniform mat3 normalMatrix; + +void main() +{ + vec3 eyeNormal = normalize(normalMatrix * normal); + vec3 lightPosition = vec3(0.0, 0.0, 1.0); + + float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); + + vec3 colorLit = diffuseColor * nDotVP; + colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); + + gl_Position = modelViewProjectionMatrix * position; +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.cpp b/examples/apple_example/imguiex-ios/debug_hud.cpp new file mode 100644 index 0000000..c75938a --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.cpp @@ -0,0 +1,45 @@ +// +// debug_hud.cpp +// imguiex + +#include + +#include "debug_hud.h" +#include "imgui.h" + +void DebugHUD_InitDefaults( DebugHUD *hud ) +{ + hud->show_test_window = true; + hud->show_example_window = true; + hud->rotation_speed = 15.0f; + + hud->cubeColor1[0] = 0.4f; + hud->cubeColor1[1] = 0.4f; + hud->cubeColor1[2] = 1.0f; + hud->cubeColor1[3] = 1.0f; + + hud->cubeColor2[0] = 1.0f; + hud->cubeColor2[1] = 0.4f; + hud->cubeColor2[2] = 0.4f; + hud->cubeColor2[3] = 1.0f; +} + +void DebugHUD_DoInterface( DebugHUD *hud ) +{ + if (hud->show_test_window) + { + ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::ShowTestWindow( &hud->show_test_window ); + } + + if (hud->show_example_window) + { + ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); + ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); + ImGui::Begin("Another Window", &hud->show_example_window); + ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); + ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); + ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); + ImGui::End(); + } +} diff --git a/examples/apple_example/imguiex-ios/debug_hud.h b/examples/apple_example/imguiex-ios/debug_hud.h new file mode 100644 index 0000000..17122f5 --- /dev/null +++ b/examples/apple_example/imguiex-ios/debug_hud.h @@ -0,0 +1,25 @@ +// +// debug_hud.h +// imguiex + +#pragma once + +typedef struct DebugHUD +{ + bool show_test_window; + bool show_example_window; + float rotation_speed; + float cubeColor1[4]; + float cubeColor2[4]; +} DebugHUD; + +#if __cplusplus +extern "C" { +#endif + +void DebugHUD_InitDefaults( DebugHUD *hud ); +void DebugHUD_DoInterface( DebugHUD *hud ); + +#if __cplusplus +} +#endif diff --git a/examples/apple_example/imguiex-ios/imgui_ex_icon.png b/examples/apple_example/imguiex-ios/imgui_ex_icon.png new file mode 100644 index 0000000..820e4d7 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_ex_icon.png Binary files differ diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.h b/examples/apple_example/imguiex-ios/imgui_impl_ios.h new file mode 100644 index 0000000..9b01dd3 --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.h @@ -0,0 +1,22 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +// by Joel Davis (joeld42@gmail.com) + +#pragma once + +#include +#include + +@interface ImGuiHelper : NSObject + +- (id) initWithView: (UIView *)view; + +- (void)connectServer: (NSString*)serverName; + +- (void)render; +- (void)newFrame; + +@end diff --git a/examples/apple_example/imguiex-ios/imgui_impl_ios.mm b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm new file mode 100644 index 0000000..b286c4d --- /dev/null +++ b/examples/apple_example/imguiex-ios/imgui_impl_ios.mm @@ -0,0 +1,803 @@ +// ImGui iOS+OpenGL+Synergy binding +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. +// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. + +#import +#import + +#include +#include +#include +#include + +#include "imgui_impl_ios.h" +#include "imgui.h" + +#include "uSynergy.h" + +// From Carbon HIToolbox/Events.h +// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +static char g_keycodeCharUnshifted[256] = {}; +static char g_keycodeCharShifted[256] = {}; + +//static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_mouseWheelX = 0.0f; +static float g_mouseWheelY = 0.0f; + +static GLuint g_FontTexture = 0; +static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; +static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; +static size_t g_VboSize = 0; +static unsigned int g_VboHandle = 0, g_VaoHandle = 0; +static float g_displayScale; + +static int usynergy_sockfd; +static bool g_synergyPtrActive = false; +static uint16_t g_mousePosX = 0; +static uint16_t g_mousePosY = 0; + +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); +bool ImGui_ImplIOS_CreateDeviceObjects(); + +static NSString *g_serverName; + +uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) +{ + // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since + // uSynergy does not support SSL. + + NSLog( @"Connect Func!"); + struct addrinfo hints, *res; + + // first, load up address structs with getaddrinfo(): + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + hints.ai_socktype = SOCK_STREAM; + + // get server address + getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); + + if (!res) + { + NSLog( @"Could not find server: %@", g_serverName ); + return USYNERGY_FALSE; + } + + // make a socket: + usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + // connect it to the address and port we passed in to getaddrinfo(): + int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); + if (!ret) { + NSLog( @"Connect suceeded..."); + } else { + NSLog( @"Connect failed, %d", ret ); + } + + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) +{ +// NSLog( @"Send Func" ); + send( usynergy_sockfd, buffer, length, 0 ); + + return USYNERGY_TRUE; +} + +uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) +{ + *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); + + return USYNERGY_TRUE; +} + +void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) +{ + usleep( timeMs * 1000 ); +} + +uint32_t ImGui_GetTimeFunc() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); +} + +void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) +{ + puts(text); +} + +void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) +{ + g_synergyPtrActive = active; +// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); +} + +void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, + uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) +{ +// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); + uSynergyContext *ctx = (uSynergyContext*)cookie; + g_mousePosX = x; + g_mousePosY = y; + g_mouseWheelX = wheelX; + g_mouseWheelY = wheelY; + g_MousePressed[0] = buttonLeft; + g_MousePressed[1] = buttonMiddle; + g_MousePressed[2] = buttonRight; + + ctx->m_mouseWheelX = 0; + ctx->m_mouseWheelY = 0; +} + +void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, + uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) +{ + int scanCode = key-1; +// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[key] = down; + io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); + io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); + io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); + io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); + + // Add this as keyboard input + if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) + { + // If this key maps to a character input, apply it + int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; + io.AddInputCharacter((unsigned short)charForKeycode); + } + +} + +void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) +{ + printf("Synergy: joystick callback TODO\n"); +} + +void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) +{ + printf("Synergy: clipboard callback TODO\n" ); +} + + +@interface ImGuiHelper () +{ + BOOL _mouseDown; + BOOL _mouseTapped; + CGPoint _touchPos; + + uSynergyContext _synergyCtx; + dispatch_queue_t _synergyQueue; +} +@property (nonatomic, weak) UIView *view; +@property (nonatomic, strong) NSString *serverName; + +@end + +@implementation ImGuiHelper + +- (id) initWithView: (UIView *)view +{ + self = [super init]; + if (self) + { + self.view = view; + + [self setupImGuiHooks]; + } + return self; +} + +- (void)setupKeymaps +{ + // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, + // but this was the best I could come up with. There are some device independent API's available + // to convert scan codes to unicode characters, but these are only available on mac and not + // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do + // this or any way to get the character codes out of usynergy. + g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; + g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; + g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; + g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; + g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; + g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; + g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; + g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; + g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; + g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; + g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; + g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; + g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; + g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; + g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; + g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; + g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; + g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; + g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; + g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; + g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; + g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; + g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; + g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; + g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; + g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; + g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; + g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; + g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; + g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; + g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; + g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; + g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; + g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharUnshifted[ kVK_Space ]=' '; + + g_keycodeCharShifted[ kVK_ANSI_A ]='A'; + g_keycodeCharShifted[ kVK_ANSI_S ]='S'; + g_keycodeCharShifted[ kVK_ANSI_D ]='D'; + g_keycodeCharShifted[ kVK_ANSI_F ]='F'; + g_keycodeCharShifted[ kVK_ANSI_H ]='H'; + g_keycodeCharShifted[ kVK_ANSI_G ]='G'; + g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; + g_keycodeCharShifted[ kVK_ANSI_X ]='X'; + g_keycodeCharShifted[ kVK_ANSI_C ]='C'; + g_keycodeCharShifted[ kVK_ANSI_V ]='V'; + g_keycodeCharShifted[ kVK_ANSI_B ]='B'; + g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; + g_keycodeCharShifted[ kVK_ANSI_W ]='W'; + g_keycodeCharShifted[ kVK_ANSI_E ]='E'; + g_keycodeCharShifted[ kVK_ANSI_R ]='R'; + g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; + g_keycodeCharShifted[ kVK_ANSI_T ]='T'; + g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; + g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; + g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; + g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; + g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; + g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; + g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; + g_keycodeCharShifted[ kVK_ANSI_9 ]='('; + g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; + g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; + g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; + g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; + g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; + g_keycodeCharShifted[ kVK_ANSI_O ]='O'; + g_keycodeCharShifted[ kVK_ANSI_U ]='U'; + g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; + g_keycodeCharShifted[ kVK_ANSI_I ]='I'; + g_keycodeCharShifted[ kVK_ANSI_P ]='P'; + g_keycodeCharShifted[ kVK_ANSI_L ]='L'; + g_keycodeCharShifted[ kVK_ANSI_J ]='J'; + g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; + g_keycodeCharShifted[ kVK_ANSI_K ]='K'; + g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; + g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; + g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; + g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; + g_keycodeCharShifted[ kVK_ANSI_N ]='N'; + g_keycodeCharShifted[ kVK_ANSI_M ]='M'; + g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; + g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; + g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; + g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; + g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; + g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; + g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; + g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; + g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; + g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; + g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; + g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; + g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; + g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; + g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; + g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; + g_keycodeCharShifted[ kVK_Space ]=' '; +} + +- (void)setupImGuiHooks +{ + ImGuiIO &io = ImGui::GetIO(); + + [self setupKeymaps]; + + // Account for retina display for glScissor + g_displayScale = [[UIScreen mainScreen] scale]; + + ImGuiStyle &style = ImGui::GetStyle(); + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + + io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; + + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; + [self.view addGestureRecognizer:panRecognizer]; + + UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; + [self.view addGestureRecognizer:tapRecoginzer]; + + // Fill out the Synergy key map + // (for some reason synergy scan codes are off by 1) + io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; + io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; + io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; + io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; + io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; + io.KeyMap[ImGuiKey_Home] = kVK_Home+1; + io.KeyMap[ImGuiKey_End] = kVK_End+1; + io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; + io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; + io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; + io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; + io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; + io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; + io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; + io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; + io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; + io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; +} + +- (void)connectServer: (NSString*)serverName +{ + self.serverName = serverName; + g_serverName = serverName; + + // Init synergy + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; + + uSynergyInit( &_synergyCtx ); + _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); + _synergyCtx.m_clientWidth = self.view.bounds.size.width; + _synergyCtx.m_clientHeight = self.view.bounds.size.height; + + _synergyCtx.m_connectFunc = ImGui_ConnectFunc; + _synergyCtx.m_sendFunc = ImGui_SendFunc; + _synergyCtx.m_receiveFunc = ImGui_RecvFunc; + _synergyCtx.m_sleepFunc = ImGui_SleepFunc; + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; + + _synergyCtx.m_traceFunc = ImGui_TraceFunc; + _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; + _synergyCtx.m_mouseCallback = ImGui_MouseCallback; + _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; + + _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; + + // Create a background thread for synergy + _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); + dispatch_async( _synergyQueue, ^{ + while (1) { + uSynergyUpdate( &_synergyCtx ); + } + }); +} + + +- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer +{ + + if ((recognizer.state == UIGestureRecognizerStateBegan) || + (recognizer.state == UIGestureRecognizerStateChanged)) + { + _mouseDown = YES; + _touchPos = [recognizer locationInView:self.view]; + } + else + { + _mouseDown = NO; + _touchPos = CGPointMake( -1, -1 ); + } +} + +- (void)viewDidTap: (UITapGestureRecognizer*)recognizer +{ + _touchPos = [recognizer locationInView:self.view]; + _mouseTapped = YES; +} + +- (void)render +{ + ImGui::Render(); +} + +- (void)newFrame +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle &style = ImGui::GetStyle(); + + if (!g_FontTexture) + { + ImGui_ImplIOS_CreateDeviceObjects(); + } + + io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); + + io.MouseDrawCursor = g_synergyPtrActive; + if (g_synergyPtrActive) + { + style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); + io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); + for (int i=0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i]; + } + + // This is an arbitrary scaling factor that works for me. Not sure what units these + // mousewheel values from synergy are supposed to be in + io.MouseWheel = g_mouseWheelY / 500.0; + } + else + { + // Synergy not active, use touch events + style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); + io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); + if ((_mouseDown) || (_mouseTapped)) + { + io.MouseDown[0] = true; + _mouseTapped = NO; + } + else + { + io.MouseDown[0] = false; + } + } + + ImGui::NewFrame(); +} +@end + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES +static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + GLint last_program, last_texture; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Setup orthographic projection matrix + const float width = ImGui::GetIO().DisplaySize.x; + const float height = ImGui::GetIO().DisplaySize.y; + const float ortho_projection[4][4] = + { + { 2.0f/width, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-height, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + ImDrawList* cmd_list = draw_data->CmdLists[n]; + ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) + { + // Grow our buffer if needed + g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); + } + + unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + if (!vtx_data) + continue; + memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + glUnmapBuffer(GL_ARRAY_BUFFER); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) + { + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)(pcmd->ClipRect.x * g_displayScale), + (int)((height - pcmd->ClipRect.w) * g_displayScale), + (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), + (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); + glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); + } + idx_buffer += pcmd->ElemCount; + } + } + + // Restore modified state + glBindVertexArray(0); + glBindBuffer( GL_ARRAY_BUFFER, 0); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glUseProgram(last_program); + glDisable(GL_SCISSOR_TEST); + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +void ImGui_ImplIOS_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); +} + +bool ImGui_ImplIOS_CreateDeviceObjects() +{ + const GLchar *vertex_shader = + "uniform mat4 ProjMtx;\n" + "attribute highp vec2 Position;\n" + "attribute highp vec2 UV;\n" + "attribute highp vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "uniform sampler2D Texture;\n" + "varying highp vec2 Frag_UV;\n" + "varying highp vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + +#if defined(DEBUG) + GLint logLength; + glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); + NSLog(@"VERTEX Shader compile log:\n%s", log); + free(log); + } +#endif + + glCompileShader(g_FragHandle); + +#if defined(DEBUG) + glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) { + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); + NSLog(@"FRAGMENT Shader compile log:\n%s", log); + free(log); + } +#endif + + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ImGui_ImplIOS_CreateFontsTexture(); + + return true; +} diff --git a/examples/apple_example/imguiex-ios/main.m b/examples/apple_example/imguiex-ios/main.m new file mode 100644 index 0000000..faba099 --- /dev/null +++ b/examples/apple_example/imguiex-ios/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/apple_example/imguiex-osx/AppDelegate.h b/examples/apple_example/imguiex-osx/AppDelegate.h new file mode 100644 index 0000000..33d199b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/examples/apple_example/imguiex-osx/AppDelegate.m b/examples/apple_example/imguiex-osx/AppDelegate.m new file mode 100644 index 0000000..59e877b --- /dev/null +++ b/examples/apple_example/imguiex-osx/AppDelegate.m @@ -0,0 +1,26 @@ +// +// AppDelegate.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b13908f --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,64 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "icon_imgui_180x180.png", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png new file mode 100644 index 0000000..f48b799 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/AppIcon.appiconset/icon_imgui_180x180.png Binary files differ diff --git a/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/examples/apple_example/imguiex-osx/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/apple_example/imguiex-osx/Info.plist b/examples/apple_example/imguiex-osx/Info.plist new file mode 100644 index 0000000..ba1c2bb --- /dev/null +++ b/examples/apple_example/imguiex-osx/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2016 Joel Davis. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/apple_example/imguiex-osx/main.m b/examples/apple_example/imguiex-osx/main.m new file mode 100644 index 0000000..20b0731 --- /dev/null +++ b/examples/apple_example/imguiex-osx/main.m @@ -0,0 +1,13 @@ +// +// main.m +// imguiex-osx +// +// Created by James Chen on 4/5/16. +// Copyright © 2016 Joel Davis. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/apple_example/imguiex.xcodeproj/project.pbxproj b/examples/apple_example/imguiex.xcodeproj/project.pbxproj new file mode 100644 index 0000000..652d15b --- /dev/null +++ b/examples/apple_example/imguiex.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F221CB39FB50090F036 /* AppDelegate.m */; }; + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A1A0F271CB39FB50090F036 /* Assets.xcassets */; }; + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F391CB3A1B20090F036 /* main.cpp */; }; + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */; }; + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */; }; + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; + 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; +/* End PBXBuildFile 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 = ""; }; + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-osx.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A1A0F2C1CB39FB50090F036 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_impl_glfw.cpp; sourceTree = ""; }; + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_glfw.h; sourceTree = ""; }; + 1A1A0F391CB3A1B20090F036 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libglfw3.dylib; path = /usr/local/lib/libglfw3.dylib; sourceTree = ""; }; + 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; + 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "imguiex-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; + 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; + 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; + 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; + 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; + 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; + 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1A1A0F1C1CB39FB50090F036 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F4E1CB3C54D0090F036 /* libglfw3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5511B2E632000C130BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, + 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1A1A0F201CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXGroup; + children = ( + 1A1A0F4D1CB3C54D0090F036 /* libglfw3.dylib */, + 1A1A0F351CB3A1B20090F036 /* opengl_example */, + 1A1A0F211CB39FB50090F036 /* AppDelegate.h */, + 1A1A0F221CB39FB50090F036 /* AppDelegate.m */, + 1A1A0F271CB39FB50090F036 /* Assets.xcassets */, + 1A1A0F2C1CB39FB50090F036 /* Info.plist */, + 1A1A0F241CB39FB50090F036 /* Supporting Files */, + ); + path = "imguiex-osx"; + sourceTree = ""; + }; + 1A1A0F241CB39FB50090F036 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1A1A0F351CB3A1B20090F036 /* opengl_example */ = { + isa = PBXGroup; + children = ( + 1A1A0F371CB3A1B20090F036 /* imgui_impl_glfw.cpp */, + 1A1A0F381CB3A1B20090F036 /* imgui_impl_glfw.h */, + 1A1A0F391CB3A1B20090F036 /* main.cpp */, + ); + name = opengl_example; + path = ../../opengl_example; + sourceTree = ""; + }; + 6D1E39141B35EEF10017B40F /* usynergy */ = { + isa = PBXGroup; + children = ( + 6D1E39151B35EEF10017B40F /* uSynergy.c */, + 6D1E39161B35EEF10017B40F /* uSynergy.h */, + ); + name = usynergy; + path = ../libs/usynergy; + sourceTree = ""; + }; + 6D2FC54B1B2E632000C130BA = { + isa = PBXGroup; + children = ( + 6D1E39141B35EEF10017B40F /* usynergy */, + 6D2FC5841B2E648D00C130BA /* imgui */, + 6D2FC5561B2E632000C130BA /* imguiex-ios */, + 1A1A0F201CB39FB50090F036 /* imguiex-osx */, + 6D2FC5551B2E632000C130BA /* Products */, + ); + sourceTree = ""; + }; + 6D2FC5551B2E632000C130BA /* Products */ = { + isa = PBXGroup; + children = ( + 6D2FC5541B2E632000C130BA /* imguiex-ios.app */, + 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */, + ); + name = Products; + sourceTree = ""; + }; + 6D2FC5561B2E632000C130BA /* imguiex-ios */ = { + isa = PBXGroup; + children = ( + 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, + 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, + 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, + 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, + 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, + 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, + 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, + 6D2FC55E1B2E632000C130BA /* Shader.fsh */, + 6D2FC5601B2E632000C130BA /* Shader.vsh */, + 6D2FC5621B2E632000C130BA /* GameViewController.h */, + 6D2FC5631B2E632000C130BA /* GameViewController.m */, + 6D2FC5651B2E632000C130BA /* Main.storyboard */, + 6D2FC5681B2E632000C130BA /* Images.xcassets */, + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, + 6D2FC5571B2E632000C130BA /* Supporting Files */, + ); + path = "imguiex-ios"; + sourceTree = ""; + }; + 6D2FC5571B2E632000C130BA /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, + 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, + 6D2FC5581B2E632000C130BA /* Info.plist */, + 6D2FC5591B2E632000C130BA /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 6D2FC5841B2E648D00C130BA /* imgui */ = { + isa = PBXGroup; + children = ( + 6D2FC5851B2E64AB00C130BA /* imconfig.h */, + 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, + 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, + 6D2FC5871B2E64AB00C130BA /* imgui.h */, + ); + name = imgui; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */; + buildPhases = ( + 1A1A0F1B1CB39FB50090F036 /* Sources */, + 1A1A0F1C1CB39FB50090F036 /* Frameworks */, + 1A1A0F1D1CB39FB50090F036 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-osx"; + productName = "imguiex-osx"; + productReference = 1A1A0F1F1CB39FB50090F036 /* imguiex-osx.app */; + productType = "com.apple.product-type.application"; + }; + 6D2FC5531B2E632000C130BA /* imguiex-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */; + buildPhases = ( + 6D2FC5501B2E632000C130BA /* Sources */, + 6D2FC5511B2E632000C130BA /* Frameworks */, + 6D2FC5521B2E632000C130BA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "imguiex-ios"; + productName = imguiex; + productReference = 6D2FC5541B2E632000C130BA /* imguiex-ios.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6D2FC54C1B2E632000C130BA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = "Joel Davis"; + TargetAttributes = { + 1A1A0F1E1CB39FB50090F036 = { + CreatedOnToolsVersion = 7.3; + }; + 6D2FC5531B2E632000C130BA = { + CreatedOnToolsVersion = 6.3.2; + }; + }; + }; + buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6D2FC54B1B2E632000C130BA; + productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D2FC5531B2E632000C130BA /* imguiex-ios */, + 1A1A0F1E1CB39FB50090F036 /* imguiex-osx */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1A1A0F1D1CB39FB50090F036 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F281CB39FB50090F036 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5521B2E632000C130BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, + 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, + 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, + 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, + 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1A1A0F1B1CB39FB50090F036 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A1A0F301CB3A0DA0090F036 /* imgui_draw.cpp in Sources */, + 1A1A0F311CB3A0DA0090F036 /* imgui.cpp in Sources */, + 1A1A0F331CB3A0E10090F036 /* imgui_demo.cpp in Sources */, + 1A1A0F341CB3A0EC0090F036 /* debug_hud.cpp in Sources */, + 1A1A0F481CB3A2E50090F036 /* main.cpp in Sources */, + 1A1A0F321CB3A0DE0090F036 /* uSynergy.c in Sources */, + 1A1A0F231CB39FB50090F036 /* AppDelegate.m in Sources */, + 1A1A0F4A1CB3A5070090F036 /* imgui_impl_glfw.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D2FC5501B2E632000C130BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, + 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, + 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, + 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, + 6D2FC55A1B2E632000C130BA /* main.m in Sources */, + 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, + 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, + 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, + 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC5661B2E632000C130BA /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 6D2FC56B1B2E632000C130BA /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1A1A0F2D1CB39FB50090F036 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 1A1A0F2E1CB39FB50090F036 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../", + /usr/local/include, + ); + INFOPLIST_FILE = "imguiex-osx/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.imguiex.imguiex-osx"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; + 6D2FC5791B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 6D2FC57A1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ""; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 6D2FC57C1B2E632000C130BA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6D2FC57D1B2E632000C130BA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = "imguiex-ios/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1A1A0F2F1CB39FB50090F036 /* Build configuration list for PBXNativeTarget "imguiex-osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1A1A0F2D1CB39FB50090F036 /* Debug */, + 1A1A0F2E1CB39FB50090F036 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC5791B2E632000C130BA /* Debug */, + 6D2FC57A1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6D2FC57C1B2E632000C130BA /* Debug */, + 6D2FC57D1B2E632000C130BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; +} diff --git a/examples/ios_example/.gitignore b/examples/ios_example/.gitignore deleted file mode 100644 index 8feda89..0000000 --- a/examples/ios_example/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -imguiex.xcodeproj/project.xcworkspace/ -imguiex.xcodeproj/xcuserdata/ \ No newline at end of file diff --git a/examples/ios_example/README.md b/examples/ios_example/README.md deleted file mode 100644 index a2ada95..0000000 --- a/examples/ios_example/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# iOS example - -## Introduction - -This example is the default XCode "OpenGL" example code, modified to support ImGui and [Synergy](http://synergy-project.org/). - -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. - -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 - -0. In Synergy, go to Preferences, and uncheck "Use SSL encryption" -0. Run the example app. -0. Tap the "servername" button in the corner -0. Enter the name or the IP of your synergy host -0. If you had previously connected to a server, you may need to kill and re-start the app. - -## Notes and TODOs - -Things that would be nice but I didn't get around to doing: - -* iOS software keyboard not supported for text inputs -* iOS hardware (bluetooth) keyboards not supported -* Graceful disconnect/reconnect from uSynergy. -* Copy/Paste not well-supported - -## C++ on iOS -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. - -In my case, most of my game code is already in C++ so it's not really an issue and I can use ImGui directly. diff --git a/examples/ios_example/imguiex.xcodeproj/project.pbxproj b/examples/ios_example/imguiex.xcodeproj/project.pbxproj deleted file mode 100644 index 26bcff4..0000000 --- a/examples/ios_example/imguiex.xcodeproj/project.pbxproj +++ /dev/null @@ -1,373 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */; }; - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 197E1E881B89443600E3FE6A /* imgui_demo.cpp */; }; - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6D1E39151B35EEF10017B40F /* uSynergy.c */; }; - 6D2FC55A1B2E632000C130BA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5591B2E632000C130BA /* main.m */; }; - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC55C1B2E632000C130BA /* AppDelegate.m */; }; - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC55E1B2E632000C130BA /* Shader.fsh */; }; - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5601B2E632000C130BA /* Shader.vsh */; }; - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5631B2E632000C130BA /* GameViewController.m */; }; - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5651B2E632000C130BA /* Main.storyboard */; }; - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC5681B2E632000C130BA /* Images.xcassets */; }; - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */; }; - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */; }; - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5861B2E64AB00C130BA /* imgui.cpp */; }; - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */; }; - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5901B30773F00C130BA /* CFNetwork.framework */; }; - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */; }; -/* End PBXBuildFile 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 = ""; }; - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../../imgui_demo.cpp; sourceTree = ""; }; - 6D1E39151B35EEF10017B40F /* uSynergy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = uSynergy.c; sourceTree = ""; }; - 6D1E39161B35EEF10017B40F /* uSynergy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uSynergy.h; sourceTree = ""; }; - 6D2FC5541B2E632000C130BA /* imguiex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = imguiex.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 6D2FC5581B2E632000C130BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6D2FC5591B2E632000C130BA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 6D2FC55E1B2E632000C130BA /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = Shaders/Shader.fsh; sourceTree = ""; }; - 6D2FC5601B2E632000C130BA /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = Shaders/Shader.vsh; sourceTree = ""; }; - 6D2FC5621B2E632000C130BA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; - 6D2FC5631B2E632000C130BA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; - 6D2FC5661B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 6D2FC5681B2E632000C130BA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6D2FC56B1B2E632000C130BA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = imgui_impl_ios.mm; sourceTree = ""; }; - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_impl_ios.h; sourceTree = ""; }; - 6D2FC5851B2E64AB00C130BA /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = ""; }; - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = ""; }; - 6D2FC5871B2E64AB00C130BA /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = ""; }; - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug_hud.cpp; sourceTree = ""; }; - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug_hud.h; sourceTree = ""; }; - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6D2FC5511B2E632000C130BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC5931B30774900C130BA /* SystemConfiguration.framework in Frameworks */, - 6D2FC5911B30773F00C130BA /* CFNetwork.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6D1E39141B35EEF10017B40F /* usynergy */ = { - isa = PBXGroup; - children = ( - 6D1E39151B35EEF10017B40F /* uSynergy.c */, - 6D1E39161B35EEF10017B40F /* uSynergy.h */, - ); - name = usynergy; - path = ../libs/usynergy; - sourceTree = ""; - }; - 6D2FC54B1B2E632000C130BA = { - isa = PBXGroup; - children = ( - 6D1E39141B35EEF10017B40F /* usynergy */, - 6D2FC5841B2E648D00C130BA /* imgui */, - 6D2FC5561B2E632000C130BA /* imguiex */, - 6D2FC5551B2E632000C130BA /* Products */, - ); - sourceTree = ""; - }; - 6D2FC5551B2E632000C130BA /* Products */ = { - isa = PBXGroup; - children = ( - 6D2FC5541B2E632000C130BA /* imguiex.app */, - ); - name = Products; - sourceTree = ""; - }; - 6D2FC5561B2E632000C130BA /* imguiex */ = { - isa = PBXGroup; - children = ( - 6D2FC5811B2E63A100C130BA /* imgui_impl_ios.mm */, - 6D2FC5821B2E63A100C130BA /* imgui_impl_ios.h */, - 197E1E881B89443600E3FE6A /* imgui_demo.cpp */, - 6D2FC5891B2E6A5500C130BA /* debug_hud.cpp */, - 6D2FC58A1B2E6A5500C130BA /* debug_hud.h */, - 6D2FC55B1B2E632000C130BA /* AppDelegate.h */, - 6D2FC55C1B2E632000C130BA /* AppDelegate.m */, - 6D2FC55E1B2E632000C130BA /* Shader.fsh */, - 6D2FC5601B2E632000C130BA /* Shader.vsh */, - 6D2FC5621B2E632000C130BA /* GameViewController.h */, - 6D2FC5631B2E632000C130BA /* GameViewController.m */, - 6D2FC5651B2E632000C130BA /* Main.storyboard */, - 6D2FC5681B2E632000C130BA /* Images.xcassets */, - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */, - 6D2FC5571B2E632000C130BA /* Supporting Files */, - ); - path = imguiex; - sourceTree = ""; - }; - 6D2FC5571B2E632000C130BA /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 6D2FC5921B30774900C130BA /* SystemConfiguration.framework */, - 6D2FC5901B30773F00C130BA /* CFNetwork.framework */, - 6D2FC5581B2E632000C130BA /* Info.plist */, - 6D2FC5591B2E632000C130BA /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 6D2FC5841B2E648D00C130BA /* imgui */ = { - isa = PBXGroup; - children = ( - 6D2FC5851B2E64AB00C130BA /* imconfig.h */, - 197E1E861B8943FE00E3FE6A /* imgui_draw.cpp */, - 6D2FC5861B2E64AB00C130BA /* imgui.cpp */, - 6D2FC5871B2E64AB00C130BA /* imgui.h */, - ); - name = imgui; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 6D2FC5531B2E632000C130BA /* imguiex */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */; - buildPhases = ( - 6D2FC5501B2E632000C130BA /* Sources */, - 6D2FC5511B2E632000C130BA /* Frameworks */, - 6D2FC5521B2E632000C130BA /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = imguiex; - productName = imguiex; - productReference = 6D2FC5541B2E632000C130BA /* imguiex.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 6D2FC54C1B2E632000C130BA /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = "Joel Davis"; - TargetAttributes = { - 6D2FC5531B2E632000C130BA = { - CreatedOnToolsVersion = 6.3.2; - }; - }; - }; - buildConfigurationList = 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 6D2FC54B1B2E632000C130BA; - productRefGroup = 6D2FC5551B2E632000C130BA /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 6D2FC5531B2E632000C130BA /* imguiex */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 6D2FC5521B2E632000C130BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC56C1B2E632000C130BA /* LaunchScreen.xib in Resources */, - 6D2FC5671B2E632000C130BA /* Main.storyboard in Resources */, - 6D2FC5691B2E632000C130BA /* Images.xcassets in Resources */, - 6D2FC5611B2E632000C130BA /* Shader.vsh in Resources */, - 6D2FC55F1B2E632000C130BA /* Shader.fsh in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6D2FC5501B2E632000C130BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6D2FC55D1B2E632000C130BA /* AppDelegate.m in Sources */, - 6D2FC5831B2E63A100C130BA /* imgui_impl_ios.mm in Sources */, - 6D1E39171B35EEF10017B40F /* uSynergy.c in Sources */, - 6D2FC5641B2E632000C130BA /* GameViewController.m in Sources */, - 6D2FC55A1B2E632000C130BA /* main.m in Sources */, - 6D2FC5881B2E64AB00C130BA /* imgui.cpp in Sources */, - 6D2FC58B1B2E6A5500C130BA /* debug_hud.cpp in Sources */, - 197E1E871B8943FE00E3FE6A /* imgui_draw.cpp in Sources */, - 197E1E891B89443600E3FE6A /* imgui_demo.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 6D2FC5651B2E632000C130BA /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC5661B2E632000C130BA /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6D2FC56A1B2E632000C130BA /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 6D2FC56B1B2E632000C130BA /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 6D2FC5791B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 6D2FC57A1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 6D2FC57C1B2E632000C130BA /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 6D2FC57D1B2E632000C130BA /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - INFOPLIST_FILE = imguiex/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 6D2FC54F1B2E632000C130BA /* Build configuration list for PBXProject "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC5791B2E632000C130BA /* Debug */, - 6D2FC57A1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D2FC57B1B2E632000C130BA /* Build configuration list for PBXNativeTarget "imguiex" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 6D2FC57C1B2E632000C130BA /* Debug */, - 6D2FC57D1B2E632000C130BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 6D2FC54C1B2E632000C130BA /* Project object */; -} diff --git a/examples/ios_example/imguiex/AppDelegate.h b/examples/ios_example/imguiex/AppDelegate.h deleted file mode 100644 index 82f1542..0000000 --- a/examples/ios_example/imguiex/AppDelegate.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// AppDelegate.h -// imguiex - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/examples/ios_example/imguiex/AppDelegate.m b/examples/ios_example/imguiex/AppDelegate.m deleted file mode 100644 index ab83101..0000000 --- a/examples/ios_example/imguiex/AppDelegate.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// AppDelegate.m -// imguiex - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib b/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib deleted file mode 100644 index 5717c00..0000000 --- a/examples/ios_example/imguiex/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/Base.lproj/Main.storyboard b/examples/ios_example/imguiex/Base.lproj/Main.storyboard deleted file mode 100644 index 90dfb2e..0000000 --- a/examples/ios_example/imguiex/Base.lproj/Main.storyboard +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/ios_example/imguiex/GameViewController.h b/examples/ios_example/imguiex/GameViewController.h deleted file mode 100644 index 3323cfd..0000000 --- a/examples/ios_example/imguiex/GameViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// GameViewController.h -// imguiex - -// This is the OpenGL Example template from XCode, modified to support ImGui - -#import -#import - -@interface GameViewController : GLKViewController - -@end diff --git a/examples/ios_example/imguiex/GameViewController.m b/examples/ios_example/imguiex/GameViewController.m deleted file mode 100644 index e902f7a..0000000 --- a/examples/ios_example/imguiex/GameViewController.m +++ /dev/null @@ -1,481 +0,0 @@ -// -// GameViewController.m -// imguiex -// -#import "GameViewController.h" -#import - -#import "imgui_impl_ios.h" -#import "debug_hud.h" - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - -#define SERVERNAME_KEY @"ServerName" - -#define SERVERNAME_ALERT_TAG (10) - -// Uniform index. -enum -{ - UNIFORM_MODELVIEWPROJECTION_MATRIX, - UNIFORM_NORMAL_MATRIX, - UNIFORM_DIFFUSE_COLOR, - - NUM_UNIFORMS -}; -GLint uniforms[NUM_UNIFORMS]; - -// Attribute index. -enum -{ - ATTRIB_VERTEX, - ATTRIB_NORMAL, - NUM_ATTRIBUTES -}; - -GLfloat gCubeVertexData[216] = -{ - // Data layout for each line below is: - // positionX, positionY, positionZ, normalX, normalY, normalZ, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f -}; - -@interface GameViewController () -{ - GLuint _program; - - GLKMatrix4 _modelViewProjectionMatrix; - GLKMatrix3 _normalMatrix; - float _rotation; - - GLuint _vertexArray; - GLuint _vertexBuffer; - - DebugHUD _hud; -} -@property (strong, nonatomic) EAGLContext *context; -@property (strong, nonatomic) GLKBaseEffect *effect; -@property (strong, nonatomic) ImGuiHelper *imgui; -@property (weak, nonatomic) IBOutlet UIButton *btnServername; - -@property (strong, nonatomic) NSString *serverName; - -- (IBAction)onServernameTapped:(id)sender; - -- (void)setupGL; -- (void)tearDownGL; - -- (BOOL)loadShaders; -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file; -- (BOOL)linkProgram:(GLuint)prog; -- (BOOL)validateProgram:(GLuint)prog; -@end - -@implementation GameViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - if (!self.context) { - NSLog(@"Failed to create ES context"); - } - - GLKView *view = (GLKView *)self.view; - view.context = self.context; - view.drawableDepthFormat = GLKViewDrawableDepthFormat24; - - [self.btnServername setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - - [self setupGL]; - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - self.serverName = [userDefaults objectForKey: SERVERNAME_KEY ]; - self.imgui = [[ImGuiHelper alloc] initWithView:self.view ]; - if (self.serverName) - { - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - [self.imgui connectServer: self.serverName ]; - } - - DebugHUD_InitDefaults( &_hud ); -} - -- (void)dealloc -{ - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - - if ([self isViewLoaded] && ([[self view] window] == nil)) { - self.view = nil; - - [self tearDownGL]; - - if ([EAGLContext currentContext] == self.context) { - [EAGLContext setCurrentContext:nil]; - } - self.context = nil; - } - - // Dispose of any resources that can be recreated. -} - - -- (BOOL)prefersStatusBarHidden { - return YES; -} - -- (IBAction)onServernameTapped:(id)sender -{ - UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Set Server" message:@"Enter server name or IP for uSynergy" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Cancel", nil ]; - alert.alertViewStyle = UIAlertViewStylePlainTextInput; - alert.tag = SERVERNAME_ALERT_TAG; // cheezy way to tell which alert view we're responding to - [alert show]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if ((buttonIndex==0)&&(alertView.tag==SERVERNAME_ALERT_TAG)) - { - // This is really janky. I usually just hardcode the servername since I'm building it anyway. - // If you want to properly handle updating the server, you'll want to tear down and recreate - // the usynergy stuff in connectServer - BOOL serverNameWasSet = self.serverName.length > 0; - NSString *serverName = [[alertView textFieldAtIndex:0] text]; - - if ([serverName length] > 0) { - self.serverName = serverName; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:serverName forKey:SERVERNAME_KEY ]; - [userDefaults synchronize]; - - [self.btnServername setTitle:self.serverName forState:UIControlStateNormal]; - - // If we hadn't previously connected, try now - if (!serverNameWasSet) { - [self.imgui connectServer:self.serverName]; - } - else - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Servername Updated" - message:@"Restart the app to connect the server" - delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; - [alert show]; - } - } - } -} - -- (void)setupGL -{ - [EAGLContext setCurrentContext:self.context]; - - [self loadShaders]; - - self.effect = [[GLKBaseEffect alloc] init]; - self.effect.light0.enabled = GL_TRUE; - self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f); - - glEnable(GL_DEPTH_TEST); - - glGenVertexArraysOES(1, &_vertexArray); - glBindVertexArrayOES(_vertexArray); - - glGenBuffers(1, &_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); - - glEnableVertexAttribArray(GLKVertexAttribPosition); - glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(GLKVertexAttribNormal); - glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); - - glBindVertexArrayOES(0); - - -} - -- (void)tearDownGL -{ - [EAGLContext setCurrentContext:self.context]; - - glDeleteBuffers(1, &_vertexBuffer); - glDeleteVertexArraysOES(1, &_vertexArray); - - self.effect = nil; - - if (_program) { - glDeleteProgram(_program); - _program = 0; - } -} - -#pragma mark - GLKView and GLKViewController delegate methods - -- (void)update -{ - float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height); - GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); - - self.effect.transform.projectionMatrix = projectionMatrix; - - GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); - baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); - - // Compute the model view matrix for the object rendered with GLKit - GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - self.effect.transform.modelviewMatrix = modelViewMatrix; - - // Compute the model view matrix for the object rendered with ES2 - modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); - modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); - modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); - - _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); - - _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); - - _rotation += self.timeSinceLastUpdate * (_hud.rotation_speed * (M_PI / 180.0)); -} - - -- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect -{ - glClearColor(0.65f, 0.65f, 0.65f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBindVertexArrayOES(_vertexArray); - - // Render the object with GLKit - [self.effect prepareToDraw]; - - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Render the object again with ES2 - glUseProgram(_program); - - glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); - glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); - glUniform3f(uniforms[UNIFORM_DIFFUSE_COLOR], _hud.cubeColor1[0], _hud.cubeColor1[1], _hud.cubeColor1[2] ); - - glDrawArrays(GL_TRIANGLES, 0, 36); - - [self.imgui newFrame]; - - // Now do our ImGUI UI - DebugHUD_DoInterface( &_hud ); - - self.effect.light0.diffuseColor = GLKVector4Make( _hud.cubeColor2[0], _hud.cubeColor2[1], _hud.cubeColor2[2], 1.0f); - - // Now render Imgui - [self.imgui render]; - -} - -#pragma mark - OpenGL ES 2 shader compilation - -- (BOOL)loadShaders -{ - GLuint vertShader, fragShader; - NSString *vertShaderPathname, *fragShaderPathname; - - // Create shader program. - _program = glCreateProgram(); - - // Create and compile vertex shader. - vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; - if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { - NSLog(@"Failed to compile vertex shader"); - return NO; - } - - // Create and compile fragment shader. - fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; - if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { - NSLog(@"Failed to compile fragment shader"); - return NO; - } - - // Attach vertex shader to program. - glAttachShader(_program, vertShader); - - // Attach fragment shader to program. - glAttachShader(_program, fragShader); - - // Bind attribute locations. - // This needs to be done prior to linking. - glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); - glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); - - // Link program. - if (![self linkProgram:_program]) { - NSLog(@"Failed to link program: %d", _program); - - if (vertShader) { - glDeleteShader(vertShader); - vertShader = 0; - } - if (fragShader) { - glDeleteShader(fragShader); - fragShader = 0; - } - if (_program) { - glDeleteProgram(_program); - _program = 0; - } - - return NO; - } - - // Get uniform locations. - uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix"); - uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix"); - uniforms[UNIFORM_DIFFUSE_COLOR] = glGetUniformLocation(_program, "diffuseColor"); - - // Release vertex and fragment shaders. - if (vertShader) { - glDetachShader(_program, vertShader); - glDeleteShader(vertShader); - } - if (fragShader) { - glDetachShader(_program, fragShader); - glDeleteShader(fragShader); - } - - return YES; -} - -- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file -{ - GLint status; - const GLchar *source; - - source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; - if (!source) { - NSLog(@"Failed to load vertex shader"); - return NO; - } - - *shader = glCreateShader(type); - glShaderSource(*shader, 1, &source, NULL); - glCompileShader(*shader); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); - NSLog(@"Shader compile log:\n%s", log); - free(log); - } -#endif - - glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); - if (status == 0) { - glDeleteShader(*shader); - return NO; - } - - return YES; -} - -- (BOOL)linkProgram:(GLuint)prog -{ - GLint status; - glLinkProgram(prog); - -#if defined(DEBUG) - GLint logLength; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program link log:\n%s", log); - free(log); - } -#endif - - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -- (BOOL)validateProgram:(GLuint)prog -{ - GLint logLength, status; - - glValidateProgram(prog); - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetProgramInfoLog(prog, logLength, &logLength, log); - NSLog(@"Program validate log:\n%s", log); - free(log); - } - - glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); - if (status == 0) { - return NO; - } - - return YES; -} - -@end diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a05a29b..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@2x~iphone.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_imgui_60@3x~iphone.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76~ipad.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_imgui_76@2x~ipad.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png deleted file mode 100644 index d728bc3..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@2x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png deleted file mode 100644 index f48b799..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_60@3x~iphone.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png deleted file mode 100644 index 67b08b8..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76@2x~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png b/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png deleted file mode 100644 index ae88e04..0000000 --- a/examples/ios_example/imguiex/Images.xcassets/AppIcon.appiconset/icon_imgui_76~ipad.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/Info.plist b/examples/ios_example/imguiex/Info.plist deleted file mode 100644 index bc6f548..0000000 --- a/examples/ios_example/imguiex/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - org.imgui.example.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarHidden - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/examples/ios_example/imguiex/Shaders/Shader.fsh b/examples/ios_example/imguiex/Shaders/Shader.fsh deleted file mode 100644 index 4000524..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.fsh +++ /dev/null @@ -1,10 +0,0 @@ -// -// Shader.fsh -// imguiex - -varying lowp vec4 colorVarying; - -void main() -{ - gl_FragColor = colorVarying; -} diff --git a/examples/ios_example/imguiex/Shaders/Shader.vsh b/examples/ios_example/imguiex/Shaders/Shader.vsh deleted file mode 100644 index 313c3d7..0000000 --- a/examples/ios_example/imguiex/Shaders/Shader.vsh +++ /dev/null @@ -1,25 +0,0 @@ -// -// Shader.vsh -// imguiex - -attribute vec4 position; -attribute vec3 normal; - -varying lowp vec4 colorVarying; - -uniform vec3 diffuseColor; -uniform mat4 modelViewProjectionMatrix; -uniform mat3 normalMatrix; - -void main() -{ - vec3 eyeNormal = normalize(normalMatrix * normal); - vec3 lightPosition = vec3(0.0, 0.0, 1.0); - - float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); - - vec3 colorLit = diffuseColor * nDotVP; - colorVarying = vec4( colorLit.x, colorLit.y, colorLit.z, 1.0 ); - - gl_Position = modelViewProjectionMatrix * position; -} diff --git a/examples/ios_example/imguiex/debug_hud.cpp b/examples/ios_example/imguiex/debug_hud.cpp deleted file mode 100644 index c75938a..0000000 --- a/examples/ios_example/imguiex/debug_hud.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// debug_hud.cpp -// imguiex - -#include - -#include "debug_hud.h" -#include "imgui.h" - -void DebugHUD_InitDefaults( DebugHUD *hud ) -{ - hud->show_test_window = true; - hud->show_example_window = true; - hud->rotation_speed = 15.0f; - - hud->cubeColor1[0] = 0.4f; - hud->cubeColor1[1] = 0.4f; - hud->cubeColor1[2] = 1.0f; - hud->cubeColor1[3] = 1.0f; - - hud->cubeColor2[0] = 1.0f; - hud->cubeColor2[1] = 0.4f; - hud->cubeColor2[2] = 0.4f; - hud->cubeColor2[3] = 1.0f; -} - -void DebugHUD_DoInterface( DebugHUD *hud ) -{ - if (hud->show_test_window) - { - ImGui::SetNextWindowPos( ImVec2( 400, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::ShowTestWindow( &hud->show_test_window ); - } - - if (hud->show_example_window) - { - ImGui::SetNextWindowPos( ImVec2( 20, 20 ), ImGuiSetCond_FirstUseEver ); - ImGui::SetNextWindowSize( ImVec2( 350, 200 ), ImGuiSetCond_FirstUseEver ); - ImGui::Begin("Another Window", &hud->show_example_window); - ImGui::ColorEdit3("Cube 1 Color", hud->cubeColor1); - ImGui::ColorEdit3("Cube 2 Color", hud->cubeColor2); - ImGui::SliderFloat("Rotation Speed", &hud->rotation_speed, 0.0f, 200.0f); - ImGui::End(); - } -} diff --git a/examples/ios_example/imguiex/debug_hud.h b/examples/ios_example/imguiex/debug_hud.h deleted file mode 100644 index 17122f5..0000000 --- a/examples/ios_example/imguiex/debug_hud.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// debug_hud.h -// imguiex - -#pragma once - -typedef struct DebugHUD -{ - bool show_test_window; - bool show_example_window; - float rotation_speed; - float cubeColor1[4]; - float cubeColor2[4]; -} DebugHUD; - -#if __cplusplus -extern "C" { -#endif - -void DebugHUD_InitDefaults( DebugHUD *hud ); -void DebugHUD_DoInterface( DebugHUD *hud ); - -#if __cplusplus -} -#endif diff --git a/examples/ios_example/imguiex/imgui_ex_icon.png b/examples/ios_example/imguiex/imgui_ex_icon.png deleted file mode 100644 index 820e4d7..0000000 --- a/examples/ios_example/imguiex/imgui_ex_icon.png +++ /dev/null Binary files differ diff --git a/examples/ios_example/imguiex/imgui_impl_ios.h b/examples/ios_example/imguiex/imgui_impl_ios.h deleted file mode 100644 index 9b01dd3..0000000 --- a/examples/ios_example/imguiex/imgui_impl_ios.h +++ /dev/null @@ -1,22 +0,0 @@ -// ImGui iOS+OpenGL+Synergy binding -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. -// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. - -// by Joel Davis (joeld42@gmail.com) - -#pragma once - -#include -#include - -@interface ImGuiHelper : NSObject - -- (id) initWithView: (UIView *)view; - -- (void)connectServer: (NSString*)serverName; - -- (void)render; -- (void)newFrame; - -@end diff --git a/examples/ios_example/imguiex/imgui_impl_ios.mm b/examples/ios_example/imguiex/imgui_impl_ios.mm deleted file mode 100644 index b286c4d..0000000 --- a/examples/ios_example/imguiex/imgui_impl_ios.mm +++ /dev/null @@ -1,803 +0,0 @@ -// ImGui iOS+OpenGL+Synergy binding -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. -// Providing a standalone iOS application with Synergy integration makes this sample more verbose than others. It also hasn't been tested as much. -// Refer to other examples to get an easier understanding of how to integrate ImGui into your existing application. - -#import -#import - -#include -#include -#include -#include - -#include "imgui_impl_ios.h" -#include "imgui.h" - -#include "uSynergy.h" - -// From Carbon HIToolbox/Events.h -// FIXME: Keyboard mapping is hacked in because Synergy doesn't give us character but only keycode which aren't really portable if you consider keyboard locale. See https://github.com/ocornut/imgui/pull/247 -enum { - kVK_ANSI_A = 0x00, - kVK_ANSI_S = 0x01, - kVK_ANSI_D = 0x02, - kVK_ANSI_F = 0x03, - kVK_ANSI_H = 0x04, - kVK_ANSI_G = 0x05, - kVK_ANSI_Z = 0x06, - kVK_ANSI_X = 0x07, - kVK_ANSI_C = 0x08, - kVK_ANSI_V = 0x09, - kVK_ANSI_B = 0x0B, - kVK_ANSI_Q = 0x0C, - kVK_ANSI_W = 0x0D, - kVK_ANSI_E = 0x0E, - kVK_ANSI_R = 0x0F, - kVK_ANSI_Y = 0x10, - kVK_ANSI_T = 0x11, - kVK_ANSI_1 = 0x12, - kVK_ANSI_2 = 0x13, - kVK_ANSI_3 = 0x14, - kVK_ANSI_4 = 0x15, - kVK_ANSI_6 = 0x16, - kVK_ANSI_5 = 0x17, - kVK_ANSI_Equal = 0x18, - kVK_ANSI_9 = 0x19, - kVK_ANSI_7 = 0x1A, - kVK_ANSI_Minus = 0x1B, - kVK_ANSI_8 = 0x1C, - kVK_ANSI_0 = 0x1D, - kVK_ANSI_RightBracket = 0x1E, - kVK_ANSI_O = 0x1F, - kVK_ANSI_U = 0x20, - kVK_ANSI_LeftBracket = 0x21, - kVK_ANSI_I = 0x22, - kVK_ANSI_P = 0x23, - kVK_ANSI_L = 0x25, - kVK_ANSI_J = 0x26, - kVK_ANSI_Quote = 0x27, - kVK_ANSI_K = 0x28, - kVK_ANSI_Semicolon = 0x29, - kVK_ANSI_Backslash = 0x2A, - kVK_ANSI_Comma = 0x2B, - kVK_ANSI_Slash = 0x2C, - kVK_ANSI_N = 0x2D, - kVK_ANSI_M = 0x2E, - kVK_ANSI_Period = 0x2F, - kVK_ANSI_Grave = 0x32, - kVK_ANSI_KeypadDecimal = 0x41, - kVK_ANSI_KeypadMultiply = 0x43, - kVK_ANSI_KeypadPlus = 0x45, - kVK_ANSI_KeypadClear = 0x47, - kVK_ANSI_KeypadDivide = 0x4B, - kVK_ANSI_KeypadEnter = 0x4C, - kVK_ANSI_KeypadMinus = 0x4E, - kVK_ANSI_KeypadEquals = 0x51, - kVK_ANSI_Keypad0 = 0x52, - kVK_ANSI_Keypad1 = 0x53, - kVK_ANSI_Keypad2 = 0x54, - kVK_ANSI_Keypad3 = 0x55, - kVK_ANSI_Keypad4 = 0x56, - kVK_ANSI_Keypad5 = 0x57, - kVK_ANSI_Keypad6 = 0x58, - kVK_ANSI_Keypad7 = 0x59, - kVK_ANSI_Keypad8 = 0x5B, - kVK_ANSI_Keypad9 = 0x5C -}; - -/* keycodes for keys that are independent of keyboard layout*/ -enum { - kVK_Return = 0x24, - kVK_Tab = 0x30, - kVK_Space = 0x31, - kVK_Delete = 0x33, - kVK_Escape = 0x35, - kVK_Command = 0x37, - kVK_Shift = 0x38, - kVK_CapsLock = 0x39, - kVK_Option = 0x3A, - kVK_Control = 0x3B, - kVK_RightShift = 0x3C, - kVK_RightOption = 0x3D, - kVK_RightControl = 0x3E, - kVK_Function = 0x3F, - kVK_F17 = 0x40, - kVK_VolumeUp = 0x48, - kVK_VolumeDown = 0x49, - kVK_Mute = 0x4A, - kVK_F18 = 0x4F, - kVK_F19 = 0x50, - kVK_F20 = 0x5A, - kVK_F5 = 0x60, - kVK_F6 = 0x61, - kVK_F7 = 0x62, - kVK_F3 = 0x63, - kVK_F8 = 0x64, - kVK_F9 = 0x65, - kVK_F11 = 0x67, - kVK_F13 = 0x69, - kVK_F16 = 0x6A, - kVK_F14 = 0x6B, - kVK_F10 = 0x6D, - kVK_F12 = 0x6F, - kVK_F15 = 0x71, - kVK_Help = 0x72, - kVK_Home = 0x73, - kVK_PageUp = 0x74, - kVK_ForwardDelete = 0x75, - kVK_F4 = 0x76, - kVK_End = 0x77, - kVK_F2 = 0x78, - kVK_PageDown = 0x79, - kVK_F1 = 0x7A, - kVK_LeftArrow = 0x7B, - kVK_RightArrow = 0x7C, - kVK_DownArrow = 0x7D, - kVK_UpArrow = 0x7E -}; - -static char g_keycodeCharUnshifted[256] = {}; -static char g_keycodeCharShifted[256] = {}; - -//static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_mouseWheelX = 0.0f; -static float g_mouseWheelY = 0.0f; - -static GLuint g_FontTexture = 0; -static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; -static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; -static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; -static size_t g_VboSize = 0; -static unsigned int g_VboHandle = 0, g_VaoHandle = 0; -static float g_displayScale; - -static int usynergy_sockfd; -static bool g_synergyPtrActive = false; -static uint16_t g_mousePosX = 0; -static uint16_t g_mousePosY = 0; - -static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data); -bool ImGui_ImplIOS_CreateDeviceObjects(); - -static NSString *g_serverName; - -uSynergyBool ImGui_ConnectFunc(uSynergyCookie cookie) -{ - // NOTE: You need to turn off "Use SSL Encryption" in Synergy preferences, since - // uSynergy does not support SSL. - - NSLog( @"Connect Func!"); - struct addrinfo hints, *res; - - // first, load up address structs with getaddrinfo(): - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever - hints.ai_socktype = SOCK_STREAM; - - // get server address - getaddrinfo([g_serverName UTF8String], "24800", &hints, &res); - - if (!res) - { - NSLog( @"Could not find server: %@", g_serverName ); - return USYNERGY_FALSE; - } - - // make a socket: - usynergy_sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - - // connect it to the address and port we passed in to getaddrinfo(): - int ret = connect(usynergy_sockfd, res->ai_addr, res->ai_addrlen); - if (!ret) { - NSLog( @"Connect suceeded..."); - } else { - NSLog( @"Connect failed, %d", ret ); - } - - - return USYNERGY_TRUE; -} - -uSynergyBool ImGui_SendFunc(uSynergyCookie cookie, const uint8_t *buffer, int length) -{ -// NSLog( @"Send Func" ); - send( usynergy_sockfd, buffer, length, 0 ); - - return USYNERGY_TRUE; -} - -uSynergyBool ImGui_RecvFunc(uSynergyCookie cookie, uint8_t *buffer, int maxLength, int* outLength) -{ - *outLength = (int)recv( usynergy_sockfd, buffer, maxLength, 0 ); - - return USYNERGY_TRUE; -} - -void ImGui_SleepFunc(uSynergyCookie cookie, int timeMs) -{ - usleep( timeMs * 1000 ); -} - -uint32_t ImGui_GetTimeFunc() -{ - struct timeval tv; - gettimeofday(&tv, NULL); - - return (int32_t)((tv.tv_sec) * 1000 + (tv.tv_usec) / 1000); -} - -void ImGui_TraceFunc(uSynergyCookie cookie, const char *text) -{ - puts(text); -} - -void ImGui_ScreenActiveCallback(uSynergyCookie cookie, uSynergyBool active) -{ - g_synergyPtrActive = active; -// printf( "Synergy: screen activate %s\n", active?"YES":"NO" ); -} - -void ImGui_MouseCallback(uSynergyCookie cookie, uint16_t x, uint16_t y, int16_t wheelX, int16_t wheelY, - uSynergyBool buttonLeft, uSynergyBool buttonRight, uSynergyBool buttonMiddle) -{ -// printf("Synergy: mouse callback %d %d -- wheel %d %d\n", x, y, wheelX, wheelY ); - uSynergyContext *ctx = (uSynergyContext*)cookie; - g_mousePosX = x; - g_mousePosY = y; - g_mouseWheelX = wheelX; - g_mouseWheelY = wheelY; - g_MousePressed[0] = buttonLeft; - g_MousePressed[1] = buttonMiddle; - g_MousePressed[2] = buttonRight; - - ctx->m_mouseWheelX = 0; - ctx->m_mouseWheelY = 0; -} - -void ImGui_KeyboardCallback(uSynergyCookie cookie, uint16_t key, - uint16_t modifiers, uSynergyBool down, uSynergyBool repeat) -{ - int scanCode = key-1; -// printf("Synergy: keyboard callback: 0x%02X (%s)", scanCode, down?"true":"false"); - ImGuiIO& io = ImGui::GetIO(); - io.KeysDown[key] = down; - io.KeyShift = (modifiers & USYNERGY_MODIFIER_SHIFT); - io.KeyCtrl = (modifiers & USYNERGY_MODIFIER_CTRL); - io.KeyAlt = (modifiers & USYNERGY_MODIFIER_ALT); - io.KeySuper = (modifiers & USYNERGY_MODIFIER_WIN); - - // Add this as keyboard input - if ((down) && (key) && (scanCode<256) && !(modifiers & USYNERGY_MODIFIER_CTRL)) - { - // If this key maps to a character input, apply it - int charForKeycode = (modifiers & USYNERGY_MODIFIER_SHIFT) ? g_keycodeCharShifted[scanCode] : g_keycodeCharUnshifted[scanCode]; - io.AddInputCharacter((unsigned short)charForKeycode); - } - -} - -void ImGui_JoystickCallback(uSynergyCookie cookie, uint8_t joyNum, uint16_t buttons, int8_t leftStickX, int8_t leftStickY, int8_t rightStickX, int8_t rightStickY) -{ - printf("Synergy: joystick callback TODO\n"); -} - -void ImGui_ClipboardCallback(uSynergyCookie cookie, enum uSynergyClipboardFormat format, const uint8_t *data, uint32_t size) -{ - printf("Synergy: clipboard callback TODO\n" ); -} - - -@interface ImGuiHelper () -{ - BOOL _mouseDown; - BOOL _mouseTapped; - CGPoint _touchPos; - - uSynergyContext _synergyCtx; - dispatch_queue_t _synergyQueue; -} -@property (nonatomic, weak) UIView *view; -@property (nonatomic, strong) NSString *serverName; - -@end - -@implementation ImGuiHelper - -- (id) initWithView: (UIView *)view -{ - self = [super init]; - if (self) - { - self.view = view; - - [self setupImGuiHooks]; - } - return self; -} - -- (void)setupKeymaps -{ - // The keyboard mapping is a big headache. I tried for a while to find a better way to do this, - // but this was the best I could come up with. There are some device independent API's available - // to convert scan codes to unicode characters, but these are only available on mac and not - // on iOS as far as I can tell (it's part of Carbon). I didn't see any better way to do - // this or any way to get the character codes out of usynergy. - g_keycodeCharUnshifted[ kVK_ANSI_A ]='a'; - g_keycodeCharUnshifted[ kVK_ANSI_S ]='s'; - g_keycodeCharUnshifted[ kVK_ANSI_D ]='d'; - g_keycodeCharUnshifted[ kVK_ANSI_F ]='f'; - g_keycodeCharUnshifted[ kVK_ANSI_H ]='h'; - g_keycodeCharUnshifted[ kVK_ANSI_G ]='g'; - g_keycodeCharUnshifted[ kVK_ANSI_Z ]='z'; - g_keycodeCharUnshifted[ kVK_ANSI_X ]='x'; - g_keycodeCharUnshifted[ kVK_ANSI_C ]='c'; - g_keycodeCharUnshifted[ kVK_ANSI_V ]='v'; - g_keycodeCharUnshifted[ kVK_ANSI_B ]='b'; - g_keycodeCharUnshifted[ kVK_ANSI_Q ]='q'; - g_keycodeCharUnshifted[ kVK_ANSI_W ]='w'; - g_keycodeCharUnshifted[ kVK_ANSI_E ]='e'; - g_keycodeCharUnshifted[ kVK_ANSI_R ]='r'; - g_keycodeCharUnshifted[ kVK_ANSI_Y ]='y'; - g_keycodeCharUnshifted[ kVK_ANSI_T ]='t'; - g_keycodeCharUnshifted[ kVK_ANSI_1 ]='1'; - g_keycodeCharUnshifted[ kVK_ANSI_2 ]='2'; - g_keycodeCharUnshifted[ kVK_ANSI_3 ]='3'; - g_keycodeCharUnshifted[ kVK_ANSI_4 ]='4'; - g_keycodeCharUnshifted[ kVK_ANSI_6 ]='6'; - g_keycodeCharUnshifted[ kVK_ANSI_5 ]='5'; - g_keycodeCharUnshifted[ kVK_ANSI_Equal ]='='; - g_keycodeCharUnshifted[ kVK_ANSI_9 ]='9'; - g_keycodeCharUnshifted[ kVK_ANSI_7 ]='7'; - g_keycodeCharUnshifted[ kVK_ANSI_Minus ]='-'; - g_keycodeCharUnshifted[ kVK_ANSI_8 ]='8'; - g_keycodeCharUnshifted[ kVK_ANSI_0 ]='0'; - g_keycodeCharUnshifted[ kVK_ANSI_RightBracket ]=']'; - g_keycodeCharUnshifted[ kVK_ANSI_O ]='o'; - g_keycodeCharUnshifted[ kVK_ANSI_U ]='u'; - g_keycodeCharUnshifted[ kVK_ANSI_LeftBracket ]='['; - g_keycodeCharUnshifted[ kVK_ANSI_I ]='i'; - g_keycodeCharUnshifted[ kVK_ANSI_P ]='p'; - g_keycodeCharUnshifted[ kVK_ANSI_L ]='l'; - g_keycodeCharUnshifted[ kVK_ANSI_J ]='j'; - g_keycodeCharUnshifted[ kVK_ANSI_Quote ]='\''; - g_keycodeCharUnshifted[ kVK_ANSI_K ]='k'; - g_keycodeCharUnshifted[ kVK_ANSI_Semicolon ]=';'; - g_keycodeCharUnshifted[ kVK_ANSI_Backslash ]='\\'; - g_keycodeCharUnshifted[ kVK_ANSI_Comma ]=','; - g_keycodeCharUnshifted[ kVK_ANSI_Slash ]='/'; - g_keycodeCharUnshifted[ kVK_ANSI_N ]='n'; - g_keycodeCharUnshifted[ kVK_ANSI_M ]='m'; - g_keycodeCharUnshifted[ kVK_ANSI_Period ]='.'; - g_keycodeCharUnshifted[ kVK_ANSI_Grave ]='`'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadDecimal ]='.'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadMultiply ]='*'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadPlus ]='+'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadDivide ]='/'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadEnter ]='\n'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadMinus ]='-'; - g_keycodeCharUnshifted[ kVK_ANSI_KeypadEquals ]='='; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad0 ]='0'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad1 ]='1'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad2 ]='2'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad3 ]='3'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad4 ]='4'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad5 ]='5'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad6 ]='6'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad7 ]='7'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad8 ]='8'; - g_keycodeCharUnshifted[ kVK_ANSI_Keypad9 ]='9'; - g_keycodeCharUnshifted[ kVK_Space ]=' '; - - g_keycodeCharShifted[ kVK_ANSI_A ]='A'; - g_keycodeCharShifted[ kVK_ANSI_S ]='S'; - g_keycodeCharShifted[ kVK_ANSI_D ]='D'; - g_keycodeCharShifted[ kVK_ANSI_F ]='F'; - g_keycodeCharShifted[ kVK_ANSI_H ]='H'; - g_keycodeCharShifted[ kVK_ANSI_G ]='G'; - g_keycodeCharShifted[ kVK_ANSI_Z ]='Z'; - g_keycodeCharShifted[ kVK_ANSI_X ]='X'; - g_keycodeCharShifted[ kVK_ANSI_C ]='C'; - g_keycodeCharShifted[ kVK_ANSI_V ]='V'; - g_keycodeCharShifted[ kVK_ANSI_B ]='B'; - g_keycodeCharShifted[ kVK_ANSI_Q ]='Q'; - g_keycodeCharShifted[ kVK_ANSI_W ]='W'; - g_keycodeCharShifted[ kVK_ANSI_E ]='E'; - g_keycodeCharShifted[ kVK_ANSI_R ]='R'; - g_keycodeCharShifted[ kVK_ANSI_Y ]='Y'; - g_keycodeCharShifted[ kVK_ANSI_T ]='T'; - g_keycodeCharShifted[ kVK_ANSI_1 ]='!'; - g_keycodeCharShifted[ kVK_ANSI_2 ]='@'; - g_keycodeCharShifted[ kVK_ANSI_3 ]='#'; - g_keycodeCharShifted[ kVK_ANSI_4 ]='$'; - g_keycodeCharShifted[ kVK_ANSI_6 ]='^'; - g_keycodeCharShifted[ kVK_ANSI_5 ]='%'; - g_keycodeCharShifted[ kVK_ANSI_Equal ]='+'; - g_keycodeCharShifted[ kVK_ANSI_9 ]='('; - g_keycodeCharShifted[ kVK_ANSI_7 ]='&'; - g_keycodeCharShifted[ kVK_ANSI_Minus ]='_'; - g_keycodeCharShifted[ kVK_ANSI_8 ]='*'; - g_keycodeCharShifted[ kVK_ANSI_0 ]=')'; - g_keycodeCharShifted[ kVK_ANSI_RightBracket ]='}'; - g_keycodeCharShifted[ kVK_ANSI_O ]='O'; - g_keycodeCharShifted[ kVK_ANSI_U ]='U'; - g_keycodeCharShifted[ kVK_ANSI_LeftBracket ]='{'; - g_keycodeCharShifted[ kVK_ANSI_I ]='I'; - g_keycodeCharShifted[ kVK_ANSI_P ]='P'; - g_keycodeCharShifted[ kVK_ANSI_L ]='L'; - g_keycodeCharShifted[ kVK_ANSI_J ]='J'; - g_keycodeCharShifted[ kVK_ANSI_Quote ]='\"'; - g_keycodeCharShifted[ kVK_ANSI_K ]='K'; - g_keycodeCharShifted[ kVK_ANSI_Semicolon ]=':'; - g_keycodeCharShifted[ kVK_ANSI_Backslash ]='|'; - g_keycodeCharShifted[ kVK_ANSI_Comma ]='<'; - g_keycodeCharShifted[ kVK_ANSI_Slash ]='?'; - g_keycodeCharShifted[ kVK_ANSI_N ]='N'; - g_keycodeCharShifted[ kVK_ANSI_M ]='M'; - g_keycodeCharShifted[ kVK_ANSI_Period ]='>'; - g_keycodeCharShifted[ kVK_ANSI_Grave ]='~'; - g_keycodeCharShifted[ kVK_ANSI_KeypadDecimal ]='.'; - g_keycodeCharShifted[ kVK_ANSI_KeypadMultiply ]='*'; - g_keycodeCharShifted[ kVK_ANSI_KeypadPlus ]='+'; - g_keycodeCharShifted[ kVK_ANSI_KeypadDivide ]='/'; - g_keycodeCharShifted[ kVK_ANSI_KeypadEnter ]='\n'; - g_keycodeCharShifted[ kVK_ANSI_KeypadMinus ]='-'; - g_keycodeCharShifted[ kVK_ANSI_KeypadEquals ]='='; - g_keycodeCharShifted[ kVK_ANSI_Keypad0 ]='0'; - g_keycodeCharShifted[ kVK_ANSI_Keypad1 ]='1'; - g_keycodeCharShifted[ kVK_ANSI_Keypad2 ]='2'; - g_keycodeCharShifted[ kVK_ANSI_Keypad3 ]='3'; - g_keycodeCharShifted[ kVK_ANSI_Keypad4 ]='4'; - g_keycodeCharShifted[ kVK_ANSI_Keypad5 ]='5'; - g_keycodeCharShifted[ kVK_ANSI_Keypad6 ]='6'; - g_keycodeCharShifted[ kVK_ANSI_Keypad7 ]='7'; - g_keycodeCharShifted[ kVK_ANSI_Keypad8 ]='8'; - g_keycodeCharShifted[ kVK_ANSI_Keypad9 ]='9'; - g_keycodeCharShifted[ kVK_Space ]=' '; -} - -- (void)setupImGuiHooks -{ - ImGuiIO &io = ImGui::GetIO(); - - [self setupKeymaps]; - - // Account for retina display for glScissor - g_displayScale = [[UIScreen mainScreen] scale]; - - ImGuiStyle &style = ImGui::GetStyle(); - style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); - - io.RenderDrawListsFn = ImGui_ImplIOS_RenderDrawLists; - - UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewDidPan:) ]; - [self.view addGestureRecognizer:panRecognizer]; - - UITapGestureRecognizer *tapRecoginzer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector( viewDidTap:)]; - [self.view addGestureRecognizer:tapRecoginzer]; - - // Fill out the Synergy key map - // (for some reason synergy scan codes are off by 1) - io.KeyMap[ImGuiKey_Tab] = kVK_Tab+1; - io.KeyMap[ImGuiKey_LeftArrow] = kVK_LeftArrow+1; - io.KeyMap[ImGuiKey_RightArrow] = kVK_RightArrow+1; - io.KeyMap[ImGuiKey_UpArrow] = kVK_UpArrow+1; - io.KeyMap[ImGuiKey_DownArrow] = kVK_DownArrow+1; - io.KeyMap[ImGuiKey_Home] = kVK_Home+1; - io.KeyMap[ImGuiKey_End] = kVK_End+1; - io.KeyMap[ImGuiKey_Delete] = kVK_ForwardDelete+1; - io.KeyMap[ImGuiKey_Backspace] = kVK_Delete+1; - io.KeyMap[ImGuiKey_Enter] = kVK_Return+1; - io.KeyMap[ImGuiKey_Escape] = kVK_Escape+1; - io.KeyMap[ImGuiKey_A] = kVK_ANSI_A+1; - io.KeyMap[ImGuiKey_C] = kVK_ANSI_C+1; - io.KeyMap[ImGuiKey_V] = kVK_ANSI_V+1; - io.KeyMap[ImGuiKey_X] = kVK_ANSI_X+1; - io.KeyMap[ImGuiKey_Y] = kVK_ANSI_Y+1; - io.KeyMap[ImGuiKey_Z] = kVK_ANSI_Z+1; -} - -- (void)connectServer: (NSString*)serverName -{ - self.serverName = serverName; - g_serverName = serverName; - - // Init synergy - NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]; - - uSynergyInit( &_synergyCtx ); - _synergyCtx.m_clientName = strdup( [bundleName UTF8String] ); - _synergyCtx.m_clientWidth = self.view.bounds.size.width; - _synergyCtx.m_clientHeight = self.view.bounds.size.height; - - _synergyCtx.m_connectFunc = ImGui_ConnectFunc; - _synergyCtx.m_sendFunc = ImGui_SendFunc; - _synergyCtx.m_receiveFunc = ImGui_RecvFunc; - _synergyCtx.m_sleepFunc = ImGui_SleepFunc; - _synergyCtx.m_traceFunc = ImGui_TraceFunc; - _synergyCtx.m_getTimeFunc = ImGui_GetTimeFunc; - - _synergyCtx.m_traceFunc = ImGui_TraceFunc; - _synergyCtx.m_screenActiveCallback = ImGui_ScreenActiveCallback; - _synergyCtx.m_mouseCallback = ImGui_MouseCallback; - _synergyCtx.m_keyboardCallback = ImGui_KeyboardCallback; - - _synergyCtx.m_cookie = (uSynergyCookie)&_synergyCtx; - - // Create a background thread for synergy - _synergyQueue = dispatch_queue_create( "imgui-usynergy", NULL ); - dispatch_async( _synergyQueue, ^{ - while (1) { - uSynergyUpdate( &_synergyCtx ); - } - }); -} - - -- (void)viewDidPan: (UIPanGestureRecognizer *)recognizer -{ - - if ((recognizer.state == UIGestureRecognizerStateBegan) || - (recognizer.state == UIGestureRecognizerStateChanged)) - { - _mouseDown = YES; - _touchPos = [recognizer locationInView:self.view]; - } - else - { - _mouseDown = NO; - _touchPos = CGPointMake( -1, -1 ); - } -} - -- (void)viewDidTap: (UITapGestureRecognizer*)recognizer -{ - _touchPos = [recognizer locationInView:self.view]; - _mouseTapped = YES; -} - -- (void)render -{ - ImGui::Render(); -} - -- (void)newFrame -{ - ImGuiIO& io = ImGui::GetIO(); - ImGuiStyle &style = ImGui::GetStyle(); - - if (!g_FontTexture) - { - ImGui_ImplIOS_CreateDeviceObjects(); - } - - io.DisplaySize = ImVec2( _view.bounds.size.width, _view.bounds.size.height ); - - io.MouseDrawCursor = g_synergyPtrActive; - if (g_synergyPtrActive) - { - style.TouchExtraPadding = ImVec2( 0.0, 0.0 ); - io.MousePos = ImVec2( g_mousePosX, g_mousePosY ); - for (int i=0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i]; - } - - // This is an arbitrary scaling factor that works for me. Not sure what units these - // mousewheel values from synergy are supposed to be in - io.MouseWheel = g_mouseWheelY / 500.0; - } - else - { - // Synergy not active, use touch events - style.TouchExtraPadding = ImVec2( 4.0, 4.0 ); - io.MousePos = ImVec2(_touchPos.x, _touchPos.y ); - if ((_mouseDown) || (_mouseTapped)) - { - io.MouseDown[0] = true; - _mouseTapped = NO; - } - else - { - io.MouseDown[0] = false; - } - } - - ImGui::NewFrame(); -} -@end - -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -// NOTE: this is copied pretty much entirely from the opengl3_example, with only minor changes for ES -static void ImGui_ImplIOS_RenderDrawLists (ImDrawData *draw_data) -{ - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled - GLint last_program, last_texture; - glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glActiveTexture(GL_TEXTURE0); - - // Setup orthographic projection matrix - const float width = ImGui::GetIO().DisplaySize.x; - const float height = ImGui::GetIO().DisplaySize.y; - const float ortho_projection[4][4] = - { - { 2.0f/width, 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f/-height, 0.0f, 0.0f }, - { 0.0f, 0.0f, -1.0f, 0.0f }, - { -1.0f, 1.0f, 0.0f, 1.0f }, - }; - glUseProgram(g_ShaderHandle); - glUniform1i(g_AttribLocationTex, 0); - glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - glBindVertexArray(g_VaoHandle); - - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - ImDrawList* cmd_list = draw_data->CmdLists[n]; - ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - int needed_vtx_size = cmd_list->VtxBuffer.size() * sizeof(ImDrawVert); - if (g_VboSize < needed_vtx_size) - { - // Grow our buffer if needed - g_VboSize = needed_vtx_size + 2000 * sizeof(ImDrawVert); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)g_VboSize, NULL, GL_STREAM_DRAW); - } - - unsigned char* vtx_data = (unsigned char*)glMapBufferRange(GL_ARRAY_BUFFER, 0, needed_vtx_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - if (!vtx_data) - continue; - memcpy(vtx_data, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); - glUnmapBuffer(GL_ARRAY_BUFFER); - - for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) - { - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)(pcmd->ClipRect.x * g_displayScale), - (int)((height - pcmd->ClipRect.w) * g_displayScale), - (int)((pcmd->ClipRect.z - pcmd->ClipRect.x) * g_displayScale), - (int)((pcmd->ClipRect.w - pcmd->ClipRect.y) * g_displayScale)); - glDrawElements( GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer ); - } - idx_buffer += pcmd->ElemCount; - } - } - - // Restore modified state - glBindVertexArray(0); - glBindBuffer( GL_ARRAY_BUFFER, 0); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - glUseProgram(last_program); - glDisable(GL_SCISSOR_TEST); - glBindTexture(GL_TEXTURE_2D, last_texture); -} - -void ImGui_ImplIOS_CreateFontsTexture() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); -} - -bool ImGui_ImplIOS_CreateDeviceObjects() -{ - const GLchar *vertex_shader = - "uniform mat4 ProjMtx;\n" - "attribute highp vec2 Position;\n" - "attribute highp vec2 UV;\n" - "attribute highp vec4 Color;\n" - "varying vec2 Frag_UV;\n" - "varying vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" - "}\n"; - - const GLchar* fragment_shader = - "uniform sampler2D Texture;\n" - "varying highp vec2 Frag_UV;\n" - "varying highp vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" - "}\n"; - - g_ShaderHandle = glCreateProgram(); - g_VertHandle = glCreateShader(GL_VERTEX_SHADER); - g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_VertHandle, 1, &vertex_shader, 0); - glShaderSource(g_FragHandle, 1, &fragment_shader, 0); - glCompileShader(g_VertHandle); - -#if defined(DEBUG) - GLint logLength; - glGetShaderiv( g_VertHandle, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(g_VertHandle, logLength, &logLength, log); - NSLog(@"VERTEX Shader compile log:\n%s", log); - free(log); - } -#endif - - glCompileShader(g_FragHandle); - -#if defined(DEBUG) - glGetShaderiv( g_FragHandle, GL_INFO_LOG_LENGTH, &logLength); - if (logLength > 0) { - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(g_FragHandle, logLength, &logLength, log); - NSLog(@"FRAGMENT Shader compile log:\n%s", log); - free(log); - } -#endif - - glAttachShader(g_ShaderHandle, g_VertHandle); - glAttachShader(g_ShaderHandle, g_FragHandle); - glLinkProgram(g_ShaderHandle); - - g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); - g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); - g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); - g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); - g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); - - glGenBuffers(1, &g_VboHandle); - - glGenVertexArrays(1, &g_VaoHandle); - glBindVertexArray(g_VaoHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); - -#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); -#undef OFFSETOF - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - ImGui_ImplIOS_CreateFontsTexture(); - - return true; -} diff --git a/examples/ios_example/imguiex/main.m b/examples/ios_example/imguiex/main.m deleted file mode 100644 index faba099..0000000 --- a/examples/ios_example/imguiex/main.m +++ /dev/null @@ -1,13 +0,0 @@ -// -// main.m -// imguiex -// - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -}