Project

General

Profile

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

library / src / main / java / org / distorted / library / main / DistortedNode.java @ 11845a9e

1 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 fe82a979 Leszek Koltunski
package org.distorted.library.main;
21 6a06a912 Leszek Koltunski
22 8dccc3c2 Leszek Koltunski
import android.opengl.GLES31;
23
24 715e7726 Leszek Koltunski
import org.distorted.library.mesh.MeshBase;
25 6c00149d Leszek Koltunski
26 6a06a912 Leszek Koltunski
import java.util.ArrayList;
27 c9f953c2 Leszek Koltunski
import java.util.Collections;
28 6a06a912 Leszek Koltunski
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30
/**
31 a09ada4c Leszek Koltunski
 * Class which represents a Node in a Tree of (InputSurface,Mesh,Effects) triplets.
32 c204c69d leszek
 * <p>
33 a09ada4c Leszek Koltunski
 * Having organized such sets into a Tree, we can then render any Node to any OutputSurface.
34 7b8086eb Leszek Koltunski
 * That recursively renders the set held in the Node and all its children.
35 c204c69d leszek
 * <p>
36
 * The class takes special care to only render identical sub-trees once. Each Node holds a reference
37
 * to sub-class 'NodeData'. Two identical sub-trees attached at different points of the main tree
38 3a70bd6d leszek
 * will point to the same NodeData; only the first of this is rendered (mData.numRender!).
39 6a06a912 Leszek Koltunski
 */
