Project

General

Profile

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

library / src / main / java / org / distorted / library / main / DistortedNode.java @ e37d470b

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.main;
21

    
22
import android.opengl.GLES31;
23

    
24
import org.distorted.library.mesh.MeshBase;
25

    
26
import java.util.ArrayList;
27
import java.util.Collections;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30
/**
31
 * Class which represents a Node in a Tree of (InputSurface,Mesh,Effects) triplets.
32
 * <p>
33
 * Having organized such sets into a Tree, we can then render any Node to any OutputSurface.
34
 * That recursively renders the set held in the Node and all its children.
35
 * <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
 * will point to the same NodeData; only the first of this is rendered (mData.numRender!).
39
 */
40
public class DistortedNode implements DistortedChildrenList.Parent
41
  {
42
  private MeshBase mMesh;
43
  private DistortedEffects mEffects;
44
  private DistortedSurface mSurface;
45
  private DistortedRenderState mState;
46
  private DistortedNodeData mData;
47
  private DistortedChildrenList mChildren;
48
  private DistortedChildrenList.Parent mParent;
49

    
50
  private int mFboW, mFboH, mFboDepthStencil;
51
  private boolean mRenderWayOIT;
52

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

    
55
  public void markForDeletion()
56
    {
57
    if( mData.removeData() )
58
      {
59
      mData.mFBO.markForDeletion();
60
      mData.mFBO = null;
61
      }
62

    
63
    mEffects.removeNode(this);
64
    }
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  private ArrayList<Long> generateIDList()
69
    {
70
    ArrayList<Long> ret = new ArrayList<>();
71
    int numChildren = mChildren.getNumChildren();
72

    
73
    if( numChildren==0 )
74
      {
75
      // 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
      ret.add(-mEffects.getID());
78
      }
79
    else
80
      {
81
      DistortedNode node;
82
   
83
      for(int i=0; i<numChildren; i++)
84
        {
85
        node = mChildren.getChild(i);
86
        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
      // different order. You will see the number of renders go back to the original 15.
103
      Collections.sort(ret);
104
      }
105

    
106
    ret.add( 0, mSurface.getID() );
107

    
108
    return ret;
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112
/**
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
    {
120
    DistortedNodeData newData = DistortedNodeData.returnData(generateIDList());
121
    boolean deleteOldFBO = mData.removeData();
122
    boolean createNewFBO = (mChildren.getNumChildren()>0 && newData.mFBO==null);
123

    
124
    if( deleteOldFBO && createNewFBO )
125
      {
126
      newData.mFBO = mData.mFBO;
127
      }
128
    else if( deleteOldFBO )
129
      {
130
      mData.mFBO.markForDeletion();
131
      mData.mFBO = null;
132
      }
133
    else if( createNewFBO )
134
      {
135
      newData.mFBO = allocateNewFBO();
136
      }
137

    
138
    mData = newData;
139

    
140
    if( mParent!=null ) mParent.adjustIsomorphism();
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
156
// return the total number of render calls issued
157

    
158
  int drawNoBlend(long currTime, DistortedOutputSurface surface)
159
    {
160
    DistortedSurface input = getInternalSurface();
161

    
162
    if( input.setAsInput() )
163
      {
164
      mState.apply();
165
      GLES31.glDisable(GLES31.GL_BLEND);
166
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
167
      GLES31.glEnable(GLES31.GL_BLEND);
168
      return 1;
169
      }
170

    
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
    DistortedSurface input = getInternalSurface();
180

    
181
    if( input.setAsInput() )
182
      {
183
      mState.apply();
184
      mEffects.drawPrivOIT(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
185
      return 1;
186
      }
187

    
188
    return 0;
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
// return the total number of render calls issued
193

    
194
  int draw(long currTime, DistortedOutputSurface surface)
195
    {
196
    DistortedSurface input = getInternalSurface();
197

    
198
    if( input.setAsInput() )
199
      {
200
      mState.apply();
201
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
202
      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
    int numChildren = mChildren.getNumChildren();
215

    
216
    if( numChildren>0 && mData.notRenderedYetAtThisTime(currTime) )
217
      {
218
      for (int i=0; i<numChildren; i++)
219
        {
220
        numRenders += mChildren.getChild(i).renderRecursive(currTime);
221
        }
222

    
223
      if( mData.mFBO==null ) mData.mFBO = allocateNewFBO();
224
      mData.mFBO.setAsOutput(currTime);
225

    
226
      if( mSurface.setAsInput() )
227
        {
228
        numRenders++;
229
        DistortedEffects.blitPriv(mData.mFBO);
230
        }
231

    
232
      numRenders += mData.mFBO.renderChildren(currTime,numChildren,mChildren,0, mRenderWayOIT);
233
      }
234

    
235
    return numRenders;
236
    }
237

    
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239

    
240
  private DistortedFramebuffer allocateNewFBO()
241
    {
242
    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
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  void sort()
257
    {
258
    if( mParent!=null )
259
      {
260
      DistortedChildrenList siblings = mParent.getChildren();
261
      siblings.removeChild(this);
262
      siblings.addSortingByBuckets(this);
263
      }
264
    }
265

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
// PUBLIC API
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269
/**
270
 * Constructs new Node.
271
 *     
272
 * @param surface InputSurface to put into the new Node.
273
 * @param effects DistortedEffects to put into the new Node.
274
 * @param mesh MeshBase to put into the new Node.
275
 */
276
  public DistortedNode(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
277
    {
278
    mSurface       = surface;
279
    mEffects       = effects;
280
    mMesh          = mesh;
281
    mState         = new DistortedRenderState();
282
    mChildren      = new DistortedChildrenList(this);
283
    mParent        = null;
284
    mRenderWayOIT  = false;
285

    
286
    mFboW            = 0;  // i.e. take this from
287
    mFboH            = 0;  // mSurface's dimensions
288
    mFboDepthStencil = DistortedFramebuffer.DEPTH_NO_STENCIL;
289

    
290
    mData = DistortedNodeData.returnData(generateIDList());
291
    mEffects.newNode(this);
292
    }
293

    
294
///////////////////////////////////////////////////////////////////////////////////////////////////  
295
/**
296
 * Copy-constructs new Node from another Node.
297
 *     
298
 * @param node The DistortedNode to copy data from.
299
 * @param flags bit field composed of a subset of the following:
300
 *        {@link Distorted#CLONE_SURFACE},  {@link Distorted#CLONE_MATRIX}, {@link Distorted#CLONE_VERTEX},
301
 *        {@link Distorted#CLONE_FRAGMENT} and {@link Distorted#CLONE_CHILDREN}.
302
 *        For example flags = CLONE_SURFACE | CLONE_CHILDREN.
303
 */
304
  public DistortedNode(DistortedNode node, int flags)
305
    {
306
    mEffects      = new DistortedEffects(node.mEffects,flags);
307
    mMesh         = node.mMesh;
308
    mState        = new DistortedRenderState();
309
    mParent       = null;
310
    mRenderWayOIT = false;
311

    
312
    mFboW            = node.mFboW;
313
    mFboH            = node.mFboH;
314
    mFboDepthStencil = node.mFboDepthStencil;
315

    
316
    if( (flags & Distorted.CLONE_SURFACE) != 0 )
317
      {
318
      mSurface = node.mSurface;
319
      }
320
    else
321
      {
322
      int w = node.mSurface.getWidth();
323
      int h = node.mSurface.getHeight();
324

    
325
      if( node.mSurface instanceof DistortedTexture )
326
        {
327
        mSurface = new DistortedTexture(w,h, DistortedSurface.TYPE_TREE);
328
        }
329
      else if( node.mSurface instanceof DistortedFramebuffer )
330
        {
331
        int depthStencil = DistortedFramebuffer.NO_DEPTH_NO_STENCIL;
332

    
333
        if( ((DistortedFramebuffer) node.mSurface).hasDepth() )
334
          {
335
          boolean hasStencil = ((DistortedFramebuffer) node.mSurface).hasStencil();
336
          depthStencil = (hasStencil ? DistortedFramebuffer.BOTH_DEPTH_STENCIL:DistortedFramebuffer.DEPTH_NO_STENCIL);
337
          }
338

    
339
        mSurface = new DistortedFramebuffer(1,depthStencil,DistortedSurface.TYPE_TREE,w,h);
340
        }
341
      }
342

    
343
    if( (flags & Distorted.CLONE_CHILDREN) != 0 )
344
      {
345
      mChildren = node.mChildren;
346
      }
347
    else
348
      {
349
      mChildren = new DistortedChildrenList(this);
350
      }
351

    
352
    mData = DistortedNodeData.returnData(generateIDList());
353
    mEffects.newNode(this);
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
  /**
358
   * When rendering this Node, should we use the Order Independent Transparency render more?
359
   * <p>
360
   * There are two modes of rendering: the fast 'normal' way, which however renders transparent
361
   * fragments in different ways depending on which fragments get rendered first, or the slower
362
   * 'oit' way, which renders transparent fragments correctly regardless of their order.
363
   *
364
   * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
365
   */
366
  public void setOrderIndependentTransparency(boolean oit)
367
    {
368
    mRenderWayOIT = oit;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372
  /**
373
   * When rendering this Node, should we use the Order Independent Transparency render more?
374
   * <p>
375
   * There are two modes of rendering: the fast 'normal' way, which however renders transparent
376
   * fragments in different ways depending on which fragments get rendered first, or the slower
377
   * 'oit' way, which renders transparent fragments correctly regardless of their order.
378
   *
379
   * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
380
   * @param initialSize Initial number of transparent fragments we expect, in screenfulls.
381
   *                    I.e '1.0' means 'the scene we are going to render contains about 1 screen
382
   *                    worth of transparent fragments'. Valid values: 0.0 &lt; initialSize &lt; 10.0
383
   *                    Even if you get this wrong, the library will detect that there are more
384
   *                    transparent fragments than it has space for and readjust its internal buffers,
385
   *                    but only after a few frames during which one will probably see missing objects.
386
   */
387
  public void setOrderIndependentTransparency(boolean oit, float initialSize)
388
    {
389
    mRenderWayOIT = oit;
390

    
391
    if( initialSize>0.0f && initialSize<10.0f )
392
      DistortedEffects.setSSBOSize(initialSize);
393
    }
394

    
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396
/**
397
 * Adds a new child to the last position in the list of our Node's children.
398
 * <p>
399
 * We cannot do this mid-render - actual attachment will be done just before the next render, by the
400
 * DistortedMaster (by calling doWork())
401
 *
402
 * @param node The new Node to add.
403
 */
404
  public void attach(DistortedNode node)
405
    {
406
    mChildren.attach(node);
407
    }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410
/**
411
 * Adds a new child to the last position in the list of our Node's children.
412
 * <p>
413
 * We cannot do this mid-render - actual attachment will be done just before the next render, by the
414
 * DistortedMaster (by calling doWork())
415
 *
416
 * @param surface InputSurface to initialize our child Node with.
417
 * @param effects DistortedEffects to initialize our child Node with.
418
 * @param mesh MeshBase to initialize our child Node with.
419
 * @return the newly constructed child Node, or null if we couldn't allocate resources.
420
 */
421
  public DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
422
    {
423
    return mChildren.attach(surface,effects,mesh);
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427
/**
428
 * Removes the first occurrence of a specified child from the list of children of our Node.
429
 * <p>
430
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
431
 * DistortedMaster (by calling doWork())
432
 *
433
 * @param node The Node to remove.
434
 */
435
  public void detach(DistortedNode node)
436
    {
437
    mChildren.detach(node);
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441
/**
442
 * Removes the first occurrence of a specified child from the list of children of our Node.
443
 * <p>
444
 * A bit questionable method as there can be many different Nodes attached as children, some
445
 * of them having the same Effects but - for instance - different Mesh. Use with care.
446
 * <p>
447
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
448
 * DistortedMaster (by calling doWork())
449
 *
450
 * @param effects DistortedEffects to remove.
451
 */
452
  public void detach(DistortedEffects effects)
453
    {
454
    mChildren.detach(effects);
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458
/**
459
 * Removes all children Nodes.
460
 * <p>
461
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
462
 * DistortedMaster (by calling doWork())
463
 */
464
  public void detachAll()
465
    {
466
    mChildren.detachAll();
467
    }
468

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470
/**
471
 * Returns the DistortedEffects object that's in the Node.
472
 * 
473
 * @return The DistortedEffects contained in the Node.
474
 */
475
  public DistortedEffects getEffects()
476
    {
477
    return mEffects;
478
    }
479

    
480
///////////////////////////////////////////////////////////////////////////////////////////////////
481
/**
482
 * Returns the DistortedSurface object that's in the Node.
483
 *
484
 * @return The DistortedSurface contained in the Node.
485
 */
486
  public DistortedSurface getSurface()
487
    {
488
    return mSurface;
489
    }
490

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492
  /**
493
   * Returns the DistortedSurface object that's in the Node.
494
   *
495
   * @return The DistortedSurface contained in the Node (if a leaf), or the FBO (if an internal Node)
496
   */
497
  public DistortedSurface getInternalSurface()
498
    {
499
    return mChildren.getNumChildren()==0 ? mSurface : mData.mFBO;
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503
/**
504
 * Returns the Mesh object that's in the Node.
505
 *
506
 * @return Mesh contained in the Node.
507
 */
508
  public MeshBase getMesh()
509
    {
510
    return mMesh;
511
    }
512

    
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514
/**
515
 * Resizes the DistortedFramebuffer object that we render this Node to.
516
 */
517
  public void resize(int width, int height)
518
    {
519
    mFboW = width;
520
    mFboH = height;
521

    
522
    if ( mData.mFBO !=null )
523
      {
524
      // TODO: potentially allocate a new NodeData if we have to
525
      mData.mFBO.resize(width,height);
526
      }
527
    }
528

    
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530
/**
531
 * Enables/disables DEPTH and STENCIL buffers in the Framebuffer object that we render this Node to.
532
 */
533
  public void enableDepthStencil(int depthStencil)
534
    {
535
    mFboDepthStencil = depthStencil;
536

    
537
    if ( mData.mFBO !=null )
538
      {
539
      // TODO: potentially allocate a new NodeData if we have to
540
      mData.mFBO.enableDepthStencil(depthStencil);
541
      }
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545
// APIs that control how to set the OpenGL state just before rendering this Node.
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547
/**
548
 * When rendering this Node, use ColorMask (r,g,b,a).
549
 *
550
 * @param r Write to the RED color channel when rendering this Node?
551
 * @param g Write to the GREEN color channel when rendering this Node?
552
 * @param b Write to the BLUE color channel when rendering this Node?
553
 * @param a Write to the ALPHA channel when rendering this Node?
554
 */
555
  @SuppressWarnings("unused")
556
  public void glColorMask(boolean r, boolean g, boolean b, boolean a)
557
    {
558
    mState.glColorMask(r,g,b,a);
559
    }
560

    
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562
/**
563
 * When rendering this Node, switch on writing to Depth buffer?
564
 *
565
 * @param mask Write to the Depth buffer when rendering this Node?
566
 */
567
  @SuppressWarnings("unused")
568
  public void glDepthMask(boolean mask)
569
    {
570
    mState.glDepthMask(mask);
571
    }
572

    
573
///////////////////////////////////////////////////////////////////////////////////////////////////
574
/**
575
 * When rendering this Node, which bits of the Stencil buffer to write to?
576
 *
577
 * @param mask Marks the bits of the Stencil buffer we will write to when rendering this Node.
578
 */
579
  @SuppressWarnings("unused")
580
  public void glStencilMask(int mask)
581
    {
582
    mState.glStencilMask(mask);
583
    }
584

    
585
///////////////////////////////////////////////////////////////////////////////////////////////////
586
/**
587
 * When rendering this Node, which Tests to enable?
588
 *
589
 * @param test Valid values: GL_DEPTH_TEST, GL_STENCIL_TEST, GL_BLEND
590
 */
591
  @SuppressWarnings("unused")
592
  public void glEnable(int test)
593
    {
594
    mState.glEnable(test);
595
    }
596

    
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598
/**
599
 * When rendering this Node, which Tests to enable?
600
 *
601
 * @param test Valid values: GL_DEPTH_TEST, GL_STENCIL_TEST, GL_BLEND
602
 */
603
  @SuppressWarnings("unused")
604
  public void glDisable(int test)
605
    {
606
    mState.glDisable(test);
607
    }
608

    
609
///////////////////////////////////////////////////////////////////////////////////////////////////
610
/**
611
 * When rendering this Node, use the following StencilFunc.
612
 *
613
 * @param func Valid values: GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL
614
 * @param ref  Reference valut to compare our stencil with.
615
 * @param mask Mask used when comparing.
616
 */
617
  @SuppressWarnings("unused")
618
  public void glStencilFunc(int func, int ref, int mask)
619
    {
620
    mState.glStencilFunc(func,ref,mask);
621
    }
622

    
623
///////////////////////////////////////////////////////////////////////////////////////////////////
624
/**
625
 * When rendering this Node, use the following StencilOp.
626
 * <p>
627
 * Valid values of all 3 parameters: GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP
628
 *
629
 * @param sfail  What to do when Stencil Test fails.
630
 * @param dpfail What to do when Depth Test fails.
631
 * @param dppass What to do when Depth Test passes.
632
 */
633
  @SuppressWarnings("unused")
634
  public void glStencilOp(int sfail, int dpfail, int dppass)
635
    {
636
    mState.glStencilOp(sfail,dpfail,dppass);
637
    }
638

    
639
///////////////////////////////////////////////////////////////////////////////////////////////////
640
/**
641
 * When rendering this Node, use the following DepthFunc.
642
 *
643
 * @param func Valid values: GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL
644
 */
645
  @SuppressWarnings("unused")
646
  public void glDepthFunc(int func)
647
    {
648
    mState.glDepthFunc(func);
649
    }
650

    
651
///////////////////////////////////////////////////////////////////////////////////////////////////
652
/**
653
 * When rendering this Node, use the following Blending mode.
654
 * <p>
655
 * Valid values: GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
656
 *               GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR,
657
 *               GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE
658
 *
659
 * @param src Source Blend function
660
 * @param dst Destination Blend function
661
 */
662
  @SuppressWarnings("unused")
663
  public void glBlendFunc(int src, int dst)
664
    {
665
    mState.glBlendFunc(src,dst);
666
    }
667

    
668
///////////////////////////////////////////////////////////////////////////////////////////////////
669
/**
670
 * Before rendering this Node, clear the following buffers.
671
 * <p>
672
 * Valid values: 0, or bitwise OR of one or more values from the set GL_COLOR_BUFFER_BIT,
673
 *               GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
674
 * Default: 0
675
 *
676
 * @param mask bitwise OR of BUFFER_BITs to clear.
677
 */
678
  @SuppressWarnings("unused")
679
  public void glClear(int mask)
680
    {
681
    mState.glClear(mask);
682
    }
683
  }
(7-7/19)