Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android glTexSubImage2D带有GL#U纹理#U外部#OES问题(OpenGL+;OpenCV+;CameraX)_Android_Opencv_Opengl Es_Glsurfaceview_Android Camerax - Fatal编程技术网

Android glTexSubImage2D带有GL#U纹理#U外部#OES问题(OpenGL+;OpenCV+;CameraX)

Android glTexSubImage2D带有GL#U纹理#U外部#OES问题(OpenGL+;OpenCV+;CameraX),android,opencv,opengl-es,glsurfaceview,android-camerax,Android,Opencv,Opengl Es,Glsurfaceview,Android Camerax,我正在编写一个应用程序,它使用CameraX捕捉相机提要,使用OpenCV修改帧,使用OpenGL在GLSurfaceView上渲染帧 我目前的方法是从CameraX渲染原始帧,构造一个像素缓冲区,一个OpenCVMat,使用glReadPixels将像素缓冲区(ByteBuffer)复制到Mat,然后对其进行处理,将像素缓冲区从Mat写入像素缓冲区,然后使用glTexSubImage2D将其渲染到纹理上 问题是,CameraX使我能够通过GL_TEXTURE\u EXTERNAL_OES访问帧

我正在编写一个应用程序,它使用CameraX捕捉相机提要,使用OpenCV修改帧,使用OpenGL在
GLSurfaceView
上渲染帧

我目前的方法是从CameraX渲染原始帧,构造一个像素缓冲区,一个OpenCV
Mat
,使用
glReadPixels
将像素缓冲区(
ByteBuffer
)复制到
Mat
,然后对其进行处理,将像素缓冲区从
Mat
写入像素缓冲区,然后使用
glTexSubImage2D
将其渲染到纹理上

问题是,CameraX使我能够通过
GL_TEXTURE\u EXTERNAL_OES
访问帧数据,根据OpenGL的文档,它不允许
glTexSubImage2D
修改纹理,而我当前使用下面代码的方法不起作用,并不断抛出
W/OpenGLRenderer:[SurfaceTexture-1-25873-0]bindTextureImage:清除总账错误:0x500
,如文档所述。OpenCV处理后,是否有其他方法将缓冲区复制到
GL\u TEXTURE\u EXTERNAL\u OES
?我能想到的另一件事是将纹理复制到
GL\u texture\u 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\u纹理\u外部\u OES
类型?只需使用普通的
GL_纹理\u 2D

这可能有效;你能给我一些建议吗,可能是一些代码,关于如何初始化新的纹理,清除当前渲染的像素,并将新的纹理渲染到屏幕上?