Set default document res to 6K. Implement blending on canvas, mixer and export equirect.

This commit is contained in:
2019-01-07 15:32:12 +01:00
parent 006c838449
commit 7773026358
9 changed files with 144 additions and 65 deletions

View File

@@ -361,7 +361,6 @@ void App::init()
glEnable(GL_LINE_SMOOTH);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendEquation(GL_FUNC_ADD);
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
initShaders();

View File

@@ -83,6 +83,24 @@ void App::initShaders()
"void main() {\n"
" frag = texture(tex, uv);\n"
"}\n";
static const char* shader_blend_f =
SHADER_VERSION
"uniform sampler2D tex;\n"
"uniform sampler2D tex_alpha;\n"
"uniform sampler2D tex_bg;\n"
"uniform mediump float alpha;\n"
"uniform int blend_mode;\n"
"in mediump vec2 uv;\n"
"out mediump vec4 frag;\n"
SHADER_FUNCTION_BLEND
"void main() {\n"
" mediump vec4 bg = texture(tex_bg, uv);\n"
" mediump vec4 fg = vec4(texture(tex, uv).rgb, texture(tex_alpha, uv).a);\n"
" if (fg.a == 0.0) { frag = bg; return; }\n"
" mediump float contribution = (1.0 - bg.a) * fg.a;\n"
" mediump float alpha_tot = bg.a + contribution;\n"
" frag = vec4(blend(bg, fg, alpha_tot, blend_mode), alpha_tot * alpha);\n"
"}\n";
static const char* shader_uv_f =
SHADER_VERSION
"in mediump vec2 uv;\n"
@@ -109,6 +127,7 @@ void App::initShaders()
SHADER_VERSION
"uniform sampler2D tex;\n"
"uniform sampler2D tex_alpha;\n"
"uniform sampler2D tex_bg;\n"
"uniform mediump float alpha;\n"
"uniform bool highlight;\n"
"in mediump vec2 uv;\n"
@@ -503,6 +522,8 @@ void App::initShaders()
LOG("Failed to create shader TextureAlpha");
if (!ShaderManager::create(kShader::TextureAlphaSep, shader_v, shader_alpha_sep_f))
LOG("Failed to create shader TextureAlphaSep");
if (!ShaderManager::create(kShader::TextureBlend, shader_v, shader_blend_f))
LOG("Failed to create shader TextureBlend");
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))

View File

@@ -46,7 +46,9 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
auto layer_index = canvas->m_canvas->m_order[i];
for (int plane_index = 0; plane_index < 6; plane_index++)
{
if (!canvas->m_canvas->m_layers[layer_index].m_visible || canvas->m_canvas->m_layers[layer_index].m_opacity == .0f)
if (!canvas->m_canvas->m_layers[layer_index].m_visible ||
canvas->m_canvas->m_layers[layer_index].m_opacity == .0f ||
!canvas->m_canvas->m_layers[layer_index].m_dirty_face)
continue;
int z = (int)(canvas->m_canvas->m_order.size() - i);

View File

@@ -244,7 +244,9 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
auto layer_index = m_current_layer_idx;
for (int plane_index = 0; plane_index < 6; plane_index++)
{
if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == .0f)
if (!m_layers[layer_index].m_visible ||
m_layers[layer_index].m_opacity == .0f ||
!m_layers[layer_index].m_dirty_face)
continue;
glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)m_mixer.getWidth() / m_mixer.getHeight(), 0.1f, 1000.f);
@@ -1018,7 +1020,7 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
ShaderManager::u_float(kShaderUniform::StrokeAlpha, 1);
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[source_idx].m_opacity);
ShaderManager::u_int(kShaderUniform::Lock, false);
ShaderManager::u_int(kShaderUniform::BlendMode, 0); // TODO: defaulted to normal, change to layer blend mode when implemented
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[source_idx].m_blend_mode);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
glActiveTexture(GL_TEXTURE0);
@@ -1273,32 +1275,60 @@ void Canvas::export_equirectangular_thread(std::string file_path)
int progress = 0;
int total = 6 + 2;
Texture2D face;
face.create(m_width, m_height);
for (int i = 0; i < 6; i++)
{
// prepare common states
glViewport(0, 0, m_width, m_height);
glEnable(GL_BLEND);
glDisable(GL_BLEND);
ShaderManager::use(kShader::TextureAlpha);
ShaderManager::u_int(kShaderUniform::Highlight, false);
ShaderManager::use(kShader::TextureBlend);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexA, 1);
ShaderManager::u_int(kShaderUniform::TexBG, 2);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
m_tmp[i].bindFramebuffer();
m_tmp[i].clear({ 1, 1, 1, 1 });
m_tmp[i].clear({ 1, 1, 1, 0 });
glActiveTexture(GL_TEXTURE0); // TODO: maybe remove this line
m_sampler_mask.bind(0);
glActiveTexture(GL_TEXTURE2);
face.bind();
m_sampler_bg.bind(0); // nearest
m_sampler_mask.bind(1); // linear
m_sampler_bg.bind(2);
for (auto layer_index : m_order)
{
if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == 0.f)
continue;
glActiveTexture(GL_TEXTURE2);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index].m_blend_mode);
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[i].bindTexture();
glActiveTexture(GL_TEXTURE1);
m_layers[layer_index].m_rtt[i].bindTexture();
m_plane.draw_fill();
m_layers[layer_index].m_rtt[i].unbindTexture();
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[i].unbindTexture();
}
m_sampler_mask.unbind();
glActiveTexture(GL_TEXTURE2);
face.unbind();
glEnable(GL_BLEND);
ShaderManager::use(kShader::Texture);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
m_sampler_mask.bind(0); // linear
glActiveTexture(GL_TEXTURE0);
face.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
m_tmp[i].clear({ 1, 1, 1, 1 });
m_plane.draw_fill();
face.unbind();
// copy result to cubemap
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
@@ -1320,6 +1350,8 @@ void Canvas::export_equirectangular_thread(std::string file_path)
}
}
face.destroy();
//auto data = std::make_unique<uint8_t[]>(m_tmp[0].bytes());
//for (int i = 0; i < 1; i++)
//{

