Project

General

Profile

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

library / src / main / java / org / distorted / library / main / DistortedNode.java @ 7602a827

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of DistortedLibrary.                                                               //
5
//                                                                                               //
6
// DistortedLibrary 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
// DistortedLibrary 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 DistortedLibrary.  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 InternalChildrenList.Parent
41
  {
42
  private MeshBase mMesh;
43
  private DistortedEffects mEffects;
44
  private InternalSurface mSurface;
45
  private InternalRenderState mState;
46
  private InternalNodeData mData;
47
  private InternalChildrenList mChildren;
48
  private InternalChildrenList.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

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

    
66
  long getBucket()
67
    {
68
    return mEffects.getQueues()[3].getID();
69
    }
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

    
73
  private ArrayList<Long> generateIDList()
74
    {
75
    ArrayList<Long> ret = new ArrayList<>();
76
    int numChildren = mChildren.getNumChildren();
77

    
78
    if( numChildren==0 )
79
      {
80
      // add a negative number so this leaf never gets confused with a internal node
81
      // with a single child that happens to have ID identical to some leaf's Effects ID.
82
      ret.add(-mEffects.getID());
83
      }
84
    else
85
      {
86
      DistortedNode node;
87
   
88
      for(int i=0; i<numChildren; i++)
89
        {
90
        node = mChildren.getChild(i);
91
        ret.add(node.mData.ID);
92
        }
93

    
94
      // A bit questionable decision here - we are sorting the children IDs, which means
95
      // that order in which we draw the children is going to be undefined (well, this is not
96
      // strictly speaking true - when rendering, if no postprocessing and isomorphism are
97
      // involved, we *DO* render the children in order they were added; if however there
98
      // are two internal nodes with the same list of identical children, just added in a
99
      // different order each time, then we consider them isomorphic, i.e. identical and only
100
      // render the first one. If then two children of such 'pseudo-isomorphic' nodes are at
101
      // exactly the same Z-height this might result in some unexpected sights).
102
      //
103
      // Reason: with the children being sorted by postprocessing buckets, the order is
104
      // undefined anyway (although only when postprocessing is applied).
105
      //
106
      // See the consequences in the 'Olympic' app - remove a few leaves and add them back in
107
      // different order. You will see the number of renders go back to the original 15.
108
      Collections.sort(ret);
109
      }
110

    
111
    ret.add( 0, mSurface.getID() );
112

    
113
    return ret;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117
/**
118
 * This is not really part of the public API. Has to be public only because it is a part of the
119
 * InternalChildrenList.Parent interface.
120
 *
121
 * @y.exclude
122
 */
123
  public void adjustIsomorphism()
124
    {
125
    InternalNodeData newData = InternalNodeData.returnData(generateIDList());
126
    boolean deleteOldFBO = mData.removeData();
127
    boolean createNewFBO = (mChildren.getNumChildren()>0 && newData.mFBO==null);
128

    
129
    if( deleteOldFBO && createNewFBO )
130
      {
131
      newData.mFBO = mData.mFBO;
132
      }
133
    else if( deleteOldFBO )
134
      {
135
      mData.mFBO.markForDeletion();
136
      mData.mFBO = null;
137
      }
138
    else if( createNewFBO )
139
      {
140
      newData.mFBO = allocateNewFBO();
141
      }
142

    
143
    mData = newData;
144

    
145
    if( mParent!=null ) mParent.adjustIsomorphism();
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
// return the total number of render calls issued
150

    
151
  int drawNoBlend(long currTime, InternalOutputSurface surface)
152
    {
153
    InternalSurface input = getInternalSurface();
154

    
155
    if( input.setAsInput() )
156
      {
157
      mState.apply();
158
      GLES31.glDisable(GLES31.GL_BLEND);
159
      DistortedLibrary.drawPriv(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
160
      GLES31.glEnable(GLES31.GL_BLEND);
161
      return 1;
162
      }
163

    
164
    return 0;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
// Use the Order Independent Transparency method to draw a non-postprocessed child.
169

    
170
  int drawOIT(long currTime, InternalOutputSurface surface)
171
    {
172
    InternalSurface input = getInternalSurface();
173

    
174
    if( input.setAsInput() )
175
      {
176
      mState.apply();
177
      DistortedLibrary.drawPrivOIT(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
178
      return 1;
179
      }
180

    
181
    return 0;
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185
// return the total number of render calls issued
186

    
187
  int draw(long currTime, InternalOutputSurface surface)
188
    {
189
    InternalSurface input = getInternalSurface();
190

    
191
    if( input.setAsInput() )
192
      {
193
      mState.apply();
194
      DistortedLibrary.drawPriv(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
195
      return 1;
196
      }
197

    
198
    return 0;
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202
// return the total number of render calls issued
203

    
204
  int renderRecursive(long currTime)
205
    {
206
    int numRenders = 0;
207
    int numChildren = mChildren.getNumChildren();
208

    
209
    if( numChildren>0 && mData.notRenderedYetAtThisTime(currTime) )
210
      {
211
      DistortedNode node;
212
      long oldBucket=0, newBucket;
213

    
214
      for (int i=0; i<numChildren; i++)
215
        {
216
        node = mChildren.getChild(i);
217
        newBucket = node.getBucket();
218
        numRenders += node.renderRecursive(currTime);
219
        if( newBucket<oldBucket ) mChildren.rearrangeByBuckets(i,newBucket);
220
        else oldBucket=newBucket;
221
        }
222

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

    
226
      if( mSurface.setAsInput() )
227
        {
228
        numRenders++;
229
        DistortedLibrary.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, InternalSurface.TYPE_TREE, width, height);
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  void setParent(InternalChildrenList.Parent parent)
250
    {
251
    mParent = parent;
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255
// PUBLIC API
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257
/**
258
 * Constructs new Node.
259
 *     
260
 * @param surface InputSurface to put into the new Node.
261
 * @param effects DistortedEffects to put into the new Node.
262
 * @param mesh MeshBase to put into the new Node.
263
 */
264
  public DistortedNode(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
265
    {
266
    mSurface       = surface;
267
    mEffects       = effects;
268
    mMesh          = mesh;
269
    mState         = new InternalRenderState();
270
    mChildren      = new InternalChildrenList(this);
271
    mParent        = null;
272
    mRenderWayOIT  = false;
273

    
274
    mFboW            = 0;  // i.e. take this from
275
    mFboH            = 0;  // mSurface's dimensions
276
    mFboDepthStencil = DistortedFramebuffer.DEPTH_NO_STENCIL;
277

    
278
    mData = InternalNodeData.returnData(generateIDList());
279
    }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////  
282
/**
283
 * Copy-constructs new Node from another Node.
284
 *     
285
 * @param node The DistortedNode to copy data from.
286
 * @param flags bit field composed of a subset of the following:
287
 *        {@link DistortedLibrary#CLONE_SURFACE},  {@link DistortedLibrary#CLONE_MATRIX}, {@link DistortedLibrary#CLONE_VERTEX},
288
 *        {@link DistortedLibrary#CLONE_FRAGMENT} and {@link DistortedLibrary#CLONE_CHILDREN}.
289
 *        For example flags = CLONE_SURFACE | CLONE_CHILDREN.
290
 */
291
  public DistortedNode(DistortedNode node, int flags)
292
    {
293
    mEffects      = new DistortedEffects(node.mEffects,flags);
294
    mMesh         = node.mMesh;
295
    mState        = new InternalRenderState();
296
    mParent       = null;
297
    mRenderWayOIT = false;
298

    
299
    mFboW            = node.mFboW;
300
    mFboH            = node.mFboH;
301
    mFboDepthStencil = node.mFboDepthStencil;
302

    
303
    if( (flags & DistortedLibrary.CLONE_SURFACE) != 0 )
304
      {
305
      mSurface = node.mSurface;
306
      }
307
    else
308
      {
309
      int w = node.mSurface.getWidth();
310
      int h = node.mSurface.getHeight();
311

    
312
      if( node.mSurface instanceof DistortedTexture )
313
        {
314
        mSurface = new DistortedTexture(w,h, InternalSurface.TYPE_TREE);
315
        }
316
      else if( node.mSurface instanceof DistortedFramebuffer )
317
        {
318
        int depthStencil = DistortedFramebuffer.NO_DEPTH_NO_STENCIL;
319

    
320
        if( ((DistortedFramebuffer) node.mSurface).hasDepth() )
321
          {
322
          boolean hasStencil = ((DistortedFramebuffer) node.mSurface).hasStencil();
323
          depthStencil = (hasStencil ? DistortedFramebuffer.BOTH_DEPTH_STENCIL:DistortedFramebuffer.DEPTH_NO_STENCIL);
324
          }
325

    
326
        mSurface = new DistortedFramebuffer(1,depthStencil, InternalSurface.TYPE_TREE,w,h);
327
        }
328
      }
329

    
330
    if( (flags & DistortedLibrary.CLONE_CHILDREN) != 0 )
331
      {
332
      mChildren = node.mChildren;
333
      }
334
    else
335
      {
336
      mChildren = new InternalChildrenList(this);
337
      }
338

    
339
    mData = InternalNodeData.returnData(generateIDList());
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
  /**
344
   * When rendering this Node, should we use the Order Independent Transparency render more?
345
   * <p>
346
   * There are two modes of rendering: the fast 'normal' way, which however renders transparent
347
   * fragments in different ways depending on which fragments get rendered first, or the slower
348
   * 'oit' way, which renders transparent fragments correctly regardless of their order.
349
   *
350
   * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
351
   */
352
  public void setOrderIndependentTransparency(boolean oit)
353
    {
354
    mRenderWayOIT = oit;
355
    }
356

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

    
377
    if( initialSize>0.0f && initialSize<10.0f )
378
      DistortedLibrary.setSSBOSize(initialSize);
379
    }
380

    
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382
/**
383
 * Adds a new child to the last position in the list of our Node's children.
384
 * <p>
385
 * We cannot do this mid-render - actual attachment will be done just before the next render, by the
386
 * InternalMaster (by calling doWork())
387
 *
388
 * @param node The new Node to add.
389
 */
390
  public void attach(DistortedNode node)
391
    {
392
    mChildren.attach(node);
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
 * InternalMaster (by calling doWork())
401
 *
402
 * @param surface InputSurface to initialize our child Node with.
403
 * @param effects DistortedEffects to initialize our child Node with.
404
 * @param mesh MeshBase to initialize our child Node with.
405
 * @return the newly constructed child Node, or null if we couldn't allocate resources.
406
 */
407
  public DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
408
    {
409
    return mChildren.attach(surface,effects,mesh);
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413
/**
414
 * Removes the first occurrence of a specified child from the list of children of our Node.
415
 * <p>
416
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
417
 * InternalMaster (by calling doWork())
418
 *
419
 * @param node The Node to remove.
420
 */
421
  public void detach(DistortedNode node)
422
    {
423
    mChildren.detach(node);
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427
/**
428
 * Removes the first occurrence of a specified child from the list of children of our Node.
429
 * <p>
430
 * A bit questionable method as there can be many different Nodes attached as children, some
431
 * of them having the same Effects but - for instance - different Mesh. Use with care.
432
 * <p>
433
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
434
 * InternalMaster (by calling doWork())
435
 *
436
 * @param effects DistortedEffects to remove.
437
 */
438
  public void detach(DistortedEffects effects)
439
    {
440
    mChildren.detach(effects);
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444
/**
445
 * Removes all children Nodes.
446
 * <p>
447
 * We cannot do this mid-render - actual detachment will be done just before the next render, by the
448
 * InternalMaster (by calling doWork())
449
 */
450
  public void detachAll()
451
    {
452
    mChildren.detachAll();
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456
/**
457
 * Returns the DistortedEffects object that's in the Node.
458
 * 
459
 * @return The DistortedEffects contained in the Node.
460
 */
461
  public DistortedEffects getEffects()
462
    {
463
    return mEffects;
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467
/**
468
 * Returns the InternalSurface object that's in the Node.
469
 *
470
 * @return The InternalSurface contained in the Node.
471
 */
472
  public InternalSurface getSurface()
473
    {
474
    return mSurface;
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478
  /**
479
   * Returns the InternalSurface object that's in the Node.
480
   *
481
   * @return The InternalSurface contained in the Node (if a leaf), or the FBO (if an internal Node)
482
   */
483
  public InternalSurface getInternalSurface()
484
    {
485
    return mChildren.getNumChildren()==0 ? mSurface : mData.mFBO;
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489
/**
490
 * Returns the Mesh object that's in the Node.
491
 *
492
 * @return Mesh contained in the Node.
493
 */
494
  public MeshBase getMesh()
495
    {
496
    return mMesh;
497
    }
498

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500
/**
501
 * Resizes the DistortedFramebuffer object that we render this Node to.
502
 */
503
  public void resize(int width, int height)
504
    {
505
    mFboW = width;
506
    mFboH = height;
507

    
508
    if ( mData.mFBO !=null )
509
      {
510
      // TODO: potentially allocate a new NodeData if we have to
511
      mData.mFBO.resize(width,height);
512
      }
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516
/**
517
 * Enables/disables DEPTH and STENCIL buffers in the Framebuffer object that we render this Node to.
518
 */
519
  public void enableDepthStencil(int depthStencil)
520
    {
521
    mFboDepthStencil = depthStencil;
522

    
523
    if ( mData.mFBO !=null )
524
      {
525
      // TODO: potentially allocate a new NodeData if we have to
526
      mData.mFBO.enableDepthStencil(depthStencil);
527
      }
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531
// APIs that control how to set the OpenGL state just before rendering this Node.
532
///////////////////////////////////////////////////////////////////////////////////////////////////
533
/**
534
 * When rendering this Node, use ColorMask (r,g,b,a).
535
 *
536
 * @param r Write to the RED color channel when rendering this Node?
537
 * @param g Write to the GREEN color channel when rendering this Node?
538
 * @param b Write to the BLUE color channel when rendering this Node?
539
 * @param a Write to the ALPHA channel when rendering this Node?
540
 */
541
  @SuppressWarnings("unused")
542
  public void glColorMask(boolean r, boolean g, boolean b, boolean a)
543
    {
544
    mState.glColorMask(r,g,b,a);
545
    }
546

    
547
///////////////////////////////////////////////////////////////////////////////////////////////////
548
/**
549
 * When rendering this Node, switch on writing to Depth buffer?
550
 *
551
 * @param mask Write to the Depth buffer when rendering this Node?
552
 */
553
  @SuppressWarnings("unused")
554
  public void glDepthMask(boolean mask)
555
    {
556
    mState.glDepthMask(mask);
557
    }
558

    
559
///////////////////////////////////////////////////////////////////////////////////////////////////
560
/**
561
 * When rendering this Node, which bits of the Stencil buffer to write to?
562
 *
563
 * @param mask Marks the bits of the Stencil buffer we will write to when rendering this Node.
564
 */
565
  @SuppressWarnings("unused")
566
  public void glStencilMask(int mask)
567
    {
568
    mState.glStencilMask(mask);
569
    }
570

    
571
///////////////////////////////////////////////////////////////////////////////////////////////////
572
/**
573
 * When rendering this Node, which Tests to enable?
574
 *
575
 * @param test Valid values: GL_DEPTH_TEST, GL_STENCIL_TEST, GL_BLEND
576
 */
577
  @SuppressWarnings("unused")
578
  public void glEnable(int test)
579
    {
580
    mState.glEnable(test);
581
    }
582

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

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596
/**
597
 * When rendering this Node, use the following StencilFunc.
598
 *
599
 * @param func Valid values: GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL
600
 * @param ref  Reference valut to compare our stencil with.
601
 * @param mask Mask used when comparing.
602
 */
603
  @SuppressWarnings("unused")
604
  public void glStencilFunc(int func, int ref, int mask)
605
    {
606
    mState.glStencilFunc(func,ref,mask);
607
    }
608

    
609
///////////////////////////////////////////////////////////////////////////////////////////////////
610
/**
611
 * When rendering this Node, use the following StencilOp.
612
 * <p>
613
 * Valid values of all 3 parameters: GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP
614
 *
615
 * @param sfail  What to do when Stencil Test fails.
616
 * @param dpfail What to do when Depth Test fails.
617
 * @param dppass What to do when Depth Test passes.
618
 */
619
  @SuppressWarnings("unused")
620
  public void glStencilOp(int sfail, int dpfail, int dppass)
621
    {
622
    mState.glStencilOp(sfail,dpfail,dppass);
623
    }
624

    
625
///////////////////////////////////////////////////////////////////////////////////////////////////
626
/**
627
 * When rendering this Node, use the following DepthFunc.
628
 *
629
 * @param func Valid values: GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL
630
 */
631
  @SuppressWarnings("unused")
632
  public void glDepthFunc(int func)
633
    {
634
    mState.glDepthFunc(func);
635
    }
636

    
637
///////////////////////////////////////////////////////////////////////////////////////////////////
638
/**
639
 * When rendering this Node, use the following Blending mode.
640
 * <p>
641
 * Valid values: GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
642
 *               GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR,
643
 *               GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE
644
 *
645
 * @param src Source Blend function
646
 * @param dst Destination Blend function
647
 */
648
  @SuppressWarnings("unused")
649
  public void glBlendFunc(int src, int dst)
650
    {
651
    mState.glBlendFunc(src,dst);
652
    }
653

    
654
///////////////////////////////////////////////////////////////////////////////////////////////////
655
/**
656
 * Before rendering this Node, clear the following buffers.
657
 * <p>
658
 * Valid values: 0, or bitwise OR of one or more values from the set GL_COLOR_BUFFER_BIT,
659
 *               GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
660
 * Default: 0
661
 *
662
 * @param mask bitwise OR of BUFFER_BITs to clear.
663
 */
664
  @SuppressWarnings("unused")
665
  public void glClear(int mask)
666
    {
667
    mState.glClear(mask);
668
    }
669
  }
(4-4/14)