#pragma once #include "rtt.h" #include "texture.h" #include "shader.h" #include "shape.h" #include "brush.h" #include "action.h" NS_START class Layer { public: RTT m_rtt[6]; bool m_visible = true; bool m_locked = false; float m_opacity = 1.f; std::string m_name; struct Snapshot { std::unique_ptr image[6]; void create(int w, int h) { for (int i = 0; i < 6; i++) image[i] = std::make_unique(w*h*4); } }; bool create(int width, int height, std::string name); void clear(const glm::vec4& c); Snapshot snapshot(std::string data_path); void restore(const Snapshot& snap); void destroy(); }; class Canvas { Plane m_plane; Plane m_plane_brush; BrushMesh m_mesh; bool m_dirty = false; public: bool m_erase = false; glm::mat4 m_mv; glm::mat4 m_proj; 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; glm::vec4 m_dirty_box[6]; bool m_dirty_face[6]; RTT m_tmp[6]; Texture2D m_tex[6]; Texture2D m_tex2[6]; static glm::vec3 m_plane_origin[6]; static glm::vec3 m_plane_normal[6]; static glm::vec3 m_plane_tangent[6]; static glm::mat4 m_plane_transform[6]; Sampler m_sampler; Sampler m_sampler_bg; glm::vec2 m_cam_rot; float m_cam_fov = 85; GLuint cube_id; RTT m_latlong; std::vector m_layers_snapshot; 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, 0 }); void snapshot_save(std::string data_path); void snapshot_restore(); void clear_context(); void save(std::string data_path); void save_project(std::string data_path); void open_project(std::string data_path); }; class ActionStroke : public Action { public: std::unique_ptr m_stroke; std::unique_ptr m_image[6]; glm::ivec4 m_box[6]; bool m_dirty[6]; int m_layer_idx; Canvas* m_canvas; virtual void run() override { } virtual void undo() override { for (int i = 0; i < 6; i++) { // empty data if (!m_image[i]) continue; m_canvas->m_layers[m_layer_idx].m_rtt[i].bindTexture(); glm::vec2 box_sz = m_box[i].zw() - m_box[i].xy(); glTexSubImage2D(GL_TEXTURE_2D, 0, m_box[i].x, m_box[i].y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, m_image[i].get()); m_canvas->m_layers[m_layer_idx].m_rtt[i].unbindTexture(); } } }; NS_END