Project

General

Profile

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

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

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
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 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
40 bd3da5b2 Leszek Koltunski
  boolean mMarked;
41
42 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 bd3da5b2 Leszek Koltunski
// must be called form a thread holding OpenGL Context
113 f6fb3c6d Leszek Koltunski
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 bd3da5b2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 bd3da5b2 Leszek Koltunski
    mFramebufferID = 0;
157 f6fb3c6d Leszek Koltunski
    mTextureID     = TEXTURE_NOT_CREATED_YET;
158 b448e6b9 Leszek Koltunski
    mFOV           = 60.0f;
159 f6fb3c6d Leszek Koltunski
    mX             = 0.0f;
160
    mY             = 0.0f;
161
162 bd3da5b2 Leszek Koltunski
    mMarked = false;
163
164 f6fb3c6d Leszek Koltunski
    createProjection();
165
    }
166
167 b448e6b9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 bd3da5b2 Leszek Koltunski
179
    mMarked = false;
180 b448e6b9 Leszek Koltunski
    }
181
182 f6fb3c6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
183
184 bd3da5b2 Leszek Koltunski
  public void markForDeletion()
185 f6fb3c6d Leszek Koltunski
    {
186 bd3da5b2 Leszek Koltunski
    DistortedRenderTargetList.markForDeletion();
187
    mMarked = true;
188 f6fb3c6d Leszek Koltunski
    }
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 bd3da5b2 Leszek Koltunski
    if( mWidth!=width || mHeight!=height )
206
      {
207
      mWidth = width;
208
      mHeight= height;
209 f6fb3c6d Leszek Koltunski
210 bd3da5b2 Leszek Koltunski
      createProjection();
211 f6fb3c6d Leszek Koltunski
212 bd3da5b2 Leszek Koltunski
      if( mTextureID>0 ) markForDeletion();
213
      }
214 f6fb3c6d Leszek Koltunski
    }
215
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217
218
  public int getFBO()
219
    {
220
    return mFramebufferID;
221
    }
222
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224 bd3da5b2 Leszek Koltunski
// set this as Render Target to draw to. Must be called from a thread holding OpenGL context.
225 f6fb3c6d Leszek Koltunski
226 bd3da5b2 Leszek Koltunski
  public void setOutput()
227 f6fb3c6d Leszek Koltunski
    {
228
    if( mTextureID==TEXTURE_NOT_CREATED_YET ) createFBO();
229
230 b448e6b9 Leszek Koltunski
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebufferID);
231 f6fb3c6d Leszek Koltunski
    }
232 bd3da5b2 Leszek Koltunski
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 f6fb3c6d Leszek Koltunski
  }