View File

@@ -8,7 +8,7 @@
#include "canvas_modes.h"
#include <stack>
#define CANVAS_RES 512
#define CANVAS_RES 1536
class Layer
{
@@ -20,7 +20,7 @@ public:
bool m_alpha_locked = false;
float m_opacity = 1.f;
bool m_hightlight = false;
bool m_blend_mode = 0;
int m_blend_mode = 0;
std::string m_name;
int w = 0;
int h = 0;

View File

@@ -65,7 +65,7 @@ void NodeCanvas::draw()
glGetIntegerv(GL_VIEWPORT, vp);
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
glClearColor(0, 0, 0, 1);
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
float zoom = root()->m_zoom;
auto box = m_clip * zoom;
@@ -96,30 +96,6 @@ void NodeCanvas::draw()
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
for (int plane_index = 0; plane_index < 6; plane_index++)
{
glm::mat4 plane_camera = glm::lookAt(m_canvas->m_plane_origin[plane_index], m_canvas->m_plane_normal[plane_index], m_canvas->m_plane_tangent[plane_index]);
m_canvas->m_plane_unproject[plane_index] = glm::inverse(m_canvas->m_proj * m_canvas->m_mv * m_canvas->m_plane_transform[plane_index]);
m_canvas->m_plane_dir[plane_index] = -(m_canvas->m_plane_transform[plane_index] * glm::vec4(m_canvas->m_plane_origin[plane_index], 1));
// face is the 2d shape of the cube plane i projected onto the window space
m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index);
auto plane_mvp = proj * camera *
glm::scale(glm::vec3(m_canvas->m_order.size() + 500)) *
m_canvas->m_plane_transform[plane_index] *
glm::translate(glm::vec3(0, 0, -1));
ShaderManager::use(kShader::Checkerboard);
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
m_face_plane.draw_fill();
}
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
float pitch = 0;
if (auto slider = root()->find<NodeSliderH>("pitch-slider"))
@@ -131,15 +107,21 @@ void NodeCanvas::draw()
if (auto slider = root()->find<NodeSliderH>("roll-slider"))
roll = (slider->get_value() - 0.5) * glm::half_pi<float>();
m_cache_rtt.bindFramebuffer();
m_cache_rtt.clear({ 1, 1, 1, 0 });
for (size_t i = 0; i < m_canvas->m_order.size(); i++)
{
auto layer_index = m_canvas->m_order[i];
for (int plane_index = 0; plane_index < 6; plane_index++)
{
if (!m_canvas->m_layers[layer_index].m_visible || m_canvas->m_layers[layer_index].m_opacity == .0f)
if (!m_canvas->m_layers[layer_index].m_visible ||
m_canvas->m_layers[layer_index].m_opacity == .0f ||
!m_canvas->m_layers[layer_index].m_dirty_face)
continue;
m_blender_rtt.bindFramebuffer();
m_blender_rtt.clear();
int z = (int)(m_canvas->m_order.size() - i);
auto plane_mvp_z = proj * camera *
glm::scale(glm::vec3(z + 1)) *
@@ -231,45 +213,80 @@ void NodeCanvas::draw()
m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture();
}
// if (m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
// {
// glDisable(GL_BLEND);
// ShaderManager::use(kShader::TextureAlpha);
// ShaderManager::u_int(kShaderUniform::Tex, 0);
// ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
// ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
// ShaderManager::u_float(kShaderUniform::Alpha, 1);
// m_canvas->m_tmp[plane_index].bindTexture();
// m_face_plane.draw_fill();
// m_canvas->m_tmp[plane_index].unbindTexture();
// glEnable(GL_BLEND);
// }
}
}
m_blender_rtt.unbindFramebuffer();
/*
if (m_canvas->m_smask_active && !m_canvas->m_show_tmp)
// draw the blended
{
glDisable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
m_sampler.bind(0);
m_sampler_linear.bind(1);
m_sampler.bind(2);
ShaderManager::use(kShader::TextureBlend);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexA, 1);
ShaderManager::u_int(kShaderUniform::TexBG, 2);
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index].m_blend_mode);
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1, 1, -1, 1));
glActiveTexture(GL_TEXTURE0);
m_blender_rtt.bindTexture();
glActiveTexture(GL_TEXTURE1);
m_blender_rtt.bindTexture();
glActiveTexture(GL_TEXTURE2);
m_blender_bg.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_blender_bg.size().x, m_blender_bg.size().y);
m_face_plane.draw_fill();
glActiveTexture(GL_TEXTURE2);
m_blender_bg.unbind();
glActiveTexture(GL_TEXTURE1);
m_blender_bg.unbind();
glActiveTexture(GL_TEXTURE0);
m_blender_rtt.unbindTexture();
}
}
}
m_cache_rtt.unbindFramebuffer();
// draw the grid behind the layers using a temporary copy
{
glEnable(GL_BLEND);
//draw the grid
for (int plane_index = 0; plane_index < 6; plane_index++)
{
glm::mat4 plane_camera = glm::lookAt(m_canvas->m_plane_origin[plane_index], m_canvas->m_plane_normal[plane_index], m_canvas->m_plane_tangent[plane_index]);
m_canvas->m_plane_unproject[plane_index] = glm::inverse(m_canvas->m_proj * m_canvas->m_mv * m_canvas->m_plane_transform[plane_index]);
m_canvas->m_plane_dir[plane_index] = -(m_canvas->m_plane_transform[plane_index] * glm::vec4(m_canvas->m_plane_origin[plane_index], 1));
// face is the 2d shape of the cube plane i projected onto the window space
m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index);
auto plane_mvp = proj * camera *
glm::scale(glm::vec3(m_canvas->m_order.size() + 500)) *
m_canvas->m_plane_transform[plane_index] *
glm::translate(glm::vec3(0, 0, -1));
ShaderManager::use(kShader::TextureAlpha);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_float(kShaderUniform::Alpha, 0.5f);
ShaderManager::u_int(kShaderUniform::Highlight, 0);
ShaderManager::use(kShader::Checkerboard);
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
glActiveTexture(GL_TEXTURE0);
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
m_face_plane.draw_fill();
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
}
// draw the layers
m_sampler.bind(0);
glActiveTexture(GL_TEXTURE0);
m_cache_rtt.bindTexture();
ShaderManager::use(kShader::Texture);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1, 1, -1, 1));
m_face_plane.draw_fill();
m_cache_rtt.unbindTexture();
}
*/
for (auto& mode : *m_canvas->m_mode)
mode->on_Draw(ortho_proj, proj, camera);
@@ -390,6 +407,9 @@ void NodeCanvas::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
m_canvas->m_mixer.create((int)new_size.x * m_canvas->m_mixer_scale,
(int)new_size.y * m_canvas->m_mixer_scale, -1, GL_RGBA32F);
#endif
m_blender_rtt.create((int)new_size.x, (int)new_size.y, -1, GL_RGBA8);
m_cache_rtt.create((int)new_size.x, (int)new_size.y, -1, GL_RGBA8);
m_blender_bg.create((int)new_size.x, (int)new_size.y, GL_RGBA8);
if (auto img = root()->find<NodeImageTexture>("tex-debug"))
img->tex.assign(m_canvas->m_mixer.getTextureID());
// m_canvas->resize((int)new_size.x, (int)new_size.y);

View File

@@ -6,6 +6,9 @@ class NodeCanvas : public Node
{
public:
std::unique_ptr<Canvas> m_canvas;
RTT m_blender_rtt;
RTT m_cache_rtt;
Texture2D m_blender_bg;
Sampler m_sampler;
Sampler m_sampler_linear;
Sampler m_sampler_stencil;

View File

@@ -132,6 +132,7 @@ void NodePanelLayer::init()
add_layer();
if (on_layer_add)
on_layer_add(this);
update_attributes();
};
btn_remove->on_click = [this](Node*) {
if (m_layers.size() == 1)

View File

@@ -42,6 +42,7 @@ enum class kShader : uint16_t
Texture = const_hash("texture"),
TextureAlpha= const_hash("texture-alpha"),
TextureAlphaSep= const_hash("texture-alpha-sep"),
TextureBlend= const_hash("texture-blend"),
CompErase = const_hash("comp-erase"),
CompDraw = const_hash("comp-draw"),
UVs = const_hash("uvs"),