Beatmup
scene.h
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #include "rendering_context.h"
21 #include "../exception.h"
22 #include "../bitmap/abstract_bitmap.h"
23 #include "../geometry.h"
24 #include "../utils/lockable_object.h"
25 #include "../shading/image_shader.h"
26 
27 #include <string>
28 #include <vector>
29 
30 
31 namespace Beatmup {
32  class SceneRenderer;
33 
34  /**
35  An ordered set of layers representing a renderable content.
36  */
37  class Scene : public LockableObject {
38  public:
39  class Layer;
40  private:
41  std::vector<Layer*> layers; //!< scene layers
42 
43  template<class Type> Type& newLayer(const char* name) {
44  Type* l = new Type();
45  l->setName(name);
46  layers.push_back(l);
47  return *l;
48  }
49 
50 
51  public:
53  private:
54  std::string getSceneLog(const Scene& scene, const std::string prefix, int recursionLeft = 100) const;
55  public:
56  SceneIntegrityError(const std::string reason, const Scene& scene);
57  };
58 
59 
60  /**
61  Abstract scene layer having name, type, geometry and some content to display.
62  The layer geometry is defined by an AffineMapping describing the position and the orientation of the layer content in the rendered image.
63  */
64  class Layer : public Object {
65  friend class SceneRenderer;
66  Layer(const Layer&) = delete; //!< disabling copying constructor
67  public:
68  enum class Type {
69  SceneLayer = 0, //!< layer containing a scene
70  BitmapLayer, //!< layer displaying a bitmap
71  MaskedBitmapLayer, //!< layer displaying a bitmap with mask
72  ShapedBitmapLayer, //!< layer displaying a bitmap within a shape
73  ShadedBitmapLayer //!< layer displaying a bitmap through a custom fragment shader
74  };
75 
76  protected:
77  Layer(Type type);
78  virtual void render(RenderingContext& context) {}
79 
80  AffineMapping mapping; //!< layer mapping
81  bool visible; //!< layer visibility
82  bool phantom; //!< if `true`, layer is ignored by selection by point
83 
84  private:
86  std::string name; //!< layer name
87 
88  public:
89  /**
90  \return type of the current layer.
91  */
92  inline Type getType() const { return type; }
93 
94  inline const std::string& getName() const { return name; }
95  inline void setName(const char* name) { this->name = name; }
96 
97  inline AffineMapping& getMapping() { return mapping; }
98  inline const AffineMapping& getMapping() const { return mapping; }
99  inline void setMapping(const AffineMapping& mapping) { this->mapping = mapping; }
100 
101  /**
102  Tests if a given point falls in the layer
103  */
104  virtual bool testPoint(float x, float y) const;
105 
106  /**
107  Picks a child layer at given point, if any
108  */
109  virtual Layer* getChild(float x, float y, unsigned int recursionDepth = 0) const;
110 
111  /**
112  Returns layer visibility flag
113  */
114  inline bool isVisible() const { return visible; }
115 
116  /**
117  Returns `true` if the layer is ignored when searching a layer by point.
118  */
119  inline bool isPhantom() const { return phantom; }
120 
121  /**
122  Sets layer visibility
123  */
124  inline void setVisible(bool visible) { this->visible = visible; }
125 
126  /**
127  Makes/unmakes the layer "phantom".
128  Phantom layers are rendered as usual but not picked when searching a layer by point.
129  */
130  inline void setPhantom(bool phantom) { this->phantom = phantom; }
131 
132  template<class LayerType> LayerType& castTo() const {
133  return (LayerType&)(*this);
134  }
135  };
136 
137 
138  /**
139  Layer containing an entire scene
140  */
141  class SceneLayer : public Layer {
142  friend class Scene;
143  private:
146  public:
147  const Beatmup::Scene& getScene() const { return scene; }
148  bool testPoint(float x, float y) const;
149  Layer* getChild(float x, float y, unsigned int recursionDepth = 0) const;
150  };
151 
152 
153  /**
154  Layer having an image to render.
155  The image has a position and orientation with respect to the layer. This is expressed with an affine mapping applied on top of the layer
156  mapping.
157  */
158  class BitmapLayer : public Layer {
159  friend class Scene;
160  friend class SceneRenderer;
161 
162  protected:
163  BitmapLayer();
166 
167  /**
168  Configures current rendering program to render this layer
169  */
171  void render(RenderingContext& context);
172 
173  float invAr; //!< inverse aspect ratio of what is rendered (set by SceneRenderer)
174  AbstractBitmap* bitmap; //!< content to display, used if the image source is set to BITMAP
175  AffineMapping bitmapMapping; //!< bitmap mapping w.r.t. the layer mapping
176  color4i modulation; //!< modulation color
177 
178  public:
179  bool testPoint(float x, float y) const;
180 
181  inline const AbstractBitmap* getBitmap() const { return bitmap; }
182  inline void setBitmap(AbstractBitmap* bitmap) { this->bitmap = bitmap; }
183 
185  inline const AffineMapping& getBitmapMapping() const { return bitmapMapping; }
186  inline void setBitmapMapping(const AffineMapping& mapping) { this->bitmapMapping = mapping; }
187 
188  inline color4i getModulationColor() const { return modulation; }
189  inline void setModulationColor(color4i color) { this->modulation = color; }
190  };
191 
192 
193  /**
194  Layer containing a bitmap and a mask applied to the bitmap when rendering.
195  Both bitmap and mask have their own positions and orientations relative to the layer's position and orientation.
196  */
198  protected:
201 
202  AffineMapping maskMapping; //!< mask mapping w.r.t. the layer mapping
203  color4i bgColor; //!< color to fill mask areas where the bitmap is not present
204  public:
206  inline const AffineMapping& getMaskMapping() const { return maskMapping; }
207  inline void setMaskMapping(const AffineMapping& mapping) { this->maskMapping = mapping; }
208 
209  inline color4i getBackgroundColor() const { return bgColor; }
210  inline void setBackgroundColor(color4i color) { this->bgColor = color; }
211  };
212 
213 
214  /**
215  Bitmap layer using another bitmap as a mask
216  */
218  friend class Scene;
219  friend class SceneRenderer;
220  private:
221  AbstractBitmap* mask; //!< mask bitmap
222  protected:
224  void render(RenderingContext& context);
225  public:
226  inline const AbstractBitmap* getMask() const { return mask; }
227  inline void setMask(AbstractBitmap* mask) { this->mask = mask; }
228  bool testPoint(float x, float y) const;
229  };
230 
231 
232  /**
233  Layer containing a bitmap and a parametric mask (shape)
234  */
236  friend class Scene;
237  friend class SceneRenderer;
238  private:
239  float borderWidth; //!< constant border thickness
240  float slopeWidth; //!< thickness of the smoothed line between border and image
241  float cornerRadius; //!< border corner radius
242  bool inPixels; //!< if `true`, the widths and radius are set in pixels
243 
244  protected:
246  void render(RenderingContext& context);
247 
248  public:
249  inline float getBorderWidth() const { return borderWidth; }
250  inline void setBorderWidth(float borderWidth) { this->borderWidth = borderWidth; }
251 
252  inline float getSlopeWidth() const { return slopeWidth; }
253  inline void setSlopeWidth(float slopeWidth) { this->slopeWidth = slopeWidth; }
254 
255  inline float getCornerRadius() const { return cornerRadius; }
256  inline void setCornerRadius(float cornerRadius) { this->cornerRadius = cornerRadius; }
257 
258  inline bool getInPixels() const { return inPixels; }
259  inline void setInPixels(bool inPixels) { this->inPixels = inPixels; }
260 
261  bool testPoint(float x, float y) const;
262  };
263 
264 
265  /**
266  Bitmap layer using a custom shader
267  */
269  friend class Scene;
270  friend class SceneRenderer;
271  private:
273  protected:
275  void render(RenderingContext& context);
276  public:
277  inline ImageShader* getShader() const { return shader; }
278  inline void setShader(ImageShader* shader) { this->shader = shader; }
279  };
280 
281  // Scene members
282  public:
283 
284  Scene();
285  ~Scene();
286 
287  BitmapLayer& newBitmapLayer(const char* name);
288  BitmapLayer& newBitmapLayer();
289  MaskedBitmapLayer& newMaskedBitmapLayer(const char* name);
290  MaskedBitmapLayer& newMaskedBitmapLayer();
291  ShapedBitmapLayer& newShapedBitmapLayer(const char* name);
292  ShapedBitmapLayer& newShapedBitmapLayer();
293  ShadedBitmapLayer& newShadedBitmapLayer(const char* name);
294  ShadedBitmapLayer& newShadedBitmapLayer();
295 
296  /**
297  Adds a subscene to the current scene.
298  */
299  SceneLayer& addScene(const Scene& scene);
300 
301  /**
302  Retrieves a layer by its name or null if not found
303  */
304  Layer* getLayer(const char* name) const;
305 
306  /**
307  Retrieves a layer by its index
308  */
309  Layer& getLayer(int index) const;
310 
311  /**
312  Retrieves a layer present at a specific point of the scene or null if not found
313  */
314  Layer* getLayer(float x, float y, unsigned int recursionDepth = 0) const;
315 
316  /**
317  Returns layer index in the scene or -1 if not found
318  */
319  int getLayerIndex(const Layer& layer) const;
320 
321  /**
322  Returns total number of layers in the scene
323  */
324  int getLayerCount() const;
325 
326  /**
327  Computes absolute mapping of a given layer with respect to the scene mapping
328  \return `true` if the given layer is reached, `false` otherwise (mapping is not changed in this case)
329  */
330  bool resolveMapping(const Layer& layer, AffineMapping& mapping) const;
331 
332  /**
333  Attaches an existing layer to the scene
334  */
335  void attachLayer(Layer& layer);
336 
337  /**
338  Detaches a layer from the scene
339  */
340  Layer* detachLayer(int index);
341  };
342 
343 }
A very basic class for any image.
2x3 affine mapping containing a 2x2 matrix and a 2D point
Definition: geometry.h:639
Base class for all exceptions.
Definition: exception.h:37
A GLSL program to process images.
Definition: image_shader.h:34
Beatmup object base class
Definition: basic_types.h:67
Stores the rendering context: current program, current mapping in the scene space,...
AbstractTask rendering a Scene.
Definition: renderer.h:29
Layer having an image to render.
Definition: scene.h:158
color4i getModulationColor() const
Definition: scene.h:188
void setBitmapMapping(const AffineMapping &mapping)
Definition: scene.h:186
void setBitmap(AbstractBitmap *bitmap)
Definition: scene.h:182
void setModulationColor(color4i color)
Definition: scene.h:189
GL::TextureHandler * resolveContent(RenderingContext &context)
Definition: scene.cpp:273
const AbstractBitmap * getBitmap() const
Definition: scene.h:181
void render(RenderingContext &context)
Definition: scene.cpp:291
float invAr
inverse aspect ratio of what is rendered (set by SceneRenderer)
Definition: scene.h:173
AffineMapping & getBitmapMapping()
Definition: scene.h:184
void configure(RenderingContext &context, GL::TextureHandler *content)
Configures current rendering program to render this layer.
Definition: scene.cpp:279
AffineMapping bitmapMapping
bitmap mapping w.r.t. the layer mapping
Definition: scene.h:175
AbstractBitmap * bitmap
content to display, used if the image source is set to BITMAP
Definition: scene.h:174
bool testPoint(float x, float y) const
Tests if a given point falls in the layer.
Definition: scene.cpp:314
color4i modulation
modulation color
Definition: scene.h:176
const AffineMapping & getBitmapMapping() const
Definition: scene.h:185
Layer containing a bitmap and a mask applied to the bitmap when rendering.
Definition: scene.h:197
void setBackgroundColor(color4i color)
Definition: scene.h:210
AffineMapping & getMaskMapping()
Definition: scene.h:205
void setMaskMapping(const AffineMapping &mapping)
Definition: scene.h:207
color4i bgColor
color to fill mask areas where the bitmap is not present
Definition: scene.h:203
void configure(RenderingContext &context, GL::TextureHandler *content)
Definition: scene.cpp:326
AffineMapping maskMapping
mask mapping w.r.t. the layer mapping
Definition: scene.h:202
const AffineMapping & getMaskMapping() const
Definition: scene.h:206
Abstract scene layer having name, type, geometry and some content to display.
Definition: scene.h:64
virtual bool testPoint(float x, float y) const
Tests if a given point falls in the layer.
Definition: scene.cpp:240
@ MaskedBitmapLayer
layer displaying a bitmap with mask
@ BitmapLayer
layer displaying a bitmap
@ ShapedBitmapLayer
layer displaying a bitmap within a shape
void setVisible(bool visible)
Sets layer visibility.
Definition: scene.h:124
void setName(const char *name)
Definition: scene.h:95
void setMapping(const AffineMapping &mapping)
Definition: scene.h:99
bool isVisible() const
Returns layer visibility flag.
Definition: scene.h:114
virtual Layer * getChild(float x, float y, unsigned int recursionDepth=0) const
Picks a child layer at given point, if any.
Definition: scene.cpp:244
virtual void render(RenderingContext &context)
Definition: scene.h:78
bool visible
layer visibility
Definition: scene.h:81
bool phantom
if true, layer is ignored by selection by point
Definition: scene.h:82
Type getType() const
Definition: scene.h:92
const std::string & getName() const
Definition: scene.h:94
const AffineMapping & getMapping() const
Definition: scene.h:98
bool isPhantom() const
Returns true if the layer is ignored when searching a layer by point.
Definition: scene.h:119
std::string name
layer name
Definition: scene.h:86
AffineMapping mapping
layer mapping
Definition: scene.h:80
AffineMapping & getMapping()
Definition: scene.h:97
void setPhantom(bool phantom)
Makes/unmakes the layer "phantom".
Definition: scene.h:130
LayerType & castTo() const
Definition: scene.h:132
Layer(const Layer &)=delete
disabling copying constructor
Bitmap layer using another bitmap as a mask.
Definition: scene.h:217
bool testPoint(float x, float y) const
Tests if a given point falls in the layer.
Definition: scene.cpp:372
void setMask(AbstractBitmap *mask)
Definition: scene.h:227
AbstractBitmap * mask
mask bitmap
Definition: scene.h:221
void render(RenderingContext &context)
Definition: scene.cpp:343
const AbstractBitmap * getMask() const
Definition: scene.h:226
std::string getSceneLog(const Scene &scene, const std::string prefix, int recursionLeft=100) const
Definition: scene.cpp:30
SceneIntegrityError(const std::string reason, const Scene &scene)
Definition: scene.cpp:91
Layer containing an entire scene.
Definition: scene.h:141
const Beatmup::Scene & scene
Definition: scene.h:144
SceneLayer(const Beatmup::Scene &scene)
Definition: scene.cpp:249
Layer * getChild(float x, float y, unsigned int recursionDepth=0) const
Picks a child layer at given point, if any.
Definition: scene.cpp:255
bool testPoint(float x, float y) const
Tests if a given point falls in the layer.
Definition: scene.cpp:251
const Beatmup::Scene & getScene() const
Definition: scene.h:147
Bitmap layer using a custom shader.
Definition: scene.h:268
ImageShader * getShader() const
Definition: scene.h:277
void setShader(ImageShader *shader)
Definition: scene.h:278
void render(RenderingContext &context)
Definition: scene.cpp:448
Layer containing a bitmap and a parametric mask (shape)
Definition: scene.h:235
void setInPixels(bool inPixels)
Definition: scene.h:259
float getCornerRadius() const
Definition: scene.h:255
float slopeWidth
thickness of the smoothed line between border and image
Definition: scene.h:240
bool inPixels
if true, the widths and radius are set in pixels
Definition: scene.h:242
void setBorderWidth(float borderWidth)
Definition: scene.h:250
float getBorderWidth() const
Definition: scene.h:249
void setCornerRadius(float cornerRadius)
Definition: scene.h:256
void render(RenderingContext &context)
Definition: scene.cpp:399
float cornerRadius
border corner radius
Definition: scene.h:241
float borderWidth
constant border thickness
Definition: scene.h:239
void setSlopeWidth(float slopeWidth)
Definition: scene.h:253
bool testPoint(float x, float y) const
Tests if a given point falls in the layer.
Definition: scene.cpp:434
An ordered set of layers representing a renderable content.
Definition: scene.h:37
Type & newLayer(const char *name)
Definition: scene.h:43
ShadedBitmapLayer & newShadedBitmapLayer()
Definition: scene.cpp:150
bool resolveMapping(const Layer &layer, AffineMapping &mapping) const
Computes absolute mapping of a given layer with respect to the scene mapping.
Definition: scene.cpp:204
void attachLayer(Layer &layer)
Attaches an existing layer to the scene.
Definition: scene.cpp:224
MaskedBitmapLayer & newMaskedBitmapLayer()
Definition: scene.cpp:130
Layer * getLayer(const char *name) const
Retrieves a layer by its name or null if not found.
Definition: scene.cpp:163
BitmapLayer & newBitmapLayer()
Definition: scene.cpp:120
Layer * detachLayer(int index)
Detaches a layer from the scene.
Definition: scene.cpp:231
int getLayerCount() const
Returns total number of layers in the scene.
Definition: scene.cpp:199
std::vector< Layer * > layers
scene layers
Definition: scene.h:39
ShapedBitmapLayer & newShapedBitmapLayer()
Definition: scene.cpp:140
int getLayerIndex(const Layer &layer) const
Returns layer index in the scene or -1 if not found.
Definition: scene.cpp:191
SceneLayer & addScene(const Scene &scene)
Adds a subscene to the current scene.
Definition: scene.cpp:155
return(jlong) new Beatmup jlong jstring name
jlong jint index
jobject jlong jint jint y
std::string content
jobject jlong jint x
Beatmup::Scene::Layer * layer
return $pool getJavaReference & scene(index)
Beatmup::AffineMapping & mapping