#pragma once #include "rtt.h" #include "texture.h" #include "shader.h" #include "shape.h" #include "brush.h" #include "action.h" NS_START class Canvas { Plane m_plane; BrushMesh m_mesh; bool m_dirty = false; public: bool m_erase = false; glm::mat4 m_mvp; glm::vec4 m_box; int m_width; int m_height; bool m_use_instanced = false; int m_current_layer_idx = 0; std::unique_ptr m_current_stroke; bool m_show_tmp = false; std::vector m_layers; std::vector m_order; RTT m_tmp; Texture2D m_tex; Texture2D m_tex2; Sampler m_sampler; Sampler m_sampler_bg; bool create(int width, int height); void resize(int width, int height); void layer_add(std::string name); void layer_order(int idx, int pos); void stroke_start(glm::vec2 point, float pressure, const ui::Brush& brush); void stroke_update(glm::vec2 point, float pressure); void stroke_draw(); void stroke_end(); void stroke_commit(); void clear(const glm::vec4& color = { 1, 1, 1, 1 }); }; class ActionStroke : public Action { public: std::unique_ptr m_stroke; std::unique_ptr m_image; glm::ivec4 m_box; int m_layer_idx; Canvas* m_canvas; virtual void run() override { } virtual void undo() override { m_canvas->m_layers[m_stroke->m_layer].m_rtt.bindTexture(); glm::vec2 box_sz = m_box.zw() - m_box.xy(); glTexSubImage2D(GL_TEXTURE_2D, 0, m_box.x, m_box.y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, m_image.get()); m_canvas->m_layers[m_stroke->m_layer].m_rtt.unbindTexture(); } }; NS_END