Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ cdd5e827

1 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 194ab46f Leszek Koltunski
import android.opengl.GLES30;
23 f6fb3c6d Leszek Koltunski
import android.opengl.Matrix;
24
25 8e34674e Leszek Koltunski
import java.util.Iterator;
26
import java.util.LinkedList;
27
28 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
29 dedacd82 Leszek Koltunski
/**
30
 * Class which represents a OpenGL Framebuffer object.
31 71c3fecc Leszek Koltunski
 * <p>
32 65362dd4 Leszek Koltunski
 * User is able to create either Framebuffers from objects already constructed outside
33
 * of the library (the first constructor; primary use case: the screen) or an offscreen
34 e0b6c593 Leszek Koltunski
 * FBOs.
35 71c3fecc Leszek Koltunski
 * <p>
36 e0b6c593 Leszek Koltunski
 * Keep all objects created in a static LinkedList. The point: we need to be able to mark
37 8e34674e Leszek Koltunski
 * Framebuffers for deletion, and delete all marked objects later at a convenient time (that's
38
 * because we can only delete from a thread that holds the OpenGL context so here we provide a
39 65362dd4 Leszek Koltunski
 * framework where one is able to mark for deletion at any time and actual deletion takes place
40 8e34674e Leszek Koltunski
 * on the next render).
41 dedacd82 Leszek Koltunski
 */
42 ed13a5de Leszek Koltunski
public class DistortedFramebuffer
43 f6fb3c6d Leszek Koltunski
  {
44 8c327653 Leszek Koltunski
  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 f6fb3c6d Leszek Koltunski
48 8e34674e Leszek Koltunski
  private static boolean mListMarked = false;
49
  private static LinkedList<DistortedFramebuffer> mList = new LinkedList<>();
50
51 8c327653 Leszek Koltunski
  private int[] colorIds = new int[1];
52
  private int[] depthIds = new int[1];
53
  private int[] fboIds   = new int[1];
54 7304d89f Leszek Koltunski
55 8e34674e Leszek Koltunski
  private boolean mMarked;
56 cdd5e827 Leszek Koltunski
  private boolean mDepthEnabled;
57 8e34674e Leszek Koltunski
58 86eb00a9 Leszek Koltunski
  private int mTexWidth, mTexHeight;
59
60 da99dd30 Leszek Koltunski
  // Projection stuff
61
  private float mX, mY, mFOV;
62 e6cf7d50 Leszek Koltunski
  int mWidth,mHeight,mDepth;
63
  float mDistance;
64 f6fb3c6d Leszek Koltunski
  float[] mProjectionMatrix;
65 bd3da5b2 Leszek Koltunski
66 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
67 6537ba91 Leszek Koltunski
// Must be called from a thread holding OpenGL Context
68 f6fb3c6d Leszek Koltunski
69 8337fa41 Leszek Koltunski
  void createFBO()
70 f6fb3c6d Leszek Koltunski
    {
71 8c327653 Leszek Koltunski
    if( colorIds[0]==NOT_CREATED_YET )
72 7cf783cb Leszek Koltunski
      {
73 194ab46f Leszek Koltunski
      GLES30.glGenTextures(1, colorIds, 0);
74
      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, colorIds[0]);
75
      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_REPEAT);
76
      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_REPEAT);
77
      GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
78
      GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
79
      GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA, mTexWidth, mTexHeight, 0, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, null);
80
81
      GLES30.glGenFramebuffers(1, fboIds, 0);
82
      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fboIds[0]);
83
      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, colorIds[0], 0);
84 dedacd82 Leszek Koltunski
85 8337fa41 Leszek Koltunski
      checkStatus("color");
86 7cf783cb Leszek Koltunski
      }
87 cdd5e827 Leszek Koltunski
    if( mDepthEnabled && depthIds[0]==NOT_CREATED_YET ) // we need to create a new DEPTH attachment
88 8c327653 Leszek Koltunski
      {
89 194ab46f Leszek Koltunski
      GLES30.glGenTextures(1, depthIds, 0);
90
      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, depthIds[0]);
91
      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_REPEAT);
92
      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_REPEAT);
93
      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
