ChillingVan / android-openGL-canvas

An Android library that provides views using openGL canvas to draw things on SurfaceView or TextureView.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot create GL program: 0

eliteSchwein opened this issue · 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()
        }
    }

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

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

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

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!

Screenshot_20210501_165637_de.eliteschw31n.moonrakerremote.jpg

Sofar so good, except it overlays everything

What view do you use? GlSurfaceView or GlTextureView

self made view for now

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

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.

can i somehow get the GL Thread?

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 {
    }
}

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.

Can you provide a example? Would be great

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)
        }        
    }
}

Thanks alot,

I will try it later

How can i prevent it that it shows over everything?

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

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.

I dont know how i reuse a bitmap