美文网首页AR/VR与AndroidAndroid技术知识Android开发
用openGL实现动态壁纸,就是这么简单

用openGL实现动态壁纸,就是这么简单

作者: 小码哥_WS | 来源:发表于2017-05-24 20:25 被阅读294次

    网上动态壁纸的实现教程有很多,但是用openGL实现动态壁纸的教程却是寥寥无几,那么今天就带领大家学习用openGL实现动态壁纸,起一个抛砖引玉吧。

    在之前曾写过一篇 ffmpeg/camera实现最近很火的视频壁纸,相机壁纸 ,动态壁纸的实现套路已经写了,今天就不追述了。

    老规矩,先看效果图让大家有个概念:

    这里写图片描述
    大家也看出来了,没错,是基于上篇openGL ES进阶教程(二)之全景图片 实现的。

    下面就具体说说实现套路,真的是套路,你看~
    1.首先要实现一个openGL动态图,什么样的图完全由自己的需求决定,比如我的就是基于我上篇的图

    2.编写一个继承自WallpaperService的动态壁纸类

    public class GLWallpaperService extends WallpaperService {
        @Override
        public Engine onCreateEngine() {
            return new GLEngine();
        }
        ...
    

    3.清单文件中声明它,在定义一个图标的xml,如下:

    这里写图片描述

    xml的内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:thumbnail="@drawable/back" />
    

    以上几个步骤即创建了一个动态壁纸,只不过没有渲染图像而已。。。当WallpaperService被系统创建时,它会创建它自己的渲染表面(Surface),让应用程序在上面绘制,即通过调用Engine这个渲染引擎。下面一个步骤即最重要的一环,如何用openGL渲染的图像在WallpaperService中显现出来

    4.完成壁纸的引擎

    正常情况下,GLSurfaceView是被加入到Activity视图层的,GLSurfaceView会调用getHolder()存取其Activity内的表面。在动态壁纸中我们需要改变这个行为,因此我们只需重载getHolder(),让其返回动态壁纸的渲染表面即可。

    class WallpaperGLSurfaceView extends GLSurfaceView {
                private static final String TAG = "WallpaperGLSurfaceView";
                WallpaperGLSurfaceView(Context context) {
                    super(context);
                }            
                @Override
                public SurfaceHolder getHolder() {
    
                    return getSurfaceHolder();
                }
    
                public void onWallpaperDestroy() {
    
                    super.onDetachedFromWindow();
                }
            }
    

    onWallpaperDestroy()方法销毁GLSurfaceView 。当调用onDetachedFromWindow()时,GLSurfaceView 就会自动的销毁自己。

    GLWallpaperService 的全部实现代码如下:

    import android.app.ActivityManager;
    import android.content.Context;
    import android.content.pm.ConfigurationInfo;
    import android.opengl.GLSurfaceView;
    import android.os.Build;
    import android.service.wallpaper.WallpaperService;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.widget.Toast;
    
    public class GLWallpaperService extends WallpaperService {
        @Override
        public Engine onCreateEngine() {
            return new GLEngine();
        }
        public class GLEngine extends Engine {
            private static final String TAG = "GLEngine";
    
            private WallpaperGLSurfaceView glSurfaceView;
            private ParticlesRenderer particlesRenderer;
            private boolean rendererSet;
    
    
            @Override
            public void onCreate(SurfaceHolder surfaceHolder) {
                super.onCreate(surfaceHolder);            
    
                glSurfaceView = new WallpaperGLSurfaceView(GLWallpaperService.this);
    
                particlesRenderer = new ParticlesRenderer(GLWallpaperService.this);
    
                    glSurfaceView.setEGLContextClientVersion(2);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        glSurfaceView.setPreserveEGLContextOnPause(true);
                    }
                    glSurfaceView.setRenderer(particlesRenderer);
                    rendererSet = true;
    
            }
    
            @Override
            public void onVisibilityChanged(boolean visible) {
                super.onVisibilityChanged(visible);
    
                if (rendererSet) {
                    if (visible) {
                        glSurfaceView.onResume();
                    } else {                   
                        glSurfaceView.onPause();
                    }
                }
            }   
    
            @Override
            public void onDestroy() {
                super.onDestroy();
    
                glSurfaceView.onWallpaperDestroy();
            }
    
    
            class WallpaperGLSurfaceView extends GLSurfaceView {
                private static final String TAG = "WallpaperGLSurfaceView";
    
                WallpaperGLSurfaceView(Context context) {
                    super(context);    
                }            
    
                @Override
                public SurfaceHolder getHolder() {
    
                    return getSurfaceHolder();
                }
    
                public void onWallpaperDestroy() {
    
                    super.onDetachedFromWindow();
                }
            }
        }
    }
    

    ps:

    Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行,最近发布了Kotlin/Native能把Kotlin编译成机器码,也就是C/C++一样的能力。本专题专注Kotlin,Kotlin/Native,KotlinJS与Kotlin_Android的那些事,让我们共同学习Kotlin壮大Kotlin~

    加入专题吧Kotlin-Android-KotlinJS-Kotlin/Native:http://www.jianshu.com/c/e88f0f9356a8

    相信各位客官已经看的很明白了……

    相关文章

      网友评论

        本文标题:用openGL实现动态壁纸,就是这么简单

        本文链接:https://www.haomeiwen.com/subject/nmwoxxtx.html