Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ 86eb00a9

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