Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ 227ac49a

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