Project

General

Profile

Download (10.5 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / DistortedEffectsPostprocess.java @ e02264ff

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.library;
21

    
22
import org.distorted.library.message.EffectListener;
23
import org.distorted.library.type.Data1D;
24

    
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

    
27
/**
28
 * Class containing the queue of postprocessing effects.
29
 * <p>
30
 * This better be separate from the main DistortedEffects class, because we want to be able to apply
31
 * the same postprocessing effects (i.e. not only the same effects, but the very same instance of this
32
 * object) to several Children of a Node. Reason for that: if several children have the same Object,
33
 * it is easy to group them into 'Buckets' where each bucket has the same postprocessing effects and
34
 * is therefore rendered to the same buffer, which is then postprocessed in one go.
35
 * <p>
36
 * The queue holds actual effects to be applied to a given bucket of several (DistortedTexture,MeshObject) combos.
37
 */
38
public class DistortedEffectsPostprocess
39
  {
40
  private static long mNextID =0;
41
  private long mID;
42

    
43
  private EffectQueuePostprocess mP;
44

    
45
  private boolean postprocessCloned;
46

    
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

    
49
  private void initializeEffectLists(DistortedEffectsPostprocess d, int flags)
50
    {
51
    if( (flags & Distorted.CLONE_POSTPROCESS) != 0 )
52
      {
53
      mP = d.mP;
54
      postprocessCloned = true;
55
      }
56
    else
57
      {
58
      mP = new EffectQueuePostprocess(mID);
59
      postprocessCloned = false;
60
      }
61
    }
62

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

    
65
  EffectQueuePostprocess getPostprocess()
66
    {
67
    return mP;
68
    }
69

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

    
72
  private void releasePriv()
73
    {
74
    if( !postprocessCloned) mP.abortAll(false);
75

    
76
    mP = null;
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80
// PUBLIC API
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82
/**
83
 * Create empty effect queue.
84
 */
85
  public DistortedEffectsPostprocess()
86
    {
87
    mID = ++mNextID;
88
    initializeEffectLists(this,0);
89
    }
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92
/**
93
 * Copy constructor.
94
 * <p>
95
 * Whatever we do not clone gets created just like in the default constructor.
96
 *
97
 * @param dc    Source object to create our object from
98
 * @param flags A bitmask of values specifying what to copy.
99
 *              Currently the only values possible are CLONE_NOTHING or CLONE_POSTPROCESS.
100
 */
101
  public DistortedEffectsPostprocess(DistortedEffectsPostprocess dc, int flags)
102
    {
103
    mID = ++mNextID;
104
    initializeEffectLists(dc,flags);
105
    }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108
/**
109
 * Releases all resources. After this call, the queue should not be used anymore.
110
 */
111
  @SuppressWarnings("unused")
112
  public synchronized void delete()
113
    {
114
    releasePriv();
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118
/**
119
 * Returns unique ID of this instance.
120
 *
121
 * @return ID of the object.
122
 */
123
  @SuppressWarnings("unused")
124
  public long getID()
125
      {
126
      return mID;
127
      }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130
/**
131
 * Adds the calling class to the list of Listeners that get notified each time some event happens 
132
 * to one of the Effects in the queues. Nothing will happen if 'el' is already in the list.
133
 * 
134
 * @param el A class implementing the EffectListener interface that wants to get notifications.
135
 */
136
  @SuppressWarnings("unused")
137
  public void registerForMessages(EffectListener el)
138
    {
139
    mP.registerForMessages(el);
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143
/**
144
 * Removes the calling class from the list of Listeners.
145
 * 
146
 * @param el A class implementing the EffectListener interface that no longer wants to get notifications.
147
 */
148
  @SuppressWarnings("unused")
149
  public void deregisterForMessages(EffectListener el)
150
    {
151
    mP.deregisterForMessages(el);
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
/**
156
 * Aborts all Effects.
157
 * @return Number of effects aborted.
158
 */
159
  @SuppressWarnings("unused")
160
  public int abortAllEffects()
161
      {
162
      return mP.abortAll(true);
163
      }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
/**
167
 * Aborts all Effects of a given type (currently only POSTPROCESSING Effects).
168
 * 
169
 * @param type one of the constants defined in {@link EffectTypes}
170
 * @return Number of effects aborted.
171
 */
172
  @SuppressWarnings("unused")
173
  public int abortEffects(EffectTypes type)
174
    {
175
    switch(type)
176
      {
177
      case POSTPROCESS: return mP.abortAll(true);
178
      default         : return 0;
179
      }
180
    }
181
    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183
/**
184
 * Aborts a single Effect.
185
 * 
186
 * @param id ID of the Effect we want to abort.
187
 * @return number of Effects aborted. Always either 0 or 1.
188
 */
189
  @SuppressWarnings("unused")
190
  public int abortEffect(long id)
191
    {
192
    int type = (int)(id&EffectTypes.MASK);
193

    
194
    if( type==EffectTypes.POSTPROCESS.type ) return mP.removeByID(id>>EffectTypes.LENGTH);
195

    
196
    return 0;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
/**
201
 * Abort all Effects of a given name, for example all blurs.
202
 * 
203
 * @param name one of the constants defined in {@link EffectNames}
204
 * @return number of Effects aborted.
205
 */
206
  @SuppressWarnings("unused")
207
  public int abortEffects(EffectNames name)
208
    {
209
    switch(name.getType())
210
      {
211
      case POSTPROCESS: return mP.removeByType(name);
212
      default         : return 0;
213
      }
214
    }
215
    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217
/**
218
 * Print some info about a given Effect to Android's standard out. Used for debugging only.
219
 * 
220
 * @param id Effect ID we want to print info about
221
 * @return <code>true</code> if a single Effect of type effectType has been found.
222
 */
223
  @SuppressWarnings("unused")
224
  public boolean printEffect(long id)
225
    {
226
    int type = (int)(id&EffectTypes.MASK);
227

    
228
    if( type==EffectTypes.POSTPROCESS.type )  return mP.printByID(id>>EffectTypes.LENGTH);
229

    
230
    return false;
231
    }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234
/**
235
 * Returns the maximum number of Postprocess effects.
236
 *
237
 * @return The maximum number of Postprocess effects
238
 */
239
  @SuppressWarnings("unused")
240
  public static int getMaxPostprocess()
241
    {
242
    return EffectQueue.getMax(EffectTypes.POSTPROCESS.ordinal());
243
    }
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246
/**
247
 * Sets the maximum number of Postprocess effects that can be stored in a single EffectQueue at one time.
248
 * This can fail if:
249
 * <ul>
250
 * <li>the value of 'max' is outside permitted range (0 &le; max &le; Byte.MAX_VALUE)
251
 * <li>We try to increase the value of 'max' when it is too late to do so already. It needs to be called
252
 *     before the Fragment Shader gets compiled, i.e. before the call to {@link Distorted#onCreate}. After this
253
 *     time only decreasing the value of 'max' is permitted.
254
 * <li>Furthermore, this needs to be called before any instances of the DistortedEffects class get created.
255
 * </ul>
256
 *
257
 * @param max new maximum number of simultaneous Postprocess Effects. Has to be a non-negative number not greater
258
 *            than Byte.MAX_VALUE
259
 * @return <code>true</code> if operation was successful, <code>false</code> otherwise.
260
 */
261
  @SuppressWarnings("unused")
262
  public static boolean setMaxPostprocess(int max)
263
    {
264
    return EffectQueue.setMax(EffectTypes.POSTPROCESS.ordinal(),max);
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////   
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269
// Individual effect functions.
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271
// Postprocess-based effects
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273
/**
274
 * Blur the object.
275
 *
276
 * @param radius The 'strength' if the effect, in pixels. 0 = no blur, 10 = when blurring a given pixel,
277
 *               take into account 10 pixels in each direction.
278
 * @return ID of the effect added, or -1 if we failed to add one.
279
 */
280
  public long blur(Data1D radius)
281
    {
282
    return mP.add(EffectNames.BLUR, radius);
283
    }
284
  }
(5-5/24)