Set default document res to 6K. Implement blending on canvas, mixer and export equirect.
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++)
|
||||
//{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
// draw the blended
|
||||
{
|
||||
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();
|
||||
|
||||
/*
|
||||
if (m_canvas->m_smask_active && !m_canvas->m_show_tmp)
|
||||
// draw the grid behind the layers using a temporary copy
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user