Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedRenderState.java @ 270c27bc

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 int sColorMaskR, sColorMaskG, sColorMaskB, sColorMaskA;   //
37
  private static int sDepthMask;                                           //
38
  private static int sStencilMask;                                         //
39
  private static int sDepthTest;                                           //
40
  private static int sStencilTest;                                         //
41
  private static int sStencilFuncFunc, sStencilFuncRef, sStencilFuncMask;  // current OpenGL state
42
  private static int sStencilOpSfail, sStencilOpDpfail, sStencilOpDppass;  //
43
  private static int sDepthFunc;                                           //
44
  private static int sBlend;                                               //
45
  private static int sBlendSrc, sBlendDst;                                 //
46

    
47
  private int mColorMaskR, mColorMaskG, mColorMaskB, mColorMaskA;          //
48
  private int mDepthMask;                                                  //
49
  private int mStencilMask;                                                //
50
  private int mDepthTest;                                                  //
51
  private int mStencilTest;                                                //
52
  private int mStencilFuncFunc, mStencilFuncRef, mStencilFuncMask;         // The state we want to have
53
  private int mStencilOpSfail, mStencilOpDpfail, mStencilOpDppass;         //
54
  private int mDepthFunc;                                                  //
55
  private int mBlend;                                                      //
56
  private int mBlendSrc, mBlendDst;                                        //
57
  private int mClear;                                                      // This does not have a 'static' compatriot
58

    
59
  private static int rStencilTest;                                         //
60
  private static int rStencilFuncFunc;                                     //
61
  private static int rStencilFuncRef;                                      // Remember values of Stencil.
62
  private static int rStencilFuncMask;                                     //
63
  private static int rStencilMask;                                         //
64

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66
// default: color writes on, depth test and writes on, blending on, stencil off.
67

    
68
  DistortedRenderState()
69
    {
70
    mColorMaskR = 1;
71
    mColorMaskG = 1;
72
    mColorMaskB = 1;
73
    mColorMaskA = 1;
74

    
75
    mDepthTest  = 1;
76
    mDepthMask  = 1;
77
    mDepthFunc  = GLES30.GL_LEQUAL;
78

    
79
    mBlend      = 1;
80
    mBlendSrc   = GLES30.GL_SRC_ALPHA;
81
    mBlendDst   = GLES30.GL_ONE_MINUS_SRC_ALPHA;
82

    
83
    mStencilTest     = 0;
84
    mStencilMask     = STENCIL_MASK;
85
    mStencilFuncFunc = GLES30.GL_NEVER;
86
    mStencilFuncRef  = 0;
87
    mStencilFuncMask = STENCIL_MASK;
88
    mStencilOpSfail  = GLES30.GL_KEEP;
89
    mStencilOpDpfail = GLES30.GL_KEEP;
90
    mStencilOpDppass = GLES30.GL_KEEP;
91

    
92
    mClear = 0;
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96
// reset state of everything to 'unknown'
97

    
98
  static void reset()
99
    {
100
    sColorMaskR = -1;
101
    sColorMaskG = -1;
102
    sColorMaskB = -1;
103
    sColorMaskA = -1;
104

    
105
    sDepthTest  = -1;
106
    sDepthMask  = -1;
107
    sDepthFunc  = -1;
108

    
109
    sBlend      = -1;
110
    sBlendSrc   = -1;
111
    sBlendDst   = -1;
112

    
113
    sStencilTest     = -1;
114
    sStencilMask     = -1;
115
    sStencilFuncFunc = -1;
116
    sStencilFuncRef  = -1;
117
    sStencilFuncMask = -1;
118
    sStencilOpSfail  = -1;
119
    sStencilOpDpfail = -1;
120
    sStencilOpDppass = -1;
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

    
125
  static void colorDepthStencilOn()
126
    {
127
    if( sColorMaskR!=1 || sColorMaskG!=1 || sColorMaskB!=1 || sColorMaskA!=1 )
128
      {
129
      sColorMaskR = 1;
130
      sColorMaskG = 1;
131
      sColorMaskB = 1;
132
      sColorMaskA = 1;
133
      GLES30.glColorMask(true,true,true,true);
134
      }
135
    if( sDepthMask!=1 )
136
      {
137
      sDepthMask = 1;
138
      GLES30.glDepthMask(true);
139
      }
140
    if( sStencilMask!= STENCIL_MASK )
141
      {
142
      sStencilMask = STENCIL_MASK;
143
      GLES30.glStencilMask(sStencilMask);
144
      }
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

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

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

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

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

    
164
  static void setUpStencilMark()
165
    {
166
    if( sStencilTest!=1 )
167
      {
168
      sStencilTest = 1;
169
      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
170
      }
171
    if( sStencilFuncFunc!=GLES30.GL_ALWAYS || sStencilFuncRef!=1 || sStencilFuncMask!=STENCIL_MASK )
172
      {
173
      sStencilFuncFunc = GLES30.GL_ALWAYS;
174
      sStencilFuncRef  = 1;
175
      sStencilFuncMask = STENCIL_MASK;
176
      GLES30.glStencilFunc(sStencilFuncFunc,sStencilFuncRef,sStencilFuncMask);
177
      }
178
    if( sStencilOpSfail!=GLES30.GL_KEEP || sStencilOpDpfail!=GLES30.GL_KEEP || sStencilOpDppass!=GLES30.GL_REPLACE )
179
      {
180
      sStencilOpSfail = GLES30.GL_KEEP;
181
      sStencilOpDpfail= GLES30.GL_KEEP;
182
      sStencilOpDppass= GLES30.GL_REPLACE;
183
      GLES30.glStencilOp(sStencilOpSfail,sStencilOpDpfail,sStencilOpDppass);
184
      }
185
    if( sColorMaskR!=0 || sColorMaskG!=0 || sColorMaskB!=0 || sColorMaskA!=0 )
186
      {
187
      sColorMaskR = 0;
188
      sColorMaskG = 0;
189
      sColorMaskB = 0;
190
      sColorMaskA = 0;
191
      GLES30.glColorMask(false,false,false,false);
192
      }
193
    if( sDepthMask!=0 )
194
      {
195
      sDepthMask = 0;
196
      GLES30.glDepthMask(false);
197
      }
198
    if( sStencilMask!= STENCIL_MASK )
199
      {
200
      sStencilMask = STENCIL_MASK;
201
      GLES30.glStencilMask(sStencilMask);
202
      }
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
  static void useStencilMark()
208
    {
209
    if( sStencilTest!=1 )
210
      {
211
      rStencilTest = sStencilTest;
212
      sStencilTest = 1;
213
      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
214
      }
215
    if( sStencilFuncFunc!=GLES30.GL_EQUAL || sStencilFuncRef!=1 || sStencilFuncMask!=STENCIL_MASK )
216
      {
217
      rStencilFuncFunc = sStencilFuncFunc;
218
      rStencilFuncRef  = sStencilFuncRef;
219
      rStencilFuncMask = sStencilFuncMask;
220
      sStencilFuncFunc = GLES30.GL_EQUAL;
221
      sStencilFuncRef  = 1;
222
      sStencilFuncMask = STENCIL_MASK;
223
      GLES30.glStencilFunc(sStencilFuncFunc,sStencilFuncRef,sStencilFuncMask);
224
      }
225

    
226
    // TODO: Debatable
227
    if( sStencilMask!= 0x00 )
228
      {
229
      rStencilMask = sStencilMask;
230
      sStencilMask = 0x00;
231
      GLES30.glStencilMask(sStencilMask);
232
      }
233
    }
234

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

    
237
  static void restoreStencilMark()
238
    {
239
    if( rStencilTest!=sStencilTest )
240
      {
241
      sStencilTest = rStencilTest;
242

    
243
      if (sStencilTest == 0)
244
        {
245
        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
246
        }
247
      else
248
        {
249
        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
250
        }
251
      }
252

    
253
    if( rStencilFuncFunc!=sStencilFuncFunc || rStencilFuncRef!=sStencilFuncRef || rStencilFuncMask!=sStencilFuncMask )
254
      {
255
      sStencilFuncFunc = rStencilFuncFunc;
256
      sStencilFuncRef  = rStencilFuncRef ;
257
      sStencilFuncMask = rStencilFuncMask;
258
      GLES30.glStencilFunc(sStencilFuncFunc,sStencilFuncRef,sStencilFuncMask);
259
      }
260

    
261
    if( rStencilMask!=sStencilMask )
262
      {
263
      sStencilMask = rStencilMask;
264
      GLES30.glStencilMask(sStencilMask);
265
      }
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  void apply()
271
    {
272
    //android.util.Log.e("State", "APPLYING STATE");
273

    
274
    /////////////////////////////////////////////////////
275
    // 1. Write to color buffer?
276
    if( mColorMaskR!=sColorMaskR || mColorMaskG!=sColorMaskG || mColorMaskB!=sColorMaskB || mColorMaskA!=sColorMaskA)
277
      {
278
      //android.util.Log.d("State", "setting color mask");
279
      sColorMaskR = mColorMaskR;
280
      sColorMaskG = mColorMaskG;
281
      sColorMaskB = mColorMaskB;
282
      sColorMaskA = mColorMaskA;
283
      GLES30.glColorMask(sColorMaskR==1,sColorMaskG==1,sColorMaskB==1,sColorMaskA==1);
284
      }
285

    
286
    /////////////////////////////////////////////////////
287
    // 2. Enable Depth test?
288
    if( mDepthTest!=sDepthTest )
289
      {
290
      sDepthTest = mDepthTest;
291

    
292
      if (sDepthTest == 0)
293
        {
294
        //android.util.Log.d("State", "disabling depth test");
295
        GLES30.glDisable(GLES30.GL_DEPTH_TEST);
296
        }
297
      else
298
        {
299
        //android.util.Log.d("State", "enable depth test");
300
        GLES30.glEnable(GLES30.GL_DEPTH_TEST);
301
        }
302
      }
303

    
304
    /////////////////////////////////////////////////////
305
    // 3. Change Depth Function?
306
    if( mDepthFunc!=sDepthFunc )
307
      {
308
      //android.util.Log.d("State", "setting depth func");
309
      sDepthFunc = mDepthFunc;
310
      GLES30.glDepthFunc(sDepthFunc);
311
      }
312

    
313
    /////////////////////////////////////////////////////
314
    // 4. Write to Depth buffer?
315
    if( mDepthMask!=sDepthMask )
316
      {
317
      //android.util.Log.d("State", "setting depth mask");
318
      sDepthMask = mDepthMask;
319
      GLES30.glDepthMask(sDepthMask==1);
320
      }
321

    
322
    /////////////////////////////////////////////////////
323
    // 5. Enable Blending?
324
    if( mBlend!=sBlend )
325
      {
326
      sBlend = mBlend;
327

    
328
      if (sBlend == 0)
329
        {
330
        //android.util.Log.d("State", "disabling blending");
331
        GLES30.glDisable(GLES30.GL_BLEND);
332
        }
333
      else
334
        {
335
        //android.util.Log.d("State", "enabling blending");
336
        GLES30.glEnable(GLES30.GL_BLEND);
337
        }
338
      }
339

    
340
    /////////////////////////////////////////////////////
341
    // 6. Change Blend function?
342
    if( mBlendSrc!=sBlendSrc || mBlendDst!=sBlendDst )
343
      {
344
      //android.util.Log.d("State", "setting blend function");
345
      sBlendSrc = mBlendSrc;
346
      sBlendDst = mBlendDst;
347
      GLES30.glBlendFunc(sBlendSrc,sBlendDst);
348
      }
349

    
350
    /////////////////////////////////////////////////////
351
    // 7. Enable/Disable Stencil Test?
352
    if( mStencilTest!=sStencilTest )
353
      {
354
      sStencilTest = mStencilTest;
355

    
356
      if (sStencilTest == 0)
357
        {
358
        //android.util.Log.d("State", "disabling stencil test");
359
        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
360
        }
361
      else
362
        {
363
        //android.util.Log.d("State", "enabling stencil test");
364
        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
365
        }
366
      }
367

    
368
    /////////////////////////////////////////////////////
369
    // 8. Adjust Stencil function?
370
    if( mStencilFuncFunc!=sStencilFuncFunc || mStencilFuncRef!=sStencilFuncRef || mStencilFuncMask!=sStencilFuncMask )
371
      {
372
      //android.util.Log.d("State", "setting stencil function");
373
      sStencilFuncFunc = mStencilFuncFunc;
374
      sStencilFuncRef  = mStencilFuncRef ;
375
      sStencilFuncMask = mStencilFuncMask;
376
      GLES30.glStencilFunc(sStencilFuncFunc,sStencilFuncRef,sStencilFuncMask);
377
      }
378

    
379
    /////////////////////////////////////////////////////
380
    // 9. Adjust Stencil operation?
381
    if( mStencilOpSfail!=sStencilOpSfail || mStencilOpDpfail!=sStencilOpDpfail || mStencilOpDppass!=sStencilOpDppass )
382
      {
383
      //android.util.Log.d("State", "setting stencil op");
384
      sStencilOpSfail = mStencilOpSfail;
385
      sStencilOpDpfail= mStencilOpDpfail;
386
      sStencilOpDppass= mStencilOpDppass;
387
      GLES30.glStencilOp(sStencilOpSfail,sStencilOpDpfail,sStencilOpDppass);
388
      }
389

    
390
    /////////////////////////////////////////////////////
391
    // 10. Write to Stencil buffer?
392
    if( mStencilMask!=sStencilMask )
393
      {
394
      //android.util.Log.d("State", "setting stencil mask");
395
      sStencilMask = mStencilMask;
396
      GLES30.glStencilMask(sStencilMask);
397
      }
398

    
399
    /////////////////////////////////////////////////////
400
    // 11. Clear buffers?
401
    if( mClear!=0 )
402
      {
403
      //android.util.Log.d("State", "clearing buffer");
404
      GLES30.glClear(mClear);
405
      }
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  void glColorMask(boolean r, boolean g, boolean b, boolean a)
411
    {
412
    mColorMaskR = (r ? 1:0);
413
    mColorMaskG = (g ? 1:0);
414
    mColorMaskB = (b ? 1:0);
415
    mColorMaskA = (a ? 1:0);
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  void glDepthMask(boolean mask)
421
    {
422
    mDepthMask = (mask ? 1:0);
423
    }
424

    
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426

    
427
  void glStencilMask(int mask)
428
    {
429
    mStencilMask = mask;
430
    }
431

    
432
///////////////////////////////////////////////////////////////////////////////////////////////////
433

    
434
  void glEnable(int test)
435
    {
436
         if( test==GLES30.GL_DEPTH_TEST   ) mDepthTest   = 1;
437
    else if( test==GLES30.GL_STENCIL_TEST ) mStencilTest = 1;
438
    else if( test==GLES30.GL_BLEND        ) mBlend       = 1;
439
    }
440

    
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442

    
443
  void glDisable(int test)
444
    {
445
         if( test==GLES30.GL_DEPTH_TEST   ) mDepthTest   = 0;
446
    else if( test==GLES30.GL_STENCIL_TEST ) mStencilTest = 0;
447
    else if( test==GLES30.GL_BLEND        ) mBlend       = 0;
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  void glStencilFunc(int func, int ref, int mask)
453
    {
454
    mStencilFuncFunc = func;
455
    mStencilFuncRef  = ref;
456
    mStencilFuncMask = mask;
457
    }
458

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

    
461
  void glStencilOp(int sfail, int dpfail, int dppass)
462
    {
463
    mStencilOpSfail = sfail;
464
    mStencilOpDpfail= dpfail;
465
    mStencilOpDppass= dppass;
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469

    
470
  void glDepthFunc(int func)
471
    {
472
    mDepthFunc = func;
473
    }
474

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476

    
477
  void glBlendFunc(int src, int dst)
478
    {
479
    mBlendSrc = src;
480
    mBlendDst = dst;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  void glClear(int mask)
486
    {
487
    mClear = mask;
488
    }
489
}
(10-10/26)