Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ 64a642c1

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