Project

General

Profile

« Previous | Next » 

Revision c5369f1b

Added by Leszek Koltunski about 7 years ago

Major: change of API.

Split DFramebuffer into Framebuffer and Screen; introduce the 'DistortedInputSurface' and 'DistortedOutputSurface' interfaces.

View differences:

src/main/java/org/distorted/library/DistortedEffects.java
183 183
// DEBUG ONLY
184 184

  
185 185
  @SuppressWarnings("unused")
186
  private void displayBoundingRect(float halfX, float halfY, float halfZ, DistortedFramebuffer df, float[] mvp, float[] vertices)
186
  private void displayBoundingRect(float halfX, float halfY, float halfZ, DistortedOutputSurface surface, float[] mvp, float[] vertices)
187 187
    {
188 188
    int len  = vertices.length/3;
189 189
    int minx = Integer.MAX_VALUE;
......
194 194

  
195 195
    float x,y,z, X,Y,W, ndcX,ndcY;
196 196

  
197
    DistortedProjection projection = surface.getProjection();
198

  
197 199
    for(int i=0; i<len; i++)
198 200
      {
199 201
      x = 2*halfX*vertices[3*i  ];
......
207 209
      ndcX = X/W;
208 210
      ndcY = Y/W;
209 211

  
210
      wx = (int)(df.mWidth *(ndcX+1)/2);
211
      wy = (int)(df.mHeight*(ndcY+1)/2);
212
      wx = (int)(projection.mWidth *(ndcX+1)/2);
213
      wy = (int)(projection.mHeight*(ndcY+1)/2);
212 214

  
213 215
      if( wx<minx ) minx = wx;
214 216
      if( wx>maxx ) maxx = wx;
......
217 219
      }
218 220

  
219 221
    mDebugProgram.useProgram();
220
    df.setAsOutput();
222
    surface.setAsOutput();
221 223

  
222 224
    Matrix.setIdentityM( mTmpMatrix, 0);
223
    Matrix.translateM  ( mTmpMatrix, 0, minx-df.mWidth/2, maxy-df.mHeight/2, -df.mDistance);
225
    Matrix.translateM  ( mTmpMatrix, 0, minx-projection.mWidth/2, maxy-projection.mHeight/2, -projection.mDistance);
224 226
    Matrix.scaleM      ( mTmpMatrix, 0, (float)(maxx-minx)/(2*halfX), (float)(maxy-miny)/(2*halfY), 1.0f);
225 227
    Matrix.translateM  ( mTmpMatrix, 0, halfX,-halfY, 0);
226
    Matrix.multiplyMM  ( mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
228
    Matrix.multiplyMM  ( mMVPMatrix, 0, projection.mProjectionMatrix, 0, mTmpMatrix, 0);
227 229

  
228 230
    GLES30.glUniform2f( mObjDH , 2*halfX, 2*halfY);
229 231
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
......
234 236

  
235 237
///////////////////////////////////////////////////////////////////////////////////////////////////
236 238

  
237
  void drawPriv(float halfInputW, float halfInputH, MeshObject mesh, DistortedFramebuffer df, long currTime)
239
  void drawPriv(float halfInputW, float halfInputH, MeshObject mesh, DistortedOutputSurface surface, long currTime)
238 240
    {
239 241
    mM.compute(currTime);
240 242
    mV.compute(currTime);
......
242 244
    mP.compute(currTime);
243 245

  
244 246
    float halfZ = halfInputW*mesh.zFactor;
245
    GLES30.glViewport(0, 0, df.mWidth, df.mHeight);
247
    DistortedProjection projection = surface.getProjection();
248
    GLES30.glViewport(0, 0, projection.mWidth, projection.mHeight);
246 249

  
247 250
    if( mP.mNumEffects==0 )
248 251
      {
249 252
      mProgram.useProgram();
250
      df.setAsOutput();
251
      mM.send(df,halfInputW,halfInputH,halfZ);
253
      surface.setAsOutput();
254
      mM.send(projection,halfInputW,halfInputH,halfZ);
252 255
      mV.send(halfInputW,halfInputH,halfZ);
253 256
      mF.send(halfInputW,halfInputH);
254 257
      GLES30.glVertexAttribPointer(mProgram.mAttribute[0], POSITION_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mesh.mMeshPositions);
......
260 263
      {
261 264
      if( mV.mNumEffects==0 && mF.mNumEffects==0 && (mesh instanceof MeshFlat) && mM.canUseShortcut() )
262 265
        {
263
        mM.constructMatrices(df,halfInputW,halfInputH);
264
        mP.render(2*halfInputW, 2*halfInputH, mM.getMVP(), df);
266
        mM.constructMatrices(projection,halfInputW,halfInputH);
267
        mP.render(2*halfInputW, 2*halfInputH, mM.getMVP(), surface);
265 268
        }
266 269
      else
267 270
        {
268 271
        mProgram.useProgram();
269
        mBufferFBO.resizeFast(df.mWidth, df.mHeight);
272
        mBufferFBO.resizeFast(projection.mWidth, projection.mHeight);
270 273
        mBufferFBO.setAsOutput();
271 274
        GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
272 275
        GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
273
        mM.send(mBufferFBO,halfInputW,halfInputH,halfZ);
276
        mM.send(mBufferFBO.getProjection(),halfInputW,halfInputH,halfZ);
274 277
        mV.send(halfInputW,halfInputH,halfZ);
275 278
        mF.send(halfInputW,halfInputH);
276 279
        GLES30.glVertexAttribPointer(mProgram.mAttribute[0], POSITION_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mesh.mMeshPositions);
......
279 282
        GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
280 283

  
281 284
        Matrix.setIdentityM(mTmpMatrix, 0);
282
        Matrix.translateM(mTmpMatrix, 0, 0, 0, -df.mDistance);
283
        Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
285
        Matrix.translateM(mTmpMatrix, 0, 0, 0, -projection.mDistance);
286
        Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mTmpMatrix, 0);
284 287

  
285 288
        mBufferFBO.setAsInput();
286
        mP.render(df.mWidth, df.mHeight, mMVPMatrix, df);
289
        mP.render(projection.mWidth, projection.mHeight, mMVPMatrix, surface);
287 290
        }
288 291
      }
289 292

  
......
294 297

  
295 298
///////////////////////////////////////////////////////////////////////////////////////////////////
296 299
   
297
  static void drawNoEffectsPriv(float halfInputW, float halfInputH, MeshObject mesh, DistortedFramebuffer df)
300
  static void drawNoEffectsPriv(float halfInputW, float halfInputH, MeshObject mesh, DistortedProjection projection)
298 301
    {
299
    GLES30.glViewport(0, 0, df.mWidth, df.mHeight);
302
    GLES30.glViewport(0, 0, projection.mWidth, projection.mHeight);
300 303

  
301 304
    Matrix.setIdentityM(mTmpMatrix, 0);
302
    Matrix.translateM(mTmpMatrix, 0, 0, 0, -df.mDistance);
303
    Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
305
    Matrix.translateM(mTmpMatrix, 0, 0, 0, -projection.mDistance);
306
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mTmpMatrix, 0);
304 307

  
305
    EffectQueueMatrix.sendZero(df,halfInputW,halfInputH,halfInputW*mesh.zFactor);
308
    EffectQueueMatrix.sendZero(projection,halfInputW,halfInputH,halfInputW*mesh.zFactor);
306 309
    EffectQueueVertex.sendZero();
307 310
    EffectQueueFragment.sendZero();
308 311

  
src/main/java/org/distorted/library/DistortedFramebuffer.java
20 20
package org.distorted.library;
21 21

  
22 22
import android.opengl.GLES30;
23
import android.opengl.Matrix;
24 23

  
25 24
///////////////////////////////////////////////////////////////////////////////////////////////////
26 25
/**
27 26
 * Class which represents a OpenGL Framebuffer object.
28 27
 * <p>
29
 * 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
 * FBOs.
32
 * <p>
33
 * Keep all objects created in a static LinkedList. The point: we need to be able to mark
34
 * 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
 * framework where one is able to mark for deletion at any time and actual deletion takes place
37
 * on the next render).
28
 * User is able to create offscreen FBOs and both a) render to them b) use their COLOR0 attachment as
29
 * an input texture.
38 30
 */
39
public class DistortedFramebuffer extends DistortedRenderable
31
public class DistortedFramebuffer extends DistortedRenderable implements DistortedInputSurface, DistortedOutputSurface
40 32
  {
41 33
  private int[] mDepthH = new int[1];
42 34
  private int[] mFBOH   = new int[1];
43

  
44 35
  private boolean mDepthEnabled;
45

  
46
  // Projection stuff
47
  private float mX, mY, mFOV;
48
  int mWidth,mHeight,mDepth;
49
  float mDistance;
50
  float[] mProjectionMatrix;
36
  private DistortedProjection mProjection;
51 37

  
52 38
///////////////////////////////////////////////////////////////////////////////////////////////////
53 39
// Must be called from a thread holding OpenGL Context
54 40
// Watch out - this has the side-effect of binding a Texture and a Framebuffer!
55 41

  
56
  void create()
42
  public void create()
57 43
    {
58 44
    if( mColorH[0]==NOT_CREATED_YET )
59 45
      {
......
146 132
    if( mDepthEnabled           ) mDepthH[0] = NOT_CREATED_YET;
147 133
    }
148 134

  
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

  
151
  void setAsOutput()
152
    {
153
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
154

  
155
    if( mDepthH[0]!=NOT_CREATED_YET )
156
      {
157
      GLES30.glEnable(GLES30.GL_DEPTH_TEST);
158
      GLES30.glDepthMask(true);
159
      }
160
    else
161
      {
162
      GLES30.glDisable(GLES30.GL_DEPTH_TEST);
163
      GLES30.glDepthMask(false);
164
      }
165
    }
166

  
167
///////////////////////////////////////////////////////////////////////////////////////////////////
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 135
///////////////////////////////////////////////////////////////////////////////////////////////////
203 136
// if new size fits into the size of the underlying Texture, just change the projection without
204 137
// reallocating the Texture. Otherwise, we need to reallocate.
......
207 140

  
208 141
  void resizeFast(int width, int height)
209 142
    {
210
    if( mWidth!=width || mHeight!=height )
143
    if( mProjection.resize(width,height) )
211 144
      {
212
      mWidth = width;
213
      mHeight= height;
214

  
215
      createProjection();
216

  
217
      if( mWidth> mSizeX || mHeight> mSizeY)
145
      if( width> mSizeX || height> mSizeY)
218 146
        {
219
        mSizeX = mWidth;
220
        mSizeY = mHeight;
147
        mSizeX = width;
148
        mSizeY = height;
221 149
        delete();
222 150
        }
223 151
      }
......
240 168
    {
241 169
    super(width,height,NOT_CREATED_YET);
242 170

  
243
    mProjectionMatrix = new float[16];
244

  
245
    mHeight      = height;
246
    mWidth       = width;
247
    mFOV         = 60.0f;
248
    mX           = 0.0f;
249
    mY           = 0.0f;
171
    mProjection  = new DistortedProjection(width,height);
250 172
    mDepthEnabled= depthEnabled;
251 173
    mFBOH[0]     = NOT_CREATED_YET;
252 174
    mDepthH[0]   = NOT_CREATED_YET;
253

  
254
    createProjection();
255 175
    }
256 176

  
257 177
///////////////////////////////////////////////////////////////////////////////////////////////////
......
267 187
    {
268 188
    super(width,height,NOT_CREATED_YET);
269 189

  
270
    mProjectionMatrix = new float[16];
271

  
272
    mHeight      = height;
273
    mWidth       = width;
274
    mFOV         = 60.0f;
275
    mX           = 0.0f;
276
    mY           = 0.0f;
190
    mProjection  = new DistortedProjection(width,height);
277 191
    mDepthEnabled= false;
278 192
    mFBOH[0]     = NOT_CREATED_YET;
279 193
    mDepthH[0]   = NOT_CREATED_YET;
280

  
281
    createProjection();
282 194
    }
283 195

  
284 196
///////////////////////////////////////////////////////////////////////////////////////////////////
285 197
/**
286
 * 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
 *
290
 * @param fbo the ID of a OpenGL Framebuffer object. Typically 0 (the screen)
198
 * Bind the underlying rectangle of pixels as a OpenGL Texture.
291 199
 */
292
  public DistortedFramebuffer(int fbo)
200
  public boolean setAsInput()
293 201
    {
294
    super(0,0,DONT_CREATE);
202
    if( mColorH[0]>0 )
203
      {
204
      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[0]);
205
      return true;
206
      }
207

  
208
    return false;
209
    }
295 210

  
296
    mProjectionMatrix = new float[16];
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212
/**
213
 * Bind this Surface as a Framebuffer we can render to.
214
 */
215
  public void setAsOutput()
216
    {
217
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
297 218

  
298
    mFOV         = 60.0f;
299
    mX           = 0.0f;
300
    mY           = 0.0f;
301
    mDepthEnabled= true;
302
    mFBOH[0]     = fbo;
303
    mDepthH[0]   = DONT_CREATE;
219
    if( mDepthH[0]!=NOT_CREATED_YET )
220
      {
221
      GLES30.glEnable(GLES30.GL_DEPTH_TEST);
222
      GLES30.glDepthMask(true);
223
      }
224
    else
225
      {
226
      GLES30.glDisable(GLES30.GL_DEPTH_TEST);
227
      GLES30.glDepthMask(false);
228
      }
304 229
    }
305 230

  
306 231
///////////////////////////////////////////////////////////////////////////////////////////////////
......
322 247
 * <p>
323 248
 * Must be called from a thread holding OpenGL Context.
324 249
 *
325
 * @param ren input Renderable to use.
250
 * @param surface InputSurface to skin our Mesh with.
326 251
 * @param mesh Class descendant from MeshObject
327 252
 * @param effects The DistortedEffects to use when rendering
328 253
 * @param time Current time, in milliseconds.
329 254
 */
330
  public void renderTo(DistortedRenderable ren, MeshObject mesh, DistortedEffects effects, long time)
255
  public void renderTo(DistortedInputSurface surface, MeshObject mesh, DistortedEffects effects, long time)
331 256
    {
332
    ren.create();  // Watch out  - this needs to be before
333
    create();      // the 'setAsInput' because this has side-effects!
257
    surface.create();  // Watch out  - this needs to be before
258
    create();          // the 'setAsInput' because this has side-effects!
334 259

  
335
    if( ren.setAsInput() )
260
    if( surface.setAsInput() )
336 261
      {
337 262
      DistortedRenderable.deleteAllMarked();
338
      effects.drawPriv(ren.getWidth()/2.0f, ren.getHeight()/2.0f, mesh, this, time);
263
      effects.drawPriv(surface.getWidth()/2.0f, surface.getHeight()/2.0f, mesh, this, time);
339 264
      }
340 265
    }
341 266

  
......
365 290
 */
366 291
  public void setProjection(float fov, float x, float y)
367 292
    {
368
    mFOV = fov;
369
    mX   = x;
370
    mY   = y;
371

  
372
    createProjection();
293
    mProjection.set(fov,x,y);
294
    mProjection.createProjection();
373 295
    }
374 296

  
375 297
///////////////////////////////////////////////////////////////////////////////////////////////////
376 298
/**
377 299
 * Resize the underlying Framebuffer.
378 300
 *
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
 * <p>
383
 * Fully creating an object, rendering to it, then resizing mid-render is also possible. Actual
384
 * resize takes place on the next render.
385
 *
386 301
 * @param width The new width.
387 302
 * @param height The new height.
388 303
 */
389 304
  public void resize(int width, int height)
390 305
    {
391
    if( mWidth!=width || mHeight!=height )
306
    if( mProjection.resize(width,height) )
392 307
      {
393
      mWidth = width;
394
      mHeight= height;
395 308
      mSizeX = width;
396 309
      mSizeY = height;
397

  
398
      createProjection();
399

  
400 310
      if( mColorH[0]>0 ) markForDeletion();
401 311
      }
402 312
    }
......
427 337
    {
428 338
    return mDepthEnabled;
429 339
    }
340

  
341
//////////////////////////////////////////////////////////////////////////////////////////////////
342
/**
343
 * Return Projection stored in this Framebuffer.
344
 *
345
 * @return DistortedProjection object.
346
 */
347
  public DistortedProjection getProjection()
348
    {
349
    return mProjection;
350
    }
430 351
  }
src/main/java/org/distorted/library/DistortedInputSurface.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
/**
25
 * A Surface that we can set as Input, i.e. take its rectangle of pixels and skin our Mesh with it.
26
 */
27

  
28
public interface DistortedInputSurface extends DistortedSurface
29
{
30
/**
31
 * Take the underlying rectangle of pixels and bind this texture to OpenGL.
32
 */
33
  boolean setAsInput();
34
}
src/main/java/org/distorted/library/DistortedOutputSurface.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
/**
25
 * A Surface that we can set as Output, i.e. render to it.
26
 */
27

  
28
public interface DistortedOutputSurface extends DistortedSurface
29
{
30
/**
31
 * Bind this Surface as a Framebuffer we can render to.
32
 */
33
 void setAsOutput();
34
/**
35
 * Return the Projection.
36
 */
37
 DistortedProjection getProjection();
38
}
src/main/java/org/distorted/library/DistortedProjection.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
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.Matrix;
23

  
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

  
26
class DistortedProjection
27
{
28
  private float mX, mY, mFOV;
29
  int mWidth,mHeight,mDepth;
30
  float mDistance;
31
  float[] mProjectionMatrix;
32

  
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

  
35
  DistortedProjection()
36
    {
37
    mProjectionMatrix = new float[16];
38

  
39
    mWidth = 0;
40
    mHeight= 0;
41

  
42
    mFOV = 60.0f;
43
    mX   =  0.0f;
44
    mY   =  0.0f;
45
    }
46

  
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

  
49
  DistortedProjection(int width, int height)
50
    {
51
    mProjectionMatrix = new float[16];
52

  
53
    mWidth = width;
54
    mHeight= height;
55

  
56
    mFOV = 60.0f;
57
    mX   =  0.0f;
58
    mY   =  0.0f;
59

  
60
    createProjection();
61
    }
62

  
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

  
65
  boolean resize(int width, int height)
66
    {
67
    if( mWidth!=width || mHeight!=height )
68
      {
69
      mWidth = width;
70
      mHeight= height;
71
      createProjection();
72
      return true;
73
      }
74

  
75
    return false;
76
    }
77

  
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

  
80
  void set(float fov, float x, float y)
81
    {
82
    mFOV = fov;
83
    mX = x;
84
    mY = y;
85
    }
86

  
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

  
89
  void createProjection()
90
    {
91
    if( mWidth>0 && mHeight>1 )
92
      {
93
      if( mFOV>0.0f )  // perspective projection
94
        {
95
        float left   = (-mX-mWidth /2.0f)/mHeight;
96
        float right  = (-mX+mWidth /2.0f)/mHeight;
97
        float bottom = (-mY-mHeight/2.0f)/mHeight;
98
        float top    = (-mY+mHeight/2.0f)/mHeight;
99
        float near   = (top-bottom) / (2.0f*(float)Math.tan(mFOV*Math.PI/360));
100
        mDistance    = mHeight*near/(top-bottom);
101
        float far    = 2*mDistance-near;
102
        mDepth       = (int)((far-near)/2);
103

  
104
        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
105
        }
106
      else             // parallel projection
107
        {
108
        float left   = -mX-mWidth /2.0f;
109
        float right  = -mX+mWidth /2.0f;
110
        float bottom = -mY-mHeight/2.0f;
111
        float top    = -mY+mHeight/2.0f;
112
        float near   = (mWidth+mHeight)/2;
113
        mDistance    = 2*near;
114
        float far    = 3*near;
115
        mDepth       = (int)near;
116

  
117
        Matrix.orthoM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
118
        }
119
      }
120
    }
121

  
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

  
124
}
src/main/java/org/distorted/library/DistortedRenderable.java
19 19

  
20 20
package org.distorted.library;
21 21

  
22
import android.opengl.GLES30;
23

  
24 22
import java.util.Iterator;
25 23
import java.util.LinkedList;
26 24

  
27 25
///////////////////////////////////////////////////////////////////////////////////////////////////
28 26
/**
29
 * Abstract class which represents a Renderable Object, i.e. something that we can take an skin our Mesh with.
30
 * <p>
31
 * Currently a DistortedTexture or a DistortedFramebuffer are Renderables.
32
 */
33
public abstract class DistortedRenderable
27
 * Keep all objects created in a static LinkedList. The point: we need to be able to mark
28
 * Objects for deletion, and delete all marked Objects later at a convenient time (that's
29
 * because we can only delete from a thread that holds the OpenGL context so here we provide a
30
 * framework where one is able to mark for deletion at any time and actual deletion takes place
31
 * on the next render).
32
*/
33
abstract class DistortedRenderable implements DistortedSurface
34 34
  {
35 35
  static final int FAILED_TO_CREATE = -1;
36 36
  static final int NOT_CREATED_YET  = -2;
......
45 45

  
46 46
///////////////////////////////////////////////////////////////////////////////////////////////////
47 47

  
48
  abstract void create();
48
  public abstract void create();
49 49
  abstract void delete();
50 50
  abstract void destroy();
51 51

  
......
75 75
      }
76 76
    }
77 77

  
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

  
80
  long getID()
81
    {
82
    return mColorH[0];
83
    }
84

  
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

  
87
  boolean setAsInput()
88
    {
89
    if( mColorH[0]>0 )
90
      {
91
      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[0]);
92
      return true;
93
      }
94

  
95
    return false;
96
    }
97

  
98 78
///////////////////////////////////////////////////////////////////////////////////////////////////
99 79

  
100 80
  static synchronized void onDestroy()
......
131 111
    mMarked     = true;
132 112
    }
133 113

  
114
////////////////////////////////////////////////////////////////////////////////////////////////////
115
/**
116
 * Return unique ID of the Renderable.
117
 */
118
  public long getID()
119
    {
120
    return mColorH[0];
121
    }
122

  
134 123
///////////////////////////////////////////////////////////////////////////////////////////////////
135 124

  
136 125
/**
src/main/java/org/distorted/library/DistortedScreen.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
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.GLES30;
23

  
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25
/**
26
 * Class which represents the Screen.
27
 * <p>
28
 * User is able to render to it just like to a DistortedFramebuffer.
29
 */
30
public class DistortedScreen extends DistortedRenderable implements DistortedOutputSurface
31
  {
32
  private int[] mFBOH   = new int[1];
33
  private DistortedProjection mProjection;
34

  
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

  
37
  public void create() {}
38
  void delete() {}
39
  void destroy() {}
40

  
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42
// PUBLIC API
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44
/**
45
 * Create a new Screen.
46
 * <p>
47
 * Has to be followed by a 'resize()' to set the size.
48
 */
49
  public DistortedScreen()
50
    {
51
    super(0,0,DONT_CREATE);
52

  
53
    mProjection  = new DistortedProjection();
54
    mFBOH[0]     = 0;
55
    }
56

  
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58
/**
59
 * Bind this Surface as a Framebuffer we can render to.
60
 */
61
  public void setAsOutput()
62
    {
63
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
64
    GLES30.glEnable(GLES30.GL_DEPTH_TEST);
65
    GLES30.glDepthMask(true);
66
    }
67

  
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

  
70
/**
71
 * Draw the (texture,mesh,effects) object to the Framebuffer.
72
 * <p>
73
 * Must be called from a thread holding OpenGL Context.
74
 *
75
 * @param surface InputSurface to skin our Mesh with.
76
 * @param mesh Class descendant from MeshObject
77
 * @param effects The DistortedEffects to use when rendering
78
 * @param time Current time, in milliseconds.
79
 */
80
  public void renderTo(DistortedInputSurface surface, MeshObject mesh, DistortedEffects effects, long time)
81
    {
82
    surface.create();  // Watch out  - this needs to be before
83
    create();          // the 'setAsInput' because this has side-effects!
84

  
85
    if( surface.setAsInput() )
86
      {
87
      DistortedRenderable.deleteAllMarked();
88
      effects.drawPriv(surface.getWidth()/2.0f, surface.getHeight()/2.0f, mesh, this, time);
89
      }
90
    }
91

  
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93
/**
94
 * Draws the Tree, and all its children, to the Framebuffer.
95
 * <p>
96
 * Must be called from a thread holding OpenGL Context.
97
 *
98
 * @param dt DistortedTree to render.
99
 * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the Tree.
100
 */
101
  public void renderTo(DistortedTree dt, long time)
102
    {
103
    DistortedRenderable.deleteAllMarked();
104
    create();
105
    dt.drawRecursive(time,this);
106
    }
107

  
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109
/**
110
 * Create new Projection matrix.
111
 *
112
 * @param fov Vertical 'field of view' of the Projection frustrum (in degrees).
113
 * @param x X-coordinate of the point at which our camera looks at. 0 is the center.
114
 * @param y Y-coordinate of the point at which our camera looks at. 0 is the center.
115
 */
116
  public void setProjection(float fov, float x, float y)
117
    {
118
    mProjection.set(fov,x,y);
119
    mProjection.createProjection();
120
    }
121

  
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123
/**
124
 * Resize the underlying Projection.
125
 *
126
 * @param width The new width.
127
 * @param height The new height.
128
 */
129
  public void resize(int width, int height)
130
    {
131
    if( mProjection.resize(width,height) )
132
      {
133
      mSizeX = width;
134
      mSizeY = height;
135
      }
136
    }
137

  
138
//////////////////////////////////////////////////////////////////////////////////////////////////
139
/**
140
 * Return Projection stored in this Framebuffer.
141
 *
142
 * @return DistortedProjection object.
143
 */
144
  public DistortedProjection getProjection()
145
    {
146
    return mProjection;
147
    }
148
  }
src/main/java/org/distorted/library/DistortedSurface.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
/**
25
 * Abstract Surface.
26
 */
27

  
28
interface DistortedSurface
29
{
30
/**
31
 * Create the underlying OpenGL part of the Surface.
32
 */
33
  void create();
34
/**
35
 * Return a unique ID of this Surface.
36
 */
37
  long getID();
38
/**
39
 * Return the width of this Surface.
40
 */
41
  int getWidth();
42
/**
43
 * Return the height of this Surface.
44
 */
45
  int getHeight();
46
}
src/main/java/org/distorted/library/DistortedTexture.java
29 29
 * Class which represents a OpenGL Texture object.
30 30
 * <p>
31 31
 * Create a Texture of arbitrary size and feed some pixels to it via the setTexture() method.
32
 * <p>
33
 * Keep all objects created in a static LinkedList. The point: we need to be able to mark
34
 * Textures 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
 * framework where one is able to mark for deletion at any time and actual deletion takes place
37
 * on the next render).
38 32
 */
39
public class DistortedTexture extends DistortedRenderable
33
public class DistortedTexture extends DistortedRenderable implements DistortedInputSurface
40 34
  {
41 35
  private Bitmap mBmp= null;
42 36

  
......
61 55
///////////////////////////////////////////////////////////////////////////////////////////////////
62 56
// must be called from a thread holding OpenGL Context
63 57

  
64
  void create()
58
  public void create()
65 59
    {
66 60
    if( mBmp!=null && mColorH !=null )
67 61
      {
......
104 98
    {
105 99
    if( mColorH[0]!=DONT_CREATE ) mColorH[0] = NOT_CREATED_YET;
106 100
    }
101

  
107 102
///////////////////////////////////////////////////////////////////////////////////////////////////
108 103

  
109 104
  static void getUniforms(int mProgramH)
......
126 121
    mBmp= null;
127 122
    }
128 123

  
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125
/**
126
 * Bind the underlying rectangle of pixels as a OpenGL Texture.
127
 */
128
  public boolean setAsInput()
129
    {
130
    if( mColorH[0]>0 )
131
      {
132
      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[0]);
133
      return true;
134
      }
135

  
136
    return false;
137
    }
138

  
129 139
///////////////////////////////////////////////////////////////////////////////////////////////////
130 140
/**
131 141
 * Sets the underlying android.graphics.Bitmap object.
src/main/java/org/distorted/library/DistortedTree.java
38 38

  
39 39
  private MeshObject mMesh;
40 40
  private DistortedEffects mEffects;
41
  private DistortedRenderable mRenderable;
41
  private DistortedInputSurface mSurface;
42 42
  private NodeData mData;
43 43

  
44 44
  private DistortedTree mParent;
......
94 94
    {
95 95
    ArrayList<Long> ret = new ArrayList<>();
96 96
     
97
    ret.add( mRenderable.getID() );
97
    ret.add( mSurface.getID() );
98 98
    DistortedTree node;
99 99
   
100 100
    for(int i=0; i<mNumChildren[0]; i++)
......
125 125
      if( newList.size()>1 )
126 126
        {
127 127
        if( mData.mFBO ==null )
128
          mData.mFBO = new DistortedFramebuffer(mRenderable.getWidth(), mRenderable.getHeight());
128
          mData.mFBO = new DistortedFramebuffer(mSurface.getWidth(), mSurface.getHeight());
129 129
        }
130 130
      else
131 131
        {
......
198 198
*/
199 199
///////////////////////////////////////////////////////////////////////////////////////////////////
200 200

  
201
  void drawRecursive(long currTime, DistortedFramebuffer df)
201
  void drawRecursive(long currTime, DistortedOutputSurface surface)
202 202
    {
203
    mRenderable.create();
204
    float halfX = mRenderable.getWidth()/2.0f;
205
    float halfY = mRenderable.getHeight()/2.0f;
203
    mSurface.create();
204
    float halfX = mSurface.getWidth()/2.0f;
205
    float halfY = mSurface.getHeight()/2.0f;
206 206

  
207 207
    if( mNumChildren[0]<=0 )
208 208
      {
209
      mRenderable.setAsInput();
209
      mSurface.setAsInput();
210 210
      }
211 211
    else
212 212
      {
......
219 219
        GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
220 220
        GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
221 221

  
222
        if( mRenderable.setAsInput() )
223
          DistortedEffects.drawNoEffectsPriv(halfX, halfY, mMesh, mData.mFBO);
222
        if( mSurface.setAsInput() )
223
          DistortedEffects.drawNoEffectsPriv(halfX, halfY, mMesh, mData.mFBO.getProjection() );
224 224

  
225 225
        synchronized(this)
226 226
          {
......
236 236
      mData.mFBO.setAsInput();
237 237
      }
238 238

  
239
    mEffects.drawPriv(halfX, halfY, mMesh, df, currTime);
239
    mEffects.drawPriv(halfX, halfY, mMesh, surface, currTime);
240 240
    }
241 241

  
242 242
///////////////////////////////////////////////////////////////////////////////////////////////////
......
245 245
/**
246 246
 * Constructs new Node of the Tree.
247 247
 *     
248
 * @param renderable DistortedRenderable to put into the new Node.
248
 * @param surface InputSurface to put into the new Node.
249 249
 * @param effects DistortedEffects to put into the new Node.
250 250
 * @param mesh MeshObject to put into the new Node.
251 251
 */
252
  public DistortedTree(DistortedRenderable renderable, DistortedEffects effects, MeshObject mesh)
252
  public DistortedTree(DistortedInputSurface surface, DistortedEffects effects, MeshObject mesh)
253 253
    {
254
    mRenderable    = renderable;
254
    mSurface       = surface;
255 255
    mEffects       = effects;
256 256
    mMesh          = mesh;
257 257
    mParent        = null;
......
260 260
    mNumChildren[0]= 0;
261 261
   
262 262
    ArrayList<Long> list = new ArrayList<>();
263
    list.add(mRenderable.getID());
263
    list.add(mSurface.getID());
264 264

  
265 265
    mData = mMapNodeID.get(list);
266 266
   
......
293 293

  
294 294
    if( (flags & Distorted.CLONE_RENDERABLE) != 0 )
295 295
      {
296
      mRenderable = node.mRenderable;
296
      mSurface = node.mSurface;
297 297
      }
298 298
    else
299 299
      {
300
      int w = node.mRenderable.getWidth();
301
      int h = node.mRenderable.getHeight();
300
      int w = node.mSurface.getWidth();
301
      int h = node.mSurface.getHeight();
302 302

  
303
      if( node.mRenderable instanceof DistortedTexture )
303
      if( node.mSurface instanceof DistortedTexture )
304 304
        {
305
        mRenderable = new DistortedTexture(w,h);
305
        mSurface = new DistortedTexture(w,h);
306 306
        }
307
      else if( node.mRenderable instanceof DistortedFramebuffer )
307
      else if( node.mSurface instanceof DistortedFramebuffer )
308 308
        {
309
        boolean hasDepth = ((DistortedFramebuffer) node.mRenderable).hasDepth();
310
        mRenderable = new DistortedFramebuffer(w,h,hasDepth);
309
        boolean hasDepth = ((DistortedFramebuffer) node.mSurface).hasDepth();
310
        mSurface = new DistortedFramebuffer(w,h,hasDepth);
311 311
        }
312 312
      }
313 313
    if( (flags & Distorted.CLONE_CHILDREN) != 0 )
......
360 360
/**
361 361
 * Adds a new child to the last position in the list of our Node's children.
362 362
 * 
363
 * @param renderable DistortedRenderable to initialize our child Node with.
363
 * @param surface InputSurface to initialize our child Node with.
364 364
 * @param effects DistortedEffects to initialize our child Node with.
365 365
 * @param mesh MeshObject to initialize our child Node with.
366 366
 * @return the newly constructed child Node, or null if we couldn't allocate resources.
367 367
 */
368
  public synchronized DistortedTree attach(DistortedRenderable renderable, DistortedEffects effects, MeshObject mesh)
368
  public synchronized DistortedTree attach(DistortedInputSurface surface, DistortedEffects effects, MeshObject mesh)
369 369
    {
370 370
    ArrayList<Long> prev = generateIDList(); 
371 371
      
372 372
    if( mChildren==null ) mChildren = new ArrayList<>(2);
373
    DistortedTree node = new DistortedTree(renderable,effects,mesh);
373
    DistortedTree node = new DistortedTree(surface,effects,mesh);
374 374
    node.mParent = this;
375 375
    mChildren.add(node);
376 376
    mNumChildren[0]++;
......
474 474

  
475 475
///////////////////////////////////////////////////////////////////////////////////////////////////
476 476
/**
477
 * Returns the DistortedRenderable object that's in the Node.
477
 * Returns the DistortedInputSurface object that's in the Node.
478 478
 *
479
 * @return The DistortedRenderable contained in the Node.
479
 * @return The DistortedInputSurface contained in the Node.
480 480
 */
481
  public DistortedRenderable getRenderable()
481
  public DistortedInputSurface getSurface()
482 482
    {
483
    return mRenderable;
483
    return mSurface;
484 484
    }
485 485

  
486 486
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/EffectQueueMatrix.java
107 107
///////////////////////////////////////////////////////////////////////////////////////////////////
108 108
// here construct the ModelView and the ModelViewProjection Matrices
109 109

  
110
  void constructMatrices(DistortedFramebuffer df, float halfX, float halfY)
110
  void constructMatrices(DistortedProjection projection, float halfX, float halfY)
111 111
    {
112 112
    Matrix.setIdentityM(mViewMatrix, 0);
113
    Matrix.translateM(mViewMatrix, 0, -df.mWidth/2, df.mHeight/2, -df.mDistance);
113
    Matrix.translateM(mViewMatrix, 0, -projection.mWidth/2, projection.mHeight/2, -projection.mDistance);
114 114

  
115 115
    float x,y,z, sx,sy,sz;
116 116

  
......
184 184
      }
185 185

  
186 186
    Matrix.translateM(mViewMatrix, 0, halfX,-halfY, 0);
187
    Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mViewMatrix, 0);
187
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
188 188
    }
189 189

  
190 190
///////////////////////////////////////////////////////////////////////////////////////////////////
......
284 284

  
285 285
///////////////////////////////////////////////////////////////////////////////////////////////////
286 286

  
287
  synchronized void send(DistortedFramebuffer df, float halfX, float halfY, float halfZ)
287
  synchronized void send(DistortedProjection projection, float halfX, float halfY, float halfZ)
288 288
    {
289
    constructMatrices(df,halfX,halfY);
289
    constructMatrices(projection,halfX,halfY);
290 290

  
291 291
    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
292
    GLES30.glUniform1f( mDepthH, df.mDepth);
292
    GLES30.glUniform1f( mDepthH, projection.mDepth);
293 293
    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
294 294
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
295 295
    }
......
297 297
///////////////////////////////////////////////////////////////////////////////////////////////////
298 298
// here construct the ModelView Matrix, but without any effects
299 299

  
300
  synchronized static void sendZero(DistortedFramebuffer df, float halfX, float halfY, float halfZ)
300
  synchronized static void sendZero(DistortedProjection projection, float halfX, float halfY, float halfZ)
301 301
    {
302 302
    Matrix.setIdentityM(mTmpMatrix, 0);
303
    Matrix.translateM(mTmpMatrix, 0, halfX-df.mWidth/2, df.mHeight/2-halfY, -df.mDistance);
304
    Matrix.multiplyMM(mMVPMatrix, 0, df.mProjectionMatrix, 0, mTmpMatrix, 0);
303
    Matrix.translateM(mTmpMatrix, 0, halfX-projection.mWidth/2, projection.mHeight/2-halfY, -projection.mDistance);
304
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mTmpMatrix, 0);
305 305
    
306 306
    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
307
    GLES30.glUniform1f( mDepthH, df.mDepth);
307
    GLES30.glUniform1f( mDepthH, projection.mDepth);
308 308
    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mTmpMatrix, 0);
309 309
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix, 0);
310 310
    }
