Project

General

Profile

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

library / src / main / java / org / distorted / library / main / DistortedNode.java @ 9ecac8cd

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