Project

General

Profile

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

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

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.GLES20;
23
import android.opengl.Matrix;
24

    
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

    
27
public class DistortedFramebuffer
28
  {
29
  private static final int TEXTURE_FAILED_TO_CREATE = -1;
30
  private static final int TEXTURE_NOT_CREATED_YET  = -2;
31
  private static final int TEXTURE_DONT_CREATE      = -3;
32

    
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
  boolean mMarked;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
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
// must be called form a thread holding OpenGL Context
112

    
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
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
147
// PUBLIC API
148

    
149
  public DistortedFramebuffer(int width, int height)
150
    {
151
    mProjectionMatrix = new float[16];
152

    
153
    mHeight        = height;
154
    mWidth         = width;
155
    mFramebufferID = 0;
156
    mTextureID     = TEXTURE_NOT_CREATED_YET;
157
    mFOV           = 60.0f;
158
    mX             = 0.0f;
159
    mY             = 0.0f;
160

    
161
    mMarked = false;
162

    
163
    createProjection();
164
    }
165

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

    
168
  public DistortedFramebuffer(int fbo)
169
    {
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

    
178
    mMarked = false;
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  public void markForDeletion()
184
    {
185
    DistortedFramebufferList.markForDeletion();
186
    mMarked = true;
187
    }
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
    if( mWidth!=width || mHeight!=height )
205
      {
206
      mWidth = width;
207
      mHeight= height;
208

    
209
      createProjection();
210

    
211
      if( mTextureID>0 ) markForDeletion();
212
      }
213
    }
214

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

    
217
  public int getFBO()
218
    {
219
    return mFramebufferID;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223
// set this as Render Target to draw to. Must be called from a thread holding OpenGL context.
224

    
225
  public void setOutput()
226
    {
227
    if( mTextureID==TEXTURE_NOT_CREATED_YET ) createFBO();
228

    
229
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebufferID);
230
    }
231

    
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
  }
(6-6/19)