Support landscape orientation
Replace hardcoded portrait-only texture coordinate rotation with SurfaceTexture.getTransformMatrix(), so the camera preview and capture re-orient correctly when the device rotates. Also drive Preview/ImageCapture targetRotation from the live display rotation, fix the crop-to-fill aspect math to swap effective camera dimensions between portrait and landscape, and make the slider control panel scroll if it doesn't fit the shorter landscape height. Bump to 1.1.6. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2633f261ef
commit
d321f07973
7 changed files with 127 additions and 55 deletions
|
|
@ -20,6 +20,15 @@ import kotlin.math.sin
|
|||
*/
|
||||
class TiltShiftShader(private val context: Context) {
|
||||
|
||||
private companion object {
|
||||
val IDENTITY_MATRIX = floatArrayOf(
|
||||
1f, 0f, 0f, 0f,
|
||||
0f, 1f, 0f, 0f,
|
||||
0f, 0f, 1f, 0f,
|
||||
0f, 0f, 0f, 1f
|
||||
)
|
||||
}
|
||||
|
||||
// --- Passthrough program (camera → FBO) ---
|
||||
|
||||
private var passthroughProgramId: Int = 0
|
||||
|
|
@ -29,6 +38,8 @@ class TiltShiftShader(private val context: Context) {
|
|||
var passthroughTexCoordLoc: Int = 0
|
||||
private set
|
||||
private var passthroughTextureLoc: Int = 0
|
||||
private var passthroughTexMatrixLoc: Int = 0
|
||||
private var passthroughMirrorLoc: Int = 0
|
||||
|
||||
// --- Blur program (FBO → FBO/screen) ---
|
||||
|
||||
|
|
@ -39,6 +50,8 @@ class TiltShiftShader(private val context: Context) {
|
|||
var blurTexCoordLoc: Int = 0
|
||||
private set
|
||||
private var blurTextureLoc: Int = 0
|
||||
private var blurTexMatrixLoc: Int = 0
|
||||
private var blurMirrorLoc: Int = 0
|
||||
private var blurModeLoc: Int = 0
|
||||
private var blurPositionXLoc: Int = 0
|
||||
private var blurPositionYLoc: Int = 0
|
||||
|
|
@ -68,6 +81,8 @@ class TiltShiftShader(private val context: Context) {
|
|||
passthroughPositionLoc = GLES20.glGetAttribLocation(passthroughProgramId, "aPosition")
|
||||
passthroughTexCoordLoc = GLES20.glGetAttribLocation(passthroughProgramId, "aTexCoord")
|
||||
passthroughTextureLoc = GLES20.glGetUniformLocation(passthroughProgramId, "uTexture")
|
||||
passthroughTexMatrixLoc = GLES20.glGetUniformLocation(passthroughProgramId, "uTexMatrix")
|
||||
passthroughMirrorLoc = GLES20.glGetUniformLocation(passthroughProgramId, "uMirrorX")
|
||||
|
||||
// Blur program
|
||||
val blurFragSource = loadShaderSource(R.raw.tiltshift_fragment)
|
||||
|
|
@ -78,6 +93,8 @@ class TiltShiftShader(private val context: Context) {
|
|||
blurPositionLoc = GLES20.glGetAttribLocation(blurProgramId, "aPosition")
|
||||
blurTexCoordLoc = GLES20.glGetAttribLocation(blurProgramId, "aTexCoord")
|
||||
blurTextureLoc = GLES20.glGetUniformLocation(blurProgramId, "uTexture")
|
||||
blurTexMatrixLoc = GLES20.glGetUniformLocation(blurProgramId, "uTexMatrix")
|
||||
blurMirrorLoc = GLES20.glGetUniformLocation(blurProgramId, "uMirrorX")
|
||||
blurModeLoc = GLES20.glGetUniformLocation(blurProgramId, "uMode")
|
||||
blurPositionXLoc = GLES20.glGetUniformLocation(blurProgramId, "uPositionX")
|
||||
blurPositionYLoc = GLES20.glGetUniformLocation(blurProgramId, "uPositionY")
|
||||
|
|
@ -96,12 +113,19 @@ class TiltShiftShader(private val context: Context) {
|
|||
|
||||
/**
|
||||
* Activates the passthrough program and binds the camera texture.
|
||||
*
|
||||
* @param cameraTextureId The OES texture receiving camera frames.
|
||||
* @param texMatrix 4x4 transform from SurfaceTexture.getTransformMatrix() —
|
||||
* encodes sensor-to-display rotation and Y-flip.
|
||||
* @param mirrorX true to horizontally mirror (front camera selfie view).
|
||||
*/
|
||||
fun usePassthrough(cameraTextureId: Int) {
|
||||
fun usePassthrough(cameraTextureId: Int, texMatrix: FloatArray, mirrorX: Boolean) {
|
||||
GLES20.glUseProgram(passthroughProgramId)
|
||||
GLES20.glActiveTexture(GLES20.GL_TEXTURE0)
|
||||
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, cameraTextureId)
|
||||
GLES20.glUniform1i(passthroughTextureLoc, 0)
|
||||
GLES20.glUniformMatrix4fv(passthroughTexMatrixLoc, 1, false, texMatrix, 0)
|
||||
GLES20.glUniform1f(passthroughMirrorLoc, if (mirrorX) 1f else 0f)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -128,6 +152,10 @@ class TiltShiftShader(private val context: Context) {
|
|||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fboTextureId)
|
||||
GLES20.glUniform1i(blurTextureLoc, 0)
|
||||
|
||||
// FBO content is already in display orientation — pass identity matrix and no mirror.
|
||||
GLES20.glUniformMatrix4fv(blurTexMatrixLoc, 1, false, IDENTITY_MATRIX, 0)
|
||||
GLES20.glUniform1f(blurMirrorLoc, 0f)
|
||||
|
||||
GLES20.glUniform1i(blurModeLoc, if (params.mode == BlurMode.RADIAL) 1 else 0)
|
||||
GLES20.glUniform1f(blurPositionXLoc, params.positionX)
|
||||
GLES20.glUniform1f(blurPositionYLoc, params.positionY)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue