簡體   English   中英

Android glTexSubImage2D 與 GL_TEXTURE_EXTERNAL_OES 問題(OpenGL + OpenCV + CameraX)

[英]Android glTexSubImage2D with GL_TEXTURE_EXTERNAL_OES problem (OpenGL + OpenCV + CameraX)

我正在編寫一個應用程序,使用 CameraX 來捕獲相機饋送,使用 OpenCV 來修改幀和使用 OpenGL 在GLSurfaceView上渲染它們。

我目前的方法是從 CameraX 渲染原始幀,構建一個像素緩沖區,一個 OpenCV Mat ,使用glReadPixels將像素緩沖區( ByteBuffer )復制到Mat ,然后處理它,將像素緩沖區從Mat寫回像素緩沖區然后使用glTexSubImage2D將其渲染到紋理上。

問題是,CameraX 使我能夠通過GL_TEXTURE_EXTERNAL_OES訪問幀數據,根據 OpenGL 的文檔,它不允許glTexSubImage2D修改紋理,而我當前的方法,使用下面的代碼,不起作用並不斷拋出W/OpenGLRenderer: [SurfaceTexture-1-25873-0] bindTextureImage: clearing GL error: 0x500 ,正如文檔所說的那樣。 在 OpenCV 處理之后,是否有另一種方法可以將緩沖區復制到GL_TEXTURE_EXTERNAL_OES 我能想到的另一件事是將紋理復制到GL_TEXTURE_2D ,然后使用glTexSubImage2D ,盡管我不知道該怎么做。 也許有人知道另一種方法可以讓我實現目標?

我的代碼:

public void onDrawFrame(GL10 gl) {
    GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT );

    if(this.resolutionSet) {
        surfaceTexture.updateTexImage();

        GLES20.glUseProgram(hProgram);

        int ph = GLES20.glGetAttribLocation(hProgram, "vPosition");
        int tch = GLES20.glGetAttribLocation(hProgram, "vTexCoord");
        int th = GLES20.glGetUniformLocation(hProgram, "sTexture");

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, hTex[0]);
        GLES20.glUniform1i(th, 0);

        GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 4 * 2, pVertex);
        GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 4 * 2, pTexCoord);
        GLES20.glEnableVertexAttribArray(ph);
        GLES20.glEnableVertexAttribArray(tch);

        GLES20.glReadPixels(0, 0, this.img.cols(), this.img.rows(), GL_RGBA, GL_UNSIGNED_BYTE, this.imgBuff);

        img.put(0, 0, this.imgBuff.array());

        Log.d(LOG_TAG, img.toString());

        Imgproc.cvtColor(img, img, Imgproc.COLOR_RGBA2BGRA);
        Imgproc.cvtColor(img, img, Imgproc.COLOR_BGRA2GRAY);

        this.imgBuff.clear();
        img.get(0, 0, this.imgBuff.array());

        GLES20.glTexImage2D(GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
        GLES20.glTexSubImage2D(GL_TEXTURE_EXTERNAL_OES, 0, 0, 0, img.width(), img.height(), GL_RGBA, GL_UNSIGNED_BYTE, this.imgBuff);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    }

    GLES20.glFlush();
}

和初始化紋理的代碼:

    hTex = new int[1];
    GLES20.glGenTextures ( 1, hTex, 0 );
    GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, hTex[0]);
    GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
    GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

鑒於您要替換整個圖像並從應用程序上傳“正常”RGBA 數據,為什么這需要是GL_TEXTURE_EXTERNAL_OES類型? 只需使用普通的GL_TEXTURE_2D

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM