Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ 7304d89f

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
///////////////////////////////////////////////////////////////////////////////////////////////////
26
27 ed13a5de Leszek Koltunski
public class DistortedFramebuffer
28 f6fb3c6d Leszek Koltunski
  {
29
  private static final int TEXTURE_FAILED_TO_CREATE = -1;
30
  private static final int TEXTURE_NOT_CREATED_YET  = -2;
31 b448e6b9 Leszek Koltunski
  private static final int TEXTURE_DONT_CREATE      = -3;
32 f6fb3c6d Leszek Koltunski
33
  private float mX, mY;
34
  private float mFOV;
35
36 7304d89f Leszek Koltunski
  private int[] texIds = new int[1];
37
  private int[] fboIds = new int[1];
38
39 f6fb3c6d Leszek Koltunski
  int mWidth,mHeight,mDepth,mDistance;
40
  float[] mProjectionMatrix;
41 bd3da5b2 Leszek Koltunski
  boolean mMarked;
42
43 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
44
45
  private void createProjection()
46
    {
47
    float ratio  = (float) mWidth / mHeight;
48
    float left   =-ratio;          //
49
    float right  = ratio;          // Create a new perspective projection matrix.
50
    float bottom = -1.0f;          //
51
    float top    =  1.0f;          // any change to those values will have serious consequences!
52
    float near, far;
53
54
    if( mFOV>0.0f )  // perspective projection
55
      {
56
      near= (float)(top / Math.tan(mFOV*Math.PI/360));
57
      mDistance = (int)(mHeight*near/(top-bottom));
58
      far = 2*mDistance-near;
59
60 16d8b8f3 Leszek Koltunski
      if( far<=0 )
61
        {
62
        android.util.Log.e("FBO", "error: far<=0. width="+mWidth+" height="+mHeight+
63
                           " mFOV="+mFOV+" mDistance="+mDistance+" far="+far+" near="+near);
64
        }
65
      else
66
        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
67 f6fb3c6d Leszek Koltunski
      }
68
    else                      // parallel projection
69
      {
70
      near= (float)(top / Math.tan(Math.PI/360));
71
      mDistance = (int)(mHeight*near/(top-bottom));
72
      far = 2*mDistance-near;
73
74
      Matrix.orthoM(mProjectionMatrix, 0, -mWidth/2, mWidth/2,-mHeight/2, mHeight/2, near, far);
75
      }
76
77
    mDepth = (int)((far-near)/2);
78
    }
79
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81
// must be called form a thread holding OpenGL Context
82
83
  private boolean createFBO()
84
    {
85 64a642c1 Leszek Koltunski
    GLES20.glGenTextures(1, texIds, 0);
86 f6fb3c6d Leszek Koltunski
87 7304d89f Leszek Koltunski
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIds[0]);
88 f6fb3c6d Leszek Koltunski
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
89
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
90
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
91
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
92
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mWidth, mHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
93
94 64a642c1 Leszek Koltunski
    GLES20.glGenFramebuffers(1, fboIds, 0);
95
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
96 7304d89f Leszek Koltunski
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texIds[0], 0);
97 f6fb3c6d Leszek Koltunski
    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
98
99
    if(status != GLES20.GL_FRAMEBUFFER_COMPLETE)
100
      {
101 64a642c1 Leszek Koltunski
      android.util.Log.e("DistortedFramebuffer", "failed to create framebuffer, error="+status);
102 f6fb3c6d Leszek Koltunski
103 64a642c1 Leszek Koltunski
      GLES20.glDeleteTextures(1, texIds, 0);
104
      GLES20.glDeleteFramebuffers(1, fboIds, 0);
105 7304d89f Leszek Koltunski
      fboIds[0] = 0;
106
      texIds[0] = TEXTURE_FAILED_TO_CREATE;
107 f6fb3c6d Leszek Koltunski
      return false;
108
      }
109
110 7304d89f Leszek Koltunski
    android.util.Log.e("FBO", "creating ("+mWidth+","+mHeight+") "+fboIds[0]);
111 16d8b8f3 Leszek Koltunski
112 f6fb3c6d Leszek Koltunski
    return true;
113
    }
114
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116 bd3da5b2 Leszek Koltunski
// must be called form a thread holding OpenGL Context
117 f6fb3c6d Leszek Koltunski
118
  private void deleteFBO()
119
    {
120 7304d89f Leszek Koltunski
    android.util.Log.e("FBO", "deleting ("+mWidth+","+mHeight+") "+fboIds[0]);
121 f6fb3c6d Leszek Koltunski
122 64a642c1 Leszek Koltunski
    GLES20.glDeleteTextures(1, texIds, 0);
123
    GLES20.glDeleteFramebuffers(1, fboIds, 0);
124 f6fb3c6d Leszek Koltunski
125 7304d89f Leszek Koltunski
    fboIds[0] = 0;
126
    texIds[0] = TEXTURE_NOT_CREATED_YET;
127 f6fb3c6d Leszek Koltunski
    }
128
129 bd3da5b2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
130 16d8b8f3 Leszek Koltunski
// must be called from a thread holding OpenGL Context
131 bd3da5b2 Leszek Koltunski
132
  void release()
133
    {
134 7304d89f Leszek Koltunski
    if( texIds[0]>=0 ) deleteFBO();
135 bd3da5b2 Leszek Koltunski
136
    mProjectionMatrix = null;
137
    mMarked = false;
138
    }
139
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
142
  void reset()
143
    {
144 7304d89f Leszek Koltunski
    texIds[0] = TEXTURE_NOT_CREATED_YET;
145 bd3da5b2 Leszek Koltunski
    }
146
147 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
148
// PUBLIC API
149
150 ed13a5de Leszek Koltunski
  public DistortedFramebuffer(int width, int height)
151 f6fb3c6d Leszek Koltunski
    {
152
    mProjectionMatrix = new float[16];
153
154
    mHeight        = height;
155
    mWidth         = width;
156 7304d89f Leszek Koltunski
    fboIds[0]      = -1;
157
    texIds[0]      = TEXTURE_NOT_CREATED_YET;
158 b448e6b9 Leszek Koltunski
    mFOV           = 60.0f;
159 f6fb3c6d Leszek Koltunski
    mX             = 0.0f;
160
    mY             = 0.0f;
161
162 bd3da5b2 Leszek Koltunski
    mMarked = false;
163
164 f6fb3c6d Leszek Koltunski
    createProjection();
165 16d8b8f3 Leszek Koltunski
166
    DistortedFramebufferList.add(this);
167 f6fb3c6d Leszek Koltunski
    }
168
169 b448e6b9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
170
171 ed13a5de Leszek Koltunski
  public DistortedFramebuffer(int fbo)
172 b448e6b9 Leszek Koltunski
    {
173
    mProjectionMatrix = new float[16];
174
175 7304d89f Leszek Koltunski
    fboIds[0]      = fbo;
176
    texIds[0]      = TEXTURE_DONT_CREATE;
177 b448e6b9 Leszek Koltunski
    mFOV           = 60.0f;
178
    mX             = 0.0f;
179
    mY             = 0.0f;
180 bd3da5b2 Leszek Koltunski
181
    mMarked = false;
182 b448e6b9 Leszek Koltunski
    }
183
184 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
185
186 bd3da5b2 Leszek Koltunski
  public void markForDeletion()
187 f6fb3c6d Leszek Koltunski
    {
188 7304d89f Leszek Koltunski
    android.util.Log.e("FBO", "marking for deletion ("+mWidth+","+mHeight+") "+fboIds[0]);
189 16d8b8f3 Leszek Koltunski
190 ed13a5de Leszek Koltunski
    DistortedFramebufferList.markForDeletion();
191 bd3da5b2 Leszek Koltunski
    mMarked = true;
192 f6fb3c6d Leszek Koltunski
    }
193
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195
196
  public void setProjection(float FOV, float x, float y)
197
    {
198
    mFOV = FOV;
199
    mX   = x;
200
    mY   = y;
201
202
    createProjection();
203
    }
204
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
207
  public void resize(int width, int height)
208
    {
209 bd3da5b2 Leszek Koltunski
    if( mWidth!=width || mHeight!=height )
210
      {
211
      mWidth = width;
212
      mHeight= height;
213 f6fb3c6d Leszek Koltunski
214 bd3da5b2 Leszek Koltunski
      createProjection();
215 f6fb3c6d Leszek Koltunski
216 7304d89f Leszek Koltunski
      if( texIds[0]>0 ) markForDeletion();
217 bd3da5b2 Leszek Koltunski
      }
218 f6fb3c6d Leszek Koltunski
    }
219
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
  public int getFBO()
223
    {
224 7304d89f Leszek Koltunski
    return fboIds[0];
225 f6fb3c6d Leszek Koltunski
    }
226
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228 bd3da5b2 Leszek Koltunski
// set this as Render Target to draw to. Must be called from a thread holding OpenGL context.
229 f6fb3c6d Leszek Koltunski
230 bd3da5b2 Leszek Koltunski
  public void setOutput()
231 f6fb3c6d Leszek Koltunski
    {
232 7304d89f Leszek Koltunski
    if( texIds[0]==TEXTURE_NOT_CREATED_YET ) createFBO();
233 f6fb3c6d Leszek Koltunski
234 7304d89f Leszek Koltunski
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
235 f6fb3c6d Leszek Koltunski
    }
236 bd3da5b2 Leszek Koltunski
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
// set this as Render Target to draw from. Must be called from a thread holding OpenGL context.
239
240
  public void setInput()
241
    {
242 7304d89f Leszek Koltunski
    if( texIds[0]==TEXTURE_NOT_CREATED_YET ) createFBO();
243 bd3da5b2 Leszek Koltunski
244 7304d89f Leszek Koltunski
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIds[0]);
245 bd3da5b2 Leszek Koltunski
    }
246
247 f6fb3c6d Leszek Koltunski
  }