本文介绍了修改使用表面纹理和OpenGL摄像机输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过经由openGL的过滤器运行它,然后在一个GLSurfaceView显示它来过滤从相机硬件传来的流。当openGL的去渲染帧时,LogCat中反复吐出一个错误:

0x502是一个通用的openGL的错误,并没有真正帮助我跟踪问题。这是一个怎样的code工作(或至少应工作在我的头上看到)的顺序,我已经复制低于我的code。我希望别人能看到我的问题是。

MainActivity.java

 公共类MainActivity扩展活动实现SurfaceTexture.OnFrameAvailableListener
{
    私人相机mCamera;
    私人MyGLSurfaceView glSurfaceView;
    私人表面表面纹理;
    MyGL20Renderer渲染器;

    @覆盖
    公共无效的onCreate(包savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        glSurfaceView =新MyGLSurfaceView(本);
        渲染= glSurfaceView.getRenderer();
        的setContentView(glSurfaceView);
    }

    公共无效startCamera(INT纹理)
    {
        表面=新的表面纹理(纹理);
        surface.setOnFrameAvailableListener(本);
        renderer.setSurface(面);

        mCamera = Camera.open();

        尝试
        {
            mCamera.set previewTexture(面);
            mCamera.start preVIEW();
        }
        赶上(IOException异常IOE)
        {
            Log.w(MainActivity,CAM发射失败);
        }
    }

    公共无效onFrameAvailable(表面纹理表面纹理)
    {
        glSurfaceView.requestRender();
    }

    @覆盖
    公共无效的onPause()
    {
        mCamera.stop preVIEW();
        mCamera.release();
        System.exit(0);
    }
 

MyGLSurfaceView.java

 类MyGLSurfaceView扩展GLSurfaceView
{
    MyGL20Renderer渲染器;
    公共MyGLSurfaceView(上下文的背景下)
    {
        超(上下文);

        setEGLContextClientVersion(2);

        渲染器=新MyGL20Renderer((MainActivity)上下文);
        setRenderer(渲染);
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    }
    公共MyGL20Renderer getRenderer()
    {
        返回渲染器;
    }
}
 

MyGL20Renderer.java

 公共类MyGL20Renderer实现GLSurfaceView.Renderer
{

    DirectVideo mDirectVideo;
    INT质感;
    私人表面表面纹理;
    MainActivity代表;

    公共MyGL20Renderer(MainActivity _delegate)
    {
        委托= _delegate;
    }

    公共无效onSurfaceCreated(GL10未使用的,EGLConfig配置)
    {
        mDirectVideo =新DirectVideo(纹理);
        质地= createTexture();
        GLES20.glClearColor(0.5F,0.5F,0.5F,1.0F);
        delegate.startCamera(纹理);
    }

    公共无效onDrawFrame(GL10未使用)
    {
            浮动[] MTX =新的浮动[16];
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
            surface.updateTexImage();
            surface.getTransformMatrix(MTX);

            mDirectVideo.draw();
    }

    公共无效onSurfaceChanged(GL10未使用的,诠释的宽度,高度INT)
    {
        GLES20.glViewport(0,0,宽度,高度);
    }

    静态公众诠释loadShader(整型,字符串着色器code)
    {
        INT着色器= GLES20.glCreateShader(类型);

        GLES20.glShaderSource(着色,着色器code);
        GLES20.glCompileShader(着色);

        返回着色器;
    }

    静态私人诠释createTexture()
    {
        INT []质地=新INT [1];

        GLES20.glGenTextures(1,纹理,0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,纹理[0]);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
     GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
     GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE);

        返回质地[0];
    }

    公共无效setSurface(表面纹理_surface)
    {
        表面= _surface;
    }
}
 

DirectVideo.java

 公共类DirectVideo {


    私人最终字符串vertexShader code =
            #extension GL_OES_EGL_image_external:需要的\ n+
            属性vec4地位; +
            属性vec4 inputTextureCoordinate; +
            不同的TextureCoordinate VEC2; +
            无效的主要()+
            {+
                GL_POSITION =地位;+
                的TextureCoordinate = inputTextureCoordinate.xy; +
            };

        私人最终字符串fragmentShader code =
            #extension GL_OES_EGL_image_external:需要的\ n+
            precision mediump浮动; +
            统一vec4 vColor; +
            无效的主要(){+
            gl_FragColor = vColor; +
            };

        私人FloatBuffer vertexBuffer,textureVerticesBuffer;
        私人ShortBuffer drawListBuffer;
         私人最终诠释mProgram;
            私人诠释mPositionHandle;
            私人诠释mColorHandle;
            私人诠释mTextureCoordHandle;


    //此数组中每个顶点的坐标数量
    静态最终诠释COORDS_PER_VERTEX = 2;
    静浮squareVertices逆时针顺序[] = {//:
         -1.0F,1.0F,
         -1.0F,-1.0F,
         1.0F,-1.0F,
         1.0F,1.0F
    };

    私人短DRAWORDER [] = {0,1,2,0,2,3}; //为了绘制顶点

    静浮textureVertices逆时针顺序[] = {//:
        1.0F,1.0F,
        1.0F,0.0,
        0.0,1.0F,
        0.0,0.0
   };

    私人最终诠释vertexStride = COORDS_PER_VERTEX * 4;每个顶点// 4字节

    私人诠释质感;

    公共DirectVideo(INT _texture)
    {
        纹理= _texture;

        ByteBuffer的BB = ByteBuffer.allocateDirect(squareVertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareVertices);
        vertexBuffer.position(0);

        ByteBuffer的DLB = ByteBuffer.allocateDirect(drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(DRAWORDER);
        drawListBuffer.position(0);

        ByteBuffer的BB2 = ByteBuffer.allocateDirect(textureVertices.length * 4);
        bb2.order(ByteOrder.nativeOrder());
        textureVerticesBuffer = bb2.asFloatBuffer();
        textureVerticesBuffer.put(textureVertices);
        textureVerticesBuffer.position(0);

        INT vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER,vertexShader code);
        INT fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShader code);

        mProgram = GLES20.glCreateProgram(); //创建空的OpenGL ES项目
        GLES20.glAttachShader(mProgram,vertexShader); //添加顶点着色器程序
        GLES20.glAttachShader(mProgram,fragmentShader); //添加片段着色器进行编程
        GLES20.glLinkProgram(mProgram);
    }

    公共无效平局()
    {
        GLES20.glUseProgram(mProgram);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,质地);

        mPositionHandle = GLES20.glGetAttribLocation(mProgram,位置);
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,假的,vertexStride,vertexBuffer);

        mTextureCoordHandle = GLES20.glGetAttribLocation(mPrograminputTextureCoordinate);
        GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
        GLES20.glVertexAttribPointer(mTextureCoordHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,假的,vertexStride,textureVerticesBuffer);

        mColorHandle = GLES20.glGetUniformLocation(mProgramvColor);

        GLES20.glDrawElements(GLES20.GL_TRIANGLES,drawOrder.length,
        GLES20.GL_UNSIGNED_SHORT,drawListBuffer);

        //禁用顶点数组
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
    }
}
 

解决方案

  mDirectVideo =新DirectVideo(纹理);
质地= createTexture();
 

 纹理= createTexture();
mDirectVideo =新DirectVideo(纹理);
 

着色

 私有最终字符串vertexShader code =
        属性vec4地位; +
        属性VEC2 inputTextureCoordinate; +
        不同的TextureCoordinate VEC2; +
        无效的主要()+
        {+
            GL_POSITION =地位;+
            的TextureCoordinate = inputTextureCoordinate; +
        };

    私人最终字符串fragmentShader code =
        #extension GL_OES_EGL_image_external:需要的\ n+
        precision mediump浮动; +
        不同的TextureCoordinate VEC2; \ N+
        统一samplerExternalOES s_texture; \ N+
        无效的主要(){+
        gl_FragColor =的Texture2D(s_texture,的TextureCoordinate); \ N+
        };
 

mColorHandle = GLES20.glGetUniformLocation(mProgram,vColor);

mColorHandle = GLES20.glGetAttribLocation(mProgram,s_texture);

从DirectVideo draw.glVertexAttribPointer删除初始化的东西等放入一些初始化函数。

 公共无效平局()
{
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,质地);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES,drawOrder.length,
            GLES20.GL_UNSIGNED_SHORT,drawListBuffer);
}
 

I am trying to filter the stream coming from the camera hardware by running it through an openGL filter, then displaying it in a GLSurfaceView. When openGL goes to render the frame, the LogCat repeatedly spits out an error:

0x502 is a generic openGL error, and doesn't really help me track down the problem. This is a sequence of how the code works (or atleast should be working as seen in my head), and I've copied my code below that. I am hoping that somebody else can see what my problem is.

MainActivity.java

public class MainActivity extends Activity implements SurfaceTexture.OnFrameAvailableListener
{
    private Camera mCamera;
    private MyGLSurfaceView glSurfaceView;
    private SurfaceTexture surface;
    MyGL20Renderer renderer;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        glSurfaceView = new MyGLSurfaceView(this);
        renderer = glSurfaceView.getRenderer();
        setContentView(glSurfaceView);
    }

    public void startCamera(int texture)
    {
        surface = new SurfaceTexture(texture);
        surface.setOnFrameAvailableListener(this);
        renderer.setSurface(surface);

        mCamera = Camera.open();

        try
        {
            mCamera.setPreviewTexture(surface);
            mCamera.startPreview();
        }
        catch (IOException ioe)
        {
            Log.w("MainActivity","CAM LAUNCH FAILED");
        }
    }

    public void onFrameAvailable(SurfaceTexture surfaceTexture)
    {
        glSurfaceView.requestRender();
    }

    @Override
    public void onPause()
    {
        mCamera.stopPreview();
        mCamera.release();
        System.exit(0);
    }

MyGLSurfaceView.java

class MyGLSurfaceView extends GLSurfaceView
{
    MyGL20Renderer renderer;
    public MyGLSurfaceView(Context context)
    {
        super(context);

        setEGLContextClientVersion(2);

        renderer = new MyGL20Renderer((MainActivity)context);
        setRenderer(renderer);
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    }
    public MyGL20Renderer getRenderer()
    {
        return renderer;
    }
}

MyGL20Renderer.java

public class MyGL20Renderer implements GLSurfaceView.Renderer
{

    DirectVideo mDirectVideo;
    int texture;
    private SurfaceTexture surface;
    MainActivity delegate;

    public MyGL20Renderer(MainActivity _delegate)
    {
        delegate = _delegate;
    }

    public void onSurfaceCreated(GL10 unused, EGLConfig config)
    {
        mDirectVideo = new DirectVideo(texture);
        texture = createTexture();
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        delegate.startCamera(texture);
    }

    public void onDrawFrame(GL10 unused)
    {
            float[] mtx = new float[16];
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
            surface.updateTexImage();
            surface.getTransformMatrix(mtx);

            mDirectVideo.draw();
    }

    public void onSurfaceChanged(GL10 unused, int width, int height)
    {
        GLES20.glViewport(0, 0, width, height);
    }

    static public int loadShader(int type, String shaderCode)
    {
        int shader = GLES20.glCreateShader(type);

        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }

    static private int createTexture()
    {
        int[] texture = new int[1];

        GLES20.glGenTextures(1,texture, 0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
     GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
     GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
             GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

        return texture[0];
    }

    public void setSurface(SurfaceTexture _surface)
    {
        surface = _surface;
    }
}

DirectVideo.java

public class DirectVideo {


    private final String vertexShaderCode =
            "#extension GL_OES_EGL_image_external : require\n"+
            "attribute vec4 position;" +
            "attribute vec4 inputTextureCoordinate;" +
            "varying vec2 textureCoordinate;" +
            "void main()" +
            "{"+
                "gl_Position = position;"+
                "textureCoordinate = inputTextureCoordinate.xy;" +
            "}";

        private final String fragmentShaderCode =
            "#extension GL_OES_EGL_image_external : require\n"+
            "precision mediump float;" +
            "uniform vec4 vColor;" +
            "void main() {" +
            "  gl_FragColor = vColor;" +
            "}";

        private FloatBuffer vertexBuffer, textureVerticesBuffer;
        private ShortBuffer drawListBuffer;
         private final int mProgram;
            private int mPositionHandle;
            private int mColorHandle;
            private int mTextureCoordHandle;


    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 2;
    static float squareVertices[] = { // in counterclockwise order:
         -1.0f,  1.0f,
         -1.0f,  -1.0f,
         1.0f,  -1.0f,
         1.0f,  1.0f
    };

    private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices

    static float textureVertices[] = { // in counterclockwise order:
        1.0f,  1.0f,
        1.0f,  0.0f,
        0.0f,  1.0f,
        0.0f,  0.0f
   };

    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

    private int texture;

    public DirectVideo(int _texture)
    {
        texture = _texture;

        ByteBuffer bb = ByteBuffer.allocateDirect(squareVertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareVertices);
        vertexBuffer.position(0);

        ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);

        ByteBuffer bb2 = ByteBuffer.allocateDirect(textureVertices.length * 4);
        bb2.order(ByteOrder.nativeOrder());
        textureVerticesBuffer = bb2.asFloatBuffer();
        textureVerticesBuffer.put(textureVertices);
        textureVerticesBuffer.position(0);

        int vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

        mProgram = GLES20.glCreateProgram();             // create empty OpenGL ES Program
        GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(mProgram);
    }

    public void draw()
    {
        GLES20.glUseProgram(mProgram);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture);

        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "position");
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,vertexStride, vertexBuffer);

        mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "inputTextureCoordinate");
        GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
        GLES20.glVertexAttribPointer(mTextureCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,vertexStride, textureVerticesBuffer);

        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
        GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
    }
}
解决方案
mDirectVideo = new DirectVideo(texture);
texture = createTexture();

should be

texture = createTexture();
mDirectVideo = new DirectVideo(texture);

Shader

private final String vertexShaderCode =
        "attribute vec4 position;" +
        "attribute vec2 inputTextureCoordinate;" +
        "varying vec2 textureCoordinate;" +
        "void main()" +
        "{"+
            "gl_Position = position;"+
            "textureCoordinate = inputTextureCoordinate;" +
        "}";

    private final String fragmentShaderCode =
        "#extension GL_OES_EGL_image_external : require\n"+
        "precision mediump float;" +
        "varying vec2 textureCoordinate;                            \n" +
        "uniform samplerExternalOES s_texture;               \n" +
        "void main() {" +
        "  gl_FragColor = texture2D( s_texture, textureCoordinate );\n" +
        "}";

mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

should be

mColorHandle = GLES20.glGetAttribLocation(mProgram, "s_texture");

remove initialization stuff from DirectVideo draw.glVertexAttribPointer etc. Put it in some init function.

public void draw()
{
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
            GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}

这篇关于修改使用表面纹理和OpenGL摄像机输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 08:54