下面列出了怎么用javax.microedition.khronos.egl.EGLConfig的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
LogUtil.i(TAG, "onSurfaceCreated:");
// This renderer required OES_EGL_image_external extension
final String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS); // API >= 8
if (!extensions.contains("OES_EGL_image_external")) {
throw new RuntimeException("This system does not support OES_EGL_image_external.");
}
// create textur ID
hTex = GLDrawer2D.initTex();
// create SurfaceTexture with texture ID.
mSTexture = new SurfaceTexture(hTex);
mSTexture.setOnFrameAvailableListener(this);
// clear screen with yellow color so that you can see rendering rectangle
GLES20.glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
final CameraGLView parent = mWeakParent.get();
if (parent != null) {
parent.mHasSurface = true;
}
// create object for preview display
mDrawer = new GLDrawer2D();
mDrawer.setMatrix(mMvpMatrix, 0);
}
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
program = GlUtil.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER);
GLES20.glUseProgram(program);
int posLocation = GLES20.glGetAttribLocation(program, "in_pos");
GLES20.glEnableVertexAttribArray(posLocation);
GLES20.glVertexAttribPointer(posLocation, 2, GLES20.GL_FLOAT, false, 0, TEXTURE_VERTICES);
texLocations[0] = GLES20.glGetAttribLocation(program, "in_tc_y");
GLES20.glEnableVertexAttribArray(texLocations[0]);
texLocations[1] = GLES20.glGetAttribLocation(program, "in_tc_u");
GLES20.glEnableVertexAttribArray(texLocations[1]);
texLocations[2] = GLES20.glGetAttribLocation(program, "in_tc_v");
GLES20.glEnableVertexAttribArray(texLocations[2]);
GlUtil.checkGlError();
colorMatrixLocation = GLES20.glGetUniformLocation(program, "mColorConversion");
GlUtil.checkGlError();
setupTextures();
GlUtil.checkGlError();
}
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
EGLConfig config, Object nativeWindow) {
EGLSurface result = null;
try {
result = egl.eglCreateWindowSurface(display, config, nativeWindow, null);
} catch (IllegalArgumentException e) {
// This exception indicates that the surface flinger surface
// is not valid. This can happen if the surface flinger surface has
// been torn down, but the application has not yet been
// notified via SurfaceHolder.Callback.surfaceDestroyed.
// In theory the application should be notified first,
// but in practice sometimes it is not. See b/4588890
Log.e(TAG, "eglCreateWindowSurface", e);
}
return result;
}
@Override
public EGLConfig chooseConfig(final EGL10 egl, final EGLDisplay display) {
// 要求されている仕様から使用可能な構成の数を抽出します。
final int[] num_config = new int[1];
if (!egl.eglChooseConfig(display, configSpec, null, 0, num_config)) {
throw new IllegalArgumentException("eglChooseConfig failed");
}
final int config_size = num_config[0];
if (config_size <= 0) {
throw new IllegalArgumentException("No configs match configSpec");
}
// 実際の構成を抽出します。
final EGLConfig[] configs = new EGLConfig[config_size];
if (!egl.eglChooseConfig(display, configSpec, configs, config_size, num_config)) {
throw new IllegalArgumentException("eglChooseConfig#2 failed");
}
final EGLConfig config = chooseConfig(egl, display, configs);
if (config == null) {
throw new IllegalArgumentException("No config chosen");
}
return config;
}
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] num_config = new int[1];
if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig failed");
}
int numConfigs = num_config[0];
if (numConfigs <= 0) {
throw new IllegalArgumentException(
"No configs match configSpec");
}
EGLConfig[] configs = new EGLConfig[numConfigs];
if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig#2 failed");
}
EGLConfig config = chooseConfig(egl, display, configs);
if (config == null) {
throw new IllegalArgumentException("No config chosen");
}
return config;
}
@RendererThread
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
mOutputViewport = new EglViewport();
mOutputTextureId = mOutputViewport.createTexture();
mInputSurfaceTexture = new SurfaceTexture(mOutputTextureId);
getView().queueEvent(new Runnable() {
@Override
public void run() {
for (RendererFrameCallback callback : mRendererFrameCallbacks) {
callback.onRendererTextureCreated(mOutputTextureId);
}
}
});
// Since we are using GLSurfaceView.RENDERMODE_WHEN_DIRTY, we must notify the SurfaceView
// of dirtyness, so that it draws again. This is how it's done.
mInputSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
getView().requestRender(); // requestRender is thread-safe.
}
});
}
private EGLContext createEglContext(
EGLContext sharedContext, EGLDisplay eglDisplay, EGLConfig eglConfig) {
if (sharedContext != null && sharedContext == EGL10.EGL_NO_CONTEXT) {
throw new RuntimeException("Invalid sharedContext");
}
int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
EGLContext rootContext = sharedContext == null ? EGL10.EGL_NO_CONTEXT : sharedContext;
final EGLContext eglContext;
synchronized (EglBase.lock) {
eglContext = egl.eglCreateContext(eglDisplay, eglConfig, rootContext, contextAttributes);
}
if (eglContext == EGL10.EGL_NO_CONTEXT) {
throw new RuntimeException(
"Failed to create EGL context: 0x" + Integer.toHexString(egl.eglGetError()));
}
return eglContext;
}
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] num_config = new int[1];
if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig failed");
}
int numConfigs = num_config[0];
if (numConfigs <= 0) {
throw new IllegalArgumentException(
"No configs match configSpec");
}
EGLConfig[] configs = new EGLConfig[numConfigs];
if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig#2 failed");
}
EGLConfig config = chooseConfig(egl, display, configs);
if (config == null) {
throw new IllegalArgumentException("No config chosen");
}
return config;
}
private void listConfig() {
Log.i(TAG, "Config List {");
for (EGLConfig config : mEGLConfigs) {
int d, s, r, g, b, a;
// Expand on this logic to dump other attributes
d = getConfigAttrib(config, EGL_DEPTH_SIZE);
s = getConfigAttrib(config, EGL_STENCIL_SIZE);
r = getConfigAttrib(config, EGL_RED_SIZE);
g = getConfigAttrib(config, EGL_GREEN_SIZE);
b = getConfigAttrib(config, EGL_BLUE_SIZE);
a = getConfigAttrib(config, EGL_ALPHA_SIZE);
Log.i(TAG, " <d,s,r,g,b,a> = <" + d + "," + s + "," +
r + "," + g + "," + b + "," + a + ">");
}
Log.i(TAG, "}");
}
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES20.glGetBooleanv(GLES20.GL_SHADER_COMPILER, mShaderCompilerSupport, 0);
if (!mShaderCompilerSupport[0]) {
String msg = "OpenGL error; GLSL shader compiler not supported.";
showError(msg);
return;
}
try {
String vertexSource = loadRawString(R.raw.star_vs);
String fragmentSource = loadRawString(R.raw.star_fs);
mShaderStar.setProgram(vertexSource, fragmentSource);
} catch (Exception ex) {
showError(ex.getMessage());
}
}
private EGLConfig chooseConfig() {
int[] attribList = new int[] {
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, 4,
EGL_NONE
};
// No error checking performed, minimum required code to elucidate logic
// Expand on this logic to be more selective in choosing a configuration
int[] numConfig = new int[1];
mEGL.eglChooseConfig(mEGLDisplay, attribList, null, 0, numConfig);
int configSize = numConfig[0];
mEGLConfigs = new EGLConfig[configSize];
mEGL.eglChooseConfig(mEGLDisplay, attribList, mEGLConfigs, configSize, numConfig);
if (LIST_CONFIGS) {
listConfig();
}
return mEGLConfigs[0]; // Best match is probably the first configuration
}
private EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] configAttributes) {
EGLConfig[] configs = new EGLConfig[1];
int[] numConfigs = new int[1];
if (!egl.eglChooseConfig(eglDisplay, configAttributes, configs, configs.length, numConfigs)) {
throw new RuntimeException(
"eglChooseConfig failed: 0x" + Integer.toHexString(egl.eglGetError()));
}
if (numConfigs[0] <= 0) {
throw new RuntimeException("Unable to find any matching EGL config");
}
final EGLConfig eglConfig = configs[0];
if (eglConfig == null) {
throw new RuntimeException("eglChooseConfig returned null");
}
return eglConfig;
}
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
EGLConfig[] configs) {
for (EGLConfig config : configs) {
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0);
if ((d >= mDepthSize) && (s >= mStencilSize)) {
int r = findConfigAttrib(egl, display, config,
EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config,
EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config,
EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config,
EGL10.EGL_ALPHA_SIZE, 0);
if ((r == mRedSize) && (g == mGreenSize)
&& (b == mBlueSize) && (a == mAlphaSize)) {
return config;
}
}
}
return null;
}
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
EGLConfig config, Object nativeWindow) {
EGLSurface result = null;
try {
result = egl.eglCreateWindowSurface(display, config, nativeWindow, null);
} catch (IllegalArgumentException e) {
// This exception indicates that the surface flinger surface
// is not valid. This can happen if the surface flinger surface has
// been torn down, but the application has not yet been
// notified via SurfaceHolder.Callback.surfaceDestroyed.
// In theory the application should be notified first,
// but in practice sometimes it is not. See b/4588890
Log.e(TAG, "eglCreateWindowSurface", e);
}
return result;
}
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
EGLConfig config, Object nativeWindow) {
EGLSurface result = null;
try {
result = egl.eglCreateWindowSurface(display, config, nativeWindow, null);
} catch (IllegalArgumentException e) {
// This exception indicates that the surface flinger surface
// is not valid. This can happen if the surface flinger surface has
// been torn down, but the application has not yet been
// notified via SurfaceHolder.Callback.surfaceDestroyed.
// In theory the application should be notified first,
// but in practice sometimes it is not. See b/4588890
Log.e(TAG, "eglCreateWindowSurface", e);
}
return result;
}
@Override
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
EGLConfig config, Object nativeWindow) {
int[] surfaceAttribs = {
EGL10.EGL_NONE
};
EGLSurface result = null;
try {
result = egl.eglCreateWindowSurface(display, config, nativeWindow, surfaceAttribs);
} catch (IllegalArgumentException e) {
// This exception indicates that the surface flinger surface
// is not valid. This can happen if the surface flinger surface has
// been torn down, but the application has not yet been
// notified via SurfaceHolder.Callback.surfaceDestroyed.
// In theory the application should be notified first,
// but in practice sometimes it is not. See b/4588890
Log.e("DefaultWindow", "eglCreateWindowSurface", e);
}
return result;
}
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] num_config = new int[1];
if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig failed");
}
int numConfigs = num_config[0];
if (numConfigs <= 0) {
throw new IllegalArgumentException(
"No configs match configSpec");
}
EGLConfig[] configs = new EGLConfig[numConfigs];
if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig#2 failed");
}
EGLConfig config = chooseConfig(egl, display, configs);
if (config == null) {
throw new IllegalArgumentException("No config chosen");
}
return config;
}
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
EGLConfig[] configs) {
for (EGLConfig config : configs) {
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0);
if ((d >= mDepthSize) && (s >= mStencilSize)) {
int r = findConfigAttrib(egl, display, config,
EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config,
EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config,
EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config,
EGL10.EGL_ALPHA_SIZE, 0);
if ((r == mRedSize) && (g == mGreenSize)
&& (b == mBlueSize) && (a == mAlphaSize)) {
return config;
}
}
}
return null;
}
private void listConfig() {
Log.i(TAG, "Config List {");
for (EGLConfig config : mEGLConfigs) {
int d, s, r, g, b, a;
// Expand on this logic to dump other attributes
d = getConfigAttrib(config, EGL_DEPTH_SIZE);
s = getConfigAttrib(config, EGL_STENCIL_SIZE);
r = getConfigAttrib(config, EGL_RED_SIZE);
g = getConfigAttrib(config, EGL_GREEN_SIZE);
b = getConfigAttrib(config, EGL_BLUE_SIZE);
a = getConfigAttrib(config, EGL_ALPHA_SIZE);
Log.i(TAG, " <d,s,r,g,b,a> = <" + d + "," + s + "," +
r + "," + g + "," + b + "," + a + ">");
}
Log.i(TAG, "}");
}
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
EGLConfig[] configs) {
for (EGLConfig config : configs) {
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0);
if ((d >= mDepthSize) && (s >= mStencilSize)) {
int r = findConfigAttrib(egl, display, config,
EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config,
EGL10.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config,
EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config,
EGL10.EGL_ALPHA_SIZE, 0);
if ((r == mRedSize) && (g == mGreenSize)
&& (b == mBlueSize) && (a == mAlphaSize)) {
return config;
}
}
}
return null;
}
public boolean eglChooseConfig(EGLDisplay display, int[] attrib_list,
EGLConfig[] configs, int config_size, int[] num_config) {
begin("eglChooseConfig");
arg("display", display);
arg("attrib_list", attrib_list);
arg("config_size", config_size);
end();
boolean result = mEgl10.eglChooseConfig(display, attrib_list, configs,
config_size, num_config);
arg("configs", configs);
arg("num_config", num_config);
returns(result);
checkError();
return result;
}
public EGLContext eglCreateContext(EGLDisplay display, EGLConfig config,
EGLContext share_context, int[] attrib_list) {
begin("eglCreateContext");
arg("display", display);
arg("config", config);
arg("share_context", share_context);
arg("attrib_list", attrib_list);
end();
EGLContext result = mEgl10.eglCreateContext(display, config,
share_context, attrib_list);
returns(result);
checkError();
return result;
}
public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
EGLConfig config, Object nativeWindow) {
EGLSurface result = null;
d = display;
c = config;
try {
mEGLPreviewSurface = egl.eglCreateWindowSurface(display, config, nativeWindow, null);
} catch (IllegalArgumentException e) {
Log.e(TAG, "eglCreateWindowSurface (native)", e);
}
// this return will trigger Renderer
result = mEGLPreviewSurface;
return result;
}
public VIASurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
setEGLContextClientVersion(2);
mRenderer = new AdavanceRenderer(context);
if(true) {
setEGLConfigChooser(new EGLConfigChooser() {
@Override
public EGLConfig chooseConfig(EGL10 egl10, EGLDisplay eglDisplay) {
final int[] attribList = {EGL14.EGL_RED_SIZE, 8, //
EGL14.EGL_GREEN_SIZE, 8, //
EGL14.EGL_BLUE_SIZE, 8, //
EGL14.EGL_ALPHA_SIZE, 8, //
EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, //
EGL14.EGL_NONE, 0, //
EGL14.EGL_NONE};
attribList[attribList.length - 3] = EGL_RECORDABLE_ANDROID;
attribList[attribList.length - 2] = 1;
int[] configNum = new int[1];
EGLConfig config = null;
egl10.eglChooseConfig(eglDisplay, attribList, null, 0, configNum);
int num = configNum[0];
if (num != 0) {
EGLConfig[] configs = new EGLConfig[num];
egl10.eglChooseConfig(eglDisplay, attribList, configs, num, configNum);
config = configs[0];
}
return config;
}
});
}
setEGLContextFactory(mRenderer.mContextFactory);
setEGLWindowSurfaceFactory(mRenderer.mWindowSurfaceFactory);
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
@Override
public EGLContext createContext(final EGL10 egl, final EGLDisplay display, final EGLConfig config) {
final int[] attrib_list;
if (EGLContextClientVersion != 0) {
attrib_list = new int[]{EGL_CONTEXT_CLIENT_VERSION, EGLContextClientVersion, EGL_NONE};
} else {
attrib_list = null;
}
return egl.eglCreateContext(display, config, EGL_NO_CONTEXT, attrib_list);
}
public boolean eglGetConfigs(EGLDisplay display, EGLConfig[] configs,
int config_size, int[] num_config) {
begin("eglGetConfigs");
arg("display", display);
arg("config_size", config_size);
end();
boolean result = mEgl10.eglGetConfigs(display, configs, config_size,
num_config);
arg("configs", configs);
arg("num_config", num_config);
returns(result);
checkError();
return result;
}
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
Log.d(TAG, "onSurfaceCreated");
// We're starting up or coming back. Either way we've got a new EGLContext that will
// need to be shared with the video encoder, so figure out if a recording is already
// in progress.
mRecordingEnabled = mVideoEncoder.isRecording();
if (mRecordingEnabled) {
mRecordingStatus = RECORDING_RESUMED;
} else {
mRecordingStatus = RECORDING_OFF;
}
// Set up the texture blitter that will be used for on-screen display. This
// is *not* applied to the recording, because that uses a separate shader.
mFullScreen = new FullFrameRect(
new Texture2dProgram(Texture2dProgram.ProgramType.TEXTURE_EXT));
mTextureId = mFullScreen.createTextureObject();
// Create a SurfaceTexture, with an external texture, in this EGL context. We don't
// have a Looper in this thread -- GLSurfaceView doesn't create one -- so the frame
// available messages will arrive on the main thread.
mSurfaceTexture = new SurfaceTexture(mTextureId);
// Tell the UI thread to enable the camera preview.
mCameraHandler.sendMessage(mCameraHandler.obtainMessage(
CameraCaptureActivity.CameraHandler.MSG_SET_SURFACE_TEXTURE, mSurfaceTexture));
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Create OES texture for storing camera preview data(YUV format)
GLES20.glGenTextures(1, camTextureId, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, camTextureId[0]);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
surfaceTexture = new SurfaceTexture(camTextureId[0]);
surfaceTexture.setOnFrameAvailableListener(this);
// Prepare vertex and texture coordinates
int bytes = vertexCoords.length * Float.SIZE / Byte.SIZE;
vertexCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexCoordsBuffer.put(vertexCoords).position(0);
textureCoordsBuffer.put(textureCoords).position(0);
// Create vertex and fragment shaders
// camTextureId->fboTexureId
progCam2FBO = Utils.createShaderProgram(vss, fssCam2FBO);
vcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vPosition");
tcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcCam2FBO);
GLES20.glEnableVertexAttribArray(tcCam2FBO);
// fboTexureId/drawTexureId -> screen
progTex2Screen = Utils.createShaderProgram(vss, fssTex2Screen);
vcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vPosition");
tcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcTex2Screen);
GLES20.glEnableVertexAttribArray(tcTex2Screen);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Create OES texture for storing camera preview data(YUV format)
GLES20.glGenTextures(1, camTextureId, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, camTextureId[0]);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
surfaceTexture = new SurfaceTexture(camTextureId[0]);
surfaceTexture.setOnFrameAvailableListener(this);
// Prepare vertex and texture coordinates
int bytes = vertexCoords.length * Float.SIZE / Byte.SIZE;
vertexCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexCoordsBuffer.put(vertexCoords).position(0);
textureCoordsBuffer.put(textureCoords).position(0);
// Create vertex and fragment shaders
// camTextureId->fboTexureId
progCam2FBO = Utils.createShaderProgram(vss, fssCam2FBO);
vcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vPosition");
tcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcCam2FBO);
GLES20.glEnableVertexAttribArray(tcCam2FBO);
// fboTexureId/drawTexureId -> screen
progTex2Screen = Utils.createShaderProgram(vss, fssTex2Screen);
vcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vPosition");
tcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcTex2Screen);
GLES20.glEnableVertexAttribArray(tcTex2Screen);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Create OES texture for storing camera preview data(YUV format)
GLES20.glGenTextures(1, camTextureId, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, camTextureId[0]);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
surfaceTexture = new SurfaceTexture(camTextureId[0]);
surfaceTexture.setOnFrameAvailableListener(this);
// Prepare vertex and texture coordinates
int bytes = vertexCoords.length * Float.SIZE / Byte.SIZE;
vertexCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexCoordsBuffer.put(vertexCoords).position(0);
textureCoordsBuffer.put(textureCoords).position(0);
// Create vertex and fragment shaders
// camTextureId->fboTexureId
progCam2FBO = Utils.createShaderProgram(vss, fssCam2FBO);
vcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vPosition");
tcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcCam2FBO);
GLES20.glEnableVertexAttribArray(tcCam2FBO);
// fboTexureId/drawTexureId -> screen
progTex2Screen = Utils.createShaderProgram(vss, fssTex2Screen);
vcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vPosition");
tcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vTexCoord");
GLES20.glEnableVertexAttribArray(vcTex2Screen);
GLES20.glEnableVertexAttribArray(tcTex2Screen);
}