You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台OpenGL ES如何实现触摸事件响应式相机旋转?

实现OpenGL ES基础相机触摸旋转控制

原Android官方示例的触摸旋转仅支持绕Z轴,拆分X/Y轴旋转时出现异常,核心问题是两次调用setRotateM会覆盖之前的矩阵,正确做法是通过矩阵乘法合并两次旋转,同时要注意触摸坐标与旋转轴的对应关系、旋转顺序。

错误原因分析

你当前的代码中:

Matrix.setRotateM(rotationMatrix, 0, angleX, 0f, 1f, 0f)
Matrix.setRotateM(rotationMatrix, 0, angleY, 1f, 0f, 0f)

第二次setRotateM会完全替换第一次生成的旋转矩阵,导致只有Y轴旋转生效,X轴旋转被覆盖,所以拖动X轴时效果异常。

正确实现步骤

1. 定义旋转变量

在Renderer中维护两个旋转角度及临时计算矩阵:

class MyGLRenderer : GLSurfaceView.Renderer {
    var angleX = 0f // 绕X轴旋转角度(对应触摸Y轴拖动)
    var angleY = 0f // 绕Y轴旋转角度(对应触摸X轴拖动)
    private val rotationMatrix = FloatArray(16)
    private val tempMatrix = FloatArray(16) // 临时矩阵用于合并旋转
    // 其他变量...
}

2. 触摸事件处理

保持触摸坐标到旋转角度的映射,注意触摸Y轴移动对应绕X轴旋转,X轴移动对应绕Y轴旋转:

private const val TOUCH_SCALE_FACTOR = 0.1f

override fun onTouchEvent(e: MotionEvent): Boolean {
    if (e.pointerCount == 1) {
        when (e.action) {
            MotionEvent.ACTION_MOVE -> {
                val dx = e.x - e.rawX
                val dy = e.y - e.rawY
                renderer.angleY += dx * TOUCH_SCALE_FACTOR
                renderer.angleX += dy * TOUCH_SCALE_FACTOR
                // 限制旋转角度,避免过度翻转(可选)
                renderer.angleX = renderer.angleX.coerceIn(-90f, 90f)
            }
        }
    }
    return true
}

3. 绘制时合并旋转矩阵

使用Matrix.multiplyMM合并X轴和Y轴的旋转矩阵,而非覆盖:

override fun onDrawFrame(gl: GL10) {
    // 清除画布
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)

    // 初始化单位矩阵
    Matrix.setIdentityM(rotationMatrix, 0)

    // 先绕X轴旋转
    Matrix.setRotateM(tempMatrix, 0, angleX, 1f, 0f, 0f)
    Matrix.multiplyMM(rotationMatrix, 0, rotationMatrix, 0, tempMatrix, 0)

    // 再绕Y轴旋转
    Matrix.setRotateM(tempMatrix, 0, angleY, 0f, 1f, 0f)
    Matrix.multiplyMM(rotationMatrix, 0, rotationMatrix, 0, tempMatrix, 0)

    // 将旋转矩阵应用到视图/模型矩阵(根据你的相机设置调整)
    Matrix.multiplyMM(mVPMatrix, 0, mProjectionMatrix, 0, rotationMatrix, 0)

    // 绘制物体...
}

4. 额外优化(可选)

  • 用ScaleGestureDetector添加双指缩放功能,模拟相机变焦
  • 限制旋转角度范围,避免相机翻转到不合理视角

替代方案:使用高层框架

如果不想手动处理矩阵,Android上可以选择:

  • Sceneform:类似iOS SceneKit的3D框架,支持一行代码开启相机控制
  • Jetpack Compose 3D:最新的Compose 3D库,提供简洁的3D交互API

内容的提问来源于stack exchange,提问作者goofy4224

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:46:34