40 11845a9e Leszek Koltunski
public class DistortedNode implements DistortedChildrenList.Parent
41 6a06a912 Leszek Koltunski
  {
42 715e7726 Leszek Koltunski
  private MeshBase mMesh;
43 07d8ef09 Leszek Koltunski
  private DistortedEffects mEffects;
44 12f9e4bb Leszek Koltunski
  private DistortedSurface mSurface;
45 c834348d leszek
  private DistortedRenderState mState;
46 8bfefd68 Leszek Koltunski
  private DistortedNodeData mData;
47 11845a9e Leszek Koltunski
  private DistortedChildrenList mChildren;
48
  private DistortedChildrenList.Parent mParent;
49
50 23eecbd9 Leszek Koltunski
  private int mFboW, mFboH, mFboDepthStencil;
51 11845a9e Leszek Koltunski
  private boolean mRenderWayOIT;
52 bd3da5b2 Leszek Koltunski
53 c43abe6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
54
55
  public void markForDeletion()
56
    {
57 8bfefd68 Leszek Koltunski
    if( mData.removeData() )
58 c43abe6c Leszek Koltunski
      {
59 8bfefd68 Leszek Koltunski
      mData.mFBO.markForDeletion();
60
      mData.mFBO = null;
61 c43abe6c Leszek Koltunski
      }
62
63
    mEffects.removeNode(this);
64
    }
65
66 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
67
68
  private ArrayList<Long> generateIDList()
69
    {
70 9361b337 Leszek Koltunski
    ArrayList<Long> ret = new ArrayList<>();
71 11845a9e Leszek Koltunski
    int numChildren = mChildren.getNumChildren();
72 7691a39f leszek
73 11845a9e Leszek Koltunski
    if( numChildren==0 )
74 7691a39f leszek
      {
75 c9f953c2 Leszek Koltunski
      // add a negative number so this leaf never gets confused with a internal node
76
      // with a single child that happens to have ID identical to some leaf's Effects ID.
77 7691a39f leszek
      ret.add(-mEffects.getID());
78
      }
79 c9f953c2 Leszek Koltunski
    else
80 6a06a912 Leszek Koltunski
      {
81 c9f953c2 Leszek Koltunski
      DistortedNode node;
82 6a06a912 Leszek Koltunski
   
83 11845a9e Leszek Koltunski
      for(int i=0; i<numChildren; i++)
84 c9f953c2 Leszek Koltunski
        {
85 11845a9e Leszek Koltunski
        node = mChildren.getChild(i);
86 c9f953c2 Leszek Koltunski
        ret.add(node.mData.ID);
87
        }
88
89
      // A bit questionable decision here - we are sorting the children IDs, which means
90
      // that order in which we draw the children is going to be undefined (well, this is not
91
      // strictly speaking true - when rendering, if no postprocessing and isomorphism are
92
      // involved, we *DO* render the children in order they were added; if however there
93
      // are two internal nodes with the same list of identical children, just added in a
94
      // different order each time, then we consider them isomorphic, i.e. identical and only
95
      // render the first one. If then two children of such 'pseudo-isomorphic' nodes are at
96
      // exactly the same Z-height this might result in some unexpected sights).
97
      //
98
      // Reason: with the children being sorted by postprocessing buckets, the order is
99
      // undefined anyway (although only when postprocessing is applied).
100
      //
101
      // See the consequences in the 'Olympic' app - remove a few leaves and add them back in
102 d5e053a5 Leszek Koltunski
      // different order. You will see the number of renders go back to the original 15.
103 c9f953c2 Leszek Koltunski
      Collections.sort(ret);
104
      }
105
106
    ret.add( 0, mSurface.getID() );
107
108 6a06a912 Leszek Koltunski
    return ret;
109
    }
110
111 9cae4322 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
112 11845a9e Leszek Koltunski
/**
113
 * This is not really part of the public API. Has to be public only because it is a part of the
114
 * DistortedChildrenList.Parent interface.
115
 *
116
 * @y.exclude
117
 */
118
  public void adjustIsomorphism()
119 9cae4322 Leszek Koltunski
    {
120 8bfefd68 Leszek Koltunski
    DistortedNodeData newData = DistortedNodeData.returnData(generateIDList());
121
    boolean deleteOldFBO = mData.removeData();
122 11845a9e Leszek Koltunski
    boolean createNewFBO = (mChildren.getNumChildren()>0 && newData.mFBO==null);
123 c204c69d leszek
124 f28fffc2 Leszek Koltunski
    if( deleteOldFBO && createNewFBO )
125
      {
126 8bfefd68 Leszek Koltunski
      newData.mFBO = mData.mFBO;
127 f28fffc2 Leszek Koltunski
      }
128
    else if( deleteOldFBO )
129
      {
130
      mData.mFBO.markForDeletion();
131
      mData.mFBO = null;
132
      }
133
    else if( createNewFBO )
134
      {
135 11845a9e Leszek Koltunski
      newData.mFBO = allocateNewFBO();
136 f28fffc2 Leszek Koltunski
      }
137 af27df87 leszek
138 f28fffc2 Leszek Koltunski
    mData = newData;
139 c204c69d leszek
140 f28fffc2 Leszek Koltunski
    if( mParent!=null ) mParent.adjustIsomorphism();
141 fee0865c Leszek Koltunski
    }
142 c204c69d leszek
143 11845a9e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
144
/**
145
 * This is not really part of the public API. Has to be public only because it is a part of the
146
 * DistortedChildrenList.Parent interface.
147
 *
148
 * @y.exclude
149
 */
150
  public DistortedChildrenList getChildren()
151
    {
152
    return mChildren;
153
    }
154
155 8dccc3c2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
156
// return the total number of render calls issued
157
158
  int drawNoBlend(long currTime, DistortedOutputSurface surface)
159
    {
160 11845a9e Leszek Koltunski
    DistortedSurface input = getInternalSurface();
161 8dccc3c2 Leszek Koltunski
162
    if( input.setAsInput() )
163
      {
164
      mState.apply();
165
      GLES31.glDisable(GLES31.GL_BLEND);
166 a13dde77 Leszek Koltunski
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
167 8dccc3c2 Leszek Koltunski
      GLES31.glEnable(GLES31.GL_BLEND);
168
      return 1;
169
      }
170 c1a38ba3 Leszek Koltunski
171
    return 0;
172
    }
173
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175
// Use the Order Independent Transparency method to draw a non-postprocessed child.
176
177
  int drawOIT(long currTime, DistortedOutputSurface surface)
178
    {
179 11845a9e Leszek Koltunski
    DistortedSurface input = getInternalSurface();
180 c1a38ba3 Leszek Koltunski
181
    if( input.setAsInput() )
182
      {
183
      mState.apply();
184 a13dde77 Leszek Koltunski
      mEffects.drawPrivOIT(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
185 c1a38ba3 Leszek Koltunski
      return 1;
186
      }
187 8dccc3c2 Leszek Koltunski
188
    return 0;
189
    }
190
191 39086ebb leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
192
// return the total number of render calls issued
193
194
  int draw(long currTime, DistortedOutputSurface surface)
195
    {
196 11845a9e Leszek Koltunski
    DistortedSurface input = getInternalSurface();
197 39086ebb leszek
198
    if( input.setAsInput() )
199
      {
200
      mState.apply();
201 a13dde77 Leszek Koltunski
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
202 39086ebb leszek
      return 1;
203
      }
204
205
    return 0;
206
    }
207
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209
// return the total number of render calls issued
210
211
  int renderRecursive(long currTime)
212
    {
213
    int numRenders = 0;
214 11845a9e Leszek Koltunski
    int numChildren = mChildren.getNumChildren();
215 39086ebb leszek
216 11845a9e Leszek Koltunski
    if( numChildren>0 && mData.notRenderedYetAtThisTime(currTime) )
217 39086ebb leszek
      {
218 11845a9e Leszek Koltunski
      for (int i=0; i<numChildren; i++)
219 0c303a2c Leszek Koltunski
        {
220 11845a9e Leszek Koltunski
        numRenders += mChildren.getChild(i).renderRecursive(currTime);
221 0c303a2c Leszek Koltunski
        }
222
223 11845a9e Leszek Koltunski
      if( mData.mFBO==null ) mData.mFBO = allocateNewFBO();
224 95c441a2 leszek
      mData.mFBO.setAsOutput(currTime);
225 39086ebb leszek
226
      if( mSurface.setAsInput() )
227
        {
228
        numRenders++;
229
        DistortedEffects.blitPriv(mData.mFBO);
230
        }
231
232 11845a9e Leszek Koltunski
      numRenders += mData.mFBO.renderChildren(currTime,numChildren,mChildren,0, mRenderWayOIT);
233 39086ebb leszek
      }
234
235
    return numRenders;
236
    }
237
238 be60d4ff leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
239
240 11845a9e Leszek Koltunski
  private DistortedFramebuffer allocateNewFBO()
241 be60d4ff leszek
    {
242 11845a9e Leszek Koltunski
    int width  = mFboW <= 0 ? mSurface.getWidth()  : mFboW;
243
    int height = mFboH <= 0 ? mSurface.getHeight() : mFboH;
244
    return new DistortedFramebuffer(1,mFboDepthStencil, DistortedSurface.TYPE_TREE, width, height);
245
    }
246
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248
249
  void setParent(DistortedChildrenList.Parent parent)
250
    {
251
    mParent = parent;
252 be60d4ff leszek
    }
253
254 26a4e5f6 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
255
256
  void sort()
257
    {
258
    if( mParent!=null )
259
      {
260 11845a9e Leszek Koltunski
      DistortedChildrenList siblings = mParent.getChildren();
261
      siblings.removeChild(this);
262
      siblings.addSortingByBuckets(this);
263 26a4e5f6 leszek
      }
264
    }
265
266 70b6a155 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
267 7a5e538a Leszek Koltunski
268
  EffectQueuePostprocess getPostprocessQueue()
269 70b6a155 Leszek Koltunski
    {
270
    return mEffects.getPostprocess();
271
    }
272
273 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
274
// PUBLIC API
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
/**
277 a09ada4c Leszek Koltunski
 * Constructs new Node.
278 6a06a912 Leszek Koltunski
 *     
279 c5369f1b leszek
 * @param surface InputSurface to put into the new Node.
280 07d8ef09 Leszek Koltunski
 * @param effects DistortedEffects to put into the new Node.
281 715e7726 Leszek Koltunski
 * @param mesh MeshBase to put into the new Node.
282 6a06a912 Leszek Koltunski
 */
283 715e7726 Leszek Koltunski
  public DistortedNode(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
284 6a06a912 Leszek Koltunski
    {
285 c5369f1b leszek
    mSurface       = surface;
286 8ca9f899 Leszek Koltunski
    mEffects       = effects;
287
    mMesh          = mesh;
288 c834348d leszek
    mState         = new DistortedRenderState();
289 11845a9e Leszek Koltunski
    mChildren      = new DistortedChildrenList(this);
290 f28fffc2 Leszek Koltunski
    mParent        = null;
291 406e2f6b Leszek Koltunski
    mRenderWayOIT  = false;
292 f28fffc2 Leszek Koltunski
293 23eecbd9 Leszek Koltunski
    mFboW            = 0;  // i.e. take this from
294
    mFboH            = 0;  // mSurface's dimensions
295
    mFboDepthStencil = DistortedFramebuffer.DEPTH_NO_STENCIL;
296
297 8bfefd68 Leszek Koltunski
    mData = DistortedNodeData.returnData(generateIDList());
298 26a4e5f6 leszek
    mEffects.newNode(this);
299 6a06a912 Leszek Koltunski
    }
300
301
///////////////////////////////////////////////////////////////////////////////////////////////////  
302
/**
303 a09ada4c Leszek Koltunski
 * Copy-constructs new Node from another Node.
304 6a06a912 Leszek Koltunski
 *     
305 a09ada4c Leszek Koltunski
 * @param node The DistortedNode to copy data from.
306 6a06a912 Leszek Koltunski
 * @param flags bit field composed of a subset of the following:
307 29a06526 Leszek Koltunski
 *        {@link Distorted#CLONE_SURFACE},  {@link Distorted#CLONE_MATRIX}, {@link Distorted#CLONE_VERTEX},
308 6a06a912 Leszek Koltunski
 *        {@link Distorted#CLONE_FRAGMENT} and {@link Distorted#CLONE_CHILDREN}.
309 29a06526 Leszek Koltunski
 *        For example flags = CLONE_SURFACE | CLONE_CHILDREN.
310 6a06a912 Leszek Koltunski
 */
311 a09ada4c Leszek Koltunski
  public DistortedNode(DistortedNode node, int flags)
312 6a06a912 Leszek Koltunski
    {
313 be60d4ff leszek
    mEffects      = new DistortedEffects(node.mEffects,flags);
314
    mMesh         = node.mMesh;
315
    mState        = new DistortedRenderState();
316
    mParent       = null;
317 406e2f6b Leszek Koltunski
    mRenderWayOIT = false;
318 9361b337 Leszek Koltunski
319 23eecbd9 Leszek Koltunski
    mFboW            = node.mFboW;
320
    mFboH            = node.mFboH;
321
    mFboDepthStencil = node.mFboDepthStencil;
322
323 29a06526 Leszek Koltunski
    if( (flags & Distorted.CLONE_SURFACE) != 0 )
324 e7a20702 Leszek Koltunski
      {
325 c5369f1b leszek
      mSurface = node.mSurface;
326 e7a20702 Leszek Koltunski
      }
327
    else
328
      {
329 c5369f1b leszek
      int w = node.mSurface.getWidth();
330
      int h = node.mSurface.getHeight();
331 8ca9f899 Leszek Koltunski
332 c5369f1b leszek
      if( node.mSurface instanceof DistortedTexture )
333 8ca9f899 Leszek Koltunski
        {
334 09ab7524 Leszek Koltunski
        mSurface = new DistortedTexture(w,h, DistortedSurface.TYPE_TREE);
335 8ca9f899 Leszek Koltunski
        }
336 c5369f1b leszek
      else if( node.mSurface instanceof DistortedFramebuffer )
337 8ca9f899 Leszek Koltunski
        {
338 23eecbd9 Leszek Koltunski
        int depthStencil = DistortedFramebuffer.NO_DEPTH_NO_STENCIL;
339 89de975c leszek
340
        if( ((DistortedFramebuffer) node.mSurface).hasDepth() )
341
          {
342
          boolean hasStencil = ((DistortedFramebuffer) node.mSurface).hasStencil();
343
          depthStencil = (hasStencil ? DistortedFramebuffer.BOTH_DEPTH_STENCIL:DistortedFramebuffer.DEPTH_NO_STENCIL);
344
          }
345
346 9ed80185 Leszek Koltunski
        mSurface = new DistortedFramebuffer(1,depthStencil,DistortedSurface.TYPE_TREE,w,h);
347 8ca9f899 Leszek Koltunski
        }
348 e7a20702 Leszek Koltunski
      }
349 11845a9e Leszek Koltunski
350 9361b337 Leszek Koltunski
    if( (flags & Distorted.CLONE_CHILDREN) != 0 )
351 6a06a912 Leszek Koltunski
      {
352
      mChildren = node.mChildren;
353
      }
354
    else
355
      {
356 11845a9e Leszek Koltunski
      mChildren = new DistortedChildrenList(this);
357 6a06a912 Leszek Koltunski
      }
358 26a4e5f6 leszek
359 8bfefd68 Leszek Koltunski
    mData = DistortedNodeData.returnData(generateIDList());
360 26a4e5f6 leszek
    mEffects.newNode(this);
361 6a06a912 Leszek Koltunski
    }
362 c204c69d leszek
363 406e2f6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
364
  /**
365
   * When rendering this Node, should we use the Order Independent Transparency render more?
366
   * <p>
367
   * There are two modes of rendering: the fast 'normal' way, which however renders transparent
368
   * fragments in different ways depending on which fragments get rendered first, or the slower
369
   * 'oit' way, which renders transparent fragments correctly regardless of their order.
370
   *
371
   * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
372
   */
373
  public void setOrderIndependentTransparency(boolean oit)
374
    {
375
    mRenderWayOIT = oit;
376
    }
377
378 12f9e4bb Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
379
  /**
380
   * When rendering this Node, should we use the Order Independent Transparency render more?
381
   * <p>
382
   * There are two modes of rendering: the fast 'normal' way, which however renders transparent
383
   * fragments in different ways depending on which fragments get rendered first, or the slower
384
   * 'oit' way, which renders transparent fragments correctly regardless of their order.
385
   *
386
   * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
387
   * @param initialSize Initial number of transparent fragments we expect, in screenfulls.
388
   *                    I.e '1.0' means 'the scene we are going to render contains about 1 screen
389
   *                    worth of transparent fragments'. Valid values: 0.0 &lt; initialSize &lt; 10.0
390
   *                    Even if you get this wrong, the library will detect that there are more
391
   *                    transparent fragments than it has space for and readjust its internal buffers,
392
   *                    but only after a few frames during which one will probably see missing objects.
393
   */
394
  public void setOrderIndependentTransparency(boolean oit, float initialSize)
395
    {
396
    mRenderWayOIT = oit;
397
398
    if( initialSize>0.0f && initialSize<10.0f )
399
      DistortedEffects.setSSBOSize(initialSize);
400
    }
401
402 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
403
/**
404
 * Adds a new child to the last position in the list of our Node's children.
405 c204c69d leszek
 * <p>
406
 * We cannot do this mid-render - actual attachment will be done just before the next render, by the
407 efe3d8fe leszek
 * DistortedMaster (by calling doWork())
408 c204c69d leszek
 *
409 6a06a912 Leszek Koltunski
 * @param node The new Node to add.
410
 */
411 c204c69d leszek
  public void attach(DistortedNode node)
412 6a06a912 Leszek Koltunski
    {
413 11845a9e Leszek Koltunski
    mChildren.attach(node);
414 6a06a912 Leszek Koltunski
    }
415 c204c69d leszek
416 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
417
/**
418
 * Adds a new child to the last position in the list of our Node's children.
419 c204c69d leszek
 * <p>
420
 * We cannot do this mid-render - actual attachment will be done just before the next render, by the
421 efe3d8fe leszek
 * DistortedMaster (by calling doWork())
422 c204c69d leszek
 *
423 c5369f1b leszek
 * @param surface InputSurface to initialize our child Node with.
424 07d8ef09 Leszek Koltunski
 * @param effects DistortedEffects to initialize our child Node with.
425 715e7726 Leszek Koltunski
 * @param mesh MeshBase to initialize our child Node with.
426 6a06a912 Leszek Koltunski
 * @return the newly constructed child Node, or null if we couldn't allocate resources.
427
 */
428 715e7726 Leszek Koltunski
  public DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
429 6a06a912 Leszek Koltunski
    {
430 11845a9e Leszek Koltunski
    return mChildren.attach(surface,effects,mesh);
431 c204c69d leszek
    }
432 f8377ef8 leszek
433 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
434
/**
435
 * Removes the first occurrence of a specified child from the list of children of our Node.
436 c204c69d leszek
 * <p>
437
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
438 efe3d8fe leszek
 * DistortedMaster (by calling doWork())
439 c204c69d leszek
 *
440 6a06a912 Leszek Koltunski
 * @param node The Node to remove.
441
 */
442 c204c69d leszek
  public void detach(DistortedNode node)
443 6a06a912 Leszek Koltunski
    {
444 11845a9e Leszek Koltunski
    mChildren.detach(node);
445 6a06a912 Leszek Koltunski
    }
446 a09ada4c Leszek Koltunski
447 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
448
/**
449
 * Removes the first occurrence of a specified child from the list of children of our Node.
450 a09ada4c Leszek Koltunski
 * <p>
451
 * A bit questionable method as there can be many different Nodes attached as children, some
452
 * of them having the same Effects but - for instance - different Mesh. Use with care.
453 c204c69d leszek
 * <p>
454
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
455 efe3d8fe leszek
 * DistortedMaster (by calling doWork())
456 a09ada4c Leszek Koltunski
 *
457 07d8ef09 Leszek Koltunski
 * @param effects DistortedEffects to remove.
458 6a06a912 Leszek Koltunski
 */
459 c204c69d leszek
  public void detach(DistortedEffects effects)
460 6a06a912 Leszek Koltunski
    {
461 11845a9e Leszek Koltunski
    mChildren.detach(effects);
462 c204c69d leszek
    }
463
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465
/**
466
 * Removes all children Nodes.
467
 * <p>
468
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
469 efe3d8fe leszek
 * DistortedMaster (by calling doWork())
470 c204c69d leszek
 */
471
  public void detachAll()
472
    {
473 11845a9e Leszek Koltunski
    mChildren.detachAll();
474 6a06a912 Leszek Koltunski
    }
475 13687207 leszek
476 27f42cd6 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
477 6a06a912 Leszek Koltunski
/**
478 421c2728 Leszek Koltunski
 * Returns the DistortedEffects object that's in the Node.
479 6a06a912 Leszek Koltunski
 * 
480 421c2728 Leszek Koltunski
 * @return The DistortedEffects contained in the Node.
481 6a06a912 Leszek Koltunski
 */
482 421c2728 Leszek Koltunski
  public DistortedEffects getEffects()
483 6a06a912 Leszek Koltunski
    {
484 07d8ef09 Leszek Koltunski
    return mEffects;
485 4e2382f3 Leszek Koltunski
    }
486
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488
/**
489 a13dde77 Leszek Koltunski
 * Returns the DistortedSurface object that's in the Node.
490 4e2382f3 Leszek Koltunski
 *
491 a13dde77 Leszek Koltunski
 * @return The DistortedSurface contained in the Node.
492 4e2382f3 Leszek Koltunski
 */
493 12f9e4bb Leszek Koltunski
  public DistortedSurface getSurface()
494 4e2382f3 Leszek Koltunski
    {
495 c5369f1b leszek
    return mSurface;
496 6a06a912 Leszek Koltunski
    }
497
498 a13dde77 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
499
  /**
500
   * Returns the DistortedSurface object that's in the Node.
501
   *
502
   * @return The DistortedSurface contained in the Node (if a leaf), or the FBO (if an internal Node)
503
   */
504
  public DistortedSurface getInternalSurface()
505
    {
506 11845a9e Leszek Koltunski
    return mChildren.getNumChildren()==0 ? mSurface : mData.mFBO;
507 a13dde77 Leszek Koltunski
    }
508
509 f1a82766 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
510
/**
511
 * Returns the Mesh object that's in the Node.
512
 *
513
 * @return Mesh contained in the Node.
514
 */
515 715e7726 Leszek Koltunski
  public MeshBase getMesh()
516 f1a82766 Leszek Koltunski
    {
517
    return mMesh;
518
    }
519
520 8c327653 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
521
/**
522 23eecbd9 Leszek Koltunski
 * Resizes the DistortedFramebuffer object that we render this Node to.
523 8c327653 Leszek Koltunski
 */
524 23eecbd9 Leszek Koltunski
  public void resize(int width, int height)
525 8c327653 Leszek Koltunski
    {
526 23eecbd9 Leszek Koltunski
    mFboW = width;
527
    mFboH = height;
528
529
    if ( mData.mFBO !=null )
530
      {
531
      // TODO: potentially allocate a new NodeData if we have to
532
      mData.mFBO.resize(width,height);
533
      }
534
    }
535
536
///////////////////////////////////////////////////////////////////////////////////////////////////
537
/**
538
 * Enables/disables DEPTH and STENCIL buffers in the Framebuffer object that we render this Node to.
539
 */
540
  public void enableDepthStencil(int depthStencil)
541
    {
542
    mFboDepthStencil = depthStencil;
543
544
    if ( mData.mFBO !=null )
545
      {
546
      // TODO: potentially allocate a new NodeData if we have to
547
      mData.mFBO.enableDepthStencil(depthStencil);
548
      }
549 8c327653 Leszek Koltunski
    }
550 6a06a912 Leszek Koltunski
551 ad16ed3b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
552
// APIs that control how to set the OpenGL state just before rendering this Node.
553 c834348d leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
554
/**
555
 * When rendering this Node, use ColorMask (r,g,b,a).
556
 *
557
 * @param r Write to the RED color channel when rendering this Node?
558
 * @param g Write to the GREEN color channel when rendering this Node?
559
 * @param b Write to the BLUE color channel when rendering this Node?
560
 * @param a Write to the ALPHA channel when rendering this Node?
561
 */
562 13687207 leszek
  @SuppressWarnings("unused")
563 c834348d leszek
  public void glColorMask(boolean r, boolean g, boolean b, boolean a)
564
    {
565
    mState.glColorMask(r,g,b,a);
566
    }
567
568
///////////////////////////////////////////////////////////////////////////////////////////////////
569
/**
570
 * When rendering this Node, switch on writing to Depth buffer?
571
 *
572
 * @param mask Write to the Depth buffer when rendering this Node?
573
 */
574 13687207 leszek
  @SuppressWarnings("unused")
575 c834348d leszek
  public void glDepthMask(boolean mask)
576
    {
577
    mState.glDepthMask(mask);
578
    }
579
580
///////////////////////////////////////////////////////////////////////////////////////////////////
581
/**
582
 * When rendering this Node, which bits of the Stencil buffer to write to?
583
 *
584
 * @param mask Marks the bits of the Stencil buffer we will write to when rendering this Node.
585
 */
586 13687207 leszek
  @SuppressWarnings("unused")
587 c834348d leszek
  public void glStencilMask(int mask)
588
    {
589
    mState.glStencilMask(mask);
590
    }
591
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593
/**
594
 * When rendering this Node, which Tests to enable?
595
 *
596
 * @param test Valid values: GL_DEPTH_TEST, GL_STENCIL_TEST, GL_BLEND
597
 */
598 13687207 leszek
  @SuppressWarnings("unused")
599 c834348d leszek
  public void glEnable(int test)
600
    {
601
    mState.glEnable(test);
602
    }
603
604
///////////////////////////////////////////////////////////////////////////////////////////////////
605
/**
606
 * When rendering this Node, which Tests to enable?
607
 *
608
 * @param test Valid values: GL_DEPTH_TEST, GL_STENCIL_TEST, GL_BLEND
609
 */
610 13687207 leszek
  @SuppressWarnings("unused")
611 c834348d leszek
  public void glDisable(int test)
612
    {
613
    mState.glDisable(test);
614
    }
615
616
///////////////////////////////////////////////////////////////////////////////////////////////////
617
/**
618
 * When rendering this Node, use the following StencilFunc.
619
 *
620
 * @param func Valid values: GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL
621
 * @param ref  Reference valut to compare our stencil with.
622
 * @param mask Mask used when comparing.
623
 */
624 13687207 leszek
  @SuppressWarnings("unused")
625 c834348d leszek
  public void glStencilFunc(int func, int ref, int mask)
626
    {
627
    mState.glStencilFunc(func,ref,mask);
628
    }
629
630
///////////////////////////////////////////////////////////////////////////////////////////////////
631
/**
632
 * When rendering this Node, use the following StencilOp.
633
 * <p>
634
 * Valid values of all 3 parameters: GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP
635
 *
636
 * @param sfail  What to do when Stencil Test fails.
637
 * @param dpfail What to do when Depth Test fails.
638
 * @param dppass What to do when Depth Test passes.
639
 */
640 13687207 leszek
  @SuppressWarnings("unused")
641 c834348d leszek
  public void glStencilOp(int sfail, int dpfail, int dppass)
642
    {
643
    mState.glStencilOp(sfail,dpfail,dppass);
644
    }
645
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647
/**
648
 * When rendering this Node, use the following DepthFunc.
649
 *
650
 * @param func Valid values: GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL
651
 */
652 13687207 leszek
  @SuppressWarnings("unused")
653 c834348d leszek
  public void glDepthFunc(int func)
654
    {
655
    mState.glDepthFunc(func);
656
    }
657
658
///////////////////////////////////////////////////////////////////////////////////////////////////
659
/**
660
 * When rendering this Node, use the following Blending mode.
661
 * <p>
662
 * Valid values: GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
663
 *               GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR,
664
 *               GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE
665
 *
666
 * @param src Source Blend function
667
 * @param dst Destination Blend function
668
 */
669 13687207 leszek
  @SuppressWarnings("unused")
670 c834348d leszek
  public void glBlendFunc(int src, int dst)
671
    {
672
    mState.glBlendFunc(src,dst);
673
    }
674 ad16ed3b Leszek Koltunski
675
///////////////////////////////////////////////////////////////////////////////////////////////////
676
/**
677
 * Before rendering this Node, clear the following buffers.
678
 * <p>
679
 * Valid values: 0, or bitwise OR of one or more values from the set GL_COLOR_BUFFER_BIT,
680
 *               GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
681
 * Default: 0
682
 *
683
 * @param mask bitwise OR of BUFFER_BITs to clear.
684
 */
685
  @SuppressWarnings("unused")
686
  public void glClear(int mask)
687
    {
688
    mState.glClear(mask);
689
    }
690 8c327653 Leszek Koltunski
  }