GLSL 壁纸服务显示黑屏

问题描述 投票:0回答:1

我正在开发一个 Android 项目,我想使用

WallpaperService
将 GLSL 着色器设置为壁纸。目标是显示一个简单的灰色着色器,但我遇到了壁纸仅显示黑屏的问题。 注意。

我知道着色器编辑器的存在,但我有一些新的想法,可以使创建和自定义着色器的过程变得非常容易。

您可以查看this以获取突出显示问题的最基本的精简版本。 设置如下:

GLSL代码:

    void main() {// basic code for testing purpose
        if(gl_FragCoord.y > 250.0){
            gl_FragColor = vec4(0.25);
        }
        else{
            gl_FragColor = vec4(0.75);
        }
    }

壁纸服务实现:

    import android.service.wallpaper.WallpaperService
    import android.view.SurfaceHolder
    import com.dhruv.hellohome.glsl.MyGLSurfaceView
    
    class GLSLWallpaperService : WallpaperService() {
        private var engine: GLWallpaperEngine? = null
    
        fun isRunning(): Boolean {
            return engine != null
        }
    
        override fun onCreateEngine(): Engine {
            return GLWallpaperEngine()
        }
    
        inner class GLWallpaperEngine : Engine() {
            private var glSurfaceView: MyGLSurfaceView? = null
    
            override fun onCreate(surfaceHolder: SurfaceHolder) {
                super.onCreate(surfaceHolder)
                glSurfaceView = MyGLSurfaceView(this@GLSLWallpaperService)
            }
    
            override fun onSurfaceCreated(holder: SurfaceHolder) {
                super.onSurfaceCreated(holder)
                glSurfaceView?.surfaceCreated(holder)
            }
    
            override fun onVisibilityChanged(visible: Boolean) {
                super.onVisibilityChanged(visible)
                if (visible) {
                    glSurfaceView?.onResume()
                } else {
                    glSurfaceView?.onPause()
                }
            }
    
            override fun onDestroy() {
                super.onDestroy()
                glSurfaceView?.let {
                    it.onPause()
                    it.onDetachedFromWindow()
                }
            }
    
            override fun onSurfaceDestroyed(holder: SurfaceHolder) {
                super.onSurfaceDestroyed(holder)
                glSurfaceView?.surfaceDestroyed(holder)
            }
        }
    }

GLSurfaceView 实现:

    import android.content.Context
    import android.opengl.GLSurfaceView
    import android.util.Log
    import android.view.SurfaceHolder

    class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {
    private val renderer: MyGLRenderer

    init {
        setEGLContextClientVersion(2)
        renderer = MyGLRenderer(ShaderData())
        setRenderer(renderer)
        renderMode = RENDERMODE_CONTINUOUSLY
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        super.surfaceCreated(holder)
        Log.d("MyGLSurfaceView", "Surface created")
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        super.surfaceDestroyed(holder)
        Log.d("MyGLSurfaceView", "Surface destroyed")
    }

    public override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
    }
}

在这种情况下,MyGLRenderer 是 GLSurfaceView.Renderer 的实现,可以正常工作。 迷你节是:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:installLocation="auto">
    <supports-screens
        android:largeScreens="true"
        android:xlargeScreens="true"/>
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="19"/>
    <!-- Required below API < 28 for exporting shaders -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="28"/>
    <uses-feature android:glEsVersion="0x00020000"/>
    <uses-feature android:name="android.hardware.camera.any"
        android:required="false"/>
    <uses-feature android:name="android.hardware.camera.autofocus"
        android:required="false"/>
    <uses-feature android:name="android.software.live_wallpaper"/>
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW"/>
            <data android:scheme="https"/>
        </intent>
    </queries>
    <application
        tools:ignore="UnusedAttribute"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.HelloHome">
        <service
            android:name=".services.GLSLWallpaperService"
            android:exported="true"
            android:description="@string/wallpaper_description"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_WALLPAPER">
            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService" />
            </intent-filter>
            <meta-data
                android:name="android.service.wallpaper"
                android:resource="@xml/wallpaper" />
        </service>
        <activity android:name="com.example.openglwallpaper.SettingsActivity" />
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.HelloHome">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".PreviewActivity" />
    </application>
