|
|
@ -4,7 +4,6 @@ package com.otaliastudios.cameraview; |
|
|
|
import android.opengl.GLES11Ext; |
|
|
|
import android.opengl.GLES11Ext; |
|
|
|
import android.opengl.GLES20; |
|
|
|
import android.opengl.GLES20; |
|
|
|
import android.opengl.Matrix; |
|
|
|
import android.opengl.Matrix; |
|
|
|
import android.util.Log; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.nio.FloatBuffer; |
|
|
|
import java.nio.FloatBuffer; |
|
|
|
|
|
|
|
|
|
|
@ -27,18 +26,6 @@ class EglViewport extends EglElement { |
|
|
|
" vTextureCoord = (uTexMatrix * aTextureCoord).xy;\n" + |
|
|
|
" vTextureCoord = (uTexMatrix * aTextureCoord).xy;\n" + |
|
|
|
"}\n"; |
|
|
|
"}\n"; |
|
|
|
|
|
|
|
|
|
|
|
// Simple vertex shader.
|
|
|
|
|
|
|
|
private static final String OVERLAY_VERTEX_SHADER = |
|
|
|
|
|
|
|
"uniform mat4 uMVPMatrix;\n" + |
|
|
|
|
|
|
|
"uniform mat4 uOverlayTexMatrix;\n" + |
|
|
|
|
|
|
|
"attribute vec4 aPosition;\n" + |
|
|
|
|
|
|
|
"attribute vec4 aTextureCoord;\n" + |
|
|
|
|
|
|
|
"varying vec2 vOverlayTextureCoord;\n" + |
|
|
|
|
|
|
|
"void main() {\n" + |
|
|
|
|
|
|
|
" gl_Position = uMVPMatrix * aPosition;\n" + |
|
|
|
|
|
|
|
" vOverlayTextureCoord = (uOverlayTexMatrix * aTextureCoord).xy;\n" + |
|
|
|
|
|
|
|
"}\n"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Simple fragment shader for use with external 2D textures
|
|
|
|
// Simple fragment shader for use with external 2D textures
|
|
|
|
private static final String SIMPLE_FRAGMENT_SHADER = |
|
|
|
private static final String SIMPLE_FRAGMENT_SHADER = |
|
|
|
"#extension GL_OES_EGL_image_external : require\n" + |
|
|
|
"#extension GL_OES_EGL_image_external : require\n" + |
|
|
@ -49,29 +36,14 @@ class EglViewport extends EglElement { |
|
|
|
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + |
|
|
|
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + |
|
|
|
"}\n"; |
|
|
|
"}\n"; |
|
|
|
|
|
|
|
|
|
|
|
// Fragment shader for use with two external 2D textures.
|
|
|
|
|
|
|
|
// A overlay texture will act as a layer on top of the camera texture,
|
|
|
|
|
|
|
|
// it covers the preview when alpha is 1 and lets the camera texture through when alpha is less
|
|
|
|
|
|
|
|
// than 1.
|
|
|
|
|
|
|
|
private static final String OVERLAY_FRAGMENT_SHADER = |
|
|
|
|
|
|
|
"#extension GL_OES_EGL_image_external : require\n" + |
|
|
|
|
|
|
|
"precision mediump float;\n" + |
|
|
|
|
|
|
|
"varying vec2 vOverlayTextureCoord;\n" + |
|
|
|
|
|
|
|
"uniform samplerExternalOES overlayTexture;\n" + |
|
|
|
|
|
|
|
"void main() {\n" + |
|
|
|
|
|
|
|
" lowp vec4 c1 = texture2D(overlayTexture, vOverlayTextureCoord);\n" + |
|
|
|
|
|
|
|
" if (c1.a == 0.0){ discard; }\n" + |
|
|
|
|
|
|
|
" gl_FragColor = c1;\n" + |
|
|
|
|
|
|
|
"}\n"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Stuff from Drawable2d.FULL_RECTANGLE
|
|
|
|
// Stuff from Drawable2d.FULL_RECTANGLE
|
|
|
|
// A full square, extending from -1 to +1 in both dimensions.
|
|
|
|
// A full square, extending from -1 to +1 in both dimensions.
|
|
|
|
// When the model/view/projection matrix is identity, this will exactly cover the viewport.
|
|
|
|
// When the model/view/projection matrix is identity, this will exactly cover the viewport.
|
|
|
|
private static final float FULL_RECTANGLE_COORDS[] = { |
|
|
|
private static final float FULL_RECTANGLE_COORDS[] = { |
|
|
|
-1.0f, -1.0f, // 0 bottom left
|
|
|
|
-1.0f, -1.0f, // 0 bottom left
|
|
|
|
1.0f, -1.0f, // 1 bottom right
|
|
|
|
1.0f, -1.0f, // 1 bottom right
|
|
|
|
-1.0f, 1.0f, // 2 top left
|
|
|
|
-1.0f, 1.0f, // 2 top left
|
|
|
|
1.0f, 1.0f, // 3 top right
|
|
|
|
1.0f, 1.0f, // 3 top right
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// Stuff from Drawable2d.FULL_RECTANGLE
|
|
|
|
// Stuff from Drawable2d.FULL_RECTANGLE
|
|
|
@ -90,38 +62,20 @@ class EglViewport extends EglElement { |
|
|
|
|
|
|
|
|
|
|
|
// Stuff from Texture2dProgram
|
|
|
|
// Stuff from Texture2dProgram
|
|
|
|
private int mProgramHandle; |
|
|
|
private int mProgramHandle; |
|
|
|
private int mProgramHandleOverlay; |
|
|
|
|
|
|
|
private int mTextureTarget; |
|
|
|
private int mTextureTarget; |
|
|
|
// Program attributes
|
|
|
|
// Program attributes
|
|
|
|
private int muMVPMatrixLocation; |
|
|
|
private int muMVPMatrixLocation; |
|
|
|
private int muOverlayMVPMatrixLocation; |
|
|
|
|
|
|
|
private int muTexMatrixLocation; |
|
|
|
private int muTexMatrixLocation; |
|
|
|
private int muOverlayTexMatrixLocation; |
|
|
|
|
|
|
|
private int muTextureLocation; |
|
|
|
|
|
|
|
private int muOverlayTextureLocation; |
|
|
|
|
|
|
|
private int maPositionLocation; |
|
|
|
private int maPositionLocation; |
|
|
|
private int maOverlayPositionLocation; |
|
|
|
|
|
|
|
private int maTextureCoordLocation; |
|
|
|
private int maTextureCoordLocation; |
|
|
|
private int maOverlayTextureCoordLocation; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// private int muKernelLoc; // Used for filtering
|
|
|
|
// private int muKernelLoc; // Used for filtering
|
|
|
|
// private int muTexOffsetLoc; // Used for filtering
|
|
|
|
// private int muTexOffsetLoc; // Used for filtering
|
|
|
|
// private int muColorAdjustLoc; // Used for filtering
|
|
|
|
// private int muColorAdjustLoc; // Used for filtering
|
|
|
|
|
|
|
|
|
|
|
|
private final boolean mHasOverlay; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EglViewport() { |
|
|
|
EglViewport() { |
|
|
|
this(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EglViewport(boolean hasOverlay) { |
|
|
|
|
|
|
|
mHasOverlay = hasOverlay; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mTextureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES; |
|
|
|
mTextureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES; |
|
|
|
mProgramHandle = createProgram(SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER); |
|
|
|
mProgramHandle = createProgram(SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER); |
|
|
|
mProgramHandleOverlay = createProgram(OVERLAY_VERTEX_SHADER, OVERLAY_FRAGMENT_SHADER); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maPositionLocation = GLES20.glGetAttribLocation(mProgramHandle, "aPosition"); |
|
|
|
maPositionLocation = GLES20.glGetAttribLocation(mProgramHandle, "aPosition"); |
|
|
|
checkLocation(maPositionLocation, "aPosition"); |
|
|
|
checkLocation(maPositionLocation, "aPosition"); |
|
|
|
maTextureCoordLocation = GLES20.glGetAttribLocation(mProgramHandle, "aTextureCoord"); |
|
|
|
maTextureCoordLocation = GLES20.glGetAttribLocation(mProgramHandle, "aTextureCoord"); |
|
|
@ -131,22 +85,6 @@ class EglViewport extends EglElement { |
|
|
|
muTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uTexMatrix"); |
|
|
|
muTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandle, "uTexMatrix"); |
|
|
|
checkLocation(muTexMatrixLocation, "uTexMatrix"); |
|
|
|
checkLocation(muTexMatrixLocation, "uTexMatrix"); |
|
|
|
|
|
|
|
|
|
|
|
maOverlayPositionLocation = GLES20.glGetAttribLocation(mProgramHandleOverlay, "aPosition"); |
|
|
|
|
|
|
|
checkLocation(maOverlayPositionLocation, "aPosition"); |
|
|
|
|
|
|
|
maOverlayTextureCoordLocation = GLES20.glGetAttribLocation(mProgramHandleOverlay, "aTextureCoord"); |
|
|
|
|
|
|
|
checkLocation(maOverlayTextureCoordLocation, "aTextureCoord"); |
|
|
|
|
|
|
|
muOverlayMVPMatrixLocation = GLES20.glGetUniformLocation(mProgramHandleOverlay, "uMVPMatrix"); |
|
|
|
|
|
|
|
checkLocation(muOverlayMVPMatrixLocation, "uMVPMatrix"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mHasOverlay) { |
|
|
|
|
|
|
|
muOverlayTexMatrixLocation = GLES20.glGetUniformLocation(mProgramHandleOverlay, "uOverlayTexMatrix"); |
|
|
|
|
|
|
|
checkLocation(muOverlayTexMatrixLocation, "uOverlayTexMatrix"); |
|
|
|
|
|
|
|
muOverlayTextureLocation = GLES20.glGetUniformLocation(mProgramHandleOverlay, "overlayTexture"); |
|
|
|
|
|
|
|
checkLocation(muOverlayTextureLocation, "overlayTexture"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
muTextureLocation = GLES20.glGetUniformLocation(mProgramHandle, "sTexture"); |
|
|
|
|
|
|
|
checkLocation(muTextureLocation, "sTexture"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Stuff from Drawable2d.FULL_RECTANGLE
|
|
|
|
// Stuff from Drawable2d.FULL_RECTANGLE
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
@ -161,20 +99,13 @@ class EglViewport extends EglElement { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int createTexture() { |
|
|
|
int createTexture() { |
|
|
|
return createTextures()[0]; |
|
|
|
int[] textures = new int[1]; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int[] createTextures() { |
|
|
|
|
|
|
|
// index 0 is reserved for the camera texture, index 1 is reserved for the overlay texture
|
|
|
|
|
|
|
|
int numTextures = mHasOverlay ? 2 : 1; |
|
|
|
|
|
|
|
int[] textures = new int[numTextures]; |
|
|
|
|
|
|
|
GLES20.glGenTextures(1, textures, 0); |
|
|
|
GLES20.glGenTextures(1, textures, 0); |
|
|
|
GLES20.glGenTextures(1, textures, 1); |
|
|
|
|
|
|
|
check("glGenTextures"); |
|
|
|
check("glGenTextures"); |
|
|
|
|
|
|
|
|
|
|
|
// camera texture
|
|
|
|
int texId = textures[0]; |
|
|
|
GLES20.glBindTexture(mTextureTarget, textures[0]); |
|
|
|
GLES20.glBindTexture(mTextureTarget, texId); |
|
|
|
check("glBindTexture " + textures[0]); |
|
|
|
check("glBindTexture " + texId); |
|
|
|
|
|
|
|
|
|
|
|
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); |
|
|
|
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); |
|
|
|
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); |
|
|
|
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); |
|
|
@ -182,19 +113,7 @@ class EglViewport extends EglElement { |
|
|
|
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_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); |
|
|
|
check("glTexParameter"); |
|
|
|
check("glTexParameter"); |
|
|
|
|
|
|
|
|
|
|
|
// overlay texture
|
|
|
|
return texId; |
|
|
|
if (mHasOverlay) { |
|
|
|
|
|
|
|
GLES20.glBindTexture(mTextureTarget, textures[1]); |
|
|
|
|
|
|
|
check("glBindTexture " + textures[1]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); |
|
|
|
|
|
|
|
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
check("glTexParameter"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return textures; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void drawFrame(int textureId, float[] textureMatrix) { |
|
|
|
void drawFrame(int textureId, float[] textureMatrix) { |
|
|
@ -203,42 +122,20 @@ class EglViewport extends EglElement { |
|
|
|
mTextureCoordinatesArray); |
|
|
|
mTextureCoordinatesArray); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void drawFrame(int textureId, float[] textureMatrix, |
|
|
|
|
|
|
|
FloatBuffer vertexBuffer, |
|
|
|
|
|
|
|
FloatBuffer texBuffer) { |
|
|
|
|
|
|
|
// 0 is not a valid texture id
|
|
|
|
|
|
|
|
drawFrame(textureId, 0, textureMatrix, null, |
|
|
|
|
|
|
|
vertexBuffer, |
|
|
|
|
|
|
|
texBuffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void drawFrameOverlay(int overlayTextureId, float[] overlayTextureMatrix) { |
|
|
|
|
|
|
|
drawFrameOverlay(overlayTextureId, overlayTextureMatrix, |
|
|
|
|
|
|
|
mVertexCoordinatesArray, |
|
|
|
|
|
|
|
mTextureCoordinatesArray); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void drawFrame(int textureId, int overlayTextureId, float[] textureMatrix, float[] overlayTextureMatrix) { |
|
|
|
|
|
|
|
drawFrame(textureId, overlayTextureId, textureMatrix, overlayTextureMatrix, |
|
|
|
|
|
|
|
mVertexCoordinatesArray, |
|
|
|
|
|
|
|
mTextureCoordinatesArray); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The issue with the CIRCLE shader is that if the textureMatrix has a scale value, |
|
|
|
* The issue with the CIRCLE shader is that if the textureMatrix has a scale value, |
|
|
|
* it fails miserably, not taking the scale into account. |
|
|
|
* it fails miserably, not taking the scale into account. |
|
|
|
* So what we can do here is |
|
|
|
* So what we can do here is |
|
|
|
* <p> |
|
|
|
* |
|
|
|
* - read textureMatrix scaleX and scaleY values. This is pretty much impossible to do from the matrix itself |
|
|
|
* - read textureMatrix scaleX and scaleY values. This is pretty much impossible to do from the matrix itself |
|
|
|
* without making risky assumptions over the order of operations. |
|
|
|
* without making risky assumptions over the order of operations. |
|
|
|
* https://www.opengl.org/discussion_boards/showthread.php/159215-Is-it-possible-to-extract-rotation-translation-scale-given-a-matrix
|
|
|
|
* https://www.opengl.org/discussion_boards/showthread.php/159215-Is-it-possible-to-extract-rotation-translation-scale-given-a-matrix
|
|
|
|
* So we prefer passing scaleX and scaleY here to the draw function. |
|
|
|
* So we prefer passing scaleX and scaleY here to the draw function. |
|
|
|
* - pass these values to the vertex shader |
|
|
|
* - pass these values to the vertex shader |
|
|
|
* - pass them to the fragment shader |
|
|
|
* - pass them to the fragment shader |
|
|
|
* - in the fragment shader, take this scale value into account |
|
|
|
* - in the fragment shader, take this scale value into account |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private void drawFrame(int textureId, int overlayTextureId, float[] textureMatrix, float[] overlayTextureMatrix, |
|
|
|
private void drawFrame(int textureId, float[] textureMatrix, |
|
|
|
FloatBuffer vertexBuffer, |
|
|
|
FloatBuffer vertexBuffer, |
|
|
|
FloatBuffer texBuffer) { |
|
|
|
FloatBuffer texBuffer) { |
|
|
|
check("draw start"); |
|
|
|
check("draw start"); |
|
|
@ -247,10 +144,15 @@ class EglViewport extends EglElement { |
|
|
|
GLES20.glUseProgram(mProgramHandle); |
|
|
|
GLES20.glUseProgram(mProgramHandle); |
|
|
|
check("glUseProgram"); |
|
|
|
check("glUseProgram"); |
|
|
|
|
|
|
|
|
|
|
|
// Set the camera texture.
|
|
|
|
// enable blending, from: http://www.learnopengles.com/android-lesson-five-an-introduction-to-blending/
|
|
|
|
|
|
|
|
GLES20.glDisable(GLES20.GL_CULL_FACE); |
|
|
|
|
|
|
|
GLES20.glDisable(GLES20.GL_DEPTH_TEST); |
|
|
|
|
|
|
|
GLES20.glEnable(GLES20.GL_BLEND); |
|
|
|
|
|
|
|
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set the texture.
|
|
|
|
GLES20.glActiveTexture(GLES20.GL_TEXTURE0); |
|
|
|
GLES20.glActiveTexture(GLES20.GL_TEXTURE0); |
|
|
|
GLES20.glBindTexture(mTextureTarget, textureId); |
|
|
|
GLES20.glBindTexture(mTextureTarget, textureId); |
|
|
|
GLES20.glUniform1i(muTextureLocation, 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy the model / view / projection matrix over.
|
|
|
|
// Copy the model / view / projection matrix over.
|
|
|
|
GLES20.glUniformMatrix4fv(muMVPMatrixLocation, 1, false, IDENTITY_MATRIX, 0); |
|
|
|
GLES20.glUniformMatrix4fv(muMVPMatrixLocation, 1, false, IDENTITY_MATRIX, 0); |
|
|
@ -274,72 +176,15 @@ class EglViewport extends EglElement { |
|
|
|
GLES20.glVertexAttribPointer(maTextureCoordLocation, 2, GLES20.GL_FLOAT, false, 8, texBuffer); |
|
|
|
GLES20.glVertexAttribPointer(maTextureCoordLocation, 2, GLES20.GL_FLOAT, false, 8, texBuffer); |
|
|
|
check("glVertexAttribPointer"); |
|
|
|
check("glVertexAttribPointer"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Draw the rect.
|
|
|
|
// Draw the rect.
|
|
|
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, VERTEX_COUNT); |
|
|
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, VERTEX_COUNT); |
|
|
|
check("glDrawArrays"); |
|
|
|
check("glDrawArrays"); |
|
|
|
|
|
|
|
|
|
|
|
// Done -- disable vertex array, textures, and program.
|
|
|
|
// Done -- disable vertex array, texture, and program.
|
|
|
|
GLES20.glDisableVertexAttribArray(maPositionLocation); |
|
|
|
GLES20.glDisableVertexAttribArray(maPositionLocation); |
|
|
|
GLES20.glDisableVertexAttribArray(maTextureCoordLocation); |
|
|
|
GLES20.glDisableVertexAttribArray(maTextureCoordLocation); |
|
|
|
GLES20.glBindTexture(mTextureTarget, 0); |
|
|
|
GLES20.glBindTexture(mTextureTarget, 0); |
|
|
|
GLES20.glUseProgram(0); |
|
|
|
GLES20.glUseProgram(0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void drawFrameOverlay(int overlayTextureId, float[] overlayTextureMatrix, |
|
|
|
|
|
|
|
FloatBuffer vertexBuffer, |
|
|
|
|
|
|
|
FloatBuffer texBuffer) { |
|
|
|
|
|
|
|
check("draw start"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Select the program.
|
|
|
|
|
|
|
|
GLES20.glUseProgram(mProgramHandleOverlay); |
|
|
|
|
|
|
|
check("glUseProgram"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// No culling of back faces
|
|
|
|
|
|
|
|
GLES20.glDisable(GLES20.GL_CULL_FACE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// No depth testing
|
|
|
|
|
|
|
|
GLES20.glDisable(GLES20.GL_DEPTH_TEST); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Enable blending
|
|
|
|
|
|
|
|
GLES20.glEnable(GLES20.GL_BLEND); |
|
|
|
|
|
|
|
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GLES20.glActiveTexture(GLES20.GL_TEXTURE1); |
|
|
|
|
|
|
|
GLES20.glBindTexture(mTextureTarget, overlayTextureId); |
|
|
|
|
|
|
|
GLES20.glUniform1i(muOverlayTextureLocation, 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy the model / view / projection matrix over.
|
|
|
|
|
|
|
|
GLES20.glUniformMatrix4fv(muOverlayMVPMatrixLocation, 1, false, IDENTITY_MATRIX, 0); |
|
|
|
|
|
|
|
check("glUniformMatrix4fv"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy the texture transformation matrix over.
|
|
|
|
|
|
|
|
GLES20.glUniformMatrix4fv(muOverlayTexMatrixLocation, 1, false, overlayTextureMatrix, 0); |
|
|
|
|
|
|
|
check("glUniformMatrix4fv"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Enable the "aPosition" vertex attribute.
|
|
|
|
|
|
|
|
// Connect vertexBuffer to "aPosition".
|
|
|
|
|
|
|
|
GLES20.glEnableVertexAttribArray(maOverlayPositionLocation); |
|
|
|
|
|
|
|
check("glEnableVertexAttribArray"); |
|
|
|
|
|
|
|
GLES20.glVertexAttribPointer(maOverlayPositionLocation, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer); |
|
|
|
|
|
|
|
check("glVertexAttribPointer"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Enable the "aTextureCoord" vertex attribute.
|
|
|
|
|
|
|
|
// Connect texBuffer to "aTextureCoord".
|
|
|
|
|
|
|
|
GLES20.glEnableVertexAttribArray(maOverlayTextureCoordLocation); |
|
|
|
|
|
|
|
check("glEnableVertexAttribArray"); |
|
|
|
|
|
|
|
GLES20.glVertexAttribPointer(maOverlayTextureCoordLocation, 2, GLES20.GL_FLOAT, false, 8, texBuffer); |
|
|
|
|
|
|
|
check("glVertexAttribPointer"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Draw the rect.
|
|
|
|
|
|
|
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, VERTEX_COUNT); |
|
|
|
|
|
|
|
check("glDrawArrays"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Done -- disable vertex array, textures, and program.
|
|
|
|
|
|
|
|
GLES20.glDisableVertexAttribArray(maOverlayPositionLocation); |
|
|
|
|
|
|
|
GLES20.glDisableVertexAttribArray(maOverlayTextureCoordLocation); |
|
|
|
|
|
|
|
GLES20.glBindTexture(mTextureTarget, 0); |
|
|
|
|
|
|
|
GLES20.glUseProgram(0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|