android-openGL-canvas icon indicating copy to clipboard operation
android-openGL-canvas copied to clipboard

Cannot create GL program: 0

Open eliteSchwein opened this issue 3 years ago • 20 comments

Hey there i get Cannot create GL program: 0

at drawBitmap

Code:

    override fun onGLDraw(canvas: ICanvasGL?) {
        Log.d("framework", canvas.toString())
        if (canvas != null) {
            this.canvas = canvas
            Thread {
                while (mIn == null) { Log.d("null", "null")}
                try {
                    val bm = mIn!!.readMjpegFrame()
                    canvas.drawBitmap(bm, 0, 0)
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }.start()
        }
    }

eliteSchwein avatar Apr 30 '21 20:04 eliteSchwein

The drawBitmap cannot be called in another threat but only in the thread in onGLDraw

ChillingVan avatar May 01 '21 01:05 ChillingVan

Well thats a problem, i cant use the main thread for network stuff

eliteSchwein avatar May 01 '21 01:05 eliteSchwein

Well thats a problem, i cant use the main thread for network stuff

Then the bitmap should be ready from other thread before it is passed to this TextureView

ChillingVan avatar May 01 '21 01:05 ChillingVan

Its based from a inputstream from a website... But i think i got an idea, i will try that in 10h or so because i have to sleep now.

thank you for the fast Response!

eliteSchwein avatar May 01 '21 02:05 eliteSchwein

Screenshot_20210501_165637_de.eliteschw31n.moonrakerremote.jpg

Sofar so good, except it overlays everything

eliteSchwein avatar May 01 '21 14:05 eliteSchwein

What view do you use? GlSurfaceView or GlTextureView

ChillingVan avatar May 01 '21 15:05 ChillingVan

self made view for now

eliteSchwein avatar May 01 '21 15:05 eliteSchwein

can you provide a methode for updating the picture? because i tried Thread.sleep in a while loop and it crashes

eliteSchwein avatar May 01 '21 15:05 eliteSchwein

Maybe you need to learn something about Android UI thread or Handler. It is a little hard to explain Thread.sleep should not be called here.

ChillingVan avatar May 01 '21 15:05 ChillingVan

can i somehow get the GL Thread?

eliteSchwein avatar May 01 '21 15:05 eliteSchwein

okay so i get the errmor message again, but this time from the same thread

class MjpegView : GLView {
    private var thread: Thread? = null
    private var mIn: MjpegInputStream? = null
    private var bitMap: Bitmap? = null
    private var canvas: ICanvasGL? = null
    private var glThread: Thread? =null

    private fun init(context: Context) {
        isFocusable = true
    }

    fun startPlayback() {
        if (mIn != null) {
            thread = Thread {
                while (!Thread.interrupted()) {
                    bitMap = mIn?.readMjpegFrame()

                    Log.d("GLThread", glThread?.id.toString())
                    glThread?.run {
                        canvas?.drawBitmap(bitMap, 0, 0) //ERROR
                    }
                    Thread.sleep(1000)
                }
            }
            Log.d("stream", mIn.toString())
            thread?.start()
        }
    }

    fun stopPlayback() {
        thread?.interrupt()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init(context)
    }

    override fun onGLDraw(canvas: ICanvasGL?) {
        glThread = Thread.currentThread()

        Log.d("GLThread1", Thread.currentThread().id.toString())
        if(canvas != null) {
            this.canvas = canvas
        }
    }

    constructor(context: Context) : super(context) {
        init(context)
    }

    fun setSource(source: MjpegInputStream?) {
        mIn = source
    }

    companion object {
    }
}

eliteSchwein avatar May 01 '21 15:05 eliteSchwein

okay so i get the errmor message again, but this time from the same thread

class MjpegView : GLView {
    private var thread: Thread? = null
    private var mIn: MjpegInputStream? = null
    private var bitMap: Bitmap? = null
    private var canvas: ICanvasGL? = null
    private var glThread: Thread? =null

    private fun init(context: Context) {
        isFocusable = true
    }

    fun startPlayback() {
        if (mIn != null) {
            thread = Thread {
                while (!Thread.interrupted()) {
                    bitMap = mIn?.readMjpegFrame()

                    Log.d("GLThread", glThread?.id.toString())
                    glThread?.run {
                        canvas?.drawBitmap(bitMap, 0, 0) //ERROR
                    }
                    Thread.sleep(1000)
                }
            }
            Log.d("stream", mIn.toString())
            thread?.start()
        }
    }

    fun stopPlayback() {
        thread?.interrupt()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init(context)
    }

    override fun onGLDraw(canvas: ICanvasGL?) {
        glThread = Thread.currentThread()

        Log.d("GLThread1", Thread.currentThread().id.toString())
        if(canvas != null) {
            this.canvas = canvas
        }
    }

    constructor(context: Context) : super(context) {
        init(context)
    }

    fun setSource(source: MjpegInputStream?) {
        mIn = source
    }

    companion object {
    }
}

Emmm.. You can try to get your bitmap outside your MyGLView and then set the Bitmap to MyGLView. After the bitmap set, you can call MyGLView.requestRender to trigger onGLDraw. The reqeustRender is inherited from GLSurfaceView.

ChillingVan avatar May 02 '21 03:05 ChillingVan

Can you provide a example? Would be great

eliteSchwein avatar May 02 '21 11:05 eliteSchwein

Can you provide a example? Would be great

    val view = MjpegView()
    
    fun startPlayback() {
         Thread {
              val bitmap = readBitmap()
              view.mBitmap = bitmap
              view.requestRender()
         }
    }

And in MjpegView

class MjpegView : GLView {
    var mBitmap = null
    fun onGLDraw() {
        mBitmap?.let {
            drawBitmap(it)
        }        
    }
}

ChillingVan avatar May 03 '21 03:05 ChillingVan

Thanks alot,

I will try it later

eliteSchwein avatar May 03 '21 09:05 eliteSchwein

How can i prevent it that it shows over everything?

eliteSchwein avatar May 03 '21 09:05 eliteSchwein

okay it doesnt work very well, it crashes after some Time and the latency is crazy high

eliteSchwein avatar May 03 '21 13:05 eliteSchwein

https://github.com/eliteSchwein/moonraker-remote-android/blob/main/app/src/main/java/de/eliteschw31n/moonrakerremote/utils/mjpeg/MjpegView.kt

i have a active Input Stream

eliteSchwein avatar May 03 '21 13:05 eliteSchwein

okay it doesnt work very well, it crashes after some Time and the latency is crazy high

Can you reused the first Bitmap to avoid creating Bitmap object continuously? And you can use canvasGL.invalidateContent() to notify the Bitmap updated.

ChillingVan avatar May 09 '21 12:05 ChillingVan

I dont know how i reuse a bitmap

eliteSchwein avatar May 09 '21 12:05 eliteSchwein