Project

General

Profile

« Previous | Next » 

Revision 040cd18c

Added by Leszek Koltunski almost 6 years ago

Port all the 'non-controversial' changes from order-independent-transparency branch.

View differences:

src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
144 144
    {
145 145
    if( mProgram1 ==null)
146 146
      {
147
      mProgram1 = mPrograms.get(mIndex1);
148
      mProgram2 = mPrograms.get(mIndex2);
147
      try
148
        {
149
        mProgram1 = mPrograms.get(mIndex1);
150
        mProgram2 = mPrograms.get(mIndex2);
151
        }
152
      catch(Exception ex)
153
        {
154
        return 0;
155
        }
149 156
      }
150 157

  
151 158
    DistortedRenderState.useStencilMark();
src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
148 148
    {
149 149
    if( mProgram1 ==null)
150 150
      {
151
      mProgram1 = mPrograms.get(mIndex1);
152
      mProgram2 = mPrograms.get(mIndex2);
151
      try
152
        {
153
        mProgram1 = mPrograms.get(mIndex1);
154
        mProgram2 = mPrograms.get(mIndex2);
155
        }
156
      catch(Exception ex)
157
        {
158
        return 0;
159
        }
153 160
      }
154 161

  
155 162
    DistortedRenderState.useStencilMark();
src/main/java/org/distorted/library/main/Distorted.java
28 28
import org.distorted.library.effect.FragmentEffect;
29 29
import org.distorted.library.effect.PostprocessEffect;
30 30
import org.distorted.library.effect.VertexEffect;
31
import org.distorted.library.program.*;
32 31

  
33 32
///////////////////////////////////////////////////////////////////////////////////////////////////
34 33
/**
......
106 105
 * Needs to be called from a thread holding the OpenGL context.
107 106
 *   
108 107
 * @param context Context of the App using the library - used to open up Resources and read Shader code.
109
 * @throws FragmentCompilationException Fragment Shader failed to compile
110
 * @throws VertexCompilationException   Vertex Shader failed to compile
111
 * @throws VertexUniformsException      Too many uniforms in the Vertex Shader
112
 * @throws FragmentUniformsException    Too many uniforms in the Fragment Shader
113
 * @throws LinkingException             Shader failed to link
114 108
 */
115 109
  public static void onCreate(final Context context)
116
  throws FragmentCompilationException,VertexCompilationException,VertexUniformsException,FragmentUniformsException,LinkingException
117 110
    {
118 111
    final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
119 112
    final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
120 113
    android.util.Log.e("DISTORTED", "Using OpenGL ES "+configurationInfo.getGlEsVersion());
121 114

  
122
    GLSL = ( (configurationInfo.reqGlEsVersion>>16)>=3 ? 300 : 100 );
123
    GLSL_VERSION= (GLSL==100 ? "#version 100\n" : "#version 300 es\n");
115
    GLSL = ( (configurationInfo.reqGlEsVersion>>16)>=3 ? 310 : 100 );
116
    GLSL_VERSION= (GLSL==100 ? "#version 100\n" : "#version 310 es\n");
124 117

  
125 118
    EffectMessageSender.startSending();
126 119

  
......
133 126

  
134 127
///////////////////////////////////////////////////////////////////////////////////////////////////
135 128
/**
136
 * Call this so that the Library can release its internal data structures.
129
 * Call this so that the Library can mark OpenGL objects that would need to be recreated when we
130
 * get resumed.
137 131
 * Must be called from Activity.onPause().
138 132
 */
139 133
  public static void onPause()
......
162 156

  
163 157
    mInitialized = false;
164 158
    }
165

  
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
/**
168
 * Return 2 or 3 depending if we have OpenGL Es 2.0 or 3.x context created.
169
 */
170
  public static int getGlVersion()
171
    {
172
    return GLSL == 300 ? 3:2;
173
    }
174 159
  }
src/main/java/org/distorted/library/main/DistortedEffects.java
31 31
import org.distorted.library.effect.VertexEffect;
32 32
import org.distorted.library.message.EffectListener;
33 33
import org.distorted.library.program.DistortedProgram;
34
import org.distorted.library.program.FragmentCompilationException;
35
import org.distorted.library.program.FragmentUniformsException;
36
import org.distorted.library.program.LinkingException;
37
import org.distorted.library.program.VertexCompilationException;
38
import org.distorted.library.program.VertexUniformsException;
39 34

  
40 35
import java.io.InputStream;
41 36
import java.nio.ByteBuffer;
......
92 87
///////////////////////////////////////////////////////////////////////////////////////////////////
93 88

  
94 89
  static void createProgram(Resources resources)
95
  throws FragmentCompilationException,VertexCompilationException,VertexUniformsException,FragmentUniformsException,LinkingException
96 90
    {
97 91
    // MAIN PROGRAM ////////////////////////////////////
98 92
    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
......
113 107

  
114 108
    String[] feedback = { "v_Position", "v_endPosition" };
115 109

  
116
    mMainProgram = new DistortedProgram( mainVertStream, mainFragStream, mainVertHeader, mainFragHeader,
117
                                         enabledEffectV, enabledEffectF, Distorted.GLSL, feedback);
110
    try
111
      {
112
      mMainProgram = new DistortedProgram(mainVertStream, mainFragStream, mainVertHeader, mainFragHeader,
113
                                          enabledEffectV, enabledEffectF, Distorted.GLSL, feedback);
114
      }
115
    catch(Exception e)
116
      {
117
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile MAIN program: "+e.getMessage());
118
      throw new RuntimeException(e.getMessage());
119
      }
118 120

  
119 121
    int mainProgramH = mMainProgram.getProgramHandle();
120 122
    EffectQueueFragment.getUniforms(mainProgramH);
......
135 137
      }
136 138
    catch(Exception e)
137 139
      {
138
      Log.e("EFFECTS", "exception trying to compile BLIT program: "+e.getMessage());
140
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT program: "+e.getMessage());
139 141
      throw new RuntimeException(e.getMessage());
140 142
      }
141 143

  
......
153 155
      }
