Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ 8ca9f899

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