</manifest>

最后是 GLSLWallpaperService 实现:

import android.service.wallpaper.WallpaperService
import android.view.SurfaceHolder
import com.dhruv.hellohome.glsl.MyGLSurfaceView

class GLSLWallpaperService : WallpaperService() {

    private var engine: GLWallpaperEngine? = null
    fun isRunning(): Boolean {
        return engine != null
    }

    override fun onCreateEngine(): Engine {
        return GLWallpaperEngine()
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    inner class GLWallpaperEngine : Engine() {
        private var glSurfaceView: MyGLSurfaceView? = null
        override fun onCreate(surfaceHolder: SurfaceHolder) {
            super.onCreate(surfaceHolder)
            glSurfaceView = MyGLSurfaceView(this@GLSLWallpaperService)
        }

        override fun onSurfaceCreated(holder: SurfaceHolder) {
            super.onSurfaceCreated(holder)
            glSurfaceView?.surfaceCreated(holder)
        }

        override fun onVisibilityChanged(visible: Boolean) {
            super.onVisibilityChanged(visible)
            if (visible) {
                glSurfaceView?.onResume()
            } else {
                glSurfaceView?.onPause()
            }
        }

        override fun onDestroy() {
            super.onDestroy()
            glSurfaceView?.let {
                it.onPause()
                it.onDetachedFromWindow()
            }
        }

        override fun onSurfaceDestroyed(holder: SurfaceHolder) {
            super.onSurfaceDestroyed(holder)
            glSurfaceView?.surfaceDestroyed(holder)
        }
    }
}

我已经被困了大约两周,似乎不明白出了什么问题。 如果有人可以帮助我,那将是一个巨大的帮助。

android kotlin opengl-es
1个回答
0
投票

好吧,问题出在 GLSLWallpaperService 如何处理 engien。

这是固定代码

class GLSLWallpaperService : WallpaperService() {

    private var engine: GLWallpaperEngine? = null

    fun isRunning(): Boolean {
        return engine != null
    }

    override fun onCreateEngine(): Engine {
        engine = GLWallpaperEngine()
        return engine!!
    }

    override fun onDestroy() {
        super.onDestroy()
        engine = null
    }

    inner class GLWallpaperEngine : Engine() {
        private var glSurfaceView: MyGLSurfaceView? = null

        override fun onCreate(surfaceHolder: SurfaceHolder) {
            super.onCreate(surfaceHolder)
            glSurfaceView = GLWallpaperSurfaceView()
        }

        override fun onSurfaceCreated(holder: SurfaceHolder) {
            super.onSurfaceCreated(holder)
            glSurfaceView?.surfaceCreated(holder)
        }

        override fun onVisibilityChanged(visible: Boolean) {
            super.onVisibilityChanged(visible)
            if (visible) {
                glSurfaceView?.onResume()
            } else {
                glSurfaceView?.onPause()
            }
        }

        override fun onDestroy() {
            super.onDestroy()
            glSurfaceView?.let {
                it.onPause()
                it.onDetachedFromWindow()
            }
        }

        override fun onSurfaceDestroyed(holder: SurfaceHolder) {
            super.onSurfaceDestroyed(holder)
            glSurfaceView?.surfaceDestroyed(holder)
        }

        inner class GLWallpaperSurfaceView : MyGLSurfaceView(this@GLSLWallpaperService) {
            override fun getHolder(): SurfaceHolder  {
                return getSurfaceHolder()
            }
        }
    }
}

这是一个愚蠢的问题,但我希望如果其他人被困在这个问题上,那么这可能会对你有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.