1 #ifndef VIEW_TRANSFORM_HPP 2 #define VIEW_TRANSFORM_HPP 3 4 #include <wayfire/view.hpp> 5 #include <wayfire/opengl.hpp> 6 7 namespace wf 8 { 9 enum transformer_z_order_t 10 { 11 /* Simple 2D transforms */ 12 TRANSFORMER_2D = 1, 13 /* 3D transforms */ 14 TRANSFORMER_3D = 2, 15 /* Highlevels transforms and above do special effects, for ex. wobbly or fire */ 16 TRANSFORMER_HIGHLEVEL = 500, 17 /* Do not use Z oder blur or more, 18 * except if you are willing to break it */ 19 TRANSFORMER_BLUR = 999, 20 }; 21 22 class view_transformer_t 23 { 24 public: 25 /** 26 * Get the Z ordering of the transformer, e.g the order in which it should 27 * be applied relative to the other transformers on the same view. 28 * Higher numbers indicate that the transform should be applied later. 29 * 30 * @return The Z order of the transformer. 31 */ 32 virtual uint32_t get_z_order() = 0; 33 34 /** 35 * Transform the opaque region of the view. 36 * 37 * It must be guaranteed that the pixels part of the returned region are 38 * opaque. The default implementation simply returns an empty region. 39 * 40 * @param box The bounding box of the view up to this transformer. 41 * @param region The opaque region to transform. 42 * 43 * @return The transformed opaque region. 44 */ 45 virtual wf::region_t transform_opaque_region( 46 wf::geometry_t box, wf::region_t region); 47 48 /** 49 * Transform a single point. 50 * 51 * @param view The bounding box of the view, in output-local 52 * coordinates. 53 * @param point The point to transform, in output-local coordinates. 54 * 55 * @return The point after transforming it, in output-local coordinates. 56 */ 57 virtual wf::pointf_t transform_point( 58 wf::geometry_t view, wf::pointf_t point) = 0; 59 60 /** 61 * Reverse the transformation of the point. 62 * 63 * @param view The bounding box of the view, in output-local 64 * coordinates. 65 * @param point The point to untransform, in output-local coordinates. 66 * 67 * @return The point before after transforming it, in output-local 68 * coordinates. If a reversal of the transformation is not possible, 69 * return NaN. 70 */ 71 virtual wf::pointf_t untransform_point( 72 wf::geometry_t view, wf::pointf_t point) = 0; 73 74 /** 75 * Compute the bounding box of the given region after transforming it. 76 * 77 * @param view The bounding box of the view, in output-local 78 * coordinates. 79 * @param region The region whose bounding box should be computed, in 80 * output-local coordinates. 81 * 82 * @return The bounding box of region after transforming it, in 83 * output-local coordinates. 84 */ 85 virtual wlr_box get_bounding_box(wf::geometry_t view, wlr_box region); 86 87 /** 88 * Render the indicated parts of the view. 89 * 90 * @param src_tex The texture of the view. 91 * @param src_box The bounding box of the view in output-local coordinates. 92 * @param damage The region to repaint, clipped to the view's bounds. 93 * It is in output-local coordinates. 94 * @param target_fb The framebuffer to draw the view to. It's geometry 95 * is in output-local coordinates. 96 * 97 * The default implementation of render_with_damage() will simply 98 * iterate over all rectangles in the damage region, apply framebuffer 99 * transform to it and then call render_box(). Plugins can override 100 * either of the functions. 101 */ 102 virtual void render_with_damage(wf::texture_t src_tex, wlr_box src_box, 103 const wf::region_t& damage, const wf::framebuffer_t& target_fb); 104 105 /** Same as render_with_damage(), but for a single rectangle of damage */ render_box(wf::texture_t src_tex,wlr_box src_box,wlr_box scissor_box,const wf::framebuffer_t & target_fb)106 virtual void render_box(wf::texture_t src_tex, wlr_box src_box, 107 wlr_box scissor_box, const wf::framebuffer_t& target_fb) 108 {} 109 ~view_transformer_t()110 virtual ~view_transformer_t() 111 {} 112 }; 113 114 /* 2D transforms operate with a coordinate system centered at the 115 * center of the main surface(the wayfire_view_t) */ 116 class view_2D : public view_transformer_t 117 { 118 protected: 119 wayfire_view view; 120 const uint32_t z_order; 121 122 public: 123 float angle = 0.0f; 124 float scale_x = 1.0f, scale_y = 1.0f; 125 float translation_x = 0.0f, translation_y = 0.0f; 126 float alpha = 1.0f; 127 128 public: 129 view_2D(wayfire_view view, uint32_t z_order_ = TRANSFORMER_2D); 130 get_z_order()131 virtual uint32_t get_z_order() override 132 { 133 return z_order; 134 } 135 136 wf::pointf_t transform_point( 137 wf::geometry_t view, wf::pointf_t point) override; 138 wf::pointf_t untransform_point( 139 wf::geometry_t view, wf::pointf_t point) override; 140 void render_box(wf::texture_t src_tex, wlr_box src_box, 141 wlr_box scissor_box, const wf::framebuffer_t& target_fb) override; 142 }; 143 144 /* Those are centered relative to the view's bounding box */ 145 class view_3D : public view_transformer_t 146 { 147 protected: 148 wayfire_view view; 149 const uint32_t z_order; 150 151 public: 152 glm::mat4 view_proj{1.0}, translation{1.0}, rotation{1.0}, scaling{1.0}; 153 glm::vec4 color{1, 1, 1, 1}; 154 155 glm::mat4 calculate_total_transform(); 156 157 public: 158 view_3D(wayfire_view view, uint32_t z_order_ = TRANSFORMER_3D); 159 get_z_order()160 virtual uint32_t get_z_order() override 161 { 162 return z_order; 163 } 164 165 wf::pointf_t transform_point( 166 wf::geometry_t view, wf::pointf_t point) override; 167 wf::pointf_t untransform_point( 168 wf::geometry_t view, wf::pointf_t point) override; 169 void render_box(wf::texture_t src_tex, wlr_box src_box, 170 wlr_box scissor_box, const wf::framebuffer_t& target_fb) override; 171 172 static const float fov; // PI / 8 173 static glm::mat4 default_view_matrix(); 174 static glm::mat4 default_proj_matrix(); 175 }; 176 177 /* create a matrix which corresponds to the inverse of the given transform */ 178 glm::mat4 get_output_matrix_from_transform(wl_output_transform transform); 179 180 /* a matrix which can be used to render wf::geometry_t directly */ 181 glm::mat4 output_get_projection(wf::output_t *output); 182 } 183 184 #endif /* end of include guard: VIEW_TRANSFORM_HPP */ 185