diff --git a/src/app_shaders.cpp b/src/app_shaders.cpp index 24dd656..bd7f35c 100644 --- a/src/app_shaders.cpp +++ b/src/app_shaders.cpp @@ -101,6 +101,7 @@ void App::initShaders() //"uniform image2D img_mixer;\n" "uniform mediump float alpha;\n" "uniform mediump int blend_mode;\n" + "uniform mediump vec2 resolution;\n" "uniform bool lock;\n" "uniform bool mask;\n" "in mediump vec3 uv;\n" @@ -139,7 +140,7 @@ void App::initShaders() "}\n" "void main(){\n" - " mediump vec4 base = texture(tex, uv.xy);\n" + " mediump vec4 base = texture(tex, gl_FragCoord.st / resolution);\n" " mediump vec4 stroke = texture(tex_stroke, uv.xy);\n" " stroke.a = mask ? stroke.a * alpha * blur(tex_mask, uv.xy).r : stroke.a * alpha;\n" diff --git a/src/app_vr.cpp b/src/app_vr.cpp index 2b88045..080b441 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -90,6 +90,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ui::ShaderManager::u_int(kShaderUniform::Tex, 0); ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); ui::ShaderManager::u_int(kShaderUniform::TexMask, 2); + ui::ShaderManager::u_vec2(ui::kShaderUniform::Resolution, canvas->m_canvas->m_size); //ui::ShaderManager::u_int(kShaderUniform::TexStencil, 3); ui::ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_stroke->m_brush.m_tip_opacity); ui::ShaderManager::u_int(kShaderUniform::Lock, canvas->m_canvas->m_layers[layer_index].m_alpha_locked); diff --git a/src/canvas.cpp b/src/canvas.cpp index 1a42d40..8cdb89d 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -291,6 +291,7 @@ void ui::Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz //ui::ShaderManager::u_int(kShaderUniform::TexA, 0); ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); ui::ShaderManager::u_int(kShaderUniform::TexMask, 2); + ui::ShaderManager::u_vec2(ui::kShaderUniform::Resolution, m_size); //ui::ShaderManager::u_int(kShaderUniform::TexStencil, 3); ui::ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity); ui::ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index].m_alpha_locked); @@ -785,6 +786,7 @@ void ui::Canvas::stroke_commit() ui::ShaderManager::u_int(kShaderUniform::Tex, 0); ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); ui::ShaderManager::u_int(kShaderUniform::TexMask, 2); + ui::ShaderManager::u_vec2(ui::kShaderUniform::Resolution, m_size); ui::ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity); ui::ShaderManager::u_int(kShaderUniform::Mask, m_smask_active); ui::ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush.m_blend_mode); @@ -960,6 +962,7 @@ void ui::Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index ui::ShaderManager::use(kShader::CompDraw); ui::ShaderManager::u_int(kShaderUniform::Tex, 0); // dest ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); // source + ui::ShaderManager::u_vec2(ui::kShaderUniform::Resolution, m_size); ui::ShaderManager::u_float(kShaderUniform::Alpha, m_layers[source_idx].m_opacity); ui::ShaderManager::u_int(kShaderUniform::Lock, false); ui::ShaderManager::u_int(kShaderUniform::BlendMode, 0); // TODO: defaulted to normal, change to layer blend mode when implemented diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index bdd2a60..dcd3302 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -914,6 +914,7 @@ void CanvasModeTransform::enter() auto center3d = canvas->point_trace(midpoint); for (auto& v : shape3d) { + v.uvs2 = v.uvs / canvas->m_size; v.uvs = (v.uvs - bb_min) / bb_sz; v.pos = center_mat * v.pos; } @@ -952,18 +953,44 @@ void CanvasModeTransform::leave() glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas->m_plane_origin[i], canvas->m_plane_tangent[i]); layer.m_rtt[i].bindFramebuffer(); + canvas->m_tex2[i].bind(); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, canvas->m_width, canvas->m_height); + canvas->m_tex2[i].unbind(); + + ui::ShaderManager::use(ui::kShader::CompDraw); + ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0); + ui::ShaderManager::u_int(ui::kShaderUniform::TexStroke, 1); + ui::ShaderManager::u_int(ui::kShaderUniform::TexMask, 2); + ui::ShaderManager::u_vec2(ui::kShaderUniform::Resolution, canvas->m_size); + ui::ShaderManager::u_float(ui::kShaderUniform::Alpha, 1); + ui::ShaderManager::u_int(ui::kShaderUniform::Mask, false); + ui::ShaderManager::u_int(ui::kShaderUniform::BlendMode, 0); + ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local); + + canvas->m_sampler.bind(1); + canvas->m_sampler.bind(0); + + glActiveTexture(GL_TEXTURE0); + canvas->m_tex2[i].bind(); + + glActiveTexture(GL_TEXTURE1); for (int j = 0; j < 6; j++) { - ui::ShaderManager::use(ui::kShader::Color); - ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local); - ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 }); - m_shape[j].draw_fill(); + //ui::ShaderManager::use(ui::kShader::Color); + //ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local); + //ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 }); + //m_shape[j].draw_fill(); + + //ui::ShaderManager::use(ui::kShader::Texture); + //ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0); + //ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local); + //m_tex[j].bind(); + //canvas->m_sampler.bind(0); + //m_shape[j].draw_fill(); + //m_tex[j].unbind(); + - ui::ShaderManager::use(ui::kShader::Texture); - ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0); - ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local); m_tex[j].bind(); - canvas->m_sampler.bind(0); m_shape[j].draw_fill(); m_tex[j].unbind(); } @@ -1019,6 +1046,7 @@ void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, m_tex[i].unbind(); } + ui::ShaderManager::use(ui::kShader::Color); auto m2d = canvas->m_proj * canvas->m_mv * m_xform * m_xform_local; for (int i = 0; i < corners.size(); i++) { diff --git a/src/main.cpp b/src/main.cpp index 25bb916..522fd68 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -495,7 +495,8 @@ int main(int argc, char** argv) LOG("GL renderer: %s", glGetString(GL_RENDERER)); static wchar_t window_title[512]; - swprintf_s(window_title, L"PanoPainter %s", g_version_number_w); + swprintf_s(window_title, L"PanoPainter %s (%s)", g_version_number_w, + str2wstr((char*)glGetString(GL_RENDERER)).c_str()); // If supported create a 3.1 context if (wglewIsSupported("WGL_ARB_create_context")) diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 2276b23..778d276 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -176,6 +176,7 @@ void NodeCanvas::draw() ui::ShaderManager::u_int(kShaderUniform::Tex, 0); ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); ui::ShaderManager::u_int(kShaderUniform::TexMask, 2); + ui::ShaderManager::u_vec2(ui::kShaderUniform::Resolution, m_canvas->m_size); //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_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked); diff --git a/src/shader.cpp b/src/shader.cpp index 52cf40d..954f150 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -115,19 +115,22 @@ void Shader::use() } void Shader::u_vec4(kShaderUniform id, const glm::vec4& v) { - if (m_umap.count(id) == 0) LOG("UNIFORM vec4 %d NOT FOUND in shader %d", (int)id, (int)name) + if (m_umap.count(id) == 0) + LOG("UNIFORM vec4 %d NOT FOUND in shader %d", (int)id, (int)name) else 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 vec2 %d NOT FOUND in shader %d", (int)id, (int)name) + if (m_umap.count(id) == 0) + LOG("UNIFORM vec2 %d NOT FOUND in shader %d", (int)id, (int)name) else 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 mat4 %d NOT FOUND in shader %d", (int)id, (int)name) + if (m_umap.count(id) == 0) + LOG("UNIFORM mat4 %d NOT FOUND in shader %d", (int)id, (int)name) else glUniformMatrix4fv(m_umap[id], 1, GL_FALSE, glm::value_ptr(m)); } void Shader::u_int(kShaderUniform id, int i) @@ -139,7 +142,8 @@ void Shader::u_int(kShaderUniform id, int i) } void Shader::u_float(kShaderUniform id, float f) { - if (m_umap.count(id) == 0) LOG("UNIFORM float %d NOT FOUND in shader %d", (int)id, (int)name) + if (m_umap.count(id) == 0) + LOG("UNIFORM float %d NOT FOUND in shader %d", (int)id, (int)name) else glUniform1f(m_umap[id], f); } GLint ui::Shader::GetAttribLocation(const char* name) diff --git a/src/shape.cpp b/src/shape.cpp index 2b4c8b7..7ab1610 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -173,10 +173,10 @@ bool RectShape::create(float w, float h) 3, 0, }; static vertex_t vertices[4]; - vertices[0] = { { -w/2, -h/2, 0, 1 }, { 0, 0 } }; // A - vertices[1] = { { -w/2, h/2, 0, 1 }, { 0, 1 } }; // B - vertices[2] = { { w/2, 0, 0, 1 }, { 1, 1 } }; // C - vertices[3] = { { w/2, -h/2, 0, 1 }, { 1, 0 } }; // D + vertices[0] = { { -w/2, -h/2, 0, 1 }, { 0, 0 }, { 0, 0 } }; // A + vertices[1] = { { -w/2, h/2, 0, 1 }, { 0, 1 }, { 0, 1 } }; // B + vertices[2] = { { w/2, 0, 0, 1 }, { 1, 1 }, { 1, 1 } }; // C + vertices[3] = { { w/2, -h/2, 0, 1 }, { 1, 0 }, { 1, 0 } }; // D count[0] = 6; count[1] = 8; ioff[0] = (GLvoid*)0; @@ -269,7 +269,7 @@ bool ui::HeightmapPlane::create(float w, float h, const Image& img, float scale) v.pos.y = oy + dy * (float)y; v.pos.z = (*px++).r / 255.f * scale; v.pos.w = 1; - v.uvs = glm::vec2(x, y) / (float)div; + v.uvs2 = v.uvs = glm::vec2(x, y) / (float)div; *pv++ = v; } } @@ -371,7 +371,7 @@ void Circle::create_impl(float radius, int div, GLushort* idx, vertex_t* vertice float theta = (float)i / div * (float)M_PI * 2.f; glm::vec2 uv = { sinf(theta), cosf(theta) }; v.pos = glm::vec4(uv * radius, 0, 1); - v.uvs = uv * 0.5f + 0.5f; + v.uvs2 = v.uvs = uv * 0.5f + 0.5f; vertices[i+1] = v; *pidx++ = 0; @@ -382,7 +382,7 @@ void Circle::create_impl(float radius, int div, GLushort* idx, vertex_t* vertice *pidx2++ = 1 + ((i+1) % div); } vertices[0].pos = { 0, 0, 0, 1 }; - vertices[0].uvs = { 0.5f, 0.5f }; + vertices[0].uvs2 = vertices[0].uvs = { 0.5f, 0.5f }; } void Circle::create_impl(float radius_out, float radius_in, int div, GLushort* idx, vertex_t* vertices, kUVMapping map) @@ -400,13 +400,13 @@ void Circle::create_impl(float radius_out, float radius_in, int div, GLushort* i glm::vec2 uv = { sinf(theta), cosf(theta) }; if (map == kUVMapping::Planar) { - vertices[i*2].uvs = uv * (radius_in/radius_out) * 0.5f + 0.5f; - vertices[i*2+1].uvs = uv * 0.5f + 0.5f; + vertices[i*2].uvs2 = vertices[i*2].uvs = uv * (radius_in/radius_out) * 0.5f + 0.5f; + vertices[i*2+1].uvs2 = vertices[i*2+1].uvs = uv * 0.5f + 0.5f; } else { - vertices[i*2].uvs = { (float)i / div, 0.f }; // inner - vertices[i*2+1].uvs = { (float)i / div, 1.f};// outer + vertices[i*2].uvs2 = vertices[i*2].uvs = { (float)i / div, 0.f }; // inner + vertices[i*2+1].uvs2 = vertices[i*2+1].uvs = { (float)i / div, 1.f};// outer } vertices[i*2].pos = glm::vec4(uv * radius_in, 0, 1); vertices[i*2+1].pos = glm::vec4(uv * radius_out, 0, 1); @@ -496,7 +496,7 @@ void Rounded::create_impl(float w, float h, float r, int div, GLushort* idx, GLu float t = (float)(i) / div; auto p = glm::normalize(glm::mix(xyz(v[a].pos)-xyz(v[c].pos), xyz(v[b].pos)-xyz(v[c].pos), t)); v[n].pos = glm::vec4(p * r + xyz(v[c].pos), 1.0f); - v[n].uvs = glm::normalize(glm::mix(v[a].uvs-v[c].uvs, v[b].uvs-v[c].uvs, t)) * glm::vec2(r/w, r/h) + v[c].uvs; + v[n].uvs2 = v[n].uvs = glm::normalize(glm::mix(v[a].uvs-v[c].uvs, v[b].uvs-v[c].uvs, t)) * glm::vec2(r/w, r/h) + v[c].uvs; idx_tmp[i] = n; n++; } diff --git a/src/shape.h b/src/shape.h index 1a9b8ac..6a44d53 100644 --- a/src/shape.h +++ b/src/shape.h @@ -62,7 +62,7 @@ protected: for (int i = 0; i < 4; i++) { float q = (d[i] + d[(i + 2) % 4]) / d[(i + 2) % 4]; - v[i]->uvs = glm::vec2(v[i]->uvs) * q; + v[i]->uvs2 = v[i]->uvs = glm::vec2(v[i]->uvs) * q; v[i]->pos.w = q; } } @@ -78,8 +78,8 @@ public: count[1] = 2; ioff[0] = (GLvoid*)0; ioff[1] = (GLvoid*)0; - vertices[0] = { { 0, 0, 0, 1 },{ 0, 0 } }; // A - vertices[1] = { { 0, 0, 0, 1 },{ 0, 1 } }; // B + vertices[0] = { { 0, 0, 0, 1 }, { 0, 0 }, { 0, 0 } }; // A + vertices[1] = { { 0, 0, 0, 1 }, { 0, 1 }, { 0, 1 } }; // B return create_buffers(vertices, sizeof(vertices)); } void update_vertices(const glm::vec4 data[2]); diff --git a/src/util.cpp b/src/util.cpp index 27e7043..5a8988b 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -293,6 +293,26 @@ std::string unescape(const std::string& s) return res; } +std::wstring str2wstr(const std::string& str) +{ + mbstate_t st = {}; + std::wstring converted; + converted.resize(str.size()); + const char* ptr = str.c_str(); + std::mbsrtowcs((wchar_t*)converted.data(), &ptr, converted.capacity(), &st); + return converted; +} + +std::string wstr2str(const std::wstring & wstr) +{ + mbstate_t st = {}; + std::string converted; + converted.resize(wstr.size()); + const wchar_t * wptr = wstr.c_str(); + std::wcsrtombs((char*)converted.data(), &wptr, converted.capacity(), &st); + return converted; +} + static const char* gl2str(GLenum err) { switch (err) diff --git a/src/util.h b/src/util.h index f82d51a..bf57980 100644 --- a/src/util.h +++ b/src/util.h @@ -59,6 +59,8 @@ glm::vec3 convert_hsv2rgb(const glm::vec3 c); glm::vec3 convert_rgb2hsv(const glm::vec3 c); std::vector split(const std::string& subject, char d, int max_split = 0); std::string unescape(const std::string& s); +std::wstring str2wstr(const std::string& str); +std::string wstr2str(const std::wstring& wstr); size_t curl_data_handler(void *contents, size_t size, size_t nmemb, void *userp); size_t curl_data_write(void *ptr, size_t size, size_t nmemb, FILE *stream);