implement multithreaded rendering with context switch, gl state save/restore, add progress bar ui node, implement stencil texture for brush, implement multithreaded canvas load/save/export pano. Missing multithread in windows.
2
.gitignore
vendored
@@ -14,3 +14,5 @@ android/src/main/assets/
|
|||||||
android/.idea
|
android/.idea
|
||||||
android/android.iml
|
android/android.iml
|
||||||
android/local.properties
|
android/local.properties
|
||||||
|
data/brushes
|
||||||
|
data/thumbs
|
||||||
|
|||||||
@@ -43,13 +43,13 @@
|
|||||||
{
|
{
|
||||||
"size" : "512x512",
|
"size" : "512x512",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon512.png",
|
"filename" : "iTunesArtwork.png",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "512x512",
|
"size" : "512x512",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"filename" : "icon1024.png",
|
"filename" : "iTunesArtwork@2x.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
@@ -6,20 +6,26 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "keymap.h"
|
#include "keymap.h"
|
||||||
|
#include "main.h"
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
#include <CoreVideo/CoreVideo.h>
|
#include <CoreVideo/CoreVideo.h>
|
||||||
#include <OpenGL/OpenGL.h>
|
#include <OpenGL/OpenGL.h>
|
||||||
|
|
||||||
@interface View : NSOpenGLView
|
@implementation View
|
||||||
|
- (void)async_lock
|
||||||
{
|
{
|
||||||
CVDisplayLinkRef dl;
|
CGLLockContext([glctx CGLContextObj]);
|
||||||
NSOpenGLContext* glctx;
|
[glctx makeCurrentContext];
|
||||||
_CGLContextObject* cgl;
|
}
|
||||||
bool gl_ready;
|
- (void)async_unlock
|
||||||
|
{
|
||||||
|
CGLUnlockContext([glctx CGLContextObj]);
|
||||||
|
}
|
||||||
|
- (void)async_swap
|
||||||
|
{
|
||||||
|
CGLFlushDrawable([glctx CGLContextObj]);
|
||||||
}
|
}
|
||||||
- (void)terminateGL;
|
|
||||||
@end @implementation View
|
|
||||||
- (instancetype)initWithFrame:(NSRect)frameRect
|
- (instancetype)initWithFrame:(NSRect)frameRect
|
||||||
{
|
{
|
||||||
gl_ready = false;
|
gl_ready = false;
|
||||||
@@ -98,22 +104,25 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
double now = hostTime / _timeFreq;
|
double now = hostTime / _timeFreq;
|
||||||
|
|
||||||
// this will not update unless 1/30th of a second has passed since the last update
|
// 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
|
// We draw on a secondary thread through the display link
|
||||||
// When resizing the view, -reshape is called automatically on the main
|
// When resizing the view, -reshape is called automatically on the main
|
||||||
// thread. Add a mutex around to avoid the threads accessing the context
|
// thread. Add a mutex around to avoid the threads accessing the context
|
||||||
// simultaneously when resizing
|
// simultaneously when resizing
|
||||||
[glctx makeCurrentContext];
|
|
||||||
CGLLockContext([glctx CGLContextObj]);
|
CGLLockContext([glctx CGLContextObj]);
|
||||||
|
[glctx makeCurrentContext];
|
||||||
|
|
||||||
App::I.clear();
|
if (App::I.redraw)
|
||||||
App::I.update(now - _prevTime);
|
{
|
||||||
|
App::I.clear();
|
||||||
|
App::I.update(now - _prevTime);
|
||||||
|
CGLFlushDrawable([glctx CGLContextObj]);
|
||||||
|
}
|
||||||
|
|
||||||
//[[self openGLContext] flushBuffer];
|
//[[self openGLContext] flushBuffer];
|
||||||
// returning NO will cause the layer to NOT be redrawn
|
// returning NO will cause the layer to NOT be redrawn
|
||||||
|
|
||||||
CGLFlushDrawable([glctx CGLContextObj]);
|
|
||||||
CGLUnlockContext([glctx CGLContextObj]);
|
CGLUnlockContext([glctx CGLContextObj]);
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
@@ -142,9 +151,11 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
// When resizing the view, -reshape is called automatically on the main
|
// When resizing the view, -reshape is called automatically on the main
|
||||||
// thread. Add a mutex around to avoid the threads accessing the context
|
// thread. Add a mutex around to avoid the threads accessing the context
|
||||||
// simultaneously when resizing
|
// simultaneously when resizing
|
||||||
[glctx makeCurrentContext];
|
|
||||||
CGLLockContext(cgl);
|
CGLLockContext(cgl);
|
||||||
|
[glctx makeCurrentContext];
|
||||||
|
|
||||||
|
App::I.redraw = true;
|
||||||
|
App::I.clear();
|
||||||
App::I.update(0);
|
App::I.update(0);
|
||||||
|
|
||||||
//[[self openGLContext] flushBuffer];
|
//[[self openGLContext] flushBuffer];
|
||||||
@@ -325,6 +336,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
|
|||||||
|
|
||||||
view = [[View alloc] initWithFrame:r];
|
view = [[View alloc] initWithFrame:r];
|
||||||
controller = [[Controller alloc] initWithWindow:window];
|
controller = [[Controller alloc] initWithWindow:window];
|
||||||
|
App::I.osx_view = view;
|
||||||
|
|
||||||
auto style = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask;
|
auto style = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask;
|
||||||
window = [[Window alloc] initWithContentRect:r styleMask:style backing:NSBackingStoreBuffered defer:NO];
|
window = [[Window alloc] initWithContentRect:r styleMask:style backing:NSBackingStoreBuffered defer:NO];
|
||||||
|
|||||||
17
PanoPainter-OSX/main.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <CoreVideo/CoreVideo.h>
|
||||||
|
#include <OpenGL/OpenGL.h>
|
||||||
|
|
||||||
|
@interface View : NSOpenGLView
|
||||||
|
{
|
||||||
|
CVDisplayLinkRef dl;
|
||||||
|
NSOpenGLContext* glctx;
|
||||||
|
_CGLContextObject* cgl;
|
||||||
|
bool gl_ready;
|
||||||
|
}
|
||||||
|
- (void)terminateGL;
|
||||||
|
- (void)async_lock;
|
||||||
|
- (void)async_unlock;
|
||||||
|
- (void)async_swap;
|
||||||
|
@end
|
||||||
@@ -83,13 +83,13 @@
|
|||||||
{
|
{
|
||||||
"size" : "83.5x83.5",
|
"size" : "83.5x83.5",
|
||||||
"idiom" : "ipad",
|
"idiom" : "ipad",
|
||||||
"filename" : "icon512.png",
|
"filename" : "Icon-83.5@2x.png",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "1024x1024",
|
"size" : "1024x1024",
|
||||||
"idiom" : "ios-marketing",
|
"idiom" : "ios-marketing",
|
||||||
"filename" : "icon1024.png",
|
"filename" : "iTunesArtwork@2x.png",
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
BIN
PanoPainter/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 266 KiB |
|
Before Width: | Height: | Size: 29 KiB |
@@ -10,7 +10,12 @@
|
|||||||
#import <GLKit/GLKit.h>
|
#import <GLKit/GLKit.h>
|
||||||
|
|
||||||
@interface GameViewController : GLKViewController <UIKeyInput>
|
@interface GameViewController : GLKViewController <UIKeyInput>
|
||||||
|
{
|
||||||
|
@public GLKView* glview;
|
||||||
|
}
|
||||||
- (void)reset_touch;
|
- (void)reset_touch;
|
||||||
|
- (void)async_lock;
|
||||||
|
- (void)async_unlock;
|
||||||
|
- (void)async_swap;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
|
||||||
@interface GameViewController () {
|
@interface GameViewController () {
|
||||||
|
NSLock* gl_lock;
|
||||||
}
|
}
|
||||||
@property (strong, nonatomic) EAGLContext *context;
|
@property (strong, nonatomic) EAGLContext *context;
|
||||||
|
|
||||||
@@ -24,6 +25,21 @@ int t_count = 0;
|
|||||||
glm::vec2 t_pos;
|
glm::vec2 t_pos;
|
||||||
|
|
||||||
@implementation GameViewController
|
@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
|
- (void)insertText:(NSString *)text
|
||||||
{
|
{
|
||||||
@@ -84,9 +100,11 @@ glm::vec2 t_pos;
|
|||||||
frame.size.height -= kbSize.height;
|
frame.size.height -= kbSize.height;
|
||||||
view.frame = frame;
|
view.frame = frame;
|
||||||
|
|
||||||
|
[gl_lock lock];
|
||||||
App::I.resize(frame.size.width * view.contentScaleFactor,
|
App::I.resize(frame.size.width * view.contentScaleFactor,
|
||||||
frame.size.height * view.contentScaleFactor);
|
frame.size.height * view.contentScaleFactor);
|
||||||
App::I.animate = false;
|
App::I.animate = false;
|
||||||
|
[gl_lock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the UIKeyboardWillHideNotification is sent
|
// Called when the UIKeyboardWillHideNotification is sent
|
||||||
@@ -94,17 +112,21 @@ glm::vec2 t_pos;
|
|||||||
{
|
{
|
||||||
CGRect frame = [[UIScreen mainScreen] bounds];
|
CGRect frame = [[UIScreen mainScreen] bounds];
|
||||||
self.view.frame = frame;
|
self.view.frame = frame;
|
||||||
|
[gl_lock lock];
|
||||||
App::I.resize(frame.size.width * self.view.contentScaleFactor,
|
App::I.resize(frame.size.width * self.view.contentScaleFactor,
|
||||||
frame.size.height * self.view.contentScaleFactor);
|
frame.size.height * self.view.contentScaleFactor);
|
||||||
App::I.animate = true;
|
App::I.animate = true;
|
||||||
|
[gl_lock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reset_touch
|
- (void)reset_touch
|
||||||
{
|
{
|
||||||
|
[gl_lock lock];
|
||||||
if (t_count == 2)
|
if (t_count == 2)
|
||||||
App::I.gesture_end();
|
App::I.gesture_end();
|
||||||
else
|
else
|
||||||
App::I.mouse_cancel(0);
|
App::I.mouse_cancel(0);
|
||||||
|
[gl_lock unlock];
|
||||||
t_count = 0;
|
t_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +138,9 @@ glm::vec2 t_pos;
|
|||||||
float scale = self.view.contentScaleFactor;
|
float scale = self.view.contentScaleFactor;
|
||||||
|
|
||||||
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
|
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);
|
App::I.mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, touch.force, source);
|
||||||
|
[gl_lock unlock];
|
||||||
t_count = 1;
|
t_count = 1;
|
||||||
t_pos = {touchLocation.x * scale, touchLocation.y * scale};
|
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);
|
p1 = glm::vec2(tl1.x * scale, tl1.y * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[gl_lock lock];
|
||||||
if (n == 2)
|
if (n == 2)
|
||||||
{
|
{
|
||||||
if (t_count == 1)
|
if (t_count == 1)
|
||||||
@@ -167,6 +192,7 @@ glm::vec2 t_pos;
|
|||||||
App::I.mouse_move(touchLocation.x * scale, touchLocation.y * scale, force, source);
|
App::I.mouse_move(touchLocation.x * scale, touchLocation.y * scale, force, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[gl_lock unlock];
|
||||||
t_pos = {tl0.x * scale, tl0.y * scale};
|
t_pos = {tl0.x * scale, tl0.y * scale};
|
||||||
}
|
}
|
||||||
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
|
||||||
@@ -177,18 +203,23 @@ glm::vec2 t_pos;
|
|||||||
|
|
||||||
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
|
kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch;
|
||||||
|
|
||||||
|
[gl_lock lock];
|
||||||
if (t_count == 2)
|
if (t_count == 2)
|
||||||
App::I.gesture_end();
|
App::I.gesture_end();
|
||||||
else
|
else
|
||||||
App::I.mouse_up(0, touchLocation.x * scale, touchLocation.y * scale, source);
|
App::I.mouse_up(0, touchLocation.x * scale, touchLocation.y * scale, source);
|
||||||
|
[gl_lock unlock];
|
||||||
|
|
||||||
t_count = 0;
|
t_count = 0;
|
||||||
t_pos = {touchLocation.x * scale, touchLocation.y * scale};
|
t_pos = {touchLocation.x * scale, touchLocation.y * scale};
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
|
||||||
{
|
{
|
||||||
|
[gl_lock lock];
|
||||||
App::I.resize(size.width * self.view.contentScaleFactor,
|
App::I.resize(size.width * self.view.contentScaleFactor,
|
||||||
size.height * self.view.contentScaleFactor);
|
size.height * self.view.contentScaleFactor);
|
||||||
|
[gl_lock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidAppear:(BOOL)animated
|
- (void)viewDidAppear:(BOOL)animated
|
||||||
@@ -211,9 +242,12 @@ glm::vec2 t_pos;
|
|||||||
NSLog(@"Failed to create ES context");
|
NSLog(@"Failed to create ES context");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl_lock = [[NSLock alloc] init];
|
||||||
|
|
||||||
GLKView *view = (GLKView *)self.view;
|
GLKView *view = (GLKView *)self.view;
|
||||||
view.context = self.context;
|
view.context = self.context;
|
||||||
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
|
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
|
||||||
|
glview = view;
|
||||||
|
|
||||||
App::I.width = view.frame.size.width * view.contentScaleFactor;
|
App::I.width = view.frame.size.width * view.contentScaleFactor;
|
||||||
App::I.height = view.frame.size.height * 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
|
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
|
||||||
{
|
{
|
||||||
|
[gl_lock lock];
|
||||||
if (!(App::I.redraw || App::I.animate))
|
if (!(App::I.redraw || App::I.animate))
|
||||||
|
{
|
||||||
|
[gl_lock unlock];
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
[EAGLContext setCurrentContext:self.context];
|
||||||
|
[view bindDrawable];
|
||||||
App::I.clear();
|
App::I.clear();
|
||||||
App::I.update(0);
|
App::I.update(0);
|
||||||
|
//[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||||
|
[gl_lock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ add_library(
|
|||||||
../engine/node_panel_layer.cpp
|
../engine/node_panel_layer.cpp
|
||||||
../engine/node_panel_stroke.cpp
|
../engine/node_panel_stroke.cpp
|
||||||
../engine/node_popup_menu.cpp
|
../engine/node_popup_menu.cpp
|
||||||
|
../engine/node_progress_bar.cpp
|
||||||
../engine/node_settings.cpp
|
../engine/node_settings.cpp
|
||||||
../engine/node_slider.cpp
|
../engine/node_slider.cpp
|
||||||
../engine/node_stroke_preview.cpp
|
../engine/node_stroke_preview.cpp
|
||||||
@@ -82,6 +83,7 @@ add_library(
|
|||||||
|
|
||||||
target_include_directories(native-lib PRIVATE
|
target_include_directories(native-lib PRIVATE
|
||||||
${ANDROID_NDK}/sources/android/native_app_glue
|
${ANDROID_NDK}/sources/android/native_app_glue
|
||||||
|
src/main/cpp
|
||||||
../engine
|
../engine
|
||||||
../libs/glm
|
../libs/glm
|
||||||
../libs/tinyxml2
|
../libs/tinyxml2
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ android {
|
|||||||
arguments '-DANDROID_PLATFORM=android-19',
|
arguments '-DANDROID_PLATFORM=android-19',
|
||||||
'-DANDROID_TOOLCHAIN=clang',
|
'-DANDROID_TOOLCHAIN=clang',
|
||||||
'-DANDROID_STL=gnustl_static',
|
'-DANDROID_STL=gnustl_static',
|
||||||
'-DCMAKE_BUILD_TYPE=Release',
|
'-DCMAKE_BUILD_TYPE=Debug',
|
||||||
'-DANDROID_ARM_NEON=TRUE'
|
'-DANDROID_ARM_NEON=TRUE'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:screenOrientation="sensorLandscape"
|
android:screenOrientation="sensorLandscape"
|
||||||
android:noHistory="true">
|
android:noHistory="true"
|
||||||
|
android:windowSoftInputMode="adjustResize">
|
||||||
<meta-data android:name="android.app.lib_name"
|
<meta-data android:name="android.app.lib_name"
|
||||||
android:value="native-lib" />
|
android:value="native-lib" />
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "asset.h"
|
#include "asset.h"
|
||||||
#include "keymap.h"
|
#include "keymap.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
typedef void (*GLDEBUGPROC)(GLenum source,
|
typedef void (*GLDEBUGPROC)(GLenum source,
|
||||||
GLenum type,
|
GLenum type,
|
||||||
@@ -47,39 +48,9 @@ typedef void (*fnDebugMessageCallback)(GLDEBUGPROC callback, const void* userPar
|
|||||||
#define GL_DEBUG_OUTPUT 0x92E0
|
#define GL_DEBUG_OUTPUT 0x92E0
|
||||||
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
|
#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;
|
EGLDisplay g_display = EGL_NO_DISPLAY;
|
||||||
EGLContext g_context = EGL_NO_CONTEXT;
|
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)
|
std::string utf8chr(int cp)
|
||||||
{
|
{
|
||||||
char c[5]={ 0x00,0x00,0x00,0x00,0x00 };
|
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;
|
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
|
// see https://groups.google.com/forum/#!topic/android-ndk/Tk3g00wLKhk
|
||||||
void displayKeyboard(android_app* mApplication, bool pShow)
|
void displayKeyboard(android_app* mApplication, bool pShow)
|
||||||
{
|
{
|
||||||
@@ -492,6 +489,7 @@ static int engine_init_display(struct engine* engine) {
|
|||||||
//glEnableClientState(GL_VERTEX_ARRAY);
|
//glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
Asset::m_am = engine->app->activity->assetManager;
|
Asset::m_am = engine->app->activity->assetManager;
|
||||||
App::I.and_app = engine->app;
|
App::I.and_app = engine->app;
|
||||||
|
App::I.and_engine = engine;
|
||||||
App::I.data_path = "/sdcard/PanoPainter";// engine->app->activity->externalDataPath;
|
App::I.data_path = "/sdcard/PanoPainter";// engine->app->activity->externalDataPath;
|
||||||
App::I.width = w;
|
App::I.width = w;
|
||||||
App::I.height = h;
|
App::I.height = h;
|
||||||
@@ -508,6 +506,7 @@ static int engine_init_display(struct engine* engine) {
|
|||||||
* Just the current frame in the display.
|
* Just the current frame in the display.
|
||||||
*/
|
*/
|
||||||
static void engine_draw_frame(struct engine* engine) {
|
static void engine_draw_frame(struct engine* engine) {
|
||||||
|
locker _lock(engine);
|
||||||
if (engine->display == NULL || !(App::I.redraw || App::I.animate))
|
if (engine->display == NULL || !(App::I.redraw || App::I.animate))
|
||||||
return;
|
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) {
|
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
|
||||||
struct engine* engine = (struct engine*)app->userData;
|
struct engine* engine = (struct engine*)app->userData;
|
||||||
int32_t eventType = AInputEvent_getType(event);
|
int32_t eventType = AInputEvent_getType(event);
|
||||||
App::I.redraw = true;
|
|
||||||
//LOG("event type: %d", eventType);
|
//LOG("event type: %d", eventType);
|
||||||
|
|
||||||
|
locker _locker{engine};
|
||||||
|
App::I.redraw = true;
|
||||||
|
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case AINPUT_EVENT_TYPE_MOTION:
|
case AINPUT_EVENT_TYPE_MOTION:
|
||||||
// switch (AInputEvent_getSource(event)) {
|
// switch (AInputEvent_getSource(event)) {
|
||||||
|
|||||||
34
android/src/main/cpp/main.h
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <EGL/eglext.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
};
|
||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 4.4 KiB |
@@ -104,7 +104,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
<!--brush-presets-item icon-->
|
<!--brush-presets-item icon-->
|
||||||
<layout id="tpl-brush-preset">
|
<layout id="tpl-brush-preset">
|
||||||
<button-custom width="100%" height="50" margin="1" pad="2" align="center" justify="center" dir="row">
|
<button-custom width="100%" height="50" margin="1" pad="5" align="center" justify="center" dir="row">
|
||||||
<image id="thumb" width="50" height="50"/>
|
<image id="thumb" width="50" height="50"/>
|
||||||
<stroke-preview id="canvas" width="1" grow="1" height="50"/>
|
<stroke-preview id="canvas" width="1" grow="1" height="50"/>
|
||||||
</button-custom>
|
</button-custom>
|
||||||
@@ -215,6 +215,24 @@
|
|||||||
</border>
|
</border>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
||||||
|
<layout id="progress-bar">
|
||||||
|
<border positioning="absolute" position="0 0" color=".4 .4 .4 .8" width="100%" height="100%" align="center" justify="center">
|
||||||
|
<border thickness="1" border-color=".2" pad="3">
|
||||||
|
<border width="400" height="30" color=".2 .2 .2 .9" dir="row" align="center" justify="center">
|
||||||
|
<text id="title" text="Just a test message" font-face="arial" font-size="11"></text>
|
||||||
|
</border>
|
||||||
|
<border width="400" color="0 0 0 .9" pad="10" dir="col">
|
||||||
|
<node height="40" grow="1" dir="row" align="flex-end" justify="flex-end">
|
||||||
|
<border width="50" height="30" grow="1" margin="0 10 0 0" color=".2">
|
||||||
|
<border id="progress" width="50%" color="1 0 0 1" height="30"/>
|
||||||
|
</border>
|
||||||
|
<button id="btn-cancel" text="Cancel" width="60" height="30" pad="10"/>
|
||||||
|
</node>
|
||||||
|
</border>
|
||||||
|
</border>
|
||||||
|
</border>
|
||||||
|
</layout>
|
||||||
|
|
||||||
<!-- Dialog Rename Layer -->
|
<!-- Dialog Rename Layer -->
|
||||||
<layout id="dialog-layer-rename">
|
<layout id="dialog-layer-rename">
|
||||||
<border positioning="absolute" position="0 0" color=".4 .4 .4 .8" width="100%" height="100%" align="center" justify="center">
|
<border positioning="absolute" position="0 0" color=".4 .4 .4 .8" width="100%" height="100%" align="center" justify="center">
|
||||||
|
|||||||
BIN
data/paper.jpg
Normal file
|
After Width: | Height: | Size: 233 KiB |
@@ -163,6 +163,9 @@
|
|||||||
ADC6F4661F3E66FB004177FA /* app_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */; };
|
ADC6F4661F3E66FB004177FA /* app_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */; };
|
||||||
ADC6F4671F3E66FB004177FA /* app_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */; };
|
ADC6F4671F3E66FB004177FA /* app_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */; };
|
||||||
ADC6F4681F3E66FB004177FA /* app_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */; };
|
ADC6F4681F3E66FB004177FA /* app_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */; };
|
||||||
|
ADD6AFD71F94DEB000E92461 /* node_progress_bar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADD6AFD61F94DEAF00E92461 /* node_progress_bar.cpp */; };
|
||||||
|
ADD6AFD81F94DEB000E92461 /* node_progress_bar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADD6AFD61F94DEAF00E92461 /* node_progress_bar.cpp */; };
|
||||||
|
ADD6AFDA1F94DEB900E92461 /* node_progress_bar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADD6AFD61F94DEAF00E92461 /* node_progress_bar.cpp */; };
|
||||||
ADD7D26F1EBF9AE300D5A897 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD7D26E1EBF9AE300D5A897 /* main.m */; };
|
ADD7D26F1EBF9AE300D5A897 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD7D26E1EBF9AE300D5A897 /* main.m */; };
|
||||||
ADD7D2721EBF9AE300D5A897 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD7D2711EBF9AE300D5A897 /* AppDelegate.m */; };
|
ADD7D2721EBF9AE300D5A897 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD7D2711EBF9AE300D5A897 /* AppDelegate.m */; };
|
||||||
ADD7D2791EBF9AE300D5A897 /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD7D2781EBF9AE300D5A897 /* GameViewController.m */; };
|
ADD7D2791EBF9AE300D5A897 /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ADD7D2781EBF9AE300D5A897 /* GameViewController.m */; };
|
||||||
@@ -293,6 +296,7 @@
|
|||||||
AD10637E1EC7ADFA002A525F /* node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = node.h; sourceTree = "<group>"; };
|
AD10637E1EC7ADFA002A525F /* node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = node.h; sourceTree = "<group>"; };
|
||||||
AD29CC601EA2B214008C8BFA /* action.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = action.cpp; sourceTree = "<group>"; };
|
AD29CC601EA2B214008C8BFA /* action.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = action.cpp; sourceTree = "<group>"; };
|
||||||
AD29CC611EA2B214008C8BFA /* action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = action.h; sourceTree = "<group>"; };
|
AD29CC611EA2B214008C8BFA /* action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = action.h; sourceTree = "<group>"; };
|
||||||
|
AD2FEBDA1F94A742002804DD /* main.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = main.h; sourceTree = "<group>"; };
|
||||||
AD30D82E1F783E0100B6A112 /* libcurl.4.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.4.tbd; path = usr/lib/libcurl.4.tbd; sourceTree = SDKROOT; };
|
AD30D82E1F783E0100B6A112 /* libcurl.4.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.4.tbd; path = usr/lib/libcurl.4.tbd; sourceTree = SDKROOT; };
|
||||||
AD30D8321F8049BC00B6A112 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; };
|
AD30D8321F8049BC00B6A112 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
AD3B1EBE1E3B8B7600E918E3 /* layout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layout.cpp; sourceTree = "<group>"; };
|
AD3B1EBE1E3B8B7600E918E3 /* layout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = layout.cpp; sourceTree = "<group>"; };
|
||||||
@@ -346,6 +350,8 @@
|
|||||||
ADC6F4601F3AFA2A004177FA /* node_dialog_layer_rename.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = node_dialog_layer_rename.h; sourceTree = "<group>"; };
|
ADC6F4601F3AFA2A004177FA /* node_dialog_layer_rename.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = node_dialog_layer_rename.h; sourceTree = "<group>"; };
|
||||||
ADC6F4611F3AFA2B004177FA /* node_dialog_layer_rename.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = node_dialog_layer_rename.cpp; sourceTree = "<group>"; };
|
ADC6F4611F3AFA2B004177FA /* node_dialog_layer_rename.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = node_dialog_layer_rename.cpp; sourceTree = "<group>"; };
|
||||||
ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = app_dialogs.cpp; sourceTree = "<group>"; };
|
ADC6F4651F3E66FA004177FA /* app_dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = app_dialogs.cpp; sourceTree = "<group>"; };
|
||||||
|
ADD6AFD51F94DEAF00E92461 /* node_progress_bar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = node_progress_bar.h; sourceTree = "<group>"; };
|
||||||
|
ADD6AFD61F94DEAF00E92461 /* node_progress_bar.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = node_progress_bar.cpp; sourceTree = "<group>"; };
|
||||||
ADD7D26B1EBF9AE300D5A897 /* PanoPainter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PanoPainter.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
ADD7D26B1EBF9AE300D5A897 /* PanoPainter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PanoPainter.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
ADD7D26E1EBF9AE300D5A897 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
ADD7D26E1EBF9AE300D5A897 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||||
ADD7D2701EBF9AE300D5A897 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
ADD7D2701EBF9AE300D5A897 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||||
@@ -428,6 +434,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
AD0E5CA21ECC6F2B00C35669 /* main.cpp */,
|
AD0E5CA21ECC6F2B00C35669 /* main.cpp */,
|
||||||
|
AD2FEBDA1F94A742002804DD /* main.h */,
|
||||||
);
|
);
|
||||||
name = "Supporting Files";
|
name = "Supporting Files";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -473,6 +480,8 @@
|
|||||||
AD10636E1EC7ADFA002A525F /* node_panel_stroke.h */,
|
AD10636E1EC7ADFA002A525F /* node_panel_stroke.h */,
|
||||||
AD10636F1EC7ADFA002A525F /* node_popup_menu.cpp */,
|
AD10636F1EC7ADFA002A525F /* node_popup_menu.cpp */,
|
||||||
AD1063701EC7ADFA002A525F /* node_popup_menu.h */,
|
AD1063701EC7ADFA002A525F /* node_popup_menu.h */,
|
||||||
|
ADD6AFD61F94DEAF00E92461 /* node_progress_bar.cpp */,
|
||||||
|
ADD6AFD51F94DEAF00E92461 /* node_progress_bar.h */,
|
||||||
AD1063711EC7ADFA002A525F /* node_settings.cpp */,
|
AD1063711EC7ADFA002A525F /* node_settings.cpp */,
|
||||||
AD1063721EC7ADFA002A525F /* node_settings.h */,
|
AD1063721EC7ADFA002A525F /* node_settings.h */,
|
||||||
AD1063731EC7ADFA002A525F /* node_slider.cpp */,
|
AD1063731EC7ADFA002A525F /* node_slider.cpp */,
|
||||||
@@ -777,6 +786,7 @@
|
|||||||
AD0E5CD21ECC72AD00C35669 /* app_events.cpp in Sources */,
|
AD0E5CD21ECC72AD00C35669 /* app_events.cpp in Sources */,
|
||||||
AD0E5CD11ECC72AD00C35669 /* app.cpp in Sources */,
|
AD0E5CD11ECC72AD00C35669 /* app.cpp in Sources */,
|
||||||
AD0E5CC21ECC72AD00C35669 /* node_image.cpp in Sources */,
|
AD0E5CC21ECC72AD00C35669 /* node_image.cpp in Sources */,
|
||||||
|
ADD6AFD71F94DEB000E92461 /* node_progress_bar.cpp in Sources */,
|
||||||
AD0E5CDB1ECC72AD00C35669 /* font.cpp in Sources */,
|
AD0E5CDB1ECC72AD00C35669 /* font.cpp in Sources */,
|
||||||
AD0E5CDA1ECC72AD00C35669 /* event.cpp in Sources */,
|
AD0E5CDA1ECC72AD00C35669 /* event.cpp in Sources */,
|
||||||
AD0E5CCB1ECC72AD00C35669 /* node_scroll.cpp in Sources */,
|
AD0E5CCB1ECC72AD00C35669 /* node_scroll.cpp in Sources */,
|
||||||
@@ -843,6 +853,7 @@
|
|||||||
AD58E0651E2A76FD006ACC15 /* shader.cpp in Sources */,
|
AD58E0651E2A76FD006ACC15 /* shader.cpp in Sources */,
|
||||||
AD4C08DA1E89BD0F0051D85F /* bezier.cpp in Sources */,
|
AD4C08DA1E89BD0F0051D85F /* bezier.cpp in Sources */,
|
||||||
AD0E11991ECA20F200CDA6BB /* app_shaders.cpp in Sources */,
|
AD0E11991ECA20F200CDA6BB /* app_shaders.cpp in Sources */,
|
||||||
|
ADD6AFDA1F94DEB900E92461 /* node_progress_bar.cpp in Sources */,
|
||||||
AD10638F1EC7ADFA002A525F /* node_settings.cpp in Sources */,
|
AD10638F1EC7ADFA002A525F /* node_settings.cpp in Sources */,
|
||||||
AD10638D1EC7ADFA002A525F /* node_panel_stroke.cpp in Sources */,
|
AD10638D1EC7ADFA002A525F /* node_panel_stroke.cpp in Sources */,
|
||||||
AD1063841EC7ADFA002A525F /* node_color_quad.cpp in Sources */,
|
AD1063841EC7ADFA002A525F /* node_color_quad.cpp in Sources */,
|
||||||
@@ -913,6 +924,7 @@
|
|||||||
ADD7D29F1EBF9E1C00D5A897 /* app.cpp in Sources */,
|
ADD7D29F1EBF9E1C00D5A897 /* app.cpp in Sources */,
|
||||||
AD1063A41EC7AE92002A525F /* node_panel_layer.cpp in Sources */,
|
AD1063A41EC7AE92002A525F /* node_panel_layer.cpp in Sources */,
|
||||||
AD1063AA1EC7AE92002A525F /* node_text_input.cpp in Sources */,
|
AD1063AA1EC7AE92002A525F /* node_text_input.cpp in Sources */,
|
||||||
|
ADD6AFD81F94DEB000E92461 /* node_progress_bar.cpp in Sources */,
|
||||||
AD0E119B1ECA215600CDA6BB /* node_scroll.cpp in Sources */,
|
AD0E119B1ECA215600CDA6BB /* node_scroll.cpp in Sources */,
|
||||||
ADD7D2941EBF9E1C00D5A897 /* asset.cpp in Sources */,
|
ADD7D2941EBF9E1C00D5A897 /* asset.cpp in Sources */,
|
||||||
ADE491191F86E65D00FB8E92 /* sweep_context.cc in Sources */,
|
ADE491191F86E65D00FB8E92 /* sweep_context.cc in Sources */,
|
||||||
|
|||||||
@@ -8,6 +8,12 @@
|
|||||||
#include <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
void android_async_lock(struct engine* engine);
|
||||||
|
void android_async_swap(struct engine* engine);
|
||||||
|
void android_async_unlock(struct engine* engine);
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
App App::I; // singleton
|
App App::I; // singleton
|
||||||
@@ -113,6 +119,49 @@ void App::init()
|
|||||||
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, width_range);
|
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, width_range);
|
||||||
LOG("GL line range: %f - %f", width_range[0], width_range[1]);
|
LOG("GL line range: %f - %f", width_range[0], width_range[1]);
|
||||||
LOG("Screen Size: %f %f", width, height);
|
LOG("Screen Size: %f %f", width, height);
|
||||||
|
|
||||||
|
GLint fb0;
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fb0);
|
||||||
|
LOG("Default Framebuffer %d", fb0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::async_start()
|
||||||
|
{
|
||||||
|
#if __OSX__
|
||||||
|
[osx_view async_lock];
|
||||||
|
#elif __IOS__
|
||||||
|
[ios_view async_lock];
|
||||||
|
#elif __ANDROID__
|
||||||
|
android_async_lock(and_engine);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::async_update()
|
||||||
|
{
|
||||||
|
#if __IOS__
|
||||||
|
[ios_view->glview bindDrawable];
|
||||||
|
#endif
|
||||||
|
redraw = true;
|
||||||
|
clear();
|
||||||
|
update(0);
|
||||||
|
#if __OSX__
|
||||||
|
[osx_view async_swap];
|
||||||
|
#elif __IOS__
|
||||||
|
[ios_view async_swap];
|
||||||
|
#elif __ANDROID__
|
||||||
|
android_async_swap(and_engine);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::async_end()
|
||||||
|
{
|
||||||
|
#if __OSX__
|
||||||
|
[osx_view async_unlock];
|
||||||
|
#elif __IOS__
|
||||||
|
[ios_view async_unlock];
|
||||||
|
#elif __ANDROID__
|
||||||
|
android_async_unlock(and_engine);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::update(float dt)
|
void App::update(float dt)
|
||||||
@@ -155,6 +204,11 @@ void App::update(float dt)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
#if __IOS__
|
||||||
|
[ios_view->glview bindDrawable];
|
||||||
|
#else
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
#endif
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
if (auto* main = layout[main_id])
|
if (auto* main = layout[main_id])
|
||||||
main->watch(observer);
|
main->watch(observer);
|
||||||
|
|||||||
17
engine/app.h
@@ -22,6 +22,14 @@
|
|||||||
#import "GameViewController.h"
|
#import "GameViewController.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__OBJC__) && defined(__OSX__)
|
||||||
|
#import "main.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include "main.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class App
|
class App
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -68,8 +76,14 @@ public:
|
|||||||
#if defined(__IOS__) && defined(__OBJC__)
|
#if defined(__IOS__) && defined(__OBJC__)
|
||||||
GameViewController* ios_view;
|
GameViewController* ios_view;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__OSX__) && defined(__OBJC__)
|
||||||
|
View* osx_view;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
struct android_app* and_app;
|
struct android_app* and_app;
|
||||||
|
struct engine* and_engine;
|
||||||
#endif
|
#endif
|
||||||
void showKeyboard();
|
void showKeyboard();
|
||||||
void hideKeyboard();
|
void hideKeyboard();
|
||||||
@@ -83,6 +97,9 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
void update_memory_usage(size_t bytes);
|
void update_memory_usage(size_t bytes);
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
void async_start();
|
||||||
|
void async_update();
|
||||||
|
void async_end();
|
||||||
void resize(float w, float h);
|
void resize(float w, float h);
|
||||||
bool mouse_down(int button, float x, float y, float pressure, kEventSource source);
|
bool mouse_down(int button, float x, float y, float pressure, kEventSource source);
|
||||||
bool mouse_move(float x, float y, float pressure, kEventSource source);
|
bool mouse_move(float x, float y, float pressure, kEventSource source);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "node_icon.h"
|
#include "node_icon.h"
|
||||||
#include "node_dialog_open.h"
|
#include "node_dialog_open.h"
|
||||||
#include "node_text.h"
|
#include "node_text.h"
|
||||||
|
#include "node_progress_bar.h"
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
|
|
||||||
@@ -529,6 +530,8 @@ void App::initLayout()
|
|||||||
|
|
||||||
brush_update();
|
brush_update();
|
||||||
|
|
||||||
|
TextureManager::load("data/paper.jpg");
|
||||||
|
|
||||||
// hacky thing to make the toolbar buttons not steal events when moving cursor fast
|
// hacky thing to make the toolbar buttons not steal events when moving cursor fast
|
||||||
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
||||||
toolbar->m_flood_events = true;
|
toolbar->m_flood_events = true;
|
||||||
|
|||||||
@@ -47,6 +47,18 @@ void App::initShaders()
|
|||||||
" vec4(clamp(vec3(.3)+c.rgb, vec3(0), vec3(1)), c.a) : \n"
|
" vec4(clamp(vec3(.3)+c.rgb, vec3(0), vec3(1)), c.a) : \n"
|
||||||
" texture(tex, uv.xy) * vec4(1,1,1,alpha);\n"
|
" texture(tex, uv.xy) * vec4(1,1,1,alpha);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
// STROKE PREVIEW
|
||||||
|
static const char* shader_stroke_preview_f =
|
||||||
|
SHADER_VERSION
|
||||||
|
"uniform sampler2D tex;\n"
|
||||||
|
"uniform mediump float alpha;\n"
|
||||||
|
"uniform mediump vec4 col;\n"
|
||||||
|
"in mediump vec3 uv;\n"
|
||||||
|
"out mediump vec4 frag;\n"
|
||||||
|
"void main(){\n"
|
||||||
|
" mediump float stroke = 1.0 - texture(tex, uv.xy).r;\n"
|
||||||
|
" frag = vec4(col.rgb, stroke * alpha);\n"
|
||||||
|
"}";
|
||||||
// TEXTURE COMP ERASE
|
// TEXTURE COMP ERASE
|
||||||
static const char* shader_comp_erase_f =
|
static const char* shader_comp_erase_f =
|
||||||
SHADER_VERSION
|
SHADER_VERSION
|
||||||
@@ -69,6 +81,8 @@ void App::initShaders()
|
|||||||
"uniform sampler2D tex;\n"
|
"uniform sampler2D tex;\n"
|
||||||
"uniform sampler2D tex_stroke;\n"
|
"uniform sampler2D tex_stroke;\n"
|
||||||
"uniform sampler2D tex_mask;\n"
|
"uniform sampler2D tex_mask;\n"
|
||||||
|
"uniform sampler2D tex_stencil;\n"
|
||||||
|
//"uniform image2D img_mixer;\n"
|
||||||
"uniform mediump float alpha;\n"
|
"uniform mediump float alpha;\n"
|
||||||
"uniform bool lock;\n"
|
"uniform bool lock;\n"
|
||||||
"uniform bool mask;\n"
|
"uniform bool mask;\n"
|
||||||
@@ -88,8 +102,10 @@ void App::initShaders()
|
|||||||
" return sum / vec4(9.0);\n"
|
" return sum / vec4(9.0);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"void main(){\n"
|
"void main(){\n"
|
||||||
|
" mediump vec2 uv2 = gl_FragCoord.st / vec2(2048) * 20.0;\n"
|
||||||
" mediump vec4 base = texture(tex, uv.xy);\n"
|
" mediump vec4 base = texture(tex, uv.xy);\n"
|
||||||
" mediump vec4 stroke = texture(tex_stroke, uv.xy);\n"
|
" mediump vec4 stroke = texture(tex_stroke, uv.xy);\n"
|
||||||
|
" mediump float stencil = pow(texture(tex_stencil, uv2).r, 8.0);\n"
|
||||||
" stroke.a = mask ? stroke.a * alpha * blur(tex_mask, uv.xy).r : stroke.a * alpha;\n"
|
" stroke.a = mask ? stroke.a * alpha * blur(tex_mask, uv.xy).r : stroke.a * alpha;\n"
|
||||||
|
|
||||||
" mediump float contribution = (1.0 - base.a) * stroke.a;\n"
|
" mediump float contribution = (1.0 - base.a) * stroke.a;\n"
|
||||||
@@ -222,12 +238,16 @@ void App::initShaders()
|
|||||||
SHADER_VERSION
|
SHADER_VERSION
|
||||||
#ifdef __IOS__
|
#ifdef __IOS__
|
||||||
"#extension GL_EXT_shader_framebuffer_fetch : enable\n"
|
"#extension GL_EXT_shader_framebuffer_fetch : enable\n"
|
||||||
|
// "#extension GL_EXT_shader_image_load_store : enable\n"
|
||||||
#endif
|
#endif
|
||||||
"uniform mediump sampler2D tex;\n"
|
"uniform mediump sampler2D tex;\n"
|
||||||
"uniform mediump sampler2D tex_bg;\n"
|
"uniform mediump sampler2D tex_bg;\n"
|
||||||
|
"uniform mediump sampler2D tex_stencil;\n"
|
||||||
|
//"layout (binding=3, rgba8) uniform image2D tex_mix;\n"
|
||||||
"uniform mediump vec4 col;\n"
|
"uniform mediump vec4 col;\n"
|
||||||
"uniform mediump vec2 resolution;\n"
|
"uniform mediump vec2 resolution;\n"
|
||||||
"uniform mediump float alpha;\n"
|
"uniform mediump float alpha;\n"
|
||||||
|
"uniform mediump vec2 stencil_offset;\n"
|
||||||
"in mediump vec2 uv;\n"
|
"in mediump vec2 uv;\n"
|
||||||
"in mediump float q;\n"
|
"in mediump float q;\n"
|
||||||
#ifdef __IOS__
|
#ifdef __IOS__
|
||||||
@@ -237,6 +257,7 @@ void App::initShaders()
|
|||||||
#endif
|
#endif
|
||||||
"void main(){\n"
|
"void main(){\n"
|
||||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||||
|
" mediump float stencil = 1-(texture(tex_stencil, (uv2+stencil_offset) * 5.0).r * 0.9);\n"
|
||||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv/q).r ) * alpha;\n"
|
" mediump float brush_alpha = ( 1.0 - texture(tex, uv/q).r ) * alpha;\n"
|
||||||
" mediump vec4 fg = vec4(col.rgb, brush_alpha);\n"
|
" mediump vec4 fg = vec4(col.rgb, brush_alpha);\n"
|
||||||
#ifdef __IOS__
|
#ifdef __IOS__
|
||||||
@@ -245,7 +266,7 @@ void App::initShaders()
|
|||||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||||
#endif
|
#endif
|
||||||
" if (fg.a < 1.0/255.0) { frag = bg; return; }\n"
|
" if (fg.a < 1.0/255.0) { frag = bg; return; }\n"
|
||||||
" mediump float contribution = max((1.0 - bg.a) * fg.a, 1.0/255.0);\n"
|
" mediump float contribution = max((1.0 - bg.a) * fg.a, 1.0/255.0) * stencil;\n"
|
||||||
" mediump float alpha_tot = bg.a + contribution;"
|
" mediump float alpha_tot = bg.a + contribution;"
|
||||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||||
" frag = vec4(rgb, clamp(alpha_tot, 0.0, 1.0));\n"
|
" frag = vec4(rgb, clamp(alpha_tot, 0.0, 1.0));\n"
|
||||||
@@ -307,6 +328,8 @@ void App::initShaders()
|
|||||||
LOG("Failed to create shader Texture");
|
LOG("Failed to create shader Texture");
|
||||||
if (!ShaderManager::create(kShader::TextureAlpha, shader_v, shader_alpha_f))
|
if (!ShaderManager::create(kShader::TextureAlpha, shader_v, shader_alpha_f))
|
||||||
LOG("Failed to create shader TextureAlpha");
|
LOG("Failed to create shader TextureAlpha");
|
||||||
|
if (!ShaderManager::create(kShader::StrokePreview, shader_v, shader_stroke_preview_f))
|
||||||
|
LOG("Failed to create shader StrokePreview");
|
||||||
if (!ShaderManager::create(kShader::CompErase, shader_v, shader_comp_erase_f))
|
if (!ShaderManager::create(kShader::CompErase, shader_v, shader_comp_erase_f))
|
||||||
LOG("Failed to create shader CompErase");
|
LOG("Failed to create shader CompErase");
|
||||||
if (!ShaderManager::create(kShader::CompDraw, shader_v, shader_comp_draw_f))
|
if (!ShaderManager::create(kShader::CompDraw, shader_v, shader_comp_draw_f))
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
|
#include "app.h"
|
||||||
|
#include "node_progress_bar.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
@@ -196,10 +199,16 @@ void ui::Canvas::stroke_draw()
|
|||||||
auto m_brush = m_current_stroke->m_brush;
|
auto m_brush = m_current_stroke->m_brush;
|
||||||
auto samples = m_current_stroke->compute_samples();
|
auto samples = m_current_stroke->compute_samples();
|
||||||
auto& tex = TextureManager::get(m_brush.m_tex_id);
|
auto& tex = TextureManager::get(m_brush.m_tex_id);
|
||||||
|
auto& stencil = TextureManager::get(const_hash("data/paper.jpg"));
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
tex.bind();
|
tex.bind();
|
||||||
m_sampler_brush.bind(0);
|
m_sampler_brush.bind(0);
|
||||||
m_sampler_bg.bind(1);
|
m_sampler_bg.bind(1);
|
||||||
m_sampler_mask.bind(2);
|
m_sampler_mask.bind(2);
|
||||||
|
m_sampler_stencil.bind(3);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
stencil.bind();
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
@@ -230,8 +239,10 @@ void ui::Canvas::stroke_draw()
|
|||||||
ShaderManager::use(ui::kShader::Stroke);
|
ShaderManager::use(ui::kShader::Stroke);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
|
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
|
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexStencil, 3); // stencil
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||||
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
|
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
|
||||||
|
ShaderManager::u_vec2(kShaderUniform::StencilOffset, glm::vec2((rand()%1000)*0.001f, (rand()%1000)*0.001f));
|
||||||
for (const auto& s : samples)
|
for (const auto& s : samples)
|
||||||
{
|
{
|
||||||
glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.size * 0.5f);
|
glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.size * 0.5f);
|
||||||
@@ -458,6 +469,7 @@ void ui::Canvas::stroke_commit()
|
|||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_bg.bind(1);
|
m_sampler_bg.bind(1);
|
||||||
m_sampler_mask.bind(2);
|
m_sampler_mask.bind(2);
|
||||||
|
m_sampler_stencil.bind(3);
|
||||||
if (m_state == kCanvasMode::Erase)
|
if (m_state == kCanvasMode::Erase)
|
||||||
{
|
{
|
||||||
ui::ShaderManager::use(kShader::CompErase);
|
ui::ShaderManager::use(kShader::CompErase);
|
||||||
@@ -482,6 +494,8 @@ void ui::Canvas::stroke_commit()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto& paper = TextureManager::get(const_hash("data/paper.jpg"));
|
||||||
|
|
||||||
ui::ShaderManager::use(kShader::CompDraw);
|
ui::ShaderManager::use(kShader::CompDraw);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
@@ -496,7 +510,11 @@ void ui::Canvas::stroke_commit()
|
|||||||
m_tmp[i].bindTexture();
|
m_tmp[i].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
m_smask.m_rtt[i].bindTexture();
|
m_smask.m_rtt[i].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
paper.bind();
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
paper.unbind();
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
m_smask.m_rtt[i].unbindTexture();
|
m_smask.m_rtt[i].unbindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
m_tmp[i].unbindTexture();
|
m_tmp[i].unbindTexture();
|
||||||
@@ -712,9 +730,11 @@ bool ui::Canvas::create(int width, int height)
|
|||||||
m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
||||||
m_sampler_bg.create(GL_NEAREST);
|
m_sampler_bg.create(GL_NEAREST);
|
||||||
m_sampler_mask.create(GL_LINEAR);
|
m_sampler_mask.create(GL_LINEAR);
|
||||||
|
m_sampler_stencil.create(GL_LINEAR, GL_REPEAT);
|
||||||
m_plane.create<1>(1, 1);
|
m_plane.create<1>(1, 1);
|
||||||
m_plane_brush.create<1>(1, 1);
|
m_plane_brush.create<1>(1, 1);
|
||||||
m_mesh.create();
|
m_mesh.create();
|
||||||
|
m_brush_mix.create(8, 8);
|
||||||
for (auto& l : m_layers)
|
for (auto& l : m_layers)
|
||||||
{
|
{
|
||||||
l.create(width, height, "");
|
l.create(width, height, "");
|
||||||
@@ -755,11 +775,27 @@ void ui::Canvas::clear_context()
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __IOS__
|
|
||||||
UIImage *image;
|
|
||||||
#endif
|
|
||||||
void ui::Canvas::export_equirectangular(std::string data_path)
|
void ui::Canvas::export_equirectangular(std::string data_path)
|
||||||
{
|
{
|
||||||
|
std::thread t(&ui::Canvas::export_equirectangular_thread, this, data_path);
|
||||||
|
t.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Canvas::export_equirectangular_thread(std::string data_path)
|
||||||
|
{
|
||||||
|
gl_state gl;
|
||||||
|
|
||||||
|
App::I.async_start();
|
||||||
|
auto pb = std::make_shared<NodeProgressBar>();
|
||||||
|
pb->m_manager = &App::I.layout;
|
||||||
|
pb->init();
|
||||||
|
pb->create();
|
||||||
|
pb->loaded();
|
||||||
|
pb->m_progress->SetWidthP(0);
|
||||||
|
pb->m_title->set_text("Export Pano Image");
|
||||||
|
App::I.layout[App::I.main_id]->add_child(pb);
|
||||||
|
App::I.async_update();
|
||||||
|
|
||||||
// save viewport and clear color states
|
// save viewport and clear color states
|
||||||
GLint vp[4];
|
GLint vp[4];
|
||||||
GLfloat cc[4];
|
GLfloat cc[4];
|
||||||
@@ -788,13 +824,16 @@ void ui::Canvas::export_equirectangular(std::string data_path)
|
|||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom
|
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
ShaderManager::use(ui::kShader::TextureAlpha);
|
int progress = 0;
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
int total = 6 + 2;
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
|
ShaderManager::use(ui::kShader::TextureAlpha);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
|
|
||||||
m_tmp[i].bindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
m_tmp[i].clear({ 1, 1, 1, 1 });
|
m_tmp[i].clear({ 1, 1, 1, 1 });
|
||||||
|
|
||||||
@@ -815,6 +854,14 @@ void ui::Canvas::export_equirectangular(std::string data_path)
|
|||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].unbindFramebuffer();
|
||||||
|
|
||||||
|
progress++;
|
||||||
|
float p = (float)progress / total * 100.f;
|
||||||
|
pb->m_progress->SetWidthP(p);
|
||||||
|
LOG("progress: %f", p);
|
||||||
|
gl.save();
|
||||||
|
App::I.async_update();
|
||||||
|
gl.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
//auto data = std::make_unique<uint8_t[]>(m_tmp[0].bytes());
|
//auto data = std::make_unique<uint8_t[]>(m_tmp[0].bytes());
|
||||||
@@ -843,6 +890,17 @@ void ui::Canvas::export_equirectangular(std::string data_path)
|
|||||||
{
|
{
|
||||||
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
|
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
|
||||||
m_latlong.readTextureData(latlong_data.get());
|
m_latlong.readTextureData(latlong_data.get());
|
||||||
|
|
||||||
|
{
|
||||||
|
progress++;
|
||||||
|
float p = (float)progress / total * 100.f;
|
||||||
|
pb->m_progress->SetWidthP(p);
|
||||||
|
LOG("progress: %f", p);
|
||||||
|
gl.save();
|
||||||
|
App::I.async_update();
|
||||||
|
gl.restore();
|
||||||
|
}
|
||||||
|
|
||||||
static char name[128];
|
static char name[128];
|
||||||
sprintf(name, "%s/latlong.jpg", data_path.c_str());
|
sprintf(name, "%s/latlong.jpg", data_path.c_str());
|
||||||
LOG("writing %s", name);
|
LOG("writing %s", name);
|
||||||
@@ -850,6 +908,17 @@ void ui::Canvas::export_equirectangular(std::string data_path)
|
|||||||
params.m_quality = 100;
|
params.m_quality = 100;
|
||||||
bool saved = jpge::compress_image_to_jpeg_file(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), params);
|
bool saved = jpge::compress_image_to_jpeg_file(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), params);
|
||||||
inject_xmp(name);
|
inject_xmp(name);
|
||||||
|
|
||||||
|
{
|
||||||
|
progress++;
|
||||||
|
float p = (float)progress / total * 100.f;
|
||||||
|
pb->m_progress->SetWidthP(p);
|
||||||
|
LOG("progress: %f", p);
|
||||||
|
gl.save();
|
||||||
|
App::I.async_update();
|
||||||
|
gl.restore();
|
||||||
|
}
|
||||||
|
|
||||||
//int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
|
//int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
|
||||||
#ifdef __IOS__
|
#ifdef __IOS__
|
||||||
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
|
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
|
||||||
@@ -875,6 +944,10 @@ void ui::Canvas::export_equirectangular(std::string data_path)
|
|||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
pb->destroy();
|
||||||
|
App::I.async_update();
|
||||||
|
App::I.async_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui::Canvas::inject_xmp(std::string jpg_path)
|
void ui::Canvas::inject_xmp(std::string jpg_path)
|
||||||
@@ -1043,6 +1116,13 @@ void ui::Canvas::export_anim(std::string data_path)
|
|||||||
|
|
||||||
void ui::Canvas::project_save(std::string data_path)
|
void ui::Canvas::project_save(std::string data_path)
|
||||||
{
|
{
|
||||||
|
std::thread t(&ui::Canvas::project_save_thread, this, data_path);
|
||||||
|
t.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Canvas::project_save_thread(std::string data_path)
|
||||||
|
{
|
||||||
|
gl_state gl;
|
||||||
// static char name[128];
|
// static char name[128];
|
||||||
// sprintf(name, "%s/latlong.pano", data_path.c_str());
|
// sprintf(name, "%s/latlong.pano", data_path.c_str());
|
||||||
FILE* fp = fopen(data_path.c_str(), "wb");
|
FILE* fp = fopen(data_path.c_str(), "wb");
|
||||||
@@ -1053,7 +1133,19 @@ void ui::Canvas::project_save(std::string data_path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load thumbnail
|
// load thumbnail
|
||||||
|
App::I.async_start();
|
||||||
Image thumb = thumbnail_generate(128, 128);
|
Image thumb = thumbnail_generate(128, 128);
|
||||||
|
auto pb = std::make_shared<NodeProgressBar>();
|
||||||
|
pb->m_manager = &App::I.layout;
|
||||||
|
pb->init();
|
||||||
|
pb->create();
|
||||||
|
pb->loaded();
|
||||||
|
pb->m_progress->SetWidthP(0);
|
||||||
|
pb->m_title->set_text("Saving Pano Project");
|
||||||
|
App::I.layout[App::I.main_id]->add_child(pb);
|
||||||
|
App::I.async_update();
|
||||||
|
App::I.async_end();
|
||||||
|
|
||||||
thumb.flip();
|
thumb.flip();
|
||||||
fwrite(&thumb.width, sizeof(int), 1, fp);
|
fwrite(&thumb.width, sizeof(int), 1, fp);
|
||||||
fwrite(&thumb.height, sizeof(int), 1, fp);
|
fwrite(&thumb.height, sizeof(int), 1, fp);
|
||||||
@@ -1066,6 +1158,9 @@ void ui::Canvas::project_save(std::string data_path)
|
|||||||
int n_layers = (int)m_layers.size();
|
int n_layers = (int)m_layers.size();
|
||||||
fwrite(&n_layers, sizeof(int), 1, fp);
|
fwrite(&n_layers, sizeof(int), 1, fp);
|
||||||
|
|
||||||
|
int progress = 0;
|
||||||
|
int total = (int)m_layers.size() * 6;
|
||||||
|
|
||||||
for (int i = 0; i < (int)m_layers.size(); i++)
|
for (int i = 0; i < (int)m_layers.size(); i++)
|
||||||
{
|
{
|
||||||
int n_order = m_order[i];
|
int n_order = m_order[i];
|
||||||
@@ -1075,7 +1170,10 @@ void ui::Canvas::project_save(std::string data_path)
|
|||||||
fwrite(&name_len, sizeof(int), 1, fp);
|
fwrite(&name_len, sizeof(int), 1, fp);
|
||||||
fwrite(m_layers[i].m_name.data(), name_len, 1, fp);
|
fwrite(m_layers[i].m_name.data(), name_len, 1, fp);
|
||||||
|
|
||||||
|
App::I.async_start();
|
||||||
auto snap = m_layers[i].snapshot(data_path);
|
auto snap = m_layers[i].snapshot(data_path);
|
||||||
|
App::I.async_update();
|
||||||
|
App::I.async_end();
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
{
|
{
|
||||||
int has_data = snap.m_dirty_face[plane_index] ? 1 : 0;
|
int has_data = snap.m_dirty_face[plane_index] ? 1 : 0;
|
||||||
@@ -1100,13 +1198,31 @@ void ui::Canvas::project_save(std::string data_path)
|
|||||||
|
|
||||||
fwrite(compressed.data(), 1, compressed.size(), fp);
|
fwrite(compressed.data(), 1, compressed.size(), fp);
|
||||||
}
|
}
|
||||||
|
progress++;
|
||||||
|
float p = (float)progress / total * 100.f;
|
||||||
|
App::I.async_start();
|
||||||
|
pb->m_progress->SetWidthP(p);
|
||||||
|
LOG("progress: %f", p);
|
||||||
|
App::I.async_update();
|
||||||
|
App::I.async_end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
LOG("project saved to %s", data_path.c_str());
|
LOG("project saved to %s", data_path.c_str());
|
||||||
|
App::I.async_start();
|
||||||
|
pb->destroy();
|
||||||
|
App::I.async_update();
|
||||||
|
App::I.async_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui::Canvas::project_open(std::string data_path)
|
void ui::Canvas::project_open(std::string data_path)
|
||||||
|
{
|
||||||
|
std::thread t(&ui::Canvas::project_open_thread, this, data_path);
|
||||||
|
t.detach();
|
||||||
|
//project_open_thread(data_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::Canvas::project_open_thread(std::string data_path)
|
||||||
{
|
{
|
||||||
// static char name[128];
|
// static char name[128];
|
||||||
// sprintf(name, "%s/latlong.pano", data_path.c_str());
|
// sprintf(name, "%s/latlong.pano", data_path.c_str());
|
||||||
@@ -1117,6 +1233,22 @@ void ui::Canvas::project_open(std::string data_path)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl_state gl;
|
||||||
|
App::I.async_start();
|
||||||
|
auto pb = std::make_shared<NodeProgressBar>();
|
||||||
|
pb->m_manager = &App::I.layout;
|
||||||
|
pb->init();
|
||||||
|
pb->create();
|
||||||
|
pb->loaded();
|
||||||
|
pb->m_progress->SetWidthP(0);
|
||||||
|
pb->m_title->set_text("Opening Pano Project");
|
||||||
|
App::I.layout[App::I.main_id]->add_child(pb);
|
||||||
|
gl.save();
|
||||||
|
App::I.async_update();
|
||||||
|
gl.restore();
|
||||||
|
App::I.async_end();
|
||||||
|
|
||||||
|
LOG("skip thumb");
|
||||||
// skip thumbnail
|
// skip thumbnail
|
||||||
Image thumb;
|
Image thumb;
|
||||||
fread(&thumb.width, sizeof(int), 1, fp);
|
fread(&thumb.width, sizeof(int), 1, fp);
|
||||||
@@ -1127,15 +1259,23 @@ void ui::Canvas::project_open(std::string data_path)
|
|||||||
fread(&m_width, sizeof(int), 1, fp);
|
fread(&m_width, sizeof(int), 1, fp);
|
||||||
fread(&m_height, sizeof(int), 1, fp);
|
fread(&m_height, sizeof(int), 1, fp);
|
||||||
|
|
||||||
int n_layers = (int)m_layers.size();
|
int n_layers = 0;
|
||||||
fread(&n_layers, sizeof(int), 1, fp);
|
fread(&n_layers, sizeof(int), 1, fp);
|
||||||
|
|
||||||
const int bytes = m_width * m_height * 4;
|
const int bytes = m_width * m_height * 4;
|
||||||
Layer::Snapshot snap;
|
Layer::Snapshot snap;
|
||||||
snap.create(m_width, m_height); // allocate single data, no box should be bigger
|
snap.create(m_width, m_height); // allocate single data, no box should be bigger
|
||||||
|
|
||||||
|
int progress = 0;
|
||||||
|
int total = n_layers * 6;
|
||||||
|
|
||||||
|
App::I.async_start();
|
||||||
|
for (auto& l : m_layers)
|
||||||
|
l.destroy();
|
||||||
m_layers.clear();
|
m_layers.clear();
|
||||||
m_order.clear();
|
m_order.clear();
|
||||||
|
App::I.async_end();
|
||||||
|
|
||||||
for (int i = 0; i < n_layers; i++)
|
for (int i = 0; i < n_layers; i++)
|
||||||
{
|
{
|
||||||
int n_order;
|
int n_order;
|
||||||
@@ -1168,17 +1308,36 @@ void ui::Canvas::project_open(std::string data_path)
|
|||||||
std::copy(rgba, rgba + (imgw*imgh * 4), snap.image[plane_index].get());
|
std::copy(rgba, rgba + (imgw*imgh * 4), snap.image[plane_index].get());
|
||||||
delete rgba;
|
delete rgba;
|
||||||
}
|
}
|
||||||
|
progress++;
|
||||||
|
float p = (float)progress / total * 100.f;
|
||||||
|
LOG("progress: %f", p);
|
||||||
|
App::I.async_start();
|
||||||
|
pb->m_progress->SetWidthP(p);
|
||||||
|
gl.save();
|
||||||
|
App::I.async_update();
|
||||||
|
gl.restore();
|
||||||
|
App::I.async_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App::I.async_start();
|
||||||
m_layers.emplace_back();
|
m_layers.emplace_back();
|
||||||
m_layers.back().create(m_width, m_height, name.c_str());
|
m_layers.back().create(m_width, m_height, name.c_str());
|
||||||
m_layers.back().restore(snap);
|
m_layers.back().restore(snap);
|
||||||
|
App::I.async_end();
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
LOG("project restore from %s", data_path.c_str());
|
LOG("project restore from %s", data_path.c_str());
|
||||||
|
App::I.async_start();
|
||||||
|
pb->destroy();
|
||||||
|
gl.save();
|
||||||
|
App::I.async_update();
|
||||||
|
gl.restore();
|
||||||
|
App::I.async_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui::Image ui::Canvas::thumbnail_generate(int w, int h)
|
ui::Image ui::Canvas::thumbnail_generate(int w, int h)
|
||||||
{
|
{
|
||||||
|
|
||||||
// save viewport and clear color states
|
// save viewport and clear color states
|
||||||
GLint vp[4];
|
GLint vp[4];
|
||||||
GLfloat cc[4];
|
GLfloat cc[4];
|
||||||
|
|||||||
@@ -41,12 +41,13 @@ public:
|
|||||||
|
|
||||||
class Canvas
|
class Canvas
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
Plane m_plane;
|
Plane m_plane;
|
||||||
Plane m_plane_brush;
|
Plane m_plane_brush;
|
||||||
BrushMesh m_mesh;
|
BrushMesh m_mesh;
|
||||||
bool m_dirty = false;
|
bool m_dirty = false;
|
||||||
bool m_commit_delayed = false;
|
bool m_commit_delayed = false;
|
||||||
public:
|
|
||||||
static Canvas* I;
|
static Canvas* I;
|
||||||
bool m_alpha_lock = false;
|
bool m_alpha_lock = false;
|
||||||
bool m_touch_lock = true;
|
bool m_touch_lock = true;
|
||||||
@@ -67,6 +68,7 @@ public:
|
|||||||
Layer m_smask; // selection mask
|
Layer m_smask; // selection mask
|
||||||
bool m_smask_active = false;
|
bool m_smask_active = false;
|
||||||
RTT m_tmp[6];
|
RTT m_tmp[6];
|
||||||
|
Texture2D m_brush_mix;
|
||||||
Texture2D m_tex[6];
|
Texture2D m_tex[6];
|
||||||
Texture2D m_tex2[6];
|
Texture2D m_tex2[6];
|
||||||
bool m_pick_ready[6];
|
bool m_pick_ready[6];
|
||||||
@@ -79,6 +81,7 @@ public:
|
|||||||
Sampler m_sampler_brush;
|
Sampler m_sampler_brush;
|
||||||
Sampler m_sampler_bg;
|
Sampler m_sampler_bg;
|
||||||
Sampler m_sampler_mask;
|
Sampler m_sampler_mask;
|
||||||
|
Sampler m_sampler_stencil;
|
||||||
glm::vec2 m_cam_rot;
|
glm::vec2 m_cam_rot;
|
||||||
glm::vec3 m_cam_pos;
|
glm::vec3 m_cam_pos;
|
||||||
float m_cam_fov = 85;
|
float m_cam_fov = 85;
|
||||||
@@ -125,9 +128,12 @@ public:
|
|||||||
void snap_history(const std::vector<int>& planes);
|
void snap_history(const std::vector<int>& planes);
|
||||||
void clear_context();
|
void clear_context();
|
||||||
void export_equirectangular(std::string data_path);
|
void export_equirectangular(std::string data_path);
|
||||||
|
void export_equirectangular_thread(std::string data_path);
|
||||||
void export_anim(std::string data_path);
|
void export_anim(std::string data_path);
|
||||||
void project_save(std::string data_path);
|
void project_save(std::string data_path);
|
||||||
|
void project_save_thread(std::string data_path);
|
||||||
void project_open(std::string data_path);
|
void project_open(std::string data_path);
|
||||||
|
void project_open_thread(std::string data_path);
|
||||||
void inject_xmp(std::string jpg_path);
|
void inject_xmp(std::string jpg_path);
|
||||||
ui::Image thumbnail_generate(int w, int h);
|
ui::Image thumbnail_generate(int w, int h);
|
||||||
ui::Image thumbnail_read(std::string data_path);
|
ui::Image thumbnail_read(std::string data_path);
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
App::I.color->m_hue->set_value(hsv.x);
|
App::I.color->m_hue->set_value(hsv.x);
|
||||||
App::I.color->m_quad->set_value(1.f - hsv.y, 1.f - hsv.z);
|
App::I.color->m_quad->set_value(1.f - hsv.y, 1.f - hsv.z);
|
||||||
}
|
}
|
||||||
|
m_cur_pos = loc;
|
||||||
break;
|
break;
|
||||||
case kEventType::MouseCancel:
|
case kEventType::MouseCancel:
|
||||||
if (m_dragging)
|
if (m_dragging)
|
||||||
@@ -134,6 +135,35 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
||||||
|
{
|
||||||
|
#ifndef __IOS__
|
||||||
|
if (!m_dragging && !m_picking)
|
||||||
|
{
|
||||||
|
ui::ShaderManager::use(ui::kShader::StrokePreview);
|
||||||
|
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
|
||||||
|
ui::ShaderManager::u_float(ui::kShaderUniform::Alpha, node->m_brush.m_tip_flow);
|
||||||
|
auto tip_color = glm::vec4(glm::vec3(node->m_brush.m_tip_color), 1);
|
||||||
|
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, tip_color);
|
||||||
|
ui::ShaderManager::u_int(ui::kShaderUniform::Highlight, 0);
|
||||||
|
float tip_scale = 1.f / glm::tan(glm::radians(ui::Canvas::I->m_cam_fov * 0.5f));
|
||||||
|
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP,
|
||||||
|
glm::scale(glm::vec3(1, -1, 1)) *
|
||||||
|
ortho *
|
||||||
|
glm::translate(glm::vec3(m_cur_pos, 0)) *
|
||||||
|
glm::scale(glm::vec3(node->m_brush.m_tip_size * 800.f * tip_scale))
|
||||||
|
);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
auto& tex = TextureManager::get(node->m_brush.m_tex_id);
|
||||||
|
tex.bind();
|
||||||
|
canvas->m_sampler_brush.bind(0);
|
||||||
|
canvas->m_plane.draw_fill();
|
||||||
|
tex.unbind();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void CanvasModePen::leave()
|
void CanvasModePen::leave()
|
||||||
{
|
{
|
||||||
m_brush = node->m_brush;
|
m_brush = node->m_brush;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class CanvasModePen : public CanvasMode
|
|||||||
{
|
{
|
||||||
bool m_dragging = false;
|
bool m_dragging = false;
|
||||||
glm::vec2 m_pan_start;
|
glm::vec2 m_pan_start;
|
||||||
|
glm::vec2 m_cur_pos;
|
||||||
float m_camera_fov;
|
float m_camera_fov;
|
||||||
float m_zoom_canvas = 1.f;
|
float m_zoom_canvas = 1.f;
|
||||||
float m_zoom_start;
|
float m_zoom_start;
|
||||||
@@ -46,6 +47,7 @@ class CanvasModePen : public CanvasMode
|
|||||||
ui::Brush m_brush;
|
ui::Brush m_brush;
|
||||||
public:
|
public:
|
||||||
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
|
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
|
||||||
|
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
|
||||||
virtual void enter() override;
|
virtual void enter() override;
|
||||||
virtual void leave() override;
|
virtual void leave() override;
|
||||||
bool m_picking = false;
|
bool m_picking = false;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ void NodeCanvas::init()
|
|||||||
m_canvas = std::make_unique<ui::Canvas>();
|
m_canvas = std::make_unique<ui::Canvas>();
|
||||||
m_canvas->create(RES, RES);
|
m_canvas->create(RES, RES);
|
||||||
m_sampler.create(GL_NEAREST);
|
m_sampler.create(GL_NEAREST);
|
||||||
|
m_sampler_stencil.create(GL_LINEAR, GL_REPEAT);
|
||||||
m_face_plane.create<1>(2, 2);
|
m_face_plane.create<1>(2, 2);
|
||||||
m_line.create();
|
m_line.create();
|
||||||
CanvasMode::node = this;
|
CanvasMode::node = this;
|
||||||
@@ -79,6 +80,7 @@ void NodeCanvas::draw()
|
|||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler.bind(1);
|
m_sampler.bind(1);
|
||||||
m_sampler.bind(2);
|
m_sampler.bind(2);
|
||||||
|
m_sampler_stencil.bind(3);
|
||||||
auto blend = glIsEnabled(GL_BLEND);
|
auto blend = glIsEnabled(GL_BLEND);
|
||||||
auto depth = glIsEnabled(GL_DEPTH_TEST);
|
auto depth = glIsEnabled(GL_DEPTH_TEST);
|
||||||
|
|
||||||
@@ -141,10 +143,12 @@ void NodeCanvas::draw()
|
|||||||
}
|
}
|
||||||
else if(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
else if(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||||
{
|
{
|
||||||
|
auto& paper = TextureManager::get(const_hash("data/paper.jpg"));
|
||||||
ui::ShaderManager::use(kShader::CompDraw);
|
ui::ShaderManager::use(kShader::CompDraw);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ui::ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
|
ui::ShaderManager::u_int(kShaderUniform::TexStencil, 3);
|
||||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[m_canvas->m_current_layer_idx].m_alpha_locked);
|
ui::ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[m_canvas->m_current_layer_idx].m_alpha_locked);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
ui::ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
||||||
@@ -155,7 +159,11 @@ void NodeCanvas::draw()
|
|||||||
m_canvas->m_tmp[plane_index].bindTexture();
|
m_canvas->m_tmp[plane_index].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
paper.bind();
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
|
paper.unbind();
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
m_canvas->m_tmp[plane_index].unbindTexture();
|
m_canvas->m_tmp[plane_index].unbindTexture();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ public:
|
|||||||
std::unique_ptr<ui::Canvas> m_canvas;
|
std::unique_ptr<ui::Canvas> m_canvas;
|
||||||
ui::Brush m_brush;
|
ui::Brush m_brush;
|
||||||
Sampler m_sampler;
|
Sampler m_sampler;
|
||||||
|
Sampler m_sampler_stencil;
|
||||||
ui::Plane m_face_plane;
|
ui::Plane m_face_plane;
|
||||||
ui::LineSegment m_line;
|
ui::LineSegment m_line;
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ void NodePanelBrush::select_brush(int brush_id)
|
|||||||
{
|
{
|
||||||
b->m_selected = true;
|
b->m_selected = true;
|
||||||
m_current = b;
|
m_current = b;
|
||||||
|
TextureManager::load(b->high_path.c_str(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
engine/node_progress_bar.cpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "node_progress_bar.h"
|
||||||
|
#include "layout.h"
|
||||||
|
|
||||||
|
Node* NodeProgressBar::clone_instantiate() const
|
||||||
|
{
|
||||||
|
return new NodeProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeProgressBar::init()
|
||||||
|
{
|
||||||
|
auto tpl = static_cast<const NodeBorder*>(init_template("progress-bar"));
|
||||||
|
m_color = tpl->m_color;
|
||||||
|
m_border_color = tpl->m_border_color;
|
||||||
|
m_thinkness = tpl->m_thinkness;
|
||||||
|
|
||||||
|
m_title = find<NodeText>("title");
|
||||||
|
btn_cancel = find<NodeButton>("btn-cancel");
|
||||||
|
btn_cancel->on_click = [&](Node*) { destroy(); };
|
||||||
|
m_progress = find<NodeBorder>("progress");
|
||||||
|
|
||||||
|
m_progress->SetWidthP(10);
|
||||||
|
}
|
||||||
16
engine/node_progress_bar.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "node.h"
|
||||||
|
#include "node_button.h"
|
||||||
|
#include "node_text.h"
|
||||||
|
#include "node_border.h"
|
||||||
|
|
||||||
|
class NodeProgressBar : public NodeBorder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Node* m_template;
|
||||||
|
NodeButton* btn_cancel;
|
||||||
|
NodeText* m_title;
|
||||||
|
NodeBorder* m_progress;
|
||||||
|
virtual Node* clone_instantiate() const override;
|
||||||
|
virtual void init() override;
|
||||||
|
};
|
||||||
@@ -11,6 +11,8 @@ enum class kShaderUniform : uint16_t
|
|||||||
TexBG = const_hash("tex_bg"),
|
TexBG = const_hash("tex_bg"),
|
||||||
TexMask = const_hash("tex_mask"),
|
TexMask = const_hash("tex_mask"),
|
||||||
TexStroke = const_hash("tex_stroke"),
|
TexStroke = const_hash("tex_stroke"),
|
||||||
|
TexStencil= const_hash("tex_stencil"),
|
||||||
|
StencilOffset = const_hash("stencil_offset"),
|
||||||
Lock = const_hash("lock"),
|
Lock = const_hash("lock"),
|
||||||
Col = const_hash("col"),
|
Col = const_hash("col"),
|
||||||
Tof = const_hash("tof"),
|
Tof = const_hash("tof"),
|
||||||
@@ -34,6 +36,7 @@ enum class kShader : uint16_t
|
|||||||
Font = const_hash("font"),
|
Font = const_hash("font"),
|
||||||
Atlas = const_hash("atlas"),
|
Atlas = const_hash("atlas"),
|
||||||
Stroke = const_hash("stroke"),
|
Stroke = const_hash("stroke"),
|
||||||
|
StrokePreview = const_hash("stroke-preview"),
|
||||||
Checkerboard= const_hash("checkerboard"),
|
Checkerboard= const_hash("checkerboard"),
|
||||||
Equirect = const_hash("equirect"),
|
Equirect = const_hash("equirect"),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,4 +111,55 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gl_state
|
||||||
|
{
|
||||||
|
GLboolean blend;
|
||||||
|
GLboolean depth_test;
|
||||||
|
GLboolean scissor_test;
|
||||||
|
GLint vp[4];
|
||||||
|
GLfloat cc[4];
|
||||||
|
GLint tex[10];
|
||||||
|
GLint cube;
|
||||||
|
GLint sampler[10];
|
||||||
|
GLint program;
|
||||||
|
GLint fb;
|
||||||
|
GLint active_tex;
|
||||||
|
void save()
|
||||||
|
{
|
||||||
|
blend = glIsEnabled(GL_BLEND);
|
||||||
|
depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||||
|
scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||||
|
glGetIntegerv(GL_VIEWPORT, vp);
|
||||||
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
||||||
|
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb);
|
||||||
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex);
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &cube);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, tex + i);
|
||||||
|
glGetIntegerv(GL_SAMPLER_BINDING, sampler + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void restore()
|
||||||
|
{
|
||||||
|
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||||
|
depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
||||||
|
scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
|
||||||
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||||
|
glUseProgram(program);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex[i]);
|
||||||
|
glBindSampler(i, sampler[i]);
|
||||||
|
}
|
||||||
|
glActiveTexture(active_tex);
|
||||||
|
glBindTexture(GL_TEXTURE_BINDING_CUBE_MAP, cube);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
NS_END
|
NS_END
|
||||||
|
|||||||