94
      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST);
95
      GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_DEPTH_COMPONENT, mTexWidth, mTexHeight, 0, GLES30.GL_DEPTH_COMPONENT, GLES30.GL_UNSIGNED_SHORT, null);
96 8c327653 Leszek Koltunski
97 194ab46f Leszek Koltunski
      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fboIds[0]);
98
      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_ATTACHMENT, GLES30.GL_TEXTURE_2D, depthIds[0], 0);
99 8c327653 Leszek Koltunski
100 8337fa41 Leszek Koltunski
      checkStatus("depth");
101 8c327653 Leszek Koltunski
      }
102 cdd5e827 Leszek Koltunski
    if( !mDepthEnabled && depthIds[0]!=NOT_CREATED_YET ) // we need to detach and destroy the DEPTH attachment.
103 8c327653 Leszek Koltunski
      {
104 194ab46f Leszek Koltunski
      GLES30.glDeleteTextures(1, depthIds, 0);
105 8c327653 Leszek Koltunski
      depthIds[0]=NOT_CREATED_YET;
106
      }
107 8337fa41 Leszek Koltunski
    }
108
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110
111
  private boolean checkStatus(String message)
112
    {
113 194ab46f Leszek Koltunski
    int status = GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER);
114 8337fa41 Leszek Koltunski
115 194ab46f Leszek Koltunski
    if(status != GLES30.GL_FRAMEBUFFER_COMPLETE)
116 8337fa41 Leszek Koltunski
      {
117
      android.util.Log.e("DistortedFramebuffer", "FRAMEBUFFER INCOMPLETE, "+message+" error="+status);
118
119 194ab46f Leszek Koltunski
      GLES30.glDeleteTextures(1, colorIds, 0);
120
      GLES30.glDeleteTextures(1, depthIds, 0);
121
      GLES30.glDeleteFramebuffers(1, fboIds, 0);
122 8337fa41 Leszek Koltunski
      fboIds[0]   = 0;
123
      colorIds[0] = FAILED_TO_CREATE;
124
      depthIds[0] = FAILED_TO_CREATE;
125
126
      return false;
127
      }
128 8c327653 Leszek Koltunski
129 f6fb3c6d Leszek Koltunski
    return true;
130
    }
131
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133 6537ba91 Leszek Koltunski
// Must be called from a thread holding OpenGL Context
134 f6fb3c6d Leszek Koltunski
135
  private void deleteFBO()
136
    {
137 8c327653 Leszek Koltunski
    if( colorIds[0]>=0 )
138 e6cf7d50 Leszek Koltunski
      {
139 46e25345 Leszek Koltunski
      //android.util.Log.e("FBO", "deleting ("+mWidth+","+mHeight+") "+fboIds[0]);
140 f6fb3c6d Leszek Koltunski
141 8c327653 Leszek Koltunski
      if( depthIds[0]>=0 )
142
        {
143 194ab46f Leszek Koltunski
        GLES30.glDeleteTextures(1, depthIds, 0);
144 8c327653 Leszek Koltunski
        depthIds[0]=NOT_CREATED_YET;
145
        }
146
147 194ab46f Leszek Koltunski
      GLES30.glDeleteTextures(1, colorIds, 0);
148 8c327653 Leszek Koltunski
      colorIds[0] = NOT_CREATED_YET;
149 bd3da5b2 Leszek Koltunski
150 194ab46f Leszek Koltunski
      GLES30.glDeleteFramebuffers(1, fboIds, 0);
151 e6cf7d50 Leszek Koltunski
      fboIds[0] = 0;
152
      }
153 bd3da5b2 Leszek Koltunski
154
    mMarked = false;
155
    }
156
157 da99dd30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
158
159
  void setAsOutput()
160
    {
161 194ab46f Leszek Koltunski
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fboIds[0]);
162 8c327653 Leszek Koltunski
163
    if( depthIds[0]!=NOT_CREATED_YET )
164
      {
165 194ab46f Leszek Koltunski
      GLES30.glEnable(GLES30.GL_DEPTH_TEST);
166
      GLES30.glDepthMask(true);
167 8c327653 Leszek Koltunski
      }
168
    else
169
      {
170 194ab46f Leszek Koltunski
      GLES30.glDisable(GLES30.GL_DEPTH_TEST);
171
      GLES30.glDepthMask(false);
172 8c327653 Leszek Koltunski
      }
173 da99dd30 Leszek Koltunski
    }
174
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176
177
  void setAsInput()
178
    {
179 194ab46f Leszek Koltunski
    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, colorIds[0]);
180 da99dd30 Leszek Koltunski
    }
181
182 09d4f4b1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
183
184
  private void createProjection()
185
    {
186
    if( mWidth>0 && mHeight>1 )
187
      {
188
      if( mFOV>0.0f )  // perspective projection
189
        {
190
        float left   = (-mX-mWidth /2.0f)/mHeight;
191
        float right  = (-mX+mWidth /2.0f)/mHeight;
192
        float bottom = (-mY-mHeight/2.0f)/mHeight;
193
        float top    = (-mY+mHeight/2.0f)/mHeight;
194
        float near   = (top-bottom) / (2.0f*(float)Math.tan(mFOV*Math.PI/360));
195
        mDistance    = mHeight*near/(top-bottom);
196
        float far    = 2*mDistance-near;
197
        mDepth       = (int)((far-near)/2);
198
199
        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
200
        }
201
      else             // parallel projection
202
        {
203
        float left   = -mX-mWidth /2.0f;
204
        float right  = -mX+mWidth /2.0f;
205
        float bottom = -mY-mHeight/2.0f;
206
        float top    = -mY+mHeight/2.0f;
207
        float near   = (mWidth+mHeight)/2;
208
        mDistance    = 2*near;
209
        float far    = 3*near;
210
        mDepth       = (int)near;
211
212
        Matrix.orthoM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
213
        }
214
      }
215
    }
216
217 8e34674e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
218
219 7b8086eb Leszek Koltunski
  static synchronized void onDestroy()
220 8e34674e Leszek Koltunski
    {
221 02de77c9 Leszek Koltunski
    for( DistortedFramebuffer fbo : mList)
222
      {
223
      if( fbo.colorIds[0]!=DONT_CREATE ) fbo.colorIds[0] = NOT_CREATED_YET;
224 cdd5e827 Leszek Koltunski
      if( fbo.mDepthEnabled) fbo.depthIds[0] = NOT_CREATED_YET;
225 02de77c9 Leszek Koltunski
      }
226 8e34674e Leszek Koltunski
    }
227
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// must be called form a thread holding OpenGL Context
230
231 d6e94c84 Leszek Koltunski
  private static synchronized void deleteAllMarked()
232 8e34674e Leszek Koltunski
    {
233
    if( mListMarked )
234
      {
235
      DistortedFramebuffer tmp;
236
      Iterator<DistortedFramebuffer> iterator = mList.iterator();
237
238
      while(iterator.hasNext())
239
        {
240
        tmp = iterator.next();
241
242
        if( tmp.mMarked )
243
          {
244 e6cf7d50 Leszek Koltunski
          tmp.deleteFBO();
245 8e34674e Leszek Koltunski
          iterator.remove();
246
          }
247
        }
248
249
      mListMarked = false;
250
      }
251
    }
252 57578636 Leszek Koltunski
253 86eb00a9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
254
// if new size fits into the size of the underlying Texture, just change the projection without
255
// reallocating the Texture. Otherwise, we need to reallocate.
256
//
257
// Must be called form a thread holding the OpenGL context.
258
259
  void resizeFast(int width, int height)
260
    {
261
    if( mWidth!=width || mHeight!=height )
262
      {
263
      mWidth = width;
264
      mHeight= height;
265
266
      createProjection();
267
268
      if( mWidth>mTexWidth || mHeight>mTexHeight )
269
        {
270
        mTexWidth = mWidth;
271
        mTexHeight= mHeight;
272
        deleteFBO();
273
        }
274
      }
275 cc0734e7 Leszek Koltunski
276
    createFBO();
277 86eb00a9 Leszek Koltunski
    }
