Add front camera texture coordinate handling
- Add separate texture coordinates for front and back cameras - Front camera uses mirrored coordinates for natural selfie view - Add setFrontCamera() method to renderer for dynamic switching - Update texture coord buffer on GL thread when camera changes - CameraScreen observes isFrontCamera state to trigger updates Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a3ce90a2fe
commit
b16dd971f2
2 changed files with 48 additions and 4 deletions
|
|
@ -36,6 +36,9 @@ class TiltShiftRenderer(
|
||||||
@Volatile
|
@Volatile
|
||||||
var blurParameters: BlurParameters = BlurParameters.DEFAULT
|
var blurParameters: BlurParameters = BlurParameters.DEFAULT
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var isFrontCamera: Boolean = false
|
||||||
|
|
||||||
// Quad vertices (full screen)
|
// Quad vertices (full screen)
|
||||||
private val vertices = floatArrayOf(
|
private val vertices = floatArrayOf(
|
||||||
-1f, -1f, // Bottom left
|
-1f, -1f, // Bottom left
|
||||||
|
|
@ -44,15 +47,26 @@ class TiltShiftRenderer(
|
||||||
1f, 1f // Top right
|
1f, 1f // Top right
|
||||||
)
|
)
|
||||||
|
|
||||||
// Texture coordinates rotated 90° for portrait mode
|
// Texture coordinates rotated 90° for portrait mode (back camera)
|
||||||
// (Camera sensors are landscape-oriented, we rotate to portrait)
|
// (Camera sensors are landscape-oriented, we rotate to portrait)
|
||||||
private val texCoords = floatArrayOf(
|
private val texCoordsBack = floatArrayOf(
|
||||||
1f, 1f, // Bottom left of screen -> bottom right of texture
|
1f, 1f, // Bottom left of screen -> bottom right of texture
|
||||||
1f, 0f, // Bottom right of screen -> top right of texture
|
1f, 0f, // Bottom right of screen -> top right of texture
|
||||||
0f, 1f, // Top left of screen -> bottom left of texture
|
0f, 1f, // Top left of screen -> bottom left of texture
|
||||||
0f, 0f // Top right of screen -> top left of texture
|
0f, 0f // Top right of screen -> top left of texture
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Texture coordinates for front camera (mirrored + rotated)
|
||||||
|
// Front camera needs horizontal mirror for natural selfie view
|
||||||
|
private val texCoordsFront = floatArrayOf(
|
||||||
|
0f, 1f, // Bottom left of screen
|
||||||
|
0f, 0f, // Bottom right of screen
|
||||||
|
1f, 1f, // Top left of screen
|
||||||
|
1f, 0f // Top right of screen
|
||||||
|
)
|
||||||
|
|
||||||
|
private var currentTexCoords = texCoordsBack
|
||||||
|
|
||||||
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
|
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
|
||||||
GLES20.glClearColor(0f, 0f, 0f, 1f)
|
GLES20.glClearColor(0f, 0f, 0f, 1f)
|
||||||
|
|
||||||
|
|
@ -68,10 +82,10 @@ class TiltShiftRenderer(
|
||||||
vertexBuffer.position(0)
|
vertexBuffer.position(0)
|
||||||
|
|
||||||
// Create texture coordinate buffer
|
// Create texture coordinate buffer
|
||||||
texCoordBuffer = ByteBuffer.allocateDirect(texCoords.size * 4)
|
texCoordBuffer = ByteBuffer.allocateDirect(currentTexCoords.size * 4)
|
||||||
.order(ByteOrder.nativeOrder())
|
.order(ByteOrder.nativeOrder())
|
||||||
.asFloatBuffer()
|
.asFloatBuffer()
|
||||||
.put(texCoords)
|
.put(currentTexCoords)
|
||||||
texCoordBuffer.position(0)
|
texCoordBuffer.position(0)
|
||||||
|
|
||||||
// Create camera texture
|
// Create camera texture
|
||||||
|
|
@ -101,6 +115,14 @@ class TiltShiftRenderer(
|
||||||
// Update texture with latest camera frame
|
// Update texture with latest camera frame
|
||||||
surfaceTexture?.updateTexImage()
|
surfaceTexture?.updateTexImage()
|
||||||
|
|
||||||
|
// Update texture coordinate buffer if camera changed
|
||||||
|
if (updateTexCoordBuffer) {
|
||||||
|
texCoordBuffer.clear()
|
||||||
|
texCoordBuffer.put(currentTexCoords)
|
||||||
|
texCoordBuffer.position(0)
|
||||||
|
updateTexCoordBuffer = false
|
||||||
|
}
|
||||||
|
|
||||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
|
||||||
|
|
||||||
// Use shader and set parameters
|
// Use shader and set parameters
|
||||||
|
|
@ -143,6 +165,22 @@ class TiltShiftRenderer(
|
||||||
blurParameters = params
|
blurParameters = params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether using front camera. Updates texture coordinates accordingly.
|
||||||
|
* Thread-safe - actual buffer update happens on next frame.
|
||||||
|
*/
|
||||||
|
fun setFrontCamera(front: Boolean) {
|
||||||
|
if (isFrontCamera != front) {
|
||||||
|
isFrontCamera = front
|
||||||
|
currentTexCoords = if (front) texCoordsFront else texCoordsBack
|
||||||
|
// Buffer will be updated on next draw
|
||||||
|
updateTexCoordBuffer = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var updateTexCoordBuffer = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases OpenGL resources.
|
* Releases OpenGL resources.
|
||||||
* Must be called from GL thread.
|
* Must be called from GL thread.
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,12 @@ fun CameraScreen(
|
||||||
glSurfaceView?.requestRender()
|
glSurfaceView?.requestRender()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update renderer when camera switches (front/back)
|
||||||
|
LaunchedEffect(isFrontCamera) {
|
||||||
|
renderer?.setFrontCamera(isFrontCamera)
|
||||||
|
glSurfaceView?.requestRender()
|
||||||
|
}
|
||||||
|
|
||||||
// Start camera when surface texture is available
|
// Start camera when surface texture is available
|
||||||
LaunchedEffect(surfaceTexture) {
|
LaunchedEffect(surfaceTexture) {
|
||||||
surfaceTexture?.let {
|
surfaceTexture?.let {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue