Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedRenderState.java @ 1d6d261e

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 switchOffDepthWriting()
149
    {
150
    if( cState.depthMask!=0 )
151
      {
152
      sState.depthMask = cState.depthMask;
153
      cState.depthMask = 0;
154
      GLES30.glDepthMask(false);
155
      }
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  static void restoreDepthWriting()
161
    {
162
    if( sState.depthMask!=cState.depthMask )
163
      {
164
      cState.depthMask = sState.depthMask;
165
      GLES30.glDepthMask(cState.depthMask==1);
166
      }
167
    }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

    
171
  static void switchOffDrawing()
172
    {
173
    GLES30.glEnable(GLES30.GL_SCISSOR_TEST);
174
    GLES30.glScissor(0,0,0,0);
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  static void restoreDrawing()
180
    {
181
    GLES30.glDisable(GLES30.GL_SCISSOR_TEST);
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
  static void setUpStencilMark()
187
    {
188
    if( cState.stencilTest!=1 )
189
      {
190
      sState.stencilTest = cState.stencilTest;
191
      cState.stencilTest = 1;
192
      //android.util.Log.d("State", "stencil test on");
193
      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
194
      }
195
    if( cState.stencilFuncFunc!=GLES30.GL_ALWAYS || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
196
      {
197
      sState.stencilFuncFunc = cState.stencilFuncFunc;
198
      sState.stencilFuncRef  = cState.stencilFuncRef;
199
      sState.stencilFuncMask = cState.stencilFuncMask;
200
      cState.stencilFuncFunc = GLES30.GL_ALWAYS;
201
      cState.stencilFuncRef  = 1;
202
      cState.stencilFuncMask = STENCIL_MASK;
203
      //android.util.Log.d("State", "stencil func on");
204
      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
205
      }
206
    if( cState.stencilOpSfail!=GLES30.GL_KEEP || cState.stencilOpDpfail!=GLES30.GL_KEEP || cState.stencilOpDppass!=GLES30.GL_REPLACE )
207
      {
208
      sState.stencilOpSfail = cState.stencilOpSfail;
209
      sState.stencilOpDpfail= cState.stencilOpDpfail;
210
      sState.stencilOpDppass= cState.stencilOpDppass;
211
      cState.stencilOpSfail = GLES30.GL_KEEP;
212
      cState.stencilOpDpfail= GLES30.GL_KEEP;
213
      cState.stencilOpDppass= GLES30.GL_REPLACE;
214
      //android.util.Log.d("State", "stencil op on");
215
      GLES30.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
216
      }
217
    if( cState.colorMaskR!=0 || cState.colorMaskG!=0 || cState.colorMaskB!=0 || cState.colorMaskA!=0 )
218
      {
219
      sState.colorMaskR = cState.colorMaskR;
220
      sState.colorMaskG = cState.colorMaskG;
221
      sState.colorMaskB = cState.colorMaskB;
222
      sState.colorMaskA = cState.colorMaskA;
223
      cState.colorMaskR = 0;
224
      cState.colorMaskG = 0;
225
      cState.colorMaskB = 0;
226
      cState.colorMaskA = 0;
227
      //android.util.Log.d("State", "switch off color writing");
228
      GLES30.glColorMask(false,false,false,false);
229
      }
230
    if( cState.depthMask!=1 )
231
      {
232
      sState.depthMask = cState.depthMask;
233
      cState.depthMask = 1;
234
      //android.util.Log.d("State", "switch on depth writing");
235
      GLES30.glDepthMask(true);
236
      }
237
    if( cState.stencilMask!= STENCIL_MASK )
238
      {
239
      sState.stencilMask = cState.stencilMask;
240
      cState.stencilMask = STENCIL_MASK;
241
      //android.util.Log.d("State", "stencil mask on");
242
      GLES30.glStencilMask(cState.stencilMask);
243
      }
244
    }
245

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

    
248
  static void unsetUpStencilMark()
249
    {
250
    if( sState.stencilTest!=cState.stencilTest )
251
      {
252
      cState.stencilTest = sState.stencilTest;
253

    
254
      if (cState.stencilTest == 0)
255
        {
256
        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
257
        }
258
      else
259
        {
260
        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
261
        }
262
      }
263
    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
264
      {
265
      cState.colorMaskR = sState.colorMaskR;
266
      cState.colorMaskG = sState.colorMaskG;
267
      cState.colorMaskB = sState.colorMaskB;
268
      cState.colorMaskA = sState.colorMaskA;
269
      GLES30.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
270
      }
271
    if( sState.depthMask!=cState.depthMask )
272
      {
273
      cState.depthMask = sState.depthMask;
274
      GLES30.glDepthMask(cState.depthMask==1);
275
      }
276
    if( sState.stencilMask!=cState.stencilMask )
277
      {
278
      cState.stencilMask = sState.stencilMask;
279
      GLES30.glStencilMask(cState.stencilMask);
280
      }
281
    }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
  static void useStencilMark()
286
    {
287
    if( cState.stencilTest!=1 )
288
      {
289
      sState.stencilTest = cState.stencilTest;
290
      cState.stencilTest = 1;
291
      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
292
      }
293
    if( cState.stencilFuncFunc!=GLES30.GL_EQUAL || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
294
      {
295
      sState.stencilFuncFunc = cState.stencilFuncFunc;
296
      sState.stencilFuncRef  = cState.stencilFuncRef;
297
      sState.stencilFuncMask = cState.stencilFuncMask;
298
      cState.stencilFuncFunc = GLES30.GL_EQUAL;
299
      cState.stencilFuncRef  = 1;
300
      cState.stencilFuncMask = STENCIL_MASK;
301
      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
302
      }
303

    
304
    // TODO: Debatable
305
    if( cState.stencilMask!= 0x00 )
306
      {
307
      sState.stencilMask = cState.stencilMask;
308
      cState.stencilMask = 0x00;
309
      GLES30.glStencilMask(cState.stencilMask);
310
      }
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  static void unuseStencilMark()
316
    {
317
    if( sState.stencilTest!=cState.stencilTest )
318
      {
319
      cState.stencilTest = sState.stencilTest;
320

    
321
      if (cState.stencilTest == 0)
322
        {
323
        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
324
        }
325
      else
326
        {
327
        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
328
        }
329
      }
330

    
331
    if( sState.stencilFuncFunc!=cState.stencilFuncFunc || sState.stencilFuncRef!=cState.stencilFuncRef || sState.stencilFuncMask!=cState.stencilFuncMask )
332
      {
333
      cState.stencilFuncFunc = sState.stencilFuncFunc;
334
      cState.stencilFuncRef  = sState.stencilFuncRef ;
335
      cState.stencilFuncMask = sState.stencilFuncMask;
336
      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
337
      }
338

    
339
    if( sState.stencilMask!=cState.stencilMask )
340
      {
341
      cState.stencilMask = sState.stencilMask;
342
      GLES30.glStencilMask(cState.stencilMask);
343
      }
344
    }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
  void apply()
349
    {
350
    //android.util.Log.e("State", "APPLYING STATE");
351

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

    
364
    /////////////////////////////////////////////////////
365
    // 2. Enable Depth test?
366
    if( mState.depthTest!=cState.depthTest )
367
      {
368
      cState.depthTest = mState.depthTest;
369

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

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

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

    
400
    /////////////////////////////////////////////////////
401
    // 5. Enable Blending?
402
    if( mState.blend!=cState.blend )
403
      {
404
      cState.blend = mState.blend;
405

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

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

    
428
    /////////////////////////////////////////////////////
429
    // 7. Enable/Disable Stencil Test?
430
    if( mState.stencilTest!=cState.stencilTest )
431
      {
432
      cState.stencilTest = mState.stencilTest;
433

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

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

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

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

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

    
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

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

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  void glDepthMask(boolean mask)
499
    {
500
    mState.depthMask = (mask ? 1:0);
501
    }
502

    
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504

    
505
  void glStencilMask(int mask)
506
    {
507
    mState.stencilMask = mask;
508
    }
509

    
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511

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

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

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

    
528
///////////////////////////////////////////////////////////////////////////////////////////////////
529

    
530
  void glStencilFunc(int func, int ref, int mask)
531
    {
532
    mState.stencilFuncFunc = func;
533
    mState.stencilFuncRef  = ref;
534
    mState.stencilFuncMask = mask;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  void glStencilOp(int sfail, int dpfail, int dppass)
540
    {
541
    mState.stencilOpSfail = sfail;
542
    mState.stencilOpDpfail= dpfail;
543
    mState.stencilOpDppass= dppass;
544
    }
545

    
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547

    
548
  void glDepthFunc(int func)
549
    {
550
    mState.depthFunc = func;
551
    }
552

    
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

    
555
  void glBlendFunc(int src, int dst)
556
    {
557
    mState.blendSrc = src;
558
    mState.blendDst = dst;
559
    }
560

    
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562

    
563
  void glClear(int mask)
564
    {
565
    mClear = mask;
566
    }
567
}
(10-10/26)