Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ 16d8b8f3

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
    int[] textureIds = new int[1];
84
    GLES20.glGenTextures(1, textureIds, 0);
85
    mTextureID = textureIds[0];
86
    int[] mFBORenderToTexture = new int[1];
87
88
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
89
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
90
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
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.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mWidth, mHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
94
95
    GLES20.glGenFramebuffers(1, mFBORenderToTexture, 0);
96
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFBORenderToTexture[0]);
97
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mTextureID, 0);
98
    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
99
100
    if(status != GLES20.GL_FRAMEBUFFER_COMPLETE)
101
      {
102
      android.util.Log.e("RenderTarget", "failed to create framebuffer, error="+status);
103
104
      GLES20.glDeleteTextures(1, textureIds, 0);
105
      GLES20.glDeleteFramebuffers(1, mFBORenderToTexture, 0);
106
      mFramebufferID = 0;
107
      mTextureID = TEXTURE_FAILED_TO_CREATE;
108
      return false;
109
      }
110
111
    mFramebufferID = mFBORenderToTexture[0];
112
113 16d8b8f3 Leszek Koltunski
    android.util.Log.e("FBO", "creating ("+mWidth+","+mHeight+") "+mFramebufferID);
114
115 f6fb3c6d Leszek Koltunski
    return true;
116
    }
117
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119 bd3da5b2 Leszek Koltunski
// must be called form a thread holding OpenGL Context
120 f6fb3c6d Leszek Koltunski
121
  private void deleteFBO()
122
    {
123 16d8b8f3 Leszek Koltunski
    android.util.Log.e("FBO", "deleting ("+mWidth+","+mHeight+") "+mFramebufferID);
124
125 f6fb3c6d Leszek Koltunski
    int[] textureIds = new int[1];
126
    int[] mFBORenderToTexture = new int[1];
127
128
    textureIds[0] = mTextureID;
129
    mFBORenderToTexture[0] = mFramebufferID;
130
131
    GLES20.glDeleteTextures(1, textureIds, 0);
132
    GLES20.glDeleteFramebuffers(1, mFBORenderToTexture, 0);
133
134
    mFramebufferID = 0;
135
    mTextureID = TEXTURE_NOT_CREATED_YET;
136
    }
137
138 bd3da5b2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
139 16d8b8f3 Leszek Koltunski
// must be called from a thread holding OpenGL Context
140 bd3da5b2 Leszek Koltunski
141
  void release()
142
    {
143
    if( mTextureID>=0 ) deleteFBO();
144
145
    mProjectionMatrix = null;
146
    mMarked = false;
147
    }
148
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150
151
  void reset()
152
    {
153
    mTextureID = TEXTURE_NOT_CREATED_YET;
154
    }
155
156 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
157
// PUBLIC API
158
159 ed13a5de Leszek Koltunski
  public DistortedFramebuffer(int width, int height)
160 f6fb3c6d Leszek Koltunski
    {
161
    mProjectionMatrix = new float[16];
162
163
    mHeight        = height;
164
    mWidth         = width;
165 16d8b8f3 Leszek Koltunski
    mFramebufferID = -1;
166 f6fb3c6d Leszek Koltunski
    mTextureID     = TEXTURE_NOT_CREATED_YET;
167 b448e6b9 Leszek Koltunski
    mFOV           = 60.0f;
168 f6fb3c6d Leszek Koltunski
    mX             = 0.0f;
169
    mY             = 0.0f;
170
171 bd3da5b2 Leszek Koltunski
    mMarked = false;
172
173 f6fb3c6d Leszek Koltunski
    createProjection();
174 16d8b8f3 Leszek Koltunski
175
    DistortedFramebufferList.add(this);
176 f6fb3c6d Leszek Koltunski
    }
177
178 b448e6b9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
179
180 ed13a5de Leszek Koltunski
  public DistortedFramebuffer(int fbo)
181 b448e6b9 Leszek Koltunski
    {
182
    mProjectionMatrix = new float[16];
183
184
    mFramebufferID = fbo;
185
    mTextureID     = TEXTURE_DONT_CREATE;
186
    mFOV           = 60.0f;
187
    mX             = 0.0f;
188
    mY             = 0.0f;
189 bd3da5b2 Leszek Koltunski
190
    mMarked = false;
191 b448e6b9 Leszek Koltunski
    }
192
193 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
194
195 bd3da5b2 Leszek Koltunski
  public void markForDeletion()
196 f6fb3c6d Leszek Koltunski
    {
197 16d8b8f3 Leszek Koltunski
    android.util.Log.e("FBO", "marking for deletion ("+mWidth+","+mHeight+") "+mFramebufferID);
198
199 ed13a5de Leszek Koltunski
    DistortedFramebufferList.markForDeletion();
200 bd3da5b2 Leszek Koltunski
    mMarked = true;
201 f6fb3c6d Leszek Koltunski
    }
202
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
205
  public void setProjection(float FOV, float x, float y)
206
    {
207
    mFOV = FOV;
208
    mX   = x;
209
    mY   = y;
210
211
    createProjection();
212
    }
213
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215
216
  public void resize(int width, int height)
217
    {
218 bd3da5b2 Leszek Koltunski
    if( mWidth!=width || mHeight!=height )
219
      {
220
      mWidth = width;
221
      mHeight= height;
222 f6fb3c6d Leszek Koltunski
223 bd3da5b2 Leszek Koltunski
      createProjection();
224 f6fb3c6d Leszek Koltunski
225 bd3da5b2 Leszek Koltunski
      if( mTextureID>0 ) markForDeletion();
226
      }
227 f6fb3c6d Leszek Koltunski
    }
228
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230
231
  public int getFBO()
232
    {
233
    return mFramebufferID;
234
    }
235
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237 bd3da5b2 Leszek Koltunski
// set this as Render Target to draw to. Must be called from a thread holding OpenGL context.
238 f6fb3c6d Leszek Koltunski
239 bd3da5b2 Leszek Koltunski
  public void setOutput()
240 f6fb3c6d Leszek Koltunski
    {
241
    if( mTextureID==TEXTURE_NOT_CREATED_YET ) createFBO();
242
243 b448e6b9 Leszek Koltunski
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebufferID);
244 f6fb3c6d Leszek Koltunski
    }
245 bd3da5b2 Leszek Koltunski
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247
// set this as Render Target to draw from. Must be called from a thread holding OpenGL context.
248
249
  public void setInput()
250
    {
251
    if( mTextureID==TEXTURE_NOT_CREATED_YET ) createFBO();
252
253
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
254
    }
255
256 f6fb3c6d Leszek Koltunski
  }