Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedEffectsPostprocess.java @ 8426bd6a

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
  int postprocess(long time, DistortedOutputSurface surface)
66
    {
67
    return mP.postprocess(time,surface);
68
    }
69

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

    
72
  long getBucket()
73
    {
74
    return mP.mNumEffects==0 ? 0: mID;
75
    }
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  private void releasePriv()
80
    {
81
    if( !postprocessCloned) mP.abortAll(false);
82

    
83
    mP = null;
84
    }
85

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

    
88
  int getQuality()
89
    {
90
    return mP.mQuality;
91
    }
92

    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94

    
95
  static void onDestroy()
96
    {
97
    mNextID = 0;
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101
// PUBLIC API
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103
/**
104
 * Create empty effect queue.
105
 */
106
  public DistortedEffectsPostprocess()
107
    {
108
    mID = ++mNextID;
109
    initializeEffectLists(this,0);
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113
/**
114
 * Copy constructor.
115
 * <p>
116
 * Whatever we do not clone gets created just like in the default constructor.
117
 *
118
 * @param dc    Source object to create our object from
119
 * @param flags A bitmask of values specifying what to copy.
120
 *              Currently the only values possible are CLONE_NOTHING or CLONE_POSTPROCESS.
121
 */
122
  public DistortedEffectsPostprocess(DistortedEffectsPostprocess dc, int flags)
123
    {
124
    mID = ++mNextID;
125
    initializeEffectLists(dc,flags);
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129
/**
130
 * Releases all resources. After this call, the queue should not be used anymore.
131
 */
132
  @SuppressWarnings("unused")
133
  public synchronized void delete()
134
    {
135
    releasePriv();
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
/**
140
 * Returns unique ID of this instance.
141
 *
142
 * @return ID of the object.
143
 */
144
  @SuppressWarnings("unused")
145
  public long getID()
146
      {
147
      return mID;
148
      }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
/**
152
 * Adds the calling class to the list of Listeners that get notified each time some event happens 
153
 * to one of the Effects in the queues. Nothing will happen if 'el' is already in the list.
154
 * 
155
 * @param el A class implementing the EffectListener interface that wants to get notifications.
156
 */
157
  @SuppressWarnings("unused")
158
  public void registerForMessages(EffectListener el)
159
    {
160
    mP.registerForMessages(el);
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164
/**
165
 * Removes the calling class from the list of Listeners.
166
 * 
167
 * @param el A class implementing the EffectListener interface that no longer wants to get notifications.
168
 */
169
  @SuppressWarnings("unused")
170
  public void deregisterForMessages(EffectListener el)
171
    {
172
    mP.deregisterForMessages(el);
173
    }
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176
/**
177
 * Aborts all Effects.
178
 * @return Number of effects aborted.
179
 */
180
  @SuppressWarnings("unused")
181
  public int abortAllEffects()
182
      {
183
      return mP.abortAll(true);
184
      }
185

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187
/**
188
 * Aborts all Effects of a given type (currently only POSTPROCESSING Effects).
189
 * 
190
 * @param type one of the constants defined in {@link EffectTypes}
191
 * @return Number of effects aborted.
192
 */
193
  @SuppressWarnings("unused")
194
  public int abortEffects(EffectTypes type)
195
    {
196
    switch(type)
197
      {
198
      case POSTPROCESS: return mP.abortAll(true);
199
      default         : return 0;
200
      }
201
    }
202
    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
/**
205
 * Aborts a single Effect.
206
 * 
207
 * @param id ID of the Effect we want to abort.
208
 * @return number of Effects aborted. Always either 0 or 1.
209
 */
210
  @SuppressWarnings("unused")
211
  public int abortEffect(long id)
212
    {
213
    int type = (int)(id&EffectTypes.MASK);
214

    
215
    if( type==EffectTypes.POSTPROCESS.type ) return mP.removeByID(id>>EffectTypes.LENGTH);
216

    
217
    return 0;
218
    }
219

    
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
/**
222
 * Abort all Effects of a given name, for example all blurs.
223
 * 
224
 * @param name one of the constants defined in {@link EffectNames}
225
 * @return number of Effects aborted.
226
 */
227
  @SuppressWarnings("unused")
228
  public int abortEffects(EffectNames name)
229
    {
230
    switch(name.getType())
231
      {
232
      case POSTPROCESS: return mP.removeByType(name);
233
      default         : return 0;
234
      }
235
    }
236
    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
/**
239
 * Print some info about a given Effect to Android's standard out. Used for debugging only.
240
 * 
241
 * @param id Effect ID we want to print info about
242
 * @return <code>true</code> if a single Effect of type effectType has been found.
243
 */
244
  @SuppressWarnings("unused")
245
  public boolean printEffect(long id)
246
    {
247
    int type = (int)(id&EffectTypes.MASK);
248

    
249
    if( type==EffectTypes.POSTPROCESS.type )  return mP.printByID(id>>EffectTypes.LENGTH);
250

    
251
    return false;
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255
/**
256
 * Returns the maximum number of Postprocess effects.
257
 *
258
 * @return The maximum number of Postprocess effects
259
 */
260
  @SuppressWarnings("unused")
261
  public static int getMaxPostprocess()
262
    {
263
    return EffectQueue.getMax(EffectTypes.POSTPROCESS.ordinal());
264
    }
265

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
/**
268
 * Sets the maximum number of Postprocess effects that can be stored in a single EffectQueue at one time.
269
 * This can fail if:
270
 * <ul>
271
 * <li>the value of 'max' is outside permitted range (0 &le; max &le; Byte.MAX_VALUE)
272
 * <li>We try to increase the value of 'max' when it is too late to do so already. It needs to be called
273
 *     before the Fragment Shader gets compiled, i.e. before the call to {@link Distorted#onCreate}. After this
274
 *     time only decreasing the value of 'max' is permitted.
275
 * <li>Furthermore, this needs to be called before any instances of the DistortedEffects class get created.
276
 * </ul>
277
 *
278
 * @param max new maximum number of simultaneous Postprocess Effects. Has to be a non-negative number not greater
279
 *            than Byte.MAX_VALUE
280
 * @return <code>true</code> if operation was successful, <code>false</code> otherwise.
281
 */
282
  @SuppressWarnings("unused")
283
  public static boolean setMaxPostprocess(int max)
284
    {
285
    return EffectQueue.setMax(EffectTypes.POSTPROCESS.ordinal(),max);
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
/**
290
 * The higher the quality, the better the effect will look like and the slower it will be.
291
 * <p>
292
 * This works by rendering into smaller and smaller intermediate buffers. Each step renders into a
293
 * buffer that's half the size of the previous one.
294
 */
295
  public void setQuality(EffectQuality quality)
296
    {
297
    mP.mQuality = quality.level;
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////   
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302
// Individual effect functions.
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304
// Postprocess-based effects
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306
/**
307
 * Blur the object.
308
 *
309
 * @param radius The 'strength' if the effect, in pixels. 0 = no blur, 10 = when blurring a given pixel,
310
 *               take into account 10 pixels in each direction.
311
 * @return ID of the effect added, or -1 if we failed to add one.
312
 */
313
  public long blur(Data1D radius)
314
    {
315
    return mP.add(EffectNames.BLUR, radius);
316
    }
317
  }
(3-3/25)