154 156
    catch(Exception e)
155 157
      {
156
      Log.e("EFFECTS", "exception trying to compile BLIT DEPTH program: "+e.getMessage());
158
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT DEPTH program: "+e.getMessage());
157 159
      throw new RuntimeException(e.getMessage());
158 160
      }
159 161

  
......
173 175
      }
174 176
    catch(Exception e)
175 177
      {
176
      Log.e("EFFECTS", "exception trying to compile NORMAL program: "+e.getMessage());
178
      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile NORMAL program: "+e.getMessage());
177 179
      throw new RuntimeException(e.getMessage());
178 180
      }
179 181

  
......
284 286
    mMainProgram.useProgram();
285 287
    GLES31.glUniform1i(mMainTextureH, 0);
286 288

  
287
    if( Distorted.GLSL >= 300 )
288
      {
289
      GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
290
      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
291
      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
292
      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
293
      GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
294
      }
295
    else
296
      {
297
      mesh.mVertAttribs.position(0);
298
      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
299
      mesh.mVertAttribs.position(MeshObject.POS_DATA_SIZE);
300
      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
301
      mesh.mVertAttribs.position(MeshObject.POS_DATA_SIZE+MeshObject.NOR_DATA_SIZE);
302
      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
303
      }
289
    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
290
    GLES31.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
291
    GLES31.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
292
    GLES31.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
293
    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
304 294

  
305 295
    mM.send(surface,halfW,halfH,halfZ,marginInPixels);
306 296
    mV.send();
src/main/java/org/distorted/library/main/DistortedFramebuffer.java
31 31
public class DistortedFramebuffer extends DistortedOutputSurface implements DistortedInputSurface
32 32
  {
33 33

  
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

  
36
  void prepareDebug(long time) {}
37
  void renderDebug(long time)  {}
38

  
39 34
///////////////////////////////////////////////////////////////////////////////////////////////////
40 35
// Must be called from a thread holding OpenGL Context
41 36

  
......
201 196
    super(width,height,NOT_CREATED_YET,numcolors,depthStencil,NOT_CREATED_YET,TYPE_USER);
202 197
    }
203 198

  
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

  
206
/**
207
 * Create new offscreen Framebuffer with COLOR0 attachment only.
208
 *
209
 * @param width Width of the COLOR0 attachment.
210
 * @param height Height of the COLOR0 attachment.
211
 */
212
  @SuppressWarnings("unused")
213
  public DistortedFramebuffer(int width, int height)
214
    {
215
    super(width,height,NOT_CREATED_YET, 1, NO_DEPTH_NO_STENCIL,NOT_CREATED_YET,TYPE_USER);
216
    }
217

  
218 199
///////////////////////////////////////////////////////////////////////////////////////////////////
219 200
/**
220 201
 * Bind the underlying rectangle of pixels as a OpenGL Texture.
src/main/java/org/distorted/library/main/DistortedMaster.java
96 96
    }
97 97

  
98 98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
// can make this logarithmic but the typical number of children is very small anyway
99
// Can make this logarithmic but the typical number of children is very small anyway.
100
//
101
// We want to keep same buckets next to each other, while avoiding changes in order of the children
102
// (if possible!) We want to keep bucket=0 (i.e. the non-postprocessed children) at the beginning.
100 103

  
101
  static void addSorted(ArrayList<DistortedNode> mChildren, DistortedNode newChild)
104
  static void addSortingByBuckets(ArrayList<DistortedNode> mChildren, DistortedNode newChild)
102 105
    {
103 106
    int i,num = mChildren.size();
104 107
    long bucket = newChild.getPostprocessQueue().getID();
108
    boolean sameBucket = false;
105 109

  
106 110
    for(i=0; i<num; i++)
107 111
      {
108
      if( mChildren.get(i).getPostprocessQueue().getID() > bucket ) break;
112
      if( mChildren.get(i).getPostprocessQueue().getID() == bucket )
113
        {
114
        sameBucket=true;
115
        }
116
      else if( sameBucket || bucket==0 )
117
        {
118
        break;
119
        }
109 120
      }
110 121

  
111 122
    mChildren.add(i,newChild);
src/main/java/org/distorted/library/main/DistortedNode.java
228 228
    if( mNumChildren[0]==0 && newData.mFBO!=null )
229 229
      {
230 230
      newData.mFBO.markForDeletion();
231
      android.util.Log.d("NODE", "ERROR!! this NodeData cannot possibly contain a non-null FBO!! "+newData.mFBO.getID() );
231
      android.util.Log.e("NODE", "ERROR!! this NodeData cannot possibly contain a non-null FBO!! "+newData.mFBO.getID() );
232 232
      newData.mFBO = null;
233 233
      }
234 234

  
......
283 283

  
284 284
    if( input.setAsInput() )
285 285
      {
286
      surface.setAsOutput(currTime);
287 286
      mState.apply();
288 287
      GLES31.glDisable(GLES31.GL_BLEND);
289 288
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime, 0);
......
303 302

  
304 303
    if( input.setAsInput() )
305 304
      {
306
      surface.setAsOutput(currTime);
307 305
      mState.apply();
308 306
      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime, 0);
309 307
      return 1;
......
364 362
    if( mParent!=null )
365 363
      {
366 364
      mParent.mChildren.remove(this);
367
      DistortedMaster.addSorted(mParent.mChildren,this);
365
      DistortedMaster.addSortingByBuckets(mParent.mChildren,this);
368 366
      }
369 367
    else if( mSurfaceParent!=null )
370 368
      {
371 369
      ArrayList<DistortedNode> children = mSurfaceParent.getChildren();
372 370
      children.remove(this);
373
      DistortedMaster.addSorted(children,this);
371
      DistortedMaster.addSortingByBuckets(children,this);
374 372
      }
375 373
    }
376 374

  
......
651 649
                     if( mChildren==null ) mChildren = new ArrayList<>(2);
652 650
                     job.node.mParent = this;
653 651
                     job.node.mSurfaceParent = null;
654
                     DistortedMaster.addSorted(mChildren,job.node);
652
                     DistortedMaster.addSortingByBuckets(mChildren,job.node);
655 653
                     mNumChildren[0]++;
656 654
                     break;
657 655
        case DETACH: numChanges++;
......
678 676
                       }
679 677
                     break;
680 678
        case SORT  : mChildren.remove(job.node);
681
                     DistortedMaster.addSorted(mChildren,job.node);
679
                     DistortedMaster.addSortingByBuckets(mChildren,job.node);
682 680
                     break;
683 681
        }
684 682
      }
src/main/java/org/distorted/library/main/DistortedObject.java
119 119
    DistortedObject object;
120 120
    int num = mDoneList.size();
121 121

  
122
    for(int i=0; i<num; i++)
122
    try
123
      {
124
      for (int i = 0; i < num; i++)
125
        {
126
        object = mDoneList.removeFirst();
127
        mToDoMap.put(object.mID, object.new Job(object, JOB_CREATE));
128
        object.recreate();
129
        }
130
      }
131
    catch( Exception ex )
123 132
      {
124
      object = mDoneList.removeFirst();
125
      mToDoMap.put(object.mID, object.new Job(object,JOB_CREATE) );
126
      object.recreate();
133
      // something else removed an object in the meantime; ignore
127 134
      }
128 135

  
129 136
    mToDo = true;
src/main/java/org/distorted/library/main/DistortedObjectCounter.java
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 java.util.ArrayList;
23

  
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25
/**
26
 * Return unique IDs of objects in a lazy way. When we create a new Object, return the lowest unused
27
 * integer. When an objects gets deleted, its ID then gets marked unused. We do not try to 'collapse'
28
 * unused holes.
29
 */
