From 2a92beca7b094bef48afeda8a3ef9fac3cfd42fb Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sun, 22 Oct 2017 19:58:20 +0100 Subject: [PATCH] stencil in brush preview --- PanoPainter/GameViewController.m | 39 +++++++++++++++++++------------- engine/app_shaders.cpp | 2 +- engine/brush.cpp | 8 ++++++- engine/canvas.cpp | 2 +- engine/node_stroke_preview.cpp | 13 ++++++++++- engine/shader.cpp | 5 ++++ 6 files changed, 49 insertions(+), 20 deletions(-) diff --git a/PanoPainter/GameViewController.m b/PanoPainter/GameViewController.m index 4f5272a..f43ba23 100644 --- a/PanoPainter/GameViewController.m +++ b/PanoPainter/GameViewController.m @@ -23,18 +23,25 @@ //std::map< int t_count = 0; glm::vec2 t_pos; +int lock_count = 0; +NSThread* lock_thread; @implementation GameViewController - (void)async_lock { - [gl_lock lock]; + if (lock_thread != [NSThread currentThread] || lock_count == 0) + [gl_lock lock]; + lock_thread = [NSThread currentThread]; + lock_count++; [EAGLContext setCurrentContext:self.context]; GLKView* view = (GLKView*)self.view; //[view bindDrawable]; } - (void)async_unlock { - [gl_lock unlock]; + lock_count--; + if (lock_count == 0) + [gl_lock unlock]; } - (void)async_swap { @@ -100,11 +107,11 @@ glm::vec2 t_pos; frame.size.height -= kbSize.height; view.frame = frame; - [gl_lock lock]; + [self async_lock]; App::I.resize(frame.size.width * view.contentScaleFactor, frame.size.height * view.contentScaleFactor); App::I.animate = false; - [gl_lock unlock]; + [self async_unlock]; } // Called when the UIKeyboardWillHideNotification is sent @@ -112,21 +119,21 @@ glm::vec2 t_pos; { CGRect frame = [[UIScreen mainScreen] bounds]; self.view.frame = frame; - [gl_lock lock]; + [self async_lock]; App::I.resize(frame.size.width * self.view.contentScaleFactor, frame.size.height * self.view.contentScaleFactor); App::I.animate = true; - [gl_lock unlock]; + [self async_unlock]; } - (void)reset_touch { - [gl_lock lock]; + [self async_lock]; if (t_count == 2) App::I.gesture_end(); else App::I.mouse_cancel(0); - [gl_lock unlock]; + [self async_unlock]; t_count = 0; } @@ -138,9 +145,9 @@ glm::vec2 t_pos; float scale = self.view.contentScaleFactor; kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch; - [gl_lock lock]; + [self async_lock]; App::I.mouse_down(0, touchLocation.x * scale, touchLocation.y * scale, touch.force, source); - [gl_lock unlock]; + [self async_unlock]; t_count = 1; t_pos = {touchLocation.x * scale, touchLocation.y * scale}; } @@ -163,7 +170,7 @@ glm::vec2 t_pos; p1 = glm::vec2(tl1.x * scale, tl1.y * scale); } - [gl_lock lock]; + [self async_lock]; if (n == 2) { if (t_count == 1) @@ -192,7 +199,7 @@ glm::vec2 t_pos; App::I.mouse_move(touchLocation.x * scale, touchLocation.y * scale, force, source); } } - [gl_lock unlock]; + [self async_unlock]; t_pos = {tl0.x * scale, tl0.y * scale}; } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event @@ -203,12 +210,12 @@ glm::vec2 t_pos; kEventSource source = touch.type == UITouchType::UITouchTypeStylus ? kEventSource::Stylus : kEventSource::Touch; - [gl_lock lock]; + [self async_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]; + [self async_unlock]; t_count = 0; t_pos = {touchLocation.x * scale, touchLocation.y * scale}; @@ -216,10 +223,10 @@ glm::vec2 t_pos; - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { - [gl_lock lock]; + [self async_lock]; App::I.resize(size.width * self.view.contentScaleFactor, size.height * self.view.contentScaleFactor); - [gl_lock unlock]; + [self async_unlock]; } - (void)viewDidAppear:(BOOL)animated diff --git a/engine/app_shaders.cpp b/engine/app_shaders.cpp index fab154a..8682eec 100644 --- a/engine/app_shaders.cpp +++ b/engine/app_shaders.cpp @@ -258,7 +258,7 @@ void App::initShaders() #endif "void main(){\n" " mediump vec2 uv2 = gl_FragCoord.st / resolution;\n" - " mediump float stencil = 1-(texture(tex_stencil, (uv2+stencil_offset) * 5.0).r * 0.9) * stencil_alpha;\n" + " mediump float stencil = 1.0 - (texture(tex_stencil, (uv2+stencil_offset) * 2.0).r * 0.9) * stencil_alpha;\n" " mediump float brush_alpha = ( 1.0 - texture(tex, uv/q).r ) * alpha;\n" " mediump vec4 fg = vec4(col.rgb, brush_alpha);\n" #ifdef __IOS__ diff --git a/engine/brush.cpp b/engine/brush.cpp index 9a72ba1..3e83695 100644 --- a/engine/brush.cpp +++ b/engine/brush.cpp @@ -107,12 +107,18 @@ bool ui::BrushMesh::create() static const char* shader_stroke_inst_f = SHADER_VERSION "uniform mediump sampler2D tex;" + "uniform mediump sampler2D tex_stencil;\n" "uniform mediump vec4 col;" + "uniform mediump vec2 resolution;\n" + "uniform mediump vec2 stencil_offset;\n" + "uniform mediump float stencil_alpha;\n" "in mediump float alpha;" "in mediump vec3 uv;" "out mediump vec4 frag;" "void main(){" - " mediump float a = (1.0 - texture(tex, uv.xy).r) * alpha;" + " mediump vec2 uv2 = gl_FragCoord.st / resolution;\n" + " mediump float stencil = 1.0 - (texture(tex_stencil, (uv2+stencil_offset)).r * 0.9) * stencil_alpha;\n" + " mediump float a = (1.0 - texture(tex, uv.xy).r) * alpha * stencil;" " frag = vec4(col.rgb, a);" "}"; diff --git a/engine/canvas.cpp b/engine/canvas.cpp index 5f84eab..e3c6e1c 100644 --- a/engine/canvas.cpp +++ b/engine/canvas.cpp @@ -242,7 +242,7 @@ void ui::Canvas::stroke_draw() ShaderManager::u_int(kShaderUniform::TexStencil, 3); // stencil ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color); ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height }); - ShaderManager::u_vec2(kShaderUniform::StencilOffset, glm::vec2((rand()%1000)*0.001f, (rand()%1000)*0.001f)); + //ShaderManager::u_vec2(kShaderUniform::StencilOffset, glm::vec2((rand()%1000)*0.001f, (rand()%1000)*0.001f)); ShaderManager::u_float(kShaderUniform::StencilAlpha, m_brush.m_tip_stencil); for (const auto& s : samples) { diff --git a/engine/node_stroke_preview.cpp b/engine/node_stroke_preview.cpp index 5fbd4ad..0dbf179 100644 --- a/engine/node_stroke_preview.cpp +++ b/engine/node_stroke_preview.cpp @@ -29,7 +29,7 @@ void NodeStrokePreview::clone_finalize(Node* dest) const void NodeStrokePreview::init_controls() { m_mesh.create(); - m_sampler.create(); + m_sampler.create(GL_LINEAR, GL_REPEAT); m_sampler_brush.create(); m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR); TextureManager::load("data/thumbs/Round-Hard.png"); @@ -74,14 +74,24 @@ void NodeStrokePreview::draw_stroke() m_stroke.m_prev_sample.origin = m_stroke.m_keypoints[0].pos; auto samples = m_stroke.compute_samples(); auto& tex = TextureManager::get(m_brush.m_tex_id); + glActiveTexture(GL_TEXTURE0); tex.bind(); m_sampler_brush.bind(0); + + auto& stencil = TextureManager::get(const_hash("data/paper.jpg")); + glActiveTexture(GL_TEXTURE1); + stencil.bind(); + m_sampler.bind(1); if (true) { m_mesh.shader.use(); m_mesh.shader.u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 }); m_mesh.shader.u_int(kShaderUniform::Tex, 0); + m_mesh.shader.u_int(kShaderUniform::TexStencil, 1); // stencil + m_mesh.shader.u_vec2(kShaderUniform::Resolution, { m_rtt.getWidth(), m_rtt.getHeight() }); + m_mesh.shader.u_vec2(kShaderUniform::StencilOffset, glm::vec2(0)); + m_mesh.shader.u_float(kShaderUniform::StencilAlpha, m_brush.m_tip_stencil); m_mesh.draw(samples, proj); } //else @@ -102,6 +112,7 @@ void NodeStrokePreview::draw_stroke() //} m_sampler_brush.unbind(); + m_sampler.unbind(); tex.unbind(); glDisable(GL_BLEND); diff --git a/engine/shader.cpp b/engine/shader.cpp index 426e3d1..e6073e1 100644 --- a/engine/shader.cpp +++ b/engine/shader.cpp @@ -105,24 +105,29 @@ void Shader::use() } void Shader::u_vec4(kShaderUniform id, const glm::vec4& v) { + if (m_umap.count(id) == 0) LOG("UNIFORM %d NOT FOUND in shader %d", (int)id, (int)name); glUniform4fv(m_umap[id], 1, glm::value_ptr(v)); } void Shader::u_vec2(kShaderUniform id, const glm::vec2& v) { + if (m_umap.count(id) == 0) LOG("UNIFORM %d NOT FOUND in shader %d", (int)id, (int)name); glUniform2fv(m_umap[id], 1, glm::value_ptr(v)); } void Shader::u_mat4(kShaderUniform id, const glm::mat4& m) { + if (m_umap.count(id) == 0) LOG("UNIFORM %d NOT FOUND in shader %d", (int)id, (int)name); glUniformMatrix4fv(m_umap[id], 1, GL_FALSE, glm::value_ptr(m)); } void Shader::u_int(kShaderUniform id, int i) { + if (m_umap.count(id) == 0) LOG("UNIFORM %d NOT FOUND in shader %d", (int)id, (int)name); glUniform1i(m_umap[id], i); } void Shader::u_float(kShaderUniform id, float f) { + if (m_umap.count(id) == 0) LOG("UNIFORM %d NOT FOUND in shader %d", (int)id, (int)name); glUniform1f(m_umap[id], f); } GLint ui::Shader::GetAttribLocation(const char* name)