Project

General

Profile

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

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

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
///////////////////////////////////////////////////////////////////////////////////////////////////
41

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

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

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

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

    
68
    mDepth = (int)((far-near)/2);
69
    }
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72
// must be called form a thread holding OpenGL Context
73

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

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

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

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

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

    
104
    mFramebufferID = mFBORenderToTexture[0];
105

    
106
    return true;
107
    }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

    
111
  private void deleteFBO()
112
    {
113
    int[] textureIds = new int[1];
114
    int[] mFBORenderToTexture = new int[1];
115

    
116
    textureIds[0] = mTextureID;
117
    mFBORenderToTexture[0] = mFramebufferID;
118

    
119
    GLES20.glDeleteTextures(1, textureIds, 0);
120
    GLES20.glDeleteFramebuffers(1, mFBORenderToTexture, 0);
121

    
122
    mFramebufferID = 0;
123
    mTextureID = TEXTURE_NOT_CREATED_YET;
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127
// PUBLIC API
128

    
129
  public DistortedRenderTarget(int width, int height)
130
    {
131
    mProjectionMatrix = new float[16];
132

    
133
    mHeight        = height;
134
    mWidth         = width;
135
    mFramebufferID = -1;
136
    mTextureID     = TEXTURE_NOT_CREATED_YET;
137
    mFOV           = 60.0f;
138
    mX             = 0.0f;
139
    mY             = 0.0f;
140

    
141
    createProjection();
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  public DistortedRenderTarget(int fbo)
147
    {
148
    mProjectionMatrix = new float[16];
149

    
150
    mFramebufferID = fbo;
151
    mTextureID     = TEXTURE_DONT_CREATE;
152
    mFOV           = 60.0f;
153
    mX             = 0.0f;
154
    mY             = 0.0f;
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  public void release()
160
    {
161
    if( mTextureID>=0 ) deleteFBO();
162

    
163
    mProjectionMatrix = null;
164
    }
165

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

    
168
  public void setProjection(float FOV, float x, float y)
169
    {
170
    mFOV = FOV;
171
    mX   = x;
172
    mY   = y;
173

    
174
    createProjection();
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  public void resize(int width, int height)
180
    {
181
    mWidth = width;
182
    mHeight= height;
183

    
184
    createProjection();
185

    
186
    if( mTextureID>0 ) deleteFBO();
187
    }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

    
191
  public int getFBO()
192
    {
193
    return mFramebufferID;
194
    }
195

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197
// set this as Render Target. Must be called from a thread holding OpenGL context.
198

    
199
  public void use()
200
    {
201
    if( mTextureID==TEXTURE_NOT_CREATED_YET ) createFBO();
202

    
203
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebufferID);
204
    }
205
  }
(12-12/19)