30
class DistortedObjectCounter
31
  {
32
  private ArrayList<Integer> mUsed;
33
  private int mFirstUnused;
34

  
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

  
37
  DistortedObjectCounter()
38
    {
39
    mUsed        = new ArrayList<>();
40
    mFirstUnused = 0;
41
    }
42

  
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

  
45
  int returnNext()
46
    {
47
    int size = mUsed.size();
48

  
49
    if( mFirstUnused<size )
50
      {
51
      int ret = mFirstUnused;
52

  
53
      mUsed.set(mFirstUnused,1);
54

  
55
      int found=-1;
56

  
57
      for(int i=mFirstUnused+1; i<size; i++ )
58
        {
59
        if( mUsed.get(i)==0 )
60
          {
61
          found = i;
62
          break;
63
          }
64
        }
65

  
66
      mFirstUnused = found<0 ? size : found;
67

  
68
      return ret;
69
      }
70

  
71
    mUsed.add(1);
72
    mFirstUnused++;
73

  
74
    return size;
75
    }
76

  
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

  
79
  void release(int objID)
80
    {
81
    int size = mUsed.size();
82

  
83
    if( objID<size && objID>=0 && mUsed.get(objID)==1 )
84
      {
85
      mUsed.set(objID,0);
86
      if( objID<mFirstUnused ) mFirstUnused = objID;
87
      }
88
    }
89

  
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91

  
92
  void releaseAll()
93
    {
94
    mUsed.clear();
95
    mFirstUnused = 0;
96
    }
97
  }
src/main/java/org/distorted/library/main/DistortedOutputSurface.java
34 34
 */
35 35
public abstract class DistortedOutputSurface extends DistortedSurface implements DistortedMaster.Slave
36 36
{
37
//////////// DEBUG FLAGS /////////////////////////////////////////////
38
/**
39
 * When rendering a Screen, show FPS in the upper-left corner?
40
 */
41
public static final int DEBUG_FPS = 1;
42
//////////// END DEBUG FLAGS /////////////////////////////////////////
43

  
44 37
/**
45 38
 * Do not create DEPTH or STENCIL attachment
46 39
 */
......
77 70
  private ArrayList<Job> mJobs = new ArrayList<>();
78 71

  
79 72
  // Global buffers used for postprocessing.
80
  private static DistortedOutputSurface[] mBuffer = new DistortedOutputSurface[EffectQuality.LENGTH];
73
  private static DistortedOutputSurface[] mBuffer = null;
81 74

  
82 75
  private long mTime;
83 76
  private float mFOV;
......
95 88
  private int mClear;
96 89
  float mMipmap;
97 90

  
98
  private int mDebugLevel;
99

  
100 91
  int mRealWidth;   // the Surface can be backed up with a texture that is
101 92
  int mRealHeight;  // larger than the viewport we have to it.
102 93
                    // mWidth,mHeight are the sizes of the Viewport, those -
103 94
                    // sizes of the backing up texture.
104 95

  
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

  
107
  abstract void prepareDebug(long time);
108
  abstract void renderDebug(long time);
109

  
110 96
///////////////////////////////////////////////////////////////////////////////////////////////////
111 97

  
112 98
  DistortedOutputSurface(int width, int height, int createColor, int numcolors, int depthStencil, int fbo, int type)
......
128 114
    mDepthStencilH[0]= 0;
129 115

  
130 116
    mTime = 0;
131
    mDebugLevel = 0;
132 117

  
133 118
    mClearR = 0.0f;
134 119
    mClearG = 0.0f;
......
184 169

  
185 170
///////////////////////////////////////////////////////////////////////////////////////////////////
186 171

  
187
  private static void createBuffers(int width, int height, float near)
172
  private static void createPostprocessingBuffers(int width, int height, float near)
188 173
    {
174
    mBuffer = new DistortedOutputSurface[EffectQuality.LENGTH];
189 175
    float mipmap=1.0f;
190 176

  
191 177
    for(int j=0; j<EffectQuality.LENGTH; j++)
......
221 207

  
222 208
  static synchronized void onDestroy()
223 209
    {
224
    for(int j=0; j<EffectQuality.LENGTH; j++)
210
    if( mBuffer!=null )
225 211
      {
226
      mBuffer[j] = null;
212
      for (int i=0; i<EffectQuality.LENGTH; i++)
213
        {
214
        mBuffer[i] = null;
215
        }
216

  
217
      mBuffer = null;
227 218
      }
228 219
    }
229 220

  
230 221
///////////////////////////////////////////////////////////////////////////////////////////////////
231 222
// The postprocessing buffers mBuffer[] are generally speaking too large (there's just one static
232
// set of them) so before we use them for output, we need to adjust the Vieport as if they were
223
// set of them) so before we use them for output, we need to adjust the Viewport as if they were
233 224
// smaller. That takes care of outputting pixels to them. When we use them as input, we have to
234 225
// adjust the texture coords - see the get{Width|Height}Correction functions.
235 226

  
236
  private static void cloneViewport(DistortedOutputSurface from)
227
  private static void clonePostprocessingViewport(DistortedOutputSurface from)
237 228
    {
238
    if( mBuffer[0].mWidth != from.mWidth )
229
    if( mBuffer[0].mWidth != from.mWidth || mBuffer[0].mHeight != from.mHeight )
239 230
      {
240 231
      DistortedOutputSurface surface;
241 232

  
......
304 295
    return 1;
305 296
    }
306 297

  
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

  
300
  void clear()
301
    {
302
    DistortedRenderState.colorDepthStencilOn();
303
    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
304
    GLES31.glClearDepthf(mClearDepth);
305
    GLES31.glClearStencil(mClearStencil);
306
    GLES31.glClear(mClear);
307
    DistortedRenderState.colorDepthStencilRestore();
308
    }
309

  
307 310
///////////////////////////////////////////////////////////////////////////////////////////////////
308 311
// Render all children, one by one. If there are no postprocessing effects, just render to THIS.
309 312
// Otherwise, render to a buffer and on each change of Postprocessing Bucket, apply the postprocessing
......
322 325
      currQueue = child1.getPostprocessQueue();
323 326
      currBucket= currQueue.getID();
324 327

  
325
      if( currBucket==0 ) numRenders += child1.draw(time,this);
328
      if( currBucket==0 )
329
        {
330
        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
331
        numRenders += child1.draw(time,this);
332
        }
326 333
      else
327 334
        {
328
        if( mBuffer[0]==null ) createBuffers(mWidth,mHeight,mNear);
335
        if( mBuffer==null ) createPostprocessingBuffers(mWidth,mHeight,mNear);
329 336

  
330 337
        if( lastBucket!=currBucket )
331 338
          {
332
          if( lastBucket!=0 )
339
          if( lastBucket==0 )
340
            {
341
            clonePostprocessingViewport(this);
342
            }
343
          else
333 344
            {
334 345
            for(int j=bucketChange; j<i; j++)
335 346
              {
......
346 357
          internalQuality = currQueue.getInternalQuality();
347 358
          quality         = currQueue.getQuality();
348 359
          bucketChange    = i;
349

  
350
          cloneViewport(this);
351 360
          }
352 361

  
362
        mBuffer[quality].setAsOutput(time);
353 363
        child1.drawNoBlend(time,mBuffer[quality]);
354 364

  
355 365
        if( i==numChildren-1 )
......
363 373
          numRenders += currQueue.postprocess(mBuffer);
364 374
          numRenders += blitWithDepth(time, mBuffer[quality]);
365 375
          }
366
        }
376
        } // end postprocessed child case
367 377

  
368 378
      lastQueue = currQueue;
369 379
      lastBucket= currBucket;
370
      }
380
      } // end main for loop
371 381

  
372 382
    return numRenders;
373 383
    }
......
423 433
///////////////////////////////////////////////////////////////////////////////////////////////////
424 434
// PUBLIC API
425 435
///////////////////////////////////////////////////////////////////////////////////////////////////
426
/**
427
 * Make the library show various debugging information.
428
 * <p>
429
 * Currently only DEBUG_FPS - show FPS in the upper-left corner of every Screen - is defined.
430
 *
431
 * @param bitmask 0, or a bitmask of DEBUG_** flags to enable (currently only DEBUG_FPS defined)
432
 */
433
  public void setDebug(int bitmask)
434
    {
435
    if( this instanceof DistortedScreen )
436
      mDebugLevel = bitmask;
437
    }
438

  
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440 436

  
441 437
/**
442 438
 * Draws all the attached children to this OutputSurface.
......
448 444
 */
449 445
  public int render(long time)
450 446
    {
451
    if( mDebugLevel!=0 ) prepareDebug(time);
452

  
453 447
    // change tree topology (attach and detach children)
454 448
/*
455 449
    boolean changed1 =
......
494 488
    setAsOutput(time);
495 489
    numRenders += renderChildren(time,mNumChildren,mChildren);
496 490

  
497
    if( mDebugLevel != 0 ) renderDebug(time);
498

  
499 491
    return numRenders;
500 492
    }
501 493

  
......
515 507
    if( mTime!=time )
516 508
      {
517 509
      mTime = time;
518
      DistortedRenderState.colorDepthStencilOn();
519
      GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
520
      GLES31.glClearDepthf(mClearDepth);
521
      GLES31.glClearStencil(mClearStencil);
522
      GLES31.glClear(mClear);
523
      DistortedRenderState.colorDepthStencilRestore();
524
/*
525
      if( mSSBO[0]>=0 )
526
        {
527
        // yes, this DOES keep on working when 'value' overflows into negative territory.
528
        int value = mIntBuffer.get(FRAME_DELAY*mSurfaceID+mLastIndex);
529

  
530
        if( value-mLastValue[mLastIndex]!=mLastDiff )
531
          {
532
          android.util.Log.d("surface", "id " + mSurfaceID +
533
                             (mType == TYPE_USER ? " USER" : (mType == TYPE_SYST ? " SYST" : " TREE")) +
534
                             " viewport: (" + mWidth + "x" + mHeight + ") last frame: " + (value - mLastValue[mLastIndex])
535
                             + " avg: " + (mAvgSum/RUNNING_AVERAGE)
536
                            );
537
          }
538

  
539
        mLastDiff = value-mLastValue[mLastIndex];
540
        mLastValue[mLastIndex] = value;
541

  
542
        mAvgSum += (mLastDiff-mRunningAvg[mAvgIndex]);
543
        mRunningAvg[mAvgIndex] = mLastDiff;
544
        if( ++mAvgIndex>=RUNNING_AVERAGE ) mAvgIndex =0;
545
        }
546

  
547
      if( ++mLastIndex >= FRAME_DELAY ) mLastIndex=0;
548
*/
510
      clear();
549 511
      }
550 512
    }
551 513

  
......
683 645
      mNear=0.99f;
684 646
      }
685 647

  
686
    if( mBuffer[0]!=null )
648
    if( mBuffer!=null )
687 649
      {
688 650
      for(int j=0; j<EffectQuality.LENGTH; j++) mBuffer[j].mNear = mNear;
689 651
      }
......
874 836
        {
875 837
        case ATTACH: if( mChildren==null ) mChildren = new ArrayList<>(2);
876 838
                     job.node.setSurfaceParent(this);
877
                     DistortedMaster.addSorted(mChildren,job.node);
839
                     DistortedMaster.addSortingByBuckets(mChildren,job.node);
878 840
                     mNumChildren++;
879 841
                     break;
880 842
        case DETACH: if( mNumChildren>0 && mChildren.remove(job.node) )
......
897 859
                       }
898 860
                     break;
899 861
        case SORT  : mChildren.remove(job.node);
900
                     DistortedMaster.addSorted(mChildren,job.node);
862
                     DistortedMaster.addSortingByBuckets(mChildren,job.node);
901 863
                     break;
902 864
        }
903 865
      }
src/main/java/org/distorted/library/main/DistortedScreen.java
1 1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
2
// Copyright 2018 Leszek Koltunski                                                               //
3 3
//                                                                                               //
4 4
// This file is part of Distorted.                                                               //
5 5
//                                                                                               //
......
34 34
 * <p>
35 35
 * User is able to render to it just like to a DistortedFramebuffer.
36 36
 */
37
public class DistortedScreen extends DistortedOutputSurface
37
public class DistortedScreen extends DistortedFramebuffer
38 38
  {
39 39
  ///// DEBUGGING ONLY /////////////////////////
40
  private boolean mShowFPS;
41

  
40 42
  private static final int NUM_FRAMES  = 100;
41 43

  
42 44
  private MeshObject fpsMesh;
......
46 48
  private Bitmap fpsBitmap;
47 49
  private Paint mPaint;
48 50
  private int fpsH, fpsW;
49
  private String fpsString = "";
51
  private String fpsString;
50 52
  private long lastTime=0;
51 53
  private long[] durations;
52 54
  private int currDuration;
53 55
  private static MatrixEffectMove mMoveEffect = new MatrixEffectMove( new Static3D(5,5,0) );
54
  private boolean mInitialized;
56
  ///// END DEBUGGING //////////////////////////
55 57

  
56 58
///////////////////////////////////////////////////////////////////////////////////////////////////
57
// here we don't manage underlying OpenGL assets ourselves
58

  
59
  void create()   {}
60
  void delete()   {}
61
  void recreate() {}
59
// PUBLIC API
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61
/**
62
 * Create a new Screen. Initially 1x1 in size.
63
 * <p>
64
 * Has to be followed by a 'resize()' to set the size.
65
 */
66
  public DistortedScreen()
67
    {
68
    super(1,1,1,BOTH_DEPTH_STENCIL);
69
    mShowFPS = false;
70
    }
62 71

  
63 72
///////////////////////////////////////////////////////////////////////////////////////////////////
73
/**
74
 * Draws all the attached children to this OutputSurface.
75
 * <p>
76
 * Must be called from a thread holding OpenGL Context.
77
 *
78
 * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
79
 * @return Number of objects rendered.
80
 */
81
  public int render(long time)
82
    {
83
    if( mShowFPS )
84
      {
85
      if( lastTime==0 ) lastTime = time;
64 86

  
65
  private void initialize()
87
      currDuration++;
88
      if (currDuration >= NUM_FRAMES) currDuration = 0;
89
      durations[NUM_FRAMES] += ((time - lastTime) - durations[currDuration]);
90
      durations[currDuration] = time - lastTime;
91

  
92
      fpsString = "" + ((int)(10000.0f*NUM_FRAMES/durations[NUM_FRAMES]))/10.0f;
93

  
94
      mPaint.setColor(0xffffffff);
95
      fpsCanvas.drawRect(0, 0, fpsW, fpsH, mPaint);
96
      mPaint.setColor(0xff000000);
97
      fpsCanvas.drawText(fpsString, fpsW/2, 0.75f*fpsH, mPaint);
98
      fpsTexture.setTexture(fpsBitmap);
99

  
100
      lastTime = time;
101
      }
102

  
103
    int numrender = super.render(time);
104

  
105
    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
106
    clear();
107
    setAsInput();
108
    GLES31.glColorMask(true,true,true,true);
109
    GLES31.glDepthMask(false);
110
    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
111
    GLES31.glDisable(GLES31.GL_DEPTH_TEST);
112
    GLES31.glDisable(GLES31.GL_BLEND);
113

  
114
    DistortedEffects.blitPriv(this);
115

  
116
    if( mShowFPS && fpsTexture.setAsInput())
117
      {
118
      fpsEffects.drawPriv(fpsW / 2.0f, fpsH / 2.0f, fpsMesh, this, time, 0);
119
      }
120

  
121
    return numrender+1;
122
    }
123

  
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125
/**
126
 * Make the library show Frames Per Second in the upper-left corner.
127
 * <p>
128
 */
129
  public void showFPS()
66 130
    {
131
    mShowFPS = true;
132

  
67 133
    fpsW = 120;
68 134
    fpsH =  70;
69 135

  
136
    fpsString = "";
70 137
    fpsBitmap = Bitmap.createBitmap(fpsW,fpsH, Bitmap.Config.ARGB_8888);
71 138
    fpsMesh = new MeshFlat(1,1);
72 139
    fpsTexture = new DistortedTexture(fpsW,fpsH);
......
85 152

  
86 153
    for(int i=0; i<NUM_FRAMES+1; i++) durations[i]=16;  // Assume FPS will be
87 154
    durations[NUM_FRAMES] = NUM_FRAMES*16;              // close to 1000/16 ~ 60
88
    mInitialized=true;
89
    }
90

  
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

  
93
  void prepareDebug(long time)
94
    {
95
    if( !mInitialized ) initialize();
96

  
97
    if( lastTime==0 ) lastTime = time;
98

  
99
    currDuration++;
100
    if (currDuration >= NUM_FRAMES) currDuration = 0;
101
    durations[NUM_FRAMES] += ((time - lastTime) - durations[currDuration]);
102
    durations[currDuration] = time - lastTime;
103

  
104
    fpsString = "" + ((int)(10000.0f*NUM_FRAMES/durations[NUM_FRAMES]))/10.0f;
105

  
106
    mPaint.setColor(0xffffffff);
107
    fpsCanvas.drawRect(0, 0, fpsW, fpsH, mPaint);
108
    mPaint.setColor(0xff000000);
109
    fpsCanvas.drawText(fpsString, fpsW/2, 0.75f*fpsH, mPaint);
110
    fpsTexture.setTexture(fpsBitmap);
111

  
112
    lastTime = time;
113
    }
114

  
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

  
117
  void renderDebug(long time)
118
    {
119
    if (fpsTexture.setAsInput())
120
      {
121
      setAsOutput(time);
122
      GLES31.glColorMask(true,true,true,true);
123
      GLES31.glDepthMask(false);
124
      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
125
      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
126
      fpsEffects.drawPriv(fpsW/2.0f, fpsH/2.0f, fpsMesh, this, time, 0);
127
      }
128
    }
129

  
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131
// PUBLIC API
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
/**
134
 * Create a new Screen.
135
 * <p>
136
 * Has to be followed by a 'resize()' to set the size.
137
 */
138
  public DistortedScreen()
139
    {
140
    // Screen also has to be created (3rd arg 'NOT_CREATED_YET') because of the SSBO inside OutputSurface.
141
    super(0,0,NOT_CREATED_YET,1,DEPTH_NO_STENCIL,0,TYPE_USER);
142

  
143
    mInitialized = false;
144 155
    }
145
  }
156
  }
src/main/java/org/distorted/library/main/EffectQueuePostprocess.java
32 32
  private static final int NUM_UNIFORMS = PostprocessEffect.NUM_UNIFORMS;
33 33
  private static final int INDEX = EffectType.POSTPROCESS.ordinal();
34 34

  
35

  
36 35
  private int mHalo;
37 36

  
38 37
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/program/DistortedProgram.java
443 443
 * Create a new Shader Program from two source strings.
444 444
 * <p>
445 445
 * Needs to be called from a thread holding the OpenGL context.
446
 * Assumed to hold GLSL 'version 300 es' source.
447 446
 *
448 447
 * @param vertex   Vertex shader code.
449 448
 * @param fragment Fragment shader code.
