Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedEffectsPostprocess.java @ 0afc143a

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
  static void onDestroy()
89
    {
90
    mNextID = 0;
91
    }
92

    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
// PUBLIC API
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96
/**
97
 * Create empty effect queue.
98
 */
99
  public DistortedEffectsPostprocess()
100
    {
101
    mID = ++mNextID;
102
    initializeEffectLists(this,0);
103
    }
104

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

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122
/**
123
 * Releases all resources. After this call, the queue should not be used anymore.
124
 */
125
  @SuppressWarnings("unused")
126
  public synchronized void delete()
127
    {
128
    releasePriv();
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132
/**
133
 * Returns unique ID of this instance.
134
 *
135
 * @return ID of the object.
136
 */
137
  @SuppressWarnings("unused")
138
  public long getID()
139
      {
140
      return mID;
141
      }
142

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

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157
/**
158
 * Removes the calling class from the list of Listeners.
159
 * 
160
 * @param el A class implementing the EffectListener interface that no longer wants to get notifications.
161
 */
162
  @SuppressWarnings("unused")
163
  public void deregisterForMessages(EffectListener el)
164
    {
165
    mP.deregisterForMessages(el);
166
    }
167

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169
/**
170
 * Aborts all Effects.
171
 * @return Number of effects aborted.
172
 */
173
  @SuppressWarnings("unused")
174
  public int abortAllEffects()
175
      {
176
      return mP.abortAll(true);
177
      }
178

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

    
208
    if( type==EffectTypes.POSTPROCESS.type ) return mP.removeByID(id>>EffectTypes.LENGTH);
209

    
210
    return 0;
211
    }
212

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

    
242
    if( type==EffectTypes.POSTPROCESS.type )  return mP.printByID(id>>EffectTypes.LENGTH);
243

    
244
    return false;
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248
/**
249
 * Returns the maximum number of Postprocess effects.
250
 *
251
 * @return The maximum number of Postprocess effects
252
 */
253
  @SuppressWarnings("unused")
254
  public static int getMaxPostprocess()
255
    {
256
    return EffectQueue.getMax(EffectTypes.POSTPROCESS.ordinal());
257
    }
258

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

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////   
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283
// Individual effect functions.
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285
// Postprocess-based effects
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287
/**
288
 * Blur the object.
289
 *
290
 * @param radius The 'strength' if the effect, in pixels. 0 = no blur, 10 = when blurring a given pixel,
291
 *               take into account 10 pixels in each direction.
292
 * @return ID of the effect added, or -1 if we failed to add one.
293
 */
294
  public long blur(Data1D radius)
295
    {
296
    return mP.add(EffectNames.BLUR, radius);
297
    }
298
  }
(3-3/24)