diff --git a/.gitignore b/.gitignore index 69d9247..79a9a7c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ android/src/main/assets/ android/.idea android/android.iml android/local.properties +data/brushes +data/thumbs diff --git a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/Contents.json b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/Contents.json index 689c82d..14fbabd 100644 --- a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -43,13 +43,13 @@ { "size" : "512x512", "idiom" : "mac", - "filename" : "icon512.png", + "filename" : "iTunesArtwork.png", "scale" : "1x" }, { "size" : "512x512", "idiom" : "mac", - "filename" : "icon1024.png", + "filename" : "iTunesArtwork@2x.png", "scale" : "2x" } ], diff --git a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/iTunesArtwork.png b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/iTunesArtwork.png new file mode 100644 index 0000000..12c9ba3 Binary files /dev/null and b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/iTunesArtwork.png differ diff --git a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png new file mode 100644 index 0000000..109d77b Binary files /dev/null and b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png differ diff --git a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/icon1024.png b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/icon1024.png deleted file mode 100644 index da62a12..0000000 Binary files a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/icon1024.png and /dev/null differ diff --git a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/icon512.png b/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/icon512.png deleted file mode 100644 index da62a12..0000000 Binary files a/PanoPainter-OSX/Assets.xcassets/AppIcon.appiconset/icon512.png and /dev/null differ diff --git a/PanoPainter-OSX/main.cpp b/PanoPainter-OSX/main.cpp index ba21059..8b2c9d4 100644 --- a/PanoPainter-OSX/main.cpp +++ b/PanoPainter-OSX/main.cpp @@ -6,20 +6,26 @@ #include "image.h" #include "app.h" #include "keymap.h" +#include "main.h" #include #include #include #include -@interface View : NSOpenGLView +@implementation View +- (void)async_lock { - CVDisplayLinkRef dl; - NSOpenGLContext* glctx; - _CGLContextObject* cgl; - bool gl_ready; + CGLLockContext([glctx CGLContextObj]); + [glctx makeCurrentContext]; +} +- (void)async_unlock +{ + CGLUnlockContext([glctx CGLContextObj]); +} +- (void)async_swap +{ + CGLFlushDrawable([glctx CGLContextObj]); } -- (void)terminateGL; -@end @implementation View - (instancetype)initWithFrame:(NSRect)frameRect { gl_ready = false; @@ -98,22 +104,25 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime double now = hostTime / _timeFreq; // this will not update unless 1/30th of a second has passed since the last update - if ( now < _prevTime + (1.0 / 30.0) && App::I.redraw ) + if (1 /*now < _prevTime + (1.0 / 30.0) &&*/ ) { // We draw on a secondary thread through the display link // When resizing the view, -reshape is called automatically on the main // thread. Add a mutex around to avoid the threads accessing the context // simultaneously when resizing - [glctx makeCurrentContext]; CGLLockContext([glctx CGLContextObj]); - - App::I.clear(); - App::I.update(now - _prevTime); + [glctx makeCurrentContext]; + + if (App::I.redraw) + { + App::I.clear(); + App::I.update(now - _prevTime); + CGLFlushDrawable([glctx CGLContextObj]); + } //[[self openGLContext] flushBuffer]; // returning NO will cause the layer to NOT be redrawn - CGLFlushDrawable([glctx CGLContextObj]); CGLUnlockContext([glctx CGLContextObj]); return NO; } @@ -142,9 +151,11 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime // When resizing the view, -reshape is called automatically on the main // thread. Add a mutex around to avoid the threads accessing the context // simultaneously when resizing - [glctx makeCurrentContext]; CGLLockContext(cgl); + [glctx makeCurrentContext]; + App::I.redraw = true; + App::I.clear(); App::I.update(0); //[[self openGLContext] flushBuffer]; @@ -325,6 +336,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime view = [[View alloc] initWithFrame:r]; controller = [[Controller alloc] initWithWindow:window]; + App::I.osx_view = view; auto style = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask; window = [[Window alloc] initWithContentRect:r styleMask:style backing:NSBackingStoreBuffered defer:NO]; diff --git a/PanoPainter-OSX/main.h b/PanoPainter-OSX/main.h new file mode 100644 index 0000000..8b3ecac --- /dev/null +++ b/PanoPainter-OSX/main.h @@ -0,0 +1,17 @@ +#include +#include +#include +#include + +@interface View : NSOpenGLView +{ + CVDisplayLinkRef dl; + NSOpenGLContext* glctx; + _CGLContextObject* cgl; + bool gl_ready; +} +- (void)terminateGL; +- (void)async_lock; +- (void)async_unlock; +- (void)async_swap; +@end diff --git a/PanoPainter/Assets.xcassets/AppIcon.appiconset/Contents.json b/PanoPainter/Assets.xcassets/AppIcon.appiconset/Contents.json index 225fd2e..7c5579c 100644 --- a/PanoPainter/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/PanoPainter/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -83,13 +83,13 @@ { "size" : "83.5x83.5", "idiom" : "ipad", - "filename" : "icon512.png", + "filename" : "Icon-83.5@2x.png", "scale" : "2x" }, { "size" : "1024x1024", "idiom" : "ios-marketing", - "filename" : "icon1024.png", + "filename" : "iTunesArtwork@2x.png", "scale" : "1x" } ], diff --git a/PanoPainter/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png b/PanoPainter/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png new file mode 100644 index 0000000..10fe93a Binary files /dev/null and b/PanoPainter/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png differ diff --git a/PanoPainter/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png b/PanoPainter/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png new file mode 100644 index 0000000..109d77b Binary files /dev/null and b/PanoPainter/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png differ diff --git a/PanoPainter/Assets.xcassets/AppIcon.appiconset/icon1024.png b/PanoPainter/Assets.xcassets/AppIcon.appiconset/icon1024.png deleted file mode 100644 index 5bf10fd..0000000 Binary files a/PanoPainter/Assets.xcassets/AppIcon.appiconset/icon1024.png and /dev/null differ diff --git a/PanoPainter/Assets.xcassets/AppIcon.appiconset/icon512.png b/PanoPainter/Assets.xcassets/AppIcon.appiconset/icon512.png deleted file mode 100644 index 92ee41c..0000000 Binary files a/PanoPainter/Assets.xcassets/AppIcon.appiconset/icon512.png and /dev/null differ diff --git a/PanoPainter/GameViewController.h b/PanoPainter/GameViewController.h index 8b11eca..8462543 100644 --- a/PanoPainter/GameViewController.h +++ b/PanoPainter/GameViewController.h @@ -10,7 +10,12 @@ #import @interface GameViewController : GLKViewController - +{ +@public GLKView* glview; +} - (void)reset_touch; +- (void)async_lock; +- (void)async_unlock; +- (void)async_swap; @end diff --git a/PanoPainter/GameViewController.m b/PanoPainter/GameViewController.m index 52731d4..4f5272a 100644 --- a/PanoPainter/GameViewController.m +++ b/PanoPainter/GameViewController.m @@ -12,6 +12,7 @@ #include "app.h" @interface GameViewController () { + NSLock* gl_lock; } @property (strong, nonatomic) EAGLContext *context; @@ -24,6 +25,21 @@ int t_count = 0; glm::vec2 t_pos; @implementation GameViewController +- (void)async_lock +{ + [gl_lock lock]; + [EAGLContext setCurrentContext:self.context]; + GLKView* view = (GLKView*)self.view; + //[view bindDrawable]; +} +- (void)async_unlock +{ + [gl_lock unlock]; +} +- (void)async_swap +{ + [[EAGLContext currentContext] presentRenderbuffer:GL_RENDERBUFFER]; +} - (void)insertText:(NSString *)text { @@ -84,9 +100,11 @@ glm::vec2 t_pos; frame.size.height -= kbSize.height; view.frame = frame; + [gl_lock lock]; App::I.resize(frame.size.width * view.contentScaleFactor, frame.size.height * view.contentScaleFactor); App::I.animate = false; + [gl_lock unlock]; } // Called when the UIKeyboardWillHideNotification is sent @@ -94,17 +112,21 @@ glm::vec2 t_pos; { CGRect frame = [[UIScreen mainScreen] bounds]; self.view.frame = frame; + [gl_lock lock]; App::I.resize(frame.size.width * self.view.contentScaleFactor, frame.size.height * self.view.contentScaleFactor); App::I.animate = true; + [gl_lock unlock]; } - (void)reset_touch { + [gl_lock lock]; if (t_count == 2) App::I.gesture_end(); else App::I.mouse_cancel(0); + [gl_lock unlock]; t_count = 0; } @@ -116,7 +138,9 @@ glm::vec2 t_pos; float scale = self.view.contentScaleFactor; kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch; + [gl_lock lock]; App::I.mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, touch.force, source); + [gl_lock unlock]; t_count = 1; t_pos = {touchLocation.x * scale, touchLocation.y * scale}; } @@ -139,6 +163,7 @@ glm::vec2 t_pos; p1 = glm::vec2(tl1.x * scale, tl1.y * scale); } + [gl_lock lock]; if (n == 2) { if (t_count == 1) @@ -167,6 +192,7 @@ glm::vec2 t_pos; App::I.mouse_move(touchLocation.x * scale, touchLocation.y * scale, force, source); } } + [gl_lock unlock]; t_pos = {tl0.x * scale, tl0.y * scale}; } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event @@ -177,18 +203,23 @@ glm::vec2 t_pos; kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch; + [gl_lock lock]; if (t_count == 2) App::I.gesture_end(); else App::I.mouse_up(0, touchLocation.x * scale, touchLocation.y * scale, source); + [gl_lock unlock]; + t_count = 0; t_pos = {touchLocation.x * scale, touchLocation.y * scale}; } - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { + [gl_lock lock]; App::I.resize(size.width * self.view.contentScaleFactor, size.height * self.view.contentScaleFactor); + [gl_lock unlock]; } - (void)viewDidAppear:(BOOL)animated @@ -211,9 +242,12 @@ glm::vec2 t_pos; NSLog(@"Failed to create ES context"); } + gl_lock = [[NSLock alloc] init]; + GLKView *view = (GLKView *)self.view; view.context = self.context; view.drawableDepthFormat = GLKViewDrawableDepthFormat24; + glview = view; App::I.width = view.frame.size.width * view.contentScaleFactor; App::I.height = view.frame.size.height * view.contentScaleFactor; @@ -273,10 +307,18 @@ glm::vec2 t_pos; - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { + [gl_lock lock]; if (!(App::I.redraw || App::I.animate)) + { + [gl_lock unlock]; return; + } + [EAGLContext setCurrentContext:self.context]; + [view bindDrawable]; App::I.clear(); App::I.update(0); + //[self.context presentRenderbuffer:GL_FRAMEBUFFER]; + [gl_lock unlock]; } @end diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt index d29613b..bb46871 100644 --- a/android/CMakeLists.txt +++ b/android/CMakeLists.txt @@ -71,6 +71,7 @@ add_library( ../engine/node_panel_layer.cpp ../engine/node_panel_stroke.cpp ../engine/node_popup_menu.cpp + ../engine/node_progress_bar.cpp ../engine/node_settings.cpp ../engine/node_slider.cpp ../engine/node_stroke_preview.cpp @@ -82,6 +83,7 @@ add_library( target_include_directories(native-lib PRIVATE ${ANDROID_NDK}/sources/android/native_app_glue + src/main/cpp ../engine ../libs/glm ../libs/tinyxml2 diff --git a/android/build.gradle b/android/build.gradle index bb8220b..f19e8eb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,7 +30,7 @@ android { arguments '-DANDROID_PLATFORM=android-19', '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static', - '-DCMAKE_BUILD_TYPE=Release', + '-DCMAKE_BUILD_TYPE=Debug', '-DANDROID_ARM_NEON=TRUE' } } diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 165e683..c260002 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -15,7 +15,8 @@ android:label="@string/app_name" android:configChanges="orientation|keyboardHidden" android:screenOrientation="sensorLandscape" - android:noHistory="true"> + android:noHistory="true" + android:windowSoftInputMode="adjustResize"> diff --git a/android/src/main/cpp/main.cpp b/android/src/main/cpp/main.cpp index c557b41..109339a 100755 --- a/android/src/main/cpp/main.cpp +++ b/android/src/main/cpp/main.cpp @@ -28,6 +28,7 @@ #include "app.h" #include "asset.h" #include "keymap.h" +#include "main.h" typedef void (*GLDEBUGPROC)(GLenum source, GLenum type, @@ -47,39 +48,9 @@ typedef void (*fnDebugMessageCallback)(GLDEBUGPROC callback, const void* userPar #define GL_DEBUG_OUTPUT 0x92E0 #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -/** - * Our saved state data. - */ -struct saved_state { - float angle; - int32_t x; - int32_t y; - EGLDisplay display; - EGLContext context; -}; - EGLDisplay g_display = EGL_NO_DISPLAY; EGLContext g_context = EGL_NO_CONTEXT; -/** - * Shared state for our app. - */ -struct engine { - struct android_app* app; - - ASensorManager* sensorManager; - const ASensor* accelerometerSensor; - ASensorEventQueue* sensorEventQueue; - - int animating; - EGLDisplay display; - EGLSurface surface; - EGLContext context; - int32_t width; - int32_t height; - struct saved_state state; -}; - std::string utf8chr(int cp) { char c[5]={ 0x00,0x00,0x00,0x00,0x00 }; @@ -144,6 +115,32 @@ int GetUnicodeChar(struct android_app* app, int eventType, int keyCode, int meta return unicodeKey; } +void android_async_lock(struct engine* engine) +{ + pthread_mutex_lock(&engine->app->mutex); + LOG("lock"); + eglMakeCurrent(engine->display, engine->surface, engine->surface, engine->context); +} + +void android_async_swap(struct engine* engine) +{ + eglSwapBuffers(engine->display, engine->surface); +} + +void android_async_unlock(struct engine* engine) +{ + eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + LOG("unlock"); + pthread_mutex_unlock(&engine->app->mutex); +} + +struct locker +{ + struct engine* e; + locker(struct engine* _e){ e = _e; android_async_lock(e); } + ~locker(){ android_async_unlock(e); } +}; + // see https://groups.google.com/forum/#!topic/android-ndk/Tk3g00wLKhk void displayKeyboard(android_app* mApplication, bool pShow) { @@ -492,6 +489,7 @@ static int engine_init_display(struct engine* engine) { //glEnableClientState(GL_VERTEX_ARRAY); Asset::m_am = engine->app->activity->assetManager; App::I.and_app = engine->app; + App::I.and_engine = engine; App::I.data_path = "/sdcard/PanoPainter";// engine->app->activity->externalDataPath; App::I.width = w; App::I.height = h; @@ -508,6 +506,7 @@ static int engine_init_display(struct engine* engine) { * Just the current frame in the display. */ static void engine_draw_frame(struct engine* engine) { + locker _lock(engine); if (engine->display == NULL || !(App::I.redraw || App::I.animate)) return; @@ -543,8 +542,11 @@ static void engine_term_display(struct engine* engine) { static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; int32_t eventType = AInputEvent_getType(event); - App::I.redraw = true; //LOG("event type: %d", eventType); + + locker _locker{engine}; + App::I.redraw = true; + switch (eventType) { case AINPUT_EVENT_TYPE_MOTION: // switch (AInputEvent_getSource(event)) { diff --git a/android/src/main/cpp/main.h b/android/src/main/cpp/main.h new file mode 100755 index 0000000..2fca58e --- /dev/null +++ b/android/src/main/cpp/main.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +/** + * Our saved state data. + */ +struct saved_state { + float angle; + int32_t x; + int32_t y; + EGLDisplay display; + EGLContext context; +}; + +/** + * Shared state for our app. + */ +struct engine { + struct android_app* app; + + ASensorManager* sensorManager; + const ASensor* accelerometerSensor; + ASensorEventQueue* sensorEventQueue; + + int animating; + EGLDisplay display; + EGLSurface surface; + EGLContext context; + int32_t width; + int32_t height; + struct saved_state state; +}; diff --git a/android/src/main/res/drawable-hdpi/ic_launcher.png b/android/src/main/res/drawable-hdpi/ic_launcher.png index 7917264..da59fd1 100644 Binary files a/android/src/main/res/drawable-hdpi/ic_launcher.png and b/android/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/android/src/main/res/drawable-ldpi/ic_launcher.png b/android/src/main/res/drawable-ldpi/ic_launcher.png index 325d02c..d81dca2 100644 Binary files a/android/src/main/res/drawable-ldpi/ic_launcher.png and b/android/src/main/res/drawable-ldpi/ic_launcher.png differ diff --git a/android/src/main/res/drawable-mdpi/ic_launcher.png b/android/src/main/res/drawable-mdpi/ic_launcher.png index af7a0c4..584c4bc 100644 Binary files a/android/src/main/res/drawable-mdpi/ic_launcher.png and b/android/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/android/src/main/res/drawable-xhdpi/ic_launcher.png b/android/src/main/res/drawable-xhdpi/ic_launcher.png index 1afe1a5..ee9b6ff 100644 Binary files a/android/src/main/res/drawable-xhdpi/ic_launcher.png and b/android/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/data/layout.xml b/data/layout.xml index f920a25..2fd08c0 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -104,7 +104,7 @@ - + @@ -215,6 +215,24 @@ + + + + + + + + + + + +