src/main/java/org/distorted/library/EffectQueuePostprocess.java
229 229
// w,h - width and height of the input texture. MVP - Model-View-Projection matrix to apply to the
230 230
// texture; df - output FBO.
231 231

  
232
  synchronized void render(float w, float h, float[] mvp, DistortedFramebuffer df)
232
  synchronized void render(float w, float h, float[] mvp, DistortedOutputSurface surface)
233 233
    {
234 234
    mBlurProgram.useProgram();
235 235

  
236
    DistortedProjection inputP  = mBufferFBO.getProjection();
237
    DistortedProjection outputP = surface.getProjection();
238

  
236 239
    int radius = (int)mUniforms[0];
237 240
    if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
238 241
    computeGaussianKernel(radius);
......
252 255
    GLES30.glViewport(0, 0, (int)w, (int)h);
253 256

  
254 257
    Matrix.setIdentityM(mTmpMatrix, 0);
255
    Matrix.translateM(mTmpMatrix, 0, 0, 0, -mBufferFBO.mDistance);
256
    Matrix.multiplyMM(mMVPMatrix, 0, mBufferFBO.mProjectionMatrix, 0, mTmpMatrix, 0);
258
    Matrix.translateM(mTmpMatrix, 0, 0, 0, -inputP.mDistance);
259
    Matrix.multiplyMM(mMVPMatrix, 0, inputP.mProjectionMatrix, 0, mTmpMatrix, 0);
257 260

  
258 261
    // horizontal blur
259 262
    GLES30.glUniform1fv( mOffsetsH ,radius+1, mOffsets,0);
......
263 266
    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
264 267

  
265 268
    mBufferFBO.setAsInput();
266
    df.setAsOutput();
267
    GLES30.glViewport(0, 0, df.mWidth, df.mHeight);
269
    surface.setAsOutput();
270

  
271
    GLES30.glViewport(0, 0, outputP.mWidth, outputP.mHeight);
268 272

  
269 273
    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w;
270 274

  

Also available in: Unified diff