Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedFramebuffer.java @ ed13a5de

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