278
279 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
280
// PUBLIC API
281 dedacd82 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
282 cdd5e827 Leszek Koltunski
/**
283
 * Create a new offscreen Framebuffer.
284
 *
285
 * @param width Width of the COLOR attachment.
286
 * @param height Height of the COLOR attachment.
287
 * @param depthEnabled Add DEPTH attachment?
288
 */
289
  @SuppressWarnings("unused")
290
  public DistortedFramebuffer(int width, int height, boolean depthEnabled)
291
    {
292
    mProjectionMatrix = new float[16];
293
294
    mHeight      = height;
295
    mWidth       = width;
296
    mTexHeight   = height;
297
    mTexWidth    = width;
298
    mFOV         = 60.0f;
299
    mX           = 0.0f;
300
    mY           = 0.0f;
301
    mMarked      = false;
302
    mDepthEnabled= depthEnabled;
303
304
    fboIds[0]  =-1;
305
    colorIds[0]= NOT_CREATED_YET;
306
    depthIds[0]= NOT_CREATED_YET;
307
308
    createProjection();
309
310
    mList.add(this);
311
    }
312
313 dedacd82 Leszek Koltunski
/**
314 57578636 Leszek Koltunski
 * Create a new offscreen Framebuffer.
315 dedacd82 Leszek Koltunski
 *
316
 * @param width Width of the COLOR attachment.
317
 * @param height Height of the COLOR attachment.
318
 */
319 1942537e Leszek Koltunski
  @SuppressWarnings("unused")
320 ed13a5de Leszek Koltunski
  public DistortedFramebuffer(int width, int height)
321 f6fb3c6d Leszek Koltunski
    {
322
    mProjectionMatrix = new float[16];
323
324 cdd5e827 Leszek Koltunski
    mHeight      = height;
325
    mWidth       = width;
326
    mTexHeight   = height;
327
    mTexWidth    = width;
328
    mFOV         = 60.0f;
329
    mX           = 0.0f;
330
    mY           = 0.0f;
331
    mMarked      = false;
332
    mDepthEnabled= false;
333 8c327653 Leszek Koltunski
334
    fboIds[0]  =-1;
335
    colorIds[0]= NOT_CREATED_YET;
336
    depthIds[0]= NOT_CREATED_YET;
337 bd3da5b2 Leszek Koltunski
338 f6fb3c6d Leszek Koltunski
    createProjection();
339 86eb00a9 Leszek Koltunski
340
    mList.add(this);
341 f6fb3c6d Leszek Koltunski
    }
342
343 b448e6b9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
344 dedacd82 Leszek Koltunski
/**
345 57578636 Leszek Koltunski
 * Create a new Framebuffer from an already created OpenGL Framebuffer.
346
 * <p>
347
 * Has to be followed by a 'resize()' to set the size.
348 dedacd82 Leszek Koltunski
 *
349
 * @param fbo the ID of a OpenGL Framebuffer object. Typically 0 (the screen)
350
 */
351 ed13a5de Leszek Koltunski
  public DistortedFramebuffer(int fbo)
352 b448e6b9 Leszek Koltunski
    {
353
    mProjectionMatrix = new float[16];
354
355 cdd5e827 Leszek Koltunski
    mFOV         = 60.0f;
356
    mX           = 0.0f;
357
    mY           = 0.0f;
358
    mMarked      = false;
359
    mDepthEnabled= true;
360 8c327653 Leszek Koltunski
361
    fboIds[0]  = fbo;
362
    colorIds[0]= DONT_CREATE;
363
    depthIds[0]= DONT_CREATE;
364
    }
365
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367
/**
368
 * Create a new DEPTH buffer and attach it or (param=false) detach an existing DEPTh attachment and destroy it.
369
 *
370 cdd5e827 Leszek Koltunski
 * @param enable <bold>true</bold> if we want to attach a new DEPTH buffer to the FBO.<br>
371
 *               <bold>false</bold> if we want to detach the DEPTH attachment.
372 8c327653 Leszek Koltunski
 */
373 cdd5e827 Leszek Koltunski
  public void enableDepthAttachment(boolean enable)
374 8c327653 Leszek Koltunski
    {
375 cdd5e827 Leszek Koltunski
    mDepthEnabled = enable;
376 b448e6b9 Leszek Koltunski
    }
377
378 a0f644b7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
379 8c327653 Leszek Koltunski
380 a0f644b7 Leszek Koltunski
/**
381 05403bba Leszek Koltunski
 * Draw the (texture,mesh,effects) object to the Framebuffer.
382 a0f644b7 Leszek Koltunski
 * <p>
383 d254d550 Leszek Koltunski
 * Must be called from a thread holding OpenGL Context.
384 a0f644b7 Leszek Koltunski
 *
385
 * @param tex input Texture to use.
386 05403bba Leszek Koltunski
 * @param mesh Class descendant from MeshObject
387 a0f644b7 Leszek Koltunski
 * @param effects The DistortedEffects to use when rendering
388
 * @param time Current time, in milliseconds.
389
 */
390 05403bba Leszek Koltunski
  public void renderTo(DistortedTexture tex, MeshObject mesh, DistortedEffects effects, long time)
391 a0f644b7 Leszek Koltunski
    {
392
    tex.createTexture();
393 86eb00a9 Leszek Koltunski
    DistortedFramebuffer.deleteAllMarked();
394
    DistortedTexture.deleteAllMarked();
395 a0f644b7 Leszek Koltunski
    createFBO();
396 b33f6f0a Leszek Koltunski
    tex.setAsInput();
397 05403bba Leszek Koltunski
    effects.drawPriv(tex.mHalfX, tex.mHalfY, mesh, this, time);
398 a0f644b7 Leszek Koltunski
    }
399
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401 52358355 Leszek Koltunski
/**
402 05403bba Leszek Koltunski
 * Draw the (framebuffer,mesh,effects) object to the Framebuffer.
403 52358355 Leszek Koltunski
 * <p>
404 d254d550 Leszek Koltunski
 * Must be called from a thread holding OpenGL Context.
405 52358355 Leszek Koltunski
 *
406 432442f9 Leszek Koltunski
 * @param fbo The Framebuffer (previously created with the first constructor, drawing FROM the screen
407 a0700272 Leszek Koltunski
 *            is unsupported!) whose COLOR attachment 0 will be used as input texture.
408 484a52a7 Leszek Koltunski
 *            Please note that rendering from an FBO to itself is unsupported by OpenGL!
409 05403bba Leszek Koltunski
 * @param mesh Class descendant from MeshObject
410 52358355 Leszek Koltunski
 * @param effects The DistortedEffects to use when rendering
411
 * @param time Current time, in milliseconds.
412
 */
413 05403bba Leszek Koltunski
  public void renderTo(DistortedFramebuffer fbo, MeshObject mesh, DistortedEffects effects, long time)
414 52358355 Leszek Koltunski
    {
415
    fbo.createFBO();
416
417 8c327653 Leszek Koltunski
    if( fbo.colorIds[0]>0 )    // fbo created with the first constructor
418 52358355 Leszek Koltunski
      {
419 86eb00a9 Leszek Koltunski
      DistortedFramebuffer.deleteAllMarked();
420
      DistortedTexture.deleteAllMarked();
421 52358355 Leszek Koltunski
      createFBO();
422 194ab46f Leszek Koltunski
      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, fbo.colorIds[0]);
423 05403bba Leszek Koltunski
      effects.drawPriv(fbo.mWidth/2, fbo.mHeight/2, mesh, this, time);
424 52358355 Leszek Koltunski
      }
425
    }
426
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428 a0f644b7 Leszek Koltunski
/**
429
 * Draws the Tree, and all its children, to the Framebuffer.
430
 * <p>
431 d254d550 Leszek Koltunski
 * Must be called from a thread holding OpenGL Context.
432 a0f644b7 Leszek Koltunski
 *
433
 * @param dt DistortedTree to render.
434
 * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the Tree.
435
 */
436
  public void renderTo(DistortedTree dt, long time)
437
    {
438 86eb00a9 Leszek Koltunski
    DistortedFramebuffer.deleteAllMarked();
439
    DistortedTexture.deleteAllMarked();
440 a0f644b7 Leszek Koltunski
    createFBO();
441
    dt.drawRecursive(time,this);
442
    }
