Android官方开发文档Training系列课程中文版:OpenGL绘图之响应触摸事件

简介: 原文地址:http://android.xsoftlab.net/training/graphics/opengl/touch.html使图形按照程序设计的轨迹旋转对OpenGL来说还是不能发挥出它应有的实力。

原文地址:http://android.xsoftlab.net/training/graphics/opengl/touch.html

使图形按照程序设计的轨迹旋转对OpenGL来说还是不能发挥出它应有的实力。但要是能使用户可以直接控制图形的旋转,这才是OpenGL的真正目的。它真正的关键所在就是使程序可以交互式触摸。这主要靠重写GLSurfaceView的onTouchEvent()的方法来实现触摸事件的监听。

这节课将会展示如何监听触摸事件来使用户可以旋转图形。

设置触摸监听器

为了可以使OpenGL监听触摸事件,必须重写GLSurfaceView类中的onTouchEvent()方法。下面的实现展示了如何监听MotionEvent.ACTION_MOVE事件,以及如何使事件驱动图形的旋转.

private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent e) {
    // MotionEvent reports input details from the touch screen
    // and other input controls. In this case, you are only
    // interested in events where the touch position changed.
    float x = e.getX();
    float y = e.getY();
    switch (e.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float dx = x - mPreviousX;
            float dy = y - mPreviousY;
            // reverse direction of rotation above the mid-line
            if (y > getHeight() / 2) {
              dx = dx * -1 ;
            }
            // reverse direction of rotation to left of the mid-line
            if (x < getWidth() / 2) {
              dy = dy * -1 ;
            }
            mRenderer.setAngle(
                    mRenderer.getAngle() +
                    ((dx + dy) * TOUCH_SCALE_FACTOR));
            requestRender();
    }
    mPreviousX = x;
    mPreviousY = y;
    return true;
}
AI 代码解读

这里需要注意的是,在计算完旋转的角度之后,这个方法调用了requestRender()方法,这个方法会通知渲染器可以渲染了。这个方法放在这个地方是最合适的,因为帧在这之前并不需要重新绘制,除非在角度上发生了变化。不管怎么样,这个方法并不会对效率有任何影响,除非你也设置了在数据发生改变的时候重新绘制的请求。这种请求通过setRenderMode()方法设置,所以要确保下面这行代码没有被注释:

public MyGLSurfaceView(Context context) {
    ...
    // Render the view only when there is a change in the drawing data
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
AI 代码解读

暴露旋转角度

上面的示例代码会要求提供一个公开的成员方法来暴露旋转的角度。一旦渲染代码运行在子线程当中,那么必须将这个公共成员声明为volatile。下面的代码声明了这个volatile的属性,并暴露了它的get,set方法:

public class MyGLRenderer implements GLSurfaceView.Renderer {
    ...
    public volatile float mAngle;
    public float getAngle() {
        return mAngle;
    }
    public void setAngle(float angle) {
        mAngle = angle;
    }
}
AI 代码解读

请求旋转

为了触摸事件驱动旋转,需要注释生成角度的代码,然后添加mAngle成员属性,mAngle中包含了触摸事件所生成的角度:

public void onDrawFrame(GL10 gl) {
    ...
    float[] scratch = new float[16];
    // Create a rotation for the triangle
    // long time = SystemClock.uptimeMillis() % 4000L;
    // float angle = 0.090f * ((int) time);
    Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
    // Combine the rotation matrix with the projection and camera view
    // Note that the mMVPMatrix factor *must be first* in order
    // for the matrix multiplication product to be correct.
    Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
    // Draw triangle
    mTriangle.draw(scratch);
}
AI 代码解读

如果完成了上面所描述的步骤,那么启动程序,然后在屏幕上拖动就可以使三角形旋转起来:

目录
打赏
0
0
0
0
1
分享
相关文章
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
229 5
全志 Android 11:实现响应全局按键
本文介绍了在全志平台Android 11上实现响应全局按键的方法,通过修改`TvWindowManager.java`来全局拦截特定的热键事件,并在`FocusActivity`中处理这些事件以启动调焦界面和控制步进电机调整焦距。
85 2
Android项目架构设计问题之实现交互响应的结构化处理如何解决
Android项目架构设计问题之实现交互响应的结构化处理如何解决
45 0
"掌握安卓开发新境界:深度解析AndroidManifest.xml中的Intent-filter配置,让你的App轻松响应scheme_url,开启无限交互可能!"
【8月更文挑战第2天】在安卓开发中,scheme_url 通过在`AndroidManifest.xml`中配置`Intent-filter`,使应用能响应特定URL启动或执行操作。基本配置下,应用可通过定义特定URL模式的`Intent-filter`响应相应链接。
181 12
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
【7月更文挑战第28天】在Android开发中,确保UI流畅性至关重要。多线程与异步编程技术可将耗时操作移至后台,避免阻塞主线程。我们通常采用`Thread`类、`Handler`与`Looper`、`AsyncTask`及`ExecutorService`等进行多线程编程。
101 2
🔥Android Jetpack全解析!拥抱Google官方库,让你的开发之旅更加顺畅无阻!🚀
【7月更文挑战第28天】在Android开发中追求高效稳定的路径?Android Jetpack作为Google官方库集合,是你的理想选择。它包含多个独立又协同工作的库,覆盖UI到安全性等多个领域,旨在减少样板代码,提高开发效率与应用质量。Jetpack核心组件如LiveData、ViewModel、Room等简化了数据绑定、状态保存及数据库操作。引入Jetpack只需在`build.gradle`中添加依赖。例如,使用Room进行数据库操作变得异常简单,从定义实体到实现CRUD操作,一切尽在掌握之中。拥抱Jetpack,提升开发效率,构建高质量应用!
190 4
SLS:使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践
本文介绍了使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践。
702 7
SLS:使用 OTel 官方 SDK 采集 Android、iOS Trace 数据实践

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等