src/main/res/raw/blit_depth_fragment_shader.glsl
17 17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
18 18
//////////////////////////////////////////////////////////////////////////////////////////////
19 19

  
20
precision lowp float;
20
precision highp float;
21 21

  
22
#if __VERSION__ != 100
23 22
out vec4 fragColor;           // The output color
24 23
in vec2 v_TexCoordinate;      // Interpolated texture coordinate per fragment.
25
#define TEXTURE texture
26
#define FRAG_COLOR fragColor
27
#else
28
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
29
#define TEXTURE texture2D
30
#define FRAG_COLOR gl_FragColor
31
#endif
32 24

  
33 25
uniform sampler2D u_Texture;
34 26
uniform sampler2D u_DepthTexture;
......
37 29

  
38 30
void main()                    		
39 31
  {
40
  gl_FragDepth = TEXTURE(u_DepthTexture,v_TexCoordinate).r;
41
  FRAG_COLOR   = TEXTURE(u_Texture     ,v_TexCoordinate);
32
  gl_FragDepth = texture(u_DepthTexture,v_TexCoordinate).r;
33
  fragColor    = texture(u_Texture     ,v_TexCoordinate);
42 34
  }
src/main/res/raw/blit_depth_vertex_shader.glsl
17 17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
18 18
//////////////////////////////////////////////////////////////////////////////////////////////
19 19

  
20
precision lowp float;
20
precision highp float;
21 21

  
22
#if __VERSION__ != 100
23 22
in vec2 a_Position;           // Per-vertex position.
24 23
out vec2 v_TexCoordinate;     //
25
#else
26
attribute vec2 a_Position;    // Per-vertex position.
27
varying vec2 v_TexCoordinate; //
28
#endif
29 24

  
30 25
uniform float u_Depth;        // distance from the near plane to render plane, in clip coords
31 26
uniform vec2  u_TexCorr;      // when we blit from postprocessing buffers, the buffers can be
src/main/res/raw/blit_fragment_shader.glsl
19 19

  
20 20
precision lowp float;
21 21

  
22
#if __VERSION__ != 100
23 22
out vec4 fragColor;           // The output color
24 23
in vec2 v_TexCoordinate;      // Interpolated texture coordinate per fragment.
25
#define TEXTURE texture
26
#define FRAG_COLOR fragColor
27
#else
28
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
29
#define TEXTURE texture2D
30
#define FRAG_COLOR gl_FragColor
31
#endif
32

  
33 24
uniform sampler2D u_Texture;  // The input texture.
34 25

  
35 26
//////////////////////////////////////////////////////////////////////////////////////////////
36 27

  
37 28
void main()                    		
38 29
  {
39
  FRAG_COLOR = TEXTURE(u_Texture,v_TexCoordinate);
30
  fragColor = texture(u_Texture,v_TexCoordinate);
40 31
  }
src/main/res/raw/blit_vertex_shader.glsl
19 19

  
20 20
precision lowp float;
21 21

  
22
#if __VERSION__ != 100
23 22
in vec2 a_Position;           // Per-vertex position.
24 23
out vec2 v_TexCoordinate;     //
25
#else
26
attribute vec2 a_Position;    // Per-vertex position.
27
varying vec2 v_TexCoordinate; //
28
#endif
29

  
30 24
uniform float u_Depth;        // distance from the near plane to render plane, in clip coords
31 25

  
32 26
//////////////////////////////////////////////////////////////////////////////////////////////
src/main/res/raw/normal_fragment_shader.glsl
19 19

  
20 20
precision lowp float;
21 21

  
22
#if __VERSION__ != 100
23 22
out vec4 fragColor;
24
#define FRAG_COLOR fragColor
25
#else
26
#define FRAG_COLOR gl_FragColor
27
#endif
28 23

  
29 24
//////////////////////////////////////////////////////////////////////////////////////////////
30 25

  
31 26
void main()
32 27
  {
33
  FRAG_COLOR = vec4(1.0,0.0,0.0,1.0);
28
  fragColor = vec4(1.0,0.0,0.0,1.0);
34 29
  }
src/main/res/raw/normal_vertex_shader.glsl
19 19

  
20 20
precision lowp float;
21 21

  
22
#if __VERSION__ != 100
23 22
in vec3 a_Position;
24
#else
25
attribute vec3 a_Position;
26
#endif
27

  
28 23
uniform mat4 u_MVPMatrix;
29 24

  
30 25
//////////////////////////////////////////////////////////////////////////////////////////////
31 26

  
32 27
void main()
33 28
  {
34
  gl_Position = u_MVPMatrix*vec4( a_Position, 1.0);
29
  gl_Position = u_MVPMatrix * vec4(a_Position, 1.0);
35 30
  }

Also available in: Unified diff