Project

General

Profile

« Previous | Next » 

Revision 8c327653

Added by Leszek Koltunski over 7 years ago

First attempt at making it possible to dynamically add and remove DEPTH attachments from an FBO.

View differences:

src/main/java/org/distorted/library/DistortedFramebuffer.java
41 41
 */
42 42
public class DistortedFramebuffer
43 43
  {
44
  private static final int TEXTURE_FAILED_TO_CREATE = -1;
45
  private static final int TEXTURE_NOT_CREATED_YET  = -2;
46
  private static final int TEXTURE_DONT_CREATE      = -3;
44
  private static final int FAILED_TO_CREATE = -1;
45
  private static final int NOT_CREATED_YET  = -2;
46
  private static final int DONT_CREATE      = -3;
47 47

  
48 48
  private static boolean mListMarked = false;
49 49
  private static LinkedList<DistortedFramebuffer> mList = new LinkedList<>();
50 50

  
51
  private int[] texIds = new int[1];
52
  private int[] fboIds = new int[1];
51
  private int[] colorIds = new int[1];
52
  private int[] depthIds = new int[1];
53
  private int[] fboIds   = new int[1];
53 54

  
54 55
  private boolean mMarked;
56
  private boolean mDepthWanted;
55 57

  
56 58
  // Projection stuff
57 59
  private float mX, mY, mFOV;
......
64 66

  
65 67
  boolean createFBO()
66 68
    {
67
    if( texIds[0]==TEXTURE_NOT_CREATED_YET )
69
    if( colorIds[0]==NOT_CREATED_YET )
68 70
      {
69
      GLES20.glGenTextures(1, texIds, 0);
70
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIds[0]);
71
      GLES20.glGenTextures(1, colorIds, 0);
72
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, colorIds[0]);
71 73
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
72 74
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
73 75
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
......
76 78

  
77 79
      GLES20.glGenFramebuffers(1, fboIds, 0);
78 80
      GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
79
      GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texIds[0], 0);
81
      GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, colorIds[0], 0);
80 82

  
81 83
      int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
82 84

  
83 85
      if(status != GLES20.GL_FRAMEBUFFER_COMPLETE)
84 86
        {
85 87
        android.util.Log.e("DistortedFramebuffer", "failed to create framebuffer, error="+status);
86
        GLES20.glDeleteTextures(1, texIds, 0);
88
        GLES20.glDeleteTextures(1, colorIds, 0);
87 89
        GLES20.glDeleteFramebuffers(1, fboIds, 0);
88
        fboIds[0] = 0;
89
        texIds[0] = TEXTURE_FAILED_TO_CREATE;
90
        fboIds[0]   = 0;
91
        colorIds[0] = FAILED_TO_CREATE;
90 92
        return false;
91 93
        }
92 94

  
......
94 96
      //android.util.Log.e("FBO", "created ("+mWidth+","+mHeight+") "+fboIds[0]);
95 97
      }
96 98

  
99
    if(  mDepthWanted && depthIds[0]==NOT_CREATED_YET ) // we need to create a new DEPTH attachment
100
      {
101
      GLES20.glGenTextures(1, depthIds, 0);
102
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, depthIds[0]);
103
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
104
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
105
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
106
      GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
107
      GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_DEPTH_COMPONENT, mWidth, mHeight, 0, GLES20.GL_DEPTH_COMPONENT, GLES20.GL_FLOAT, null);
108

  
109
      GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
110
      GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_TEXTURE_2D, depthIds[0], 0);
111

  
112
      int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
113

  
114
      if(status != GLES20.GL_FRAMEBUFFER_COMPLETE)
115
        {
116
        android.util.Log.e("DistortedFramebuffer", "failed to create depth, error="+status);
117
        GLES20.glDeleteTextures(1, colorIds, 0);
118
        GLES20.glDeleteFramebuffers(1, fboIds, 0);
119
        fboIds[0]   = 0;
120
        depthIds[0] = FAILED_TO_CREATE;
121
        return false;
122
        }
123
      }
124
    if( !mDepthWanted && depthIds[0]!=NOT_CREATED_YET ) // we need to detach and destroy the DEPTH attachment.
125
      {
126
      GLES20.glDeleteTextures(1, depthIds, 0);
127
      depthIds[0]=NOT_CREATED_YET;
128
      }
129

  
97 130
    return true;
98 131
    }
99 132

  
......
102 135

  
103 136
  private void deleteFBO()
104 137
    {
105
    if( texIds[0]>=0 )
138
    if( colorIds[0]>=0 )
106 139
      {
107 140
      //android.util.Log.e("FBO", "deleting ("+mWidth+","+mHeight+") "+fboIds[0]);
108 141

  
109
      GLES20.glDeleteTextures(1, texIds, 0);
110
      GLES20.glDeleteFramebuffers(1, fboIds, 0);
142
      if( depthIds[0]>=0 )
143
        {
144
        GLES20.glDeleteTextures(1, depthIds, 0);
145
        depthIds[0]=NOT_CREATED_YET;
146
        }
147

  
148
      GLES20.glDeleteTextures(1, colorIds, 0);
149
      colorIds[0] = NOT_CREATED_YET;
111 150

  
151
      GLES20.glDeleteFramebuffers(1, fboIds, 0);
112 152
      fboIds[0] = 0;
113
      texIds[0] = TEXTURE_NOT_CREATED_YET;
114 153
      }
115 154

  
116 155
    mMarked = false;
......
120 159

  
121 160
  void reset()
122 161
    {
123
    if( texIds[0]!=TEXTURE_DONT_CREATE)
124
      texIds[0] = TEXTURE_NOT_CREATED_YET;
162
    if( colorIds[0]!=DONT_CREATE )
163
      colorIds[0] = NOT_CREATED_YET;
164

  
165
    if( mDepthWanted ) depthIds[0] = NOT_CREATED_YET;
125 166
    }
126 167

  
127 168
///////////////////////////////////////////////////////////////////////////////////////////////////
......
129 170
  void setAsOutput()
130 171
    {
131 172
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
173

  
174
    if( depthIds[0]!=NOT_CREATED_YET )
175
      {
176
      GLES20.glEnable(GLES20.GL_DEPTH_TEST);
177
      GLES20.glDepthMask(true);
178
      }
179
    else
180
      {
181
      GLES20.glDisable(GLES20.GL_DEPTH_TEST);
182
      GLES20.glDepthMask(false);
183
      }
132 184
    }
133 185

  
134 186
///////////////////////////////////////////////////////////////////////////////////////////////////
135 187

  
136 188
  void setAsInput()
137 189
    {
138
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIds[0]);
190
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, colorIds[0]);
139 191
    }
140 192

  
141 193
///////////////////////////////////////////////////////////////////////////////////////////////////
......
227 279
    {
228 280
    mProjectionMatrix = new float[16];
229 281

  
230
    mHeight  = height;
231
    mWidth   = width;
232
    fboIds[0]= -1;
233
    texIds[0]= TEXTURE_NOT_CREATED_YET;
234
    mFOV     = 60.0f;
235
    mX       = 0.0f;
236
    mY       = 0.0f;
237
    mMarked  = false;
282
    mHeight     = height;
283
    mWidth      = width;
284
    mFOV        = 60.0f;
285
    mX          = 0.0f;
286
    mY          = 0.0f;
287
    mMarked     = false;
288
    mDepthWanted= false;
289

  
290
    fboIds[0]  =-1;
291
    colorIds[0]= NOT_CREATED_YET;
292
    depthIds[0]= NOT_CREATED_YET;
238 293

  
239 294
    createProjection();
240 295
    }
......
251 306
    {
252 307
    mProjectionMatrix = new float[16];
253 308

  
254
    fboIds[0]= fbo;
255
    texIds[0]= TEXTURE_DONT_CREATE;
256
    mFOV     = 60.0f;
257
    mX       = 0.0f;
258
    mY       = 0.0f;
259
    mMarked  = false;
309
    mFOV        = 60.0f;
310
    mX          = 0.0f;
311
    mY          = 0.0f;
312
    mMarked     = false;
313
    mDepthWanted= true;
314

  
315
    fboIds[0]  = fbo;
316
    colorIds[0]= DONT_CREATE;
317
    depthIds[0]= DONT_CREATE;
318
    }
319

  
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321
/**
322
 * Create a new DEPTH buffer and attach it or (param=false) detach an existing DEPTh attachment and destroy it.
323
 *
324
 * @param hasDepthAttachment <bold>true</bold> if we want to attach a new DEPTH buffer to the FBO.<br>
325
 *                           <bold>false</bold> if we want to detach the DEPTH attachment.
326
 */
327
  public void setDepthAttachment(boolean hasDepthAttachment)
328
    {
329
    mDepthWanted = hasDepthAttachment;
260 330
    }
261 331

  
262 332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

  
263 334
/**
264 335
 * Draw the (texture,mesh,effects) object to the Framebuffer.
265 336
 * <p>
......
275 346
    tex.createTexture();
276 347
    tex.setAsInput();
277 348
    createFBO();
278
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
349
    setAsOutput();
279 350
    effects.drawPriv(tex.mHalfX, tex.mHalfY, mesh, this, time);
280 351
    DistortedFramebuffer.deleteAllMarked();
281 352
    DistortedTexture.deleteAllMarked();
......
298 369
    {
299 370
    fbo.createFBO();
300 371

  
301
    if( fbo.texIds[0]>0 )    // fbo created with the first constructor
372
    if( fbo.colorIds[0]>0 )    // fbo created with the first constructor
302 373
      {
303 374
      createFBO();
304
      GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
305
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.texIds[0]);
375
      setAsOutput();
376
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.colorIds[0]);
306 377
      effects.drawPriv(fbo.mWidth/2, fbo.mHeight/2, mesh, this, time);
307 378
      DistortedFramebuffer.deleteAllMarked();
308 379
      DistortedTexture.deleteAllMarked();
......
321 392
  public void renderTo(DistortedTree dt, long time)
322 393
    {
323 394
    createFBO();
324
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
395
    setAsOutput();
325 396
    dt.drawRecursive(time,this);
326 397
    DistortedFramebuffer.deleteAllMarked();
327 398
    DistortedTexture.deleteAllMarked();
......
379 450

  
380 451
      createProjection();
381 452

  
382
      if( texIds[0]>0 ) markForDeletion();
453
      if( colorIds[0]>0 ) markForDeletion();
383 454
      }
384 455
    }
385 456

  
......
396 467
 */
397 468
  public int getTextureID()
398 469
    {
399
    return texIds[0];
470
    return colorIds[0];
471
    }
472

  
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474
/**
475
 * Return true if the FBO contains a DEPTH attachment.
476
 *
477
 * @return <bold>true</bold> if the FBO contains a DEPTH attachment.
478
 */
479
  public boolean hasDepth()
480
    {
481
    return mDepthWanted;
400 482
    }
401 483
  }

Also available in: Unified diff