FBO.java
4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.cnlive.demo.stream.gles;
import android.content.Context;
import android.opengl.GLES20;
import android.util.Log;
import com.cnlive.demo.stream.Config;
import com.cnlive.demo.stream.R;
import com.cnlive.demo.stream.filter.CameraFilterBeauty;
/**
* Created by jerikc on 16/2/23.
*/
public class FBO {
private static final String TAG = "FBO";
private boolean mEnable = Config.FILTER_ENABLED;
private int mSurfaceWidth;
private int mSurfaceHeight;
private static int[] mCurveArrays = new int[] {
R.raw.cross_1, R.raw.cross_2, R.raw.cross_3, R.raw.cross_4, R.raw.cross_5,
R.raw.cross_6, R.raw.cross_7, R.raw.cross_8, R.raw.cross_9, R.raw.cross_10,
R.raw.cross_11,
};
private int mCurveIndex = 10;
// Used for off-screen rendering.
private int mOffscreenTexture;
private int mFramebuffer;
private FullFrameRect mFullScreen;
public void updateSurfaceSize(int width, int height) {
if (!mEnable) {
return;
}
mSurfaceWidth = width;
mSurfaceHeight = height;
}
public void initialize(Context context) {
if (!mEnable) {
return;
}
if (mFullScreen != null) {
mFullScreen.release(false);
}
/**
* Create a new full frame renderer with beauty filter.
* There are two another filter, you can have a try.
*/
// mFullScreen = new FullFrameRect(new CameraFilterToneCurve(context,
// context.getResources().openRawResource(mCurveArrays[mCurveIndex])));
// mFullScreen = new FullFrameRect(new CameraFilterMosaic(context));
mFullScreen = new FullFrameRect(new CameraFilterBeauty(context));
mOffscreenTexture = 0;
}
public void release() {
if (!mEnable) {
return;
}
mFullScreen.release(true);
}
/**
* Prepares the off-screen framebuffer.
*/
private void prepareFramebuffer(int width, int height) {
GlUtil.checkGlError("start");
int[] values = new int[1];
// Create a texture object and bind it. This will be the color buffer.
GLES20.glGenTextures(1, values, 0);
GlUtil.checkGlError("glGenTextures");
mOffscreenTexture = values[0]; // expected > 0
Log.i(TAG, "prepareFramebuffer mOffscreenTexture:" + mOffscreenTexture);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mOffscreenTexture);
GlUtil.checkGlError("glBindTexture");
// Create texture storage.
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GlUtil.checkGlError("glTexParameter");
// Create framebuffer object and bind it.
GLES20.glGenFramebuffers(1, values, 0);
GlUtil.checkGlError("glGenFramebuffers");
mFramebuffer = values[0]; // expected > 0
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebuffer);
GlUtil.checkGlError("glBindFramebuffer " + mFramebuffer);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, mOffscreenTexture, 0);
// See if GLES is happy with all this.
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) {
throw new RuntimeException("Framebuffer not complete, status=" + status);
}
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
// Switch back to the default framebuffer.
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GlUtil.checkGlError("glBindFramebuffer");
}
public int drawFrame(int texId, int texWidth, int texHeight) {
if (!mEnable) {
return texId;
}
GLES20.glViewport(0, 0, texWidth, texHeight);
if (mOffscreenTexture == 0) {
prepareFramebuffer(texWidth, texHeight);
}
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebuffer);
mFullScreen.getFilter().setTextureSize(texWidth, texHeight);
mFullScreen.drawFrame(texId);
// Blit to display.
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glViewport(0, 0, mSurfaceWidth, mSurfaceHeight);
return mOffscreenTexture;
}
}