Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ 133cbb2b

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