Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedRenderState.java @ 81f0078a

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.library;
21

    
22
import android.opengl.GLES30;
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25
/**
26
 * Remember the OpenGL state.
27
 * <p>
28
 * This is a member of DistortedNode. Remembers the OpenGL state we want to set just before rendering
29
 * the Node.
30
 */
31
class DistortedRenderState
32
{
33
  // TODO: figure this out dynamically; this assumes 8 bit stencil buffer.
34
  private static final int STENCIL_MASK = (1<<8)-1;
35

    
36
  private static class RenderState
37
    {
38
    private int colorMaskR, colorMaskG, colorMaskB, colorMaskA;
39
    private int depthMask;
40
    private int stencilMask;
41
    private int depthTest;
42
    private int stencilTest;
43
    private int stencilFuncFunc, stencilFuncRef, stencilFuncMask;
44
    private int stencilOpSfail, stencilOpDpfail, stencilOpDppass;
45
    private int depthFunc;
46
    private int blend;
47
    private int blendSrc, blendDst;
48
    }
49

    
50
  private RenderState mState;          // state the current object wants to have
51
  static private RenderState cState = new RenderState();   // current OpenGL Stave
52
  static private RenderState sState = new RenderState();   // saved OpenGL state
53

    
54
  private int mClear;
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
// default: color writes on, depth test and writes on, blending on, stencil off.
58

    
59
  DistortedRenderState()
60
    {
61
    mState = new RenderState();
62

    
63
    mState.colorMaskR = 1;
64
    mState.colorMaskG = 1;
65
    mState.colorMaskB = 1;
66
    mState.colorMaskA = 1;
67

    
68
    mState.depthTest  = 1;
69
    mState.depthMask  = 1;
70
    mState.depthFunc  = GLES30.GL_LEQUAL;
71

    
72
    mState.blend      = 1;
73
    mState.blendSrc   = GLES30.GL_SRC_ALPHA;
74
    mState.blendDst   = GLES30.GL_ONE_MINUS_SRC_ALPHA;
75

    
76
    mState.stencilTest     = 0;
77
    mState.stencilMask     = STENCIL_MASK;
78
    mState.stencilFuncFunc = GLES30.GL_NEVER;
79
    mState.stencilFuncRef  = 0;
80
    mState.stencilFuncMask = STENCIL_MASK;
81
    mState.stencilOpSfail  = GLES30.GL_KEEP;
82
    mState.stencilOpDpfail = GLES30.GL_KEEP;
83
    mState.stencilOpDppass = GLES30.GL_KEEP;
84

    
85
    mClear = 0;
86
    }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
// reset state of everything to 'unknown'
90

    
91
  static void reset()
92
    {
93
    cState.colorMaskR = -1;
94
    cState.colorMaskG = -1;
95
    cState.colorMaskB = -1;
96
    cState.colorMaskA = -1;
97

    
98
    cState.depthTest  = -1;
99
    cState.depthMask  = -1;
100
    cState.depthFunc  = -1;
101

    
102
    cState.blend      = -1;
103
    cState.blendSrc   = -1;
104
    cState.blendDst   = -1;
105

    
106
    cState.stencilTest     = -1;
107
    cState.stencilMask     = -1;
108
    cState.stencilFuncFunc = -1;
109
    cState.stencilFuncRef  = -1;
110
    cState.stencilFuncMask = -1;
111
    cState.stencilOpSfail  = -1;
112
    cState.stencilOpDpfail = -1;
113
    cState.stencilOpDppass = -1;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  static void colorDepthStencilOn()
119
    {
120
    if( cState.colorMaskR!=1 || cState.colorMaskG!=1 || cState.colorMaskB!=1 || cState.colorMaskA!=1 )
121
      {
122
      sState.colorMaskR = cState.colorMaskR;
123
      sState.colorMaskG = cState.colorMaskG;
124
      sState.colorMaskB = cState.colorMaskB;
125
      sState.colorMaskA = cState.colorMaskA;
126
      cState.colorMaskR = 1;
127
      cState.colorMaskG = 1;
128
      cState.colorMaskB = 1;
129
      cState.colorMaskA = 1;
130
      GLES30.glColorMask(true,true,true,true);
131
      }
132
    if( cState.depthMask!=1 )
133
      {
134
      sState.depthMask = cState.depthMask;
135
      cState.depthMask = 1;
136
      GLES30.glDepthMask(true);
137
      }
138
    if( cState.stencilMask!= STENCIL_MASK )
139
      {
140
      sState.stencilMask = cState.stencilMask;
141
      cState.stencilMask = STENCIL_MASK;
142
      GLES30.glStencilMask(cState.stencilMask);
143
      }
144
    }
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  static void switchOffDrawing()
149
    {
150
    GLES30.glEnable(GLES30.GL_SCISSOR_TEST);
151
    GLES30.glScissor(0,0,0,0);
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  static void restoreDrawing()
157
    {
158
    GLES30.glDisable(GLES30.GL_SCISSOR_TEST);
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

    
163
  static void setUpStencilMark()
164
    {
165
    if( cState.stencilTest!=1 )
166
      {
167
      sState.stencilTest = cState.stencilTest;
168
      cState.stencilTest = 1;
169
      //android.util.Log.d("State", "stencil test on");
170
      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
171
      }
172
    if( cState.stencilFuncFunc!=GLES30.GL_ALWAYS || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
173
      {
174
      sState.stencilFuncFunc = cState.stencilFuncFunc;
175
      sState.stencilFuncRef  = cState.stencilFuncRef;
176
      sState.stencilFuncMask = cState.stencilFuncMask;
177
      cState.stencilFuncFunc = GLES30.GL_ALWAYS;
178
      cState.stencilFuncRef  = 1;
179
      cState.stencilFuncMask = STENCIL_MASK;
180
      //android.util.Log.d("State", "stencil func on");
181
      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
182
      }
183
    if( cState.stencilOpSfail!=GLES30.GL_KEEP || cState.stencilOpDpfail!=GLES30.GL_KEEP || cState.stencilOpDppass!=GLES30.GL_REPLACE )
184
      {
185
      sState.stencilOpSfail = cState.stencilOpSfail;
186
      sState.stencilOpDpfail= cState.stencilOpDpfail;
187
      sState.stencilOpDppass= cState.stencilOpDppass;
188
      cState.stencilOpSfail = GLES30.GL_KEEP;
189
      cState.stencilOpDpfail= GLES30.GL_KEEP;
190
      cState.stencilOpDppass= GLES30.GL_REPLACE;
191
      //android.util.Log.d("State", "stencil op on");
192
      GLES30.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
193
      }
194
    if( cState.colorMaskR!=0 || cState.colorMaskG!=0 || cState.colorMaskB!=0 || cState.colorMaskA!=0 )
195
      {
196
      sState.colorMaskR = cState.colorMaskR;
197
      sState.colorMaskG = cState.colorMaskG;
198
      sState.colorMaskB = cState.colorMaskB;
199
      sState.colorMaskA = cState.colorMaskA;
200
      cState.colorMaskR = 0;
201
      cState.colorMaskG = 0;
202
      cState.colorMaskB = 0;
203
      cState.colorMaskA = 0;
204
      //android.util.Log.d("State", "switch off color writing");
205
      GLES30.glColorMask(false,false,false,false);
206
      }
207
    if( cState.depthMask!=1 )
208
      {
209
      sState.depthMask = cState.depthMask;
210
      cState.depthMask = 1;
211
      //android.util.Log.d("State", "switch on depth writing");
212
      GLES30.glDepthMask(true);
213
      }
214
    if( cState.stencilMask!= STENCIL_MASK )
215
      {
216
      sState.stencilMask = cState.stencilMask;
217
      cState.stencilMask = STENCIL_MASK;
218
      //android.util.Log.d("State", "stencil mask on");
219
      GLES30.glStencilMask(cState.stencilMask);
220
      }
221
    }
222

    
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

    
225
  static void unsetUpStencilMark()
226
    {
227
    if( sState.stencilTest!=cState.stencilTest )
228
      {
229
      cState.stencilTest = sState.stencilTest;
230

    
231
      if (cState.stencilTest == 0)
232
        {
233
        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
234
        }
235
      else
236
        {
237
        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
238
        }
239
      }
240
    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
241
      {
242
      cState.colorMaskR = sState.colorMaskR;
243
      cState.colorMaskG = sState.colorMaskG;
244
      cState.colorMaskB = sState.colorMaskB;
245
      cState.colorMaskA = sState.colorMaskA;
246
      GLES30.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
247
      }
248
    if( sState.depthMask!=cState.depthMask )
249
      {
250
      cState.depthMask = sState.depthMask;
251
      GLES30.glDepthMask(cState.depthMask==1);
252
      }
253
    if( sState.stencilMask!=cState.stencilMask )
254
      {
255
      cState.stencilMask = sState.stencilMask;
256
      GLES30.glStencilMask(cState.stencilMask);
257
      }
258
    }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
  static void useStencilMark()
263
    {
264
    if( cState.stencilTest!=1 )
265
      {
266
      sState.stencilTest = cState.stencilTest;
267
      cState.stencilTest = 1;
268
      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
269
      }
270
    if( cState.stencilFuncFunc!=GLES30.GL_EQUAL || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
271
      {
272
      sState.stencilFuncFunc = cState.stencilFuncFunc;
273
      sState.stencilFuncRef  = cState.stencilFuncRef;
274
      sState.stencilFuncMask = cState.stencilFuncMask;
275
      cState.stencilFuncFunc = GLES30.GL_EQUAL;
276
      cState.stencilFuncRef  = 1;
277
      cState.stencilFuncMask = STENCIL_MASK;
278
      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
279
      }
280
    if( cState.stencilMask!= 0x00 )
281
      {
282
      sState.stencilMask = cState.stencilMask;
283
      cState.stencilMask = 0x00;
284
      GLES30.glStencilMask(cState.stencilMask);
285
      }
286
     if( cState.depthMask!=0 )
287
      {
288
      sState.depthMask = cState.depthMask;
289
      cState.depthMask = 0;
290
      GLES30.glDepthMask(false);
291
      }
292
    if( cState.depthTest!=0 )
293
      {
294
      sState.depthTest = cState.depthTest;
295
      cState.depthTest = 0;
296
      GLES30.glDisable(GLES30.GL_DEPTH_TEST);
297
      }
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
  static void unuseStencilMark()
303
    {
304
    if( sState.stencilTest!=cState.stencilTest )
305
      {
306
      cState.stencilTest = sState.stencilTest;
307

    
308
      if (cState.stencilTest == 0)
309
        {
310
        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
311
        }
312
      else
313
        {
314
        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
315
        }
316
      }
317
    if( sState.stencilFuncFunc!=cState.stencilFuncFunc || sState.stencilFuncRef!=cState.stencilFuncRef || sState.stencilFuncMask!=cState.stencilFuncMask )
318
      {
319
      cState.stencilFuncFunc = sState.stencilFuncFunc;
320
      cState.stencilFuncRef  = sState.stencilFuncRef ;
321
      cState.stencilFuncMask = sState.stencilFuncMask;
322
      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
323
      }
324
    if( sState.stencilMask!=cState.stencilMask )
325
      {
326
      cState.stencilMask = sState.stencilMask;
327
      GLES30.glStencilMask(cState.stencilMask);
328
      }
329
    if( sState.depthMask!=cState.depthMask )
330
      {
331
      cState.depthMask = sState.depthMask;
332
      GLES30.glDepthMask(cState.depthMask==1);
333
      }
334
    if( sState.depthTest!=cState.depthTest )
335
      {
336
      cState.depthTest = sState.depthTest;
337

    
338
      if (cState.depthTest == 0)
339
        {
340
        GLES30.glDisable(GLES30.GL_DEPTH_TEST);
341
        }
342
      else
343
        {
344
        GLES30.glEnable(GLES30.GL_DEPTH_TEST);
345
        }
346
      }
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

    
351
  void apply()
352
    {
353
    //android.util.Log.e("State", "APPLYING STATE");
354

    
355
    /////////////////////////////////////////////////////
356
    // 1. Write to color buffer?
357
    if( mState.colorMaskR!=cState.colorMaskR || mState.colorMaskG!=cState.colorMaskG || mState.colorMaskB!=cState.colorMaskB || mState.colorMaskA!=cState.colorMaskA)
358
      {
359
      //android.util.Log.d("State", "setting color mask");
360
      cState.colorMaskR = mState.colorMaskR;
361
      cState.colorMaskG = mState.colorMaskG;
362
      cState.colorMaskB = mState.colorMaskB;
363
      cState.colorMaskA = mState.colorMaskA;
364
      GLES30.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
365
      }
366

    
367
    /////////////////////////////////////////////////////
368
    // 2. Enable Depth test?
369
    if( mState.depthTest!=cState.depthTest )
370
      {
371
      cState.depthTest = mState.depthTest;
372

    
373
      if (cState.depthTest == 0)
374
        {
375
        //android.util.Log.d("State", "disabling depth test");
376
        GLES30.glDisable(GLES30.GL_DEPTH_TEST);
377
        }
378
      else
379
        {
380
        //android.util.Log.d("State", "enable depth test");
381
        GLES30.glEnable(GLES30.GL_DEPTH_TEST);
382
        }
383
      }
384

    
385
    /////////////////////////////////////////////////////
386
    // 3. Change Depth Function?
387
    if( mState.depthFunc!=cState.depthFunc )
388
      {
389
      //android.util.Log.d("State", "setting depth func");
390
      cState.depthFunc = mState.depthFunc;
391
      GLES30.glDepthFunc(cState.depthFunc);
392
      }
393

    
394
    /////////////////////////////////////////////////////
395
    // 4. Write to Depth buffer?
396
    if( mState.depthMask!=cState.depthMask )
397
      {
398
      //android.util.Log.d("State", "setting depth mask");
399
      cState.depthMask = mState.depthMask;
400
      GLES30.glDepthMask(cState.depthMask==1);
401
      }
402

    
403
    /////////////////////////////////////////////////////
404
    // 5. Enable Blending?
405
    if( mState.blend!=cState.blend )
406
      {
407
      cState.blend = mState.blend;
408

    
409
      if (cState.blend == 0)
410
        {
411
        //android.util.Log.d("State", "disabling blending");
412
        GLES30.glDisable(GLES30.GL_BLEND);
413
        }
414
      else
415
        {
416
        //android.util.Log.d("State", "enabling blending");
417
        GLES30.glEnable(GLES30.GL_BLEND);
418
        }
419
      }
420

    
421
    /////////////////////////////////////////////////////
422
    // 6. Change Blend function?
423
    if( mState.blendSrc!=cState.blendSrc || mState.blendDst!=cState.blendDst )
424
      {
425
      //android.util.Log.d("State", "setting blend function");
426
      cState.blendSrc = mState.blendSrc;
427
      cState.blendDst = mState.blendDst;
428
      GLES30.glBlendFunc(cState.blendSrc,cState.blendDst);
429
      }
430

    
431
    /////////////////////////////////////////////////////
432
    // 7. Enable/Disable Stencil Test?
433
    if( mState.stencilTest!=cState.stencilTest )
434
      {
435
      cState.stencilTest = mState.stencilTest;
436

    
437
      if (cState.stencilTest == 0)
438
        {
439
        //android.util.Log.d("State", "disabling stencil test");
440
        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
441
        }
442
      else
443
        {
444
        //android.util.Log.d("State", "enabling stencil test");
445
        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
446
        }
447
      }
448

    
449
    /////////////////////////////////////////////////////
450
    // 8. Adjust Stencil function?
451
    if( mState.stencilFuncFunc!=cState.stencilFuncFunc || mState.stencilFuncRef!=cState.stencilFuncRef || mState.stencilFuncMask!=cState.stencilFuncMask )
452
      {
453
      //android.util.Log.d("State", "setting stencil function");
454
      cState.stencilFuncFunc = mState.stencilFuncFunc;
455
      cState.stencilFuncRef  = mState.stencilFuncRef ;
456
      cState.stencilFuncMask = mState.stencilFuncMask;
457
      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
458
      }
459

    
460
    /////////////////////////////////////////////////////
461
    // 9. Adjust Stencil operation?
462
    if( mState.stencilOpSfail!=cState.stencilOpSfail || mState.stencilOpDpfail!=cState.stencilOpDpfail || mState.stencilOpDppass!=cState.stencilOpDppass )
463
      {
464
      //android.util.Log.d("State", "setting stencil op");
465
      cState.stencilOpSfail = mState.stencilOpSfail;
466
      cState.stencilOpDpfail= mState.stencilOpDpfail;
467
      cState.stencilOpDppass= mState.stencilOpDppass;
468
      GLES30.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
469
      }
470

    
471
    /////////////////////////////////////////////////////
472
    // 10. Write to Stencil buffer?
473
    if( mState.stencilMask!=cState.stencilMask )
474
      {
475
      //android.util.Log.d("State", "setting stencil mask");
476
      cState.stencilMask = mState.stencilMask;
477
      GLES30.glStencilMask(cState.stencilMask);
478
      }
479

    
480
    /////////////////////////////////////////////////////
481
    // 11. Clear buffers?
482
    if( mClear!=0 )
483
      {
484
      //android.util.Log.d("State", "clearing buffer");
485
      GLES30.glClear(mClear);
486
      }
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  void glColorMask(boolean r, boolean g, boolean b, boolean a)
492
    {
493
    mState.colorMaskR = (r ? 1:0);
494
    mState.colorMaskG = (g ? 1:0);
495
    mState.colorMaskB = (b ? 1:0);
496
    mState.colorMaskA = (a ? 1:0);
497
    }
498

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

    
501
  void glDepthMask(boolean mask)
502
    {
503
    mState.depthMask = (mask ? 1:0);
504
    }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
  void glStencilMask(int mask)
509
    {
510
    mState.stencilMask = mask;
511
    }
512

    
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514

    
515
  void glEnable(int test)
516
    {
517
         if( test==GLES30.GL_DEPTH_TEST   ) mState.depthTest   = 1;
518
    else if( test==GLES30.GL_STENCIL_TEST ) mState.stencilTest = 1;
519
    else if( test==GLES30.GL_BLEND        ) mState.blend       = 1;
520
    }
521

    
522
///////////////////////////////////////////////////////////////////////////////////////////////////
523

    
524
  void glDisable(int test)
525
    {
526
         if( test==GLES30.GL_DEPTH_TEST   ) mState.depthTest   = 0;
527
    else if( test==GLES30.GL_STENCIL_TEST ) mState.stencilTest = 0;
528
    else if( test==GLES30.GL_BLEND        ) mState.blend       = 0;
529
    }
530

    
531
///////////////////////////////////////////////////////////////////////////////////////////////////
532

    
533
  void glStencilFunc(int func, int ref, int mask)
534
    {
535
    mState.stencilFuncFunc = func;
536
    mState.stencilFuncRef  = ref;
537
    mState.stencilFuncMask = mask;
538
    }
539

    
540
///////////////////////////////////////////////////////////////////////////////////////////////////
541

    
542
  void glStencilOp(int sfail, int dpfail, int dppass)
543
    {
544
    mState.stencilOpSfail = sfail;
545
    mState.stencilOpDpfail= dpfail;
546
    mState.stencilOpDppass= dppass;
547
    }
548

    
549
///////////////////////////////////////////////////////////////////////////////////////////////////
550

    
551
  void glDepthFunc(int func)
552
    {
553
    mState.depthFunc = func;
554
    }
555

    
556
///////////////////////////////////////////////////////////////////////////////////////////////////
557

    
558
  void glBlendFunc(int src, int dst)
559
    {
560
    mState.blendSrc = src;
561
    mState.blendDst = dst;
562
    }
563

    
564
///////////////////////////////////////////////////////////////////////////////////////////////////
565

    
566
  void glClear(int mask)
567
    {
568
    mClear = mask;
569
    }
570
}
(10-10/26)