Project

General

Profile

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

library / src / main / java / org / distorted / library / DistortedRenderTarget.java @ bd3da5b2

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 DistortedRenderTarget
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

    
40
  boolean mMarked;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
  private void createProjection()
45
    {
46
    float ratio  = (float) mWidth / mHeight;
47
    float left   =-ratio;          //
48
    float right  = ratio;          // Create a new perspective projection matrix.
49
    float bottom = -1.0f;          //
50
    float top    =  1.0f;          // any change to those values will have serious consequences!
51
    float near, far;
52

    
53
    if( mFOV>0.0f )  // perspective projection
54
      {
55
      near= (float)(top / Math.tan(mFOV*Math.PI/360));
56
      mDistance = (int)(mHeight*near/(top-bottom));
57
      far = 2*mDistance-near;
58

    
59
      Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
60
      }
61
    else                      // parallel projection
62
      {
63
      near= (float)(top / Math.tan(Math.PI/360));
64
      mDistance = (int)(mHeight*near/(top-bottom));
65
      far = 2*mDistance-near;
66

    
67
      Matrix.orthoM(mProjectionMatrix, 0, -mWidth/2, mWidth/2,-mHeight/2, mHeight/2, near, far);
68
      }
69

    
70
    mDepth = (int)((far-near)/2);
71
    }
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74
// must be called form a thread holding OpenGL Context
75

    
76
  private boolean createFBO()
77
    {
78
    int[] textureIds = new int[1];
79
    GLES20.glGenTextures(1, textureIds, 0);
80
    mTextureID = textureIds[0];
81
    int[] mFBORenderToTexture = new int[1];
82

    
83
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
84
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
85
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
86
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
87
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
88
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mWidth, mHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
89

    
90
    GLES20.glGenFramebuffers(1, mFBORenderToTexture, 0);
91
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFBORenderToTexture[0]);
92
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mTextureID, 0);
93
    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
94

    
95
    if(status != GLES20.GL_FRAMEBUFFER_COMPLETE)
96
      {
97
      android.util.Log.e("RenderTarget", "failed to create framebuffer, error="+status);
98

    
99
      GLES20.glDeleteTextures(1, textureIds, 0);
100
      GLES20.glDeleteFramebuffers(1, mFBORenderToTexture, 0);
101
      mFramebufferID = 0;
102
      mTextureID = TEXTURE_FAILED_TO_CREATE;
103
      return false;
104
      }
105

    
106
    mFramebufferID = mFBORenderToTexture[0];
107

    
108
    return true;
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112
// must be called form a thread holding OpenGL Context
113

    
114
  private void deleteFBO()
115
    {
116
    int[] textureIds = new int[1];
117
    int[] mFBORenderToTexture = new int[1];
118

    
119
    textureIds[0] = mTextureID;
120
    mFBORenderToTexture[0] = mFramebufferID;
121

    
122
    GLES20.glDeleteTextures(1, textureIds, 0);
123
    GLES20.glDeleteFramebuffers(1, mFBORenderToTexture, 0);
124

    
125
    mFramebufferID = 0;
126
    mTextureID = TEXTURE_NOT_CREATED_YET;
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130
// must be called form a thread holding OpenGL Context
131

    
132
  void release()
133
    {
134
    if( mTextureID>=0 ) deleteFBO();
135

    
136
    mProjectionMatrix = null;
137
    mMarked = false;
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  void reset()
143
    {
144
    mTextureID = TEXTURE_NOT_CREATED_YET;
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
// PUBLIC API
149

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

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

    
162
    mMarked = false;
163

    
164
    createProjection();
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  public DistortedRenderTarget(int fbo)
170
    {
171
    mProjectionMatrix = new float[16];
172

    
173
    mFramebufferID = fbo;
174
    mTextureID     = TEXTURE_DONT_CREATE;
175
    mFOV           = 60.0f;
176
    mX             = 0.0f;
177
    mY             = 0.0f;
178

    
179
    mMarked = false;
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  public void markForDeletion()
185
    {
186
    DistortedRenderTargetList.markForDeletion();
187
    mMarked = true;
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

    
192
  public void setProjection(float FOV, float x, float y)
193
    {
194
    mFOV = FOV;
195
    mX   = x;
196
    mY   = y;
197

    
198
    createProjection();
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  public void resize(int width, int height)
204
    {
205
    if( mWidth!=width || mHeight!=height )
206
      {
207
      mWidth = width;
208
      mHeight= height;
209

    
210
      createProjection();
211

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

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

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

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

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

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

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234
// set this as Render Target to draw from. Must be called from a thread holding OpenGL context.
235

    
236
  public void setInput()
237
    {
238
    if( mTextureID==TEXTURE_NOT_CREATED_YET ) createFBO();
239

    
240
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);
241
    }
242

    
243
  }
(11-11/19)