diff --git a/data/layout.xml b/data/layout.xml index 15faf10..0ccdccb 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -1024,7 +1024,7 @@ PanoPainter - Copyright 2018 OmixLab Ltd In the late 2016 Facebook started to make it possible for users to post 360 content captured from the first 360 cameras born after the advent of the VR to the market. - That's where me and a bounch or artists started to wonder about making art in 360. + That's where me and a bunch or artists started to wonder about making art in 360. I then started coding in my spare time to create something that would have helped artists in the long process of creating a panoramic painting (panopainting). @@ -1036,6 +1036,7 @@ PanoPainter - Copyright 2018 OmixLab Ltd - Instagram: @panopainter - Twitter: @panopainter - Facebook: fb.me/panopainter + - Reddit: reddit.com/r/panopainter ------------------------------------------------- FREE SOFTWARE LICENSES ------------------------------------------------- diff --git a/data/shaders/comp-draw.glsl b/data/shaders/comp-draw.glsl index 49acc43..3eef859 100644 --- a/data/shaders/comp-draw.glsl +++ b/data/shaders/comp-draw.glsl @@ -51,7 +51,8 @@ void main() { mediump vec4 base = texture(tex, uv); mediump vec4 stroke = texture(tex_stroke, uv); - if (stroke.a == 0) + + if (stroke.a == 0.0) { frag = base; return; @@ -68,13 +69,13 @@ void main() patt = brightness1(patt, 1.0 - pattern_bright); if (pattern_contr != 0.5) patt = contrast1(patt, pattern_contr); - stroke.a = blend_stroke(stroke.a, patt, pattern_depth, patt_blend_mode); + stroke.a = clamp(blend_stroke(stroke.a, patt, pattern_depth, patt_blend_mode), 0.0, 1.0); } if (use_dual) { mediump vec4 dual = texture(tex_dual, uv); - stroke.a = blend_stroke(stroke.a, dual.a, dual_alpha, dual_blend_mode); + stroke.a = clamp(blend_stroke(stroke.a, dual.a, dual_alpha, dual_blend_mode), 0.0, 1.0); } stroke.a = mask ? stroke.a * blur(tex_mask, uv).r : stroke.a; diff --git a/src/abr.cpp b/src/abr.cpp index 713635b..d41a052 100644 --- a/src/abr.cpp +++ b/src/abr.cpp @@ -27,6 +27,7 @@ bool ABR::section_desc() LOG("%s", l.c_str()); } } + snap(); return true; } @@ -167,7 +168,7 @@ std::vector> ABR::compute_brushes(const std::string& path b->m_jitter_scale = jitter_size->value("jitter") * 0.01f; // TODO: p->value("minimumDiameter") * 0.001f; // minimum size if (jitter_size->value("bVTy") == 2) - b->m_tip_size_pressure; + b->m_tip_size_pressure = true; } auto jitter_angle = p->get("angleDynamics"); diff --git a/src/app_shaders.cpp b/src/app_shaders.cpp index 67d6a8a..4b8fc60 100644 --- a/src/app_shaders.cpp +++ b/src/app_shaders.cpp @@ -4,6 +4,10 @@ void App::initShaders() { +#ifdef _DEBUG + if (!check_uniform_uniqueness()) + std::logic_error("check_uniform_uniqueness() failed"); +#endif // _DEBUG GLint n_exts; glGetIntegerv(GL_NUM_EXTENSIONS, &n_exts); diff --git a/src/canvas.cpp b/src/canvas.cpp index 5a595df..ec6bc64 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -558,7 +558,8 @@ void Canvas::stroke_draw() ShaderManager::u_float(kShaderUniform::Noise, 0); glActiveTexture(GL_TEXTURE0); - dual_brush->m_tip_texture->bind(); + if (dual_brush->m_tip_texture) + dual_brush->m_tip_texture->bind(); auto frames_dual = stroke_draw_compute(*m_dual_stroke); for (auto& f : frames_dual) { @@ -580,8 +581,6 @@ void Canvas::stroke_draw() m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], rect), glm::vec4(0), glm::vec4(m_width)); } } - glActiveTexture(GL_TEXTURE0); - dual_brush->m_tip_texture->unbind(); } m_sampler_brush.unbind(); @@ -1440,9 +1439,14 @@ void Canvas::export_equirectangular_thread(std::string file_path) LOG("writing %s", file_path.c_str()); if (file_path.substr(file_path.size() - 4) == ".jpg") + { stbi_write_jpg(file_path.c_str(), m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), 100); + inject_xmp(file_path); + } else if (file_path.substr(file_path.size() - 4) == ".png") + { stbi_write_png(file_path.c_str(), m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), 0); + } { progress++; diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index 98e0405..37d90bd 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -1155,7 +1155,6 @@ void CanvasModeTransform::leave() ShaderManager::use(kShader::CompDraw); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::TexStroke, 1); - ShaderManager::u_int(kShaderUniform::TexMask, 2); ShaderManager::u_float(kShaderUniform::Alpha, 1); ShaderManager::u_int(kShaderUniform::Lock, false); ShaderManager::u_int(kShaderUniform::Mask, false); diff --git a/src/main.cpp b/src/main.cpp index 098d068..cd194a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -608,10 +608,10 @@ int main(int argc, char** argv) SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1))); - LOG("set redraw interval"); - SetTimer(hWnd, 1, 500, [](HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { - App::I.redraw = true; - }); + //LOG("set redraw interval"); + //SetTimer(hWnd, 1, 500, [](HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { + // App::I.redraw = true; + //}); running = 1; diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp index d2273e0..c859e99 100644 --- a/src/node_panel_stroke.cpp +++ b/src/node_panel_stroke.cpp @@ -37,23 +37,20 @@ bool NodePanelStroke::import_abr(const std::string& path) name = m[2].str(); ext = m[3].str(); - if (!str_iequals(ext, "abr")) + if (!str_iequals(ext, "abr") || !Asset::exist(path)) return false; - if (!abr.open(path)) - { - LOG("ABR read failed"); - return false; - } - - int tot = abr.m_samples.size() + abr.m_patterns.size() + abr.m_presets.size(); - std::atomic_int count(0); async_start(); auto pb = App::I.show_progress("Importing ABR"); app_redraw(); async_update(); async_end(); + abr.open(path); + + int tot = abr.m_samples.size() + abr.m_patterns.size() + abr.m_presets.size(); + std::atomic_int count(0); + parallel_for(abr.m_samples.size(), [&](size_t i) //for (const auto& samp : abr.m_samples) { diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index c950949..85187b1 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -278,9 +278,9 @@ void NodeStrokePreview::draw_stroke() } { - float w = m_size.x; - float h = m_size.y; - float pad = m_size.x * .15f; + float w = m_size.x * App::I.zoom; + float h = m_size.y * App::I.zoom; + float pad = m_size.x * App::I.zoom * .15f; std::vector kp = { { pad, pad },{ pad, h - pad },{ w - pad, pad },{ w - pad, h - pad } }; for (int i = 0; i < 20; i++) { @@ -326,7 +326,8 @@ void NodeStrokePreview::draw_stroke() ShaderManager::u_float(kShaderUniform::Wet, 0); ShaderManager::u_float(kShaderUniform::Noise, 0); glActiveTexture(GL_TEXTURE0); - dual_brush->m_tip_texture->bind(); + if (dual_brush->m_tip_texture) + dual_brush->m_tip_texture->bind(); auto frames_dual = stroke_draw_compute(m_dual_stroke); for (auto& f : frames_dual) { @@ -335,8 +336,6 @@ void NodeStrokePreview::draw_stroke() ShaderManager::u_float(kShaderUniform::Opacity, f.opacity); auto rect = stroke_draw_samples(f.shapes, m_tex_dual); } - glActiveTexture(GL_TEXTURE0); - dual_brush->m_tip_texture->unbind(); // copy raw stroke to tex glActiveTexture(GL_TEXTURE1); diff --git a/src/shader.cpp b/src/shader.cpp index 8e390c5..f0052ac 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -394,3 +394,60 @@ void ShaderManager::invalidate() { m_shaders.clear(); } + +bool check_uniform_uniqueness() +{ + std::vector v = { + const_hash("mvp"), + const_hash("tex"), + const_hash("tex_alpha"), + const_hash("tex_fg"), + const_hash("tex_bg"), + const_hash("tex_mix"), + const_hash("tex_mix_alpha"), + const_hash("tex_mask"), + const_hash("tex_dual"), + const_hash("tex_stroke"), + const_hash("tex_pattern"), + const_hash("pattern_offset"), + const_hash("pattern_alpha"), + const_hash("mix_alpha"), + const_hash("opacity"), + const_hash("wet"), + const_hash("lock"), + const_hash("col"), + const_hash("tof"), + const_hash("tsz"), + const_hash("alpha"), + const_hash("mask"), + const_hash("resolution"), + const_hash("highlight"), + const_hash("blend_mode"), + const_hash("dual_blend_mode"), + const_hash("noise"), + const_hash("dir"), + const_hash("use_dual"), + const_hash("use_pattern"), + const_hash("light_dir"), + const_hash("mode"), + const_hash("ambient"), + const_hash("pattern_invert"), + const_hash("pattern_scale"), + const_hash("pattern_bright"), + const_hash("pattern_contr"), + const_hash("pattern_depth"), + const_hash("patt_blend_mode"), + const_hash("colorize"), + const_hash("dual_alpha"), + const_hash("draw_on_screen"), + }; + std::sort(v.begin(), v.end()); + int last = 0; + for (auto o : v) + { + if (o == last) + return false; + last = o; + } + return true; +} diff --git a/src/shader.h b/src/shader.h index 1e47a13..b0f2c35 100644 --- a/src/shader.h +++ b/src/shader.h @@ -1,6 +1,8 @@ #pragma once #include "util.h" +bool check_uniform_uniqueness(); + enum class kShaderUniform : uint16_t { MVP = const_hash("mvp"),