443
444 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
445 dedacd82 Leszek Koltunski
/**
446
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
447
 */
448 bd3da5b2 Leszek Koltunski
  public void markForDeletion()
449 f6fb3c6d Leszek Koltunski
    {
450 46e25345 Leszek Koltunski
    //android.util.Log.e("FBO", "marking for deletion ("+mWidth+","+mHeight+") "+fboIds[0]);
451 16d8b8f3 Leszek Koltunski
452 8e34674e Leszek Koltunski
    mListMarked = true;
453
    mMarked     = true;
454 f6fb3c6d Leszek Koltunski
    }
455
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457 dedacd82 Leszek Koltunski
/**
458
 * Create new Projection matrix.
459
 *
460
 * @param fov Vertical 'field of view' of the Projection frustrum (in degrees).
461 46a52b78 Leszek Koltunski
 * @param x X-coordinate of the point at which our camera looks at. 0 is the center.
462
 * @param y Y-coordinate of the point at which our camera looks at. 0 is the center.
463 dedacd82 Leszek Koltunski
 */
464
  public void setProjection(float fov, float x, float y)
465 f6fb3c6d Leszek Koltunski
    {
466 dedacd82 Leszek Koltunski
    mFOV = fov;
467 f6fb3c6d Leszek Koltunski
    mX   = x;
468
    mY   = y;
469
470
    createProjection();
471
    }
472
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474 dedacd82 Leszek Koltunski
/**
475
 * Resize the underlying Framebuffer.
476
 *
477
 * As the Framebuffer is not created until the first render, typical usage of this API is actually
478
 * to set the size of an not-yet-created Framebuffer of an object that has been created with the
479
 * second constructor.
480 71c3fecc Leszek Koltunski
 * <p>
481 65362dd4 Leszek Koltunski
 * Fully creating an object, rendering to it, then resizing mid-render is also possible. Actual
482
 * resize takes place on the next render.
483 dedacd82 Leszek Koltunski
 *
484
 * @param width The new width.
485
 * @param height The new height.
486
 */
487 f6fb3c6d Leszek Koltunski
  public void resize(int width, int height)
488
    {
489 bd3da5b2 Leszek Koltunski
    if( mWidth!=width || mHeight!=height )
490
      {
491 86eb00a9 Leszek Koltunski
      mWidth    = width;
492
      mHeight   = height;
493
      mTexWidth = width;
494
      mTexHeight= height;
495 f6fb3c6d Leszek Koltunski
496 bd3da5b2 Leszek Koltunski
      createProjection();
497 f6fb3c6d Leszek Koltunski
498 8c327653 Leszek Koltunski
      if( colorIds[0]>0 ) markForDeletion();
499 bd3da5b2 Leszek Koltunski
      }
500 f6fb3c6d Leszek Koltunski
    }
501 d1e740c5 Leszek Koltunski
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503
/**
504 09d4f4b1 Leszek Koltunski
 * Return the ID of the Texture (COLOR attachment 0) that's backing this FBO.
505
 * <p>
506
 * Catch: this will only work if the library has had time to actually create the texture. Remember
507
 * that the texture gets created only on first render, thus creating a Texture object and immediately
508
 * calling this method will return an invalid (negative) result.
509
 *
510 ab12f06b Leszek Koltunski
 * @return If there was not a single render between creation of the Object and calling this method on
511
 *         it, return a negative value. Otherwise, return ID of COLOR attachment 0.
512 d1e740c5 Leszek Koltunski
 */
513 09d4f4b1 Leszek Koltunski
  public int getTextureID()
514 d1e740c5 Leszek Koltunski
    {
515 8c327653 Leszek Koltunski
    return colorIds[0];
516
    }
517
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519
/**
520
 * Return true if the FBO contains a DEPTH attachment.
521
 *
522
 * @return <bold>true</bold> if the FBO contains a DEPTH attachment.
523
 */
524
  public boolean hasDepth()
525
    {
526 cdd5e827 Leszek Koltunski
    return mDepthEnabled;
527 d1e740c5 Leszek Koltunski
    }
528 f6fb3c6d Leszek Koltunski
  }