Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/215.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 如何将自定义视图渲染为OpenGL纹理。在线提供的解决方案仅对渲染Web视图有用,但我希望对自定义视图执行此操作_Android_Opengl Es_Textures_Android Canvas - Fatal编程技术网

Android 如何将自定义视图渲染为OpenGL纹理。在线提供的解决方案仅对渲染Web视图有用,但我希望对自定义视图执行此操作

Android 如何将自定义视图渲染为OpenGL纹理。在线提供的解决方案仅对渲染Web视图有用,但我希望对自定义视图执行此操作,android,opengl-es,textures,android-canvas,Android,Opengl Es,Textures,Android Canvas,我正在将自定义视图渲染到OpenGL纹理。我已在表面纹理上方创建了一个曲面,并使用surface.lockCanvas返回的画布在CustomView的onDraw方法中进行绘制。我在surfaceTexture.UpdateMaximage()方法附近遇到异常 下面是显示的错误,我已将代码复制到下面。请告诉我哪里出了问题 java.lang.RuntimeException: Error during updateTexImage at

我正在将自定义视图渲染到OpenGL纹理。我已在表面纹理上方创建了一个曲面,并使用surface.lockCanvas返回的画布在CustomView的onDraw方法中进行绘制。我在surfaceTexture.UpdateMaximage()方法附近遇到异常

下面是显示的错误,我已将代码复制到下面。请告诉我哪里出了问题

java.lang.RuntimeException: Error during updateTexImage                             
at android.graphics.SurfaceTexture.nativeUpdateTexImage(Native Method)                                                                                 
at android.graphics.SurfaceTexture.updateTexImage(SurfaceTexture.java:169)
代码:Main Activity.java

public class MainActivity extends Activity {
    GLSurfaceView ourSurface;
    CustomView myView;
    GLCubeRendererEx renderer;

    private final  int TEXTURE_WIDTH=256;
    private final int TEXTURE_HEIGHT =256;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ourSurface = new GLSurfaceView(this);
        myView = new CustomView(this);
        renderer= new  GLCubeRendererEx(getBaseContext());
        ourSurface.setRenderer(renderer);

        setContentView(ourSurface);

        addContentView( myView, new ViewGroup.LayoutParams( TEXTURE_WIDTH, TEXTURE_HEIGHT ) );
    }

    @Override
    protected void onResume() {
        super.onResume();
        ourSurface.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        ourSurface.onPause();
    }

    public class CustomView extends View {

        public CustomView(Context context) {
            super(context);
            setLayoutParams( new ViewGroup.LayoutParams( TEXTURE_WIDTH, TEXTURE_HEIGHT ) );
        }

        @Override
        protected void onDraw(Canvas canvas) {

            if(renderer.surface!=null) {
                try {

                    final Canvas surfaceCanvas  = renderer.surface.lockCanvas(null);

                    super.onDraw(surfaceCanvas);
                    surfaceCanvas.drawColor(Color.WHITE);

                    Paint ourBlue = new Paint();
                    ourBlue.setColor(Color.BLUE);
                    Paint ourRed = new Paint();
                    ourRed.setColor(Color.RED);
                    Paint ourGreen = new Paint();
                    ourGreen.setColor(Color.GREEN);
                    Paint ourYellow = new Paint();
                    ourYellow.setColor(Color.YELLOW);

                    //Implementing drawCircle
                    surfaceCanvas.drawCircle(800, 800, 50, ourRed);
                    surfaceCanvas.drawCircle(200, 200, 50, ourBlue);
                    surfaceCanvas.drawCircle(400, 400, 50, ourGreen);
                    surfaceCanvas.drawCircle(600, 600, 50, textPaint);



                    renderer.surface.unlockCanvasAndPost(surfaceCanvas);
                }

                catch(Surface.OutOfResourcesException e)
                {
                    e.printStackTrace();
                }


            }
        }
    }
}
glcuberenderex.java-具有导致异常的代码

public class GLCubeRendererEx implements GLSurfaceView.Renderer{

    private GLCube cube;
    private Context context;
    private SurfaceTexture surfaceTexture = null;
    public Surface surface;
    private final  int TEXTURE_WIDTH=256;
    private final int TEXTURE_HEIGHT =256;
    int glSurfaceTex;

    public GLCubeRendererEx(Context context)
    {    
        this.context=context;
        cube = new GLCube();
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig eglconfig) 
    {

        gl.glEnable(GL_TEXTURE_2D);         //Enable Texture Mapping ( NEW )
        gl.glShadeModel(GL10.GL_SMOOTH);

        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glClearColor(.2f,0f,.8f,1); //COLOR
        gl.glClearDepthf(1f);
          gl.glEnable(GL10.GL_DEPTH_TEST);          //Enables Depth Testing
        gl.glDepthFunc(GL10.GL_LEQUAL);

    }

    @Override
    public void onDrawFrame(GL10 gl)
    {

        //problematic code
        synchronized ( this ) {

            surfaceTexture.updateTexImage(); // Update texture

        }

        gl.glDisable(GL10.GL_DITHER);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        GLU.gluLookAt(gl,0,0,-5,0,0,0,0,2,0);

        long time = SystemClock.uptimeMillis() % 4000L;
        float angle = 0.090f * ((int)time);

        gl.glRotatef(angle,1,0,0);
        gl.glRotatef(angle,0,1,0);
        gl.glRotatef(angle,0,0,1);


        cube.draw(gl);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height)  //landscape to potrail -changes how everything is setup
    {

        surface = null;
        surfaceTexture = null;
        glSurfaceTex = cube.Engine_CreateSurfaceTexture( gl,TEXTURE_WIDTH, TEXTURE_HEIGHT );
        if ( glSurfaceTex > 0 ) {
            surfaceTexture = new SurfaceTexture( glSurfaceTex );
            surfaceTexture.setDefaultBufferSize( TEXTURE_WIDTH, TEXTURE_HEIGHT );

           surface = new Surface( surfaceTexture );

            if(surface!=null)
                System.out.println("surface isnt null");

        }
        gl.glViewport(0,0,width,height);
        float ratio = (float) width/height;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glFrustumf(-ratio, ratio, -1, 1, 1,25);
    }
}
GLCube.java

public class GLCube{
    private float vertices[]={

            -1.0f, -1.0f, 1.0f, //Vertex 0
            1.0f, -1.0f, 1.0f,  //v1
            -1.0f, 1.0f, 1.0f,  //v2
            1.0f, 1.0f, 1.0f,   //v3

            1.0f, -1.0f, 1.0f,  //...
            1.0f, -1.0f, -1.0f,
            1.0f, 1.0f, 1.0f,
            1.0f, 1.0f, -1.0f,

            1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f, -1.0f,
            1.0f, 1.0f, -1.0f,
            -1.0f, 1.0f, -1.0f,

            -1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f, 1.0f,
            -1.0f, 1.0f, -1.0f,
            -1.0f, 1.0f, 1.0f,

            -1.0f, -1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f, 1.0f,
            1.0f, -1.0f, 1.0f,

            -1.0f, 1.0f, 1.0f,
            1.0f, 1.0f, 1.0f,
            -1.0f, 1.0f, -1.0f,
            1.0f, 1.0f, -1.0f,



    };

    private float rgbaVals[]={

            1,1,0,5f,
            .25f,0,.85f,1,
            0,1,1,1
    };

    private float texture[] = {
            //Mapping coordinates for the vertices
            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,

            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,

            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,

            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,

            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,

            0.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            1.0f, 1.0f,


    };

    private FloatBuffer vertBuff,colorBuff;
    /** The buffer holding the texture coordinates */
    private FloatBuffer textureBuffer;
    /** Our texture pointer */
    private int[] textures = new int[1];

    private short[] pIndex = {
            0,1,3, 0,3,2,           //Face front
            4,5,7, 4,7,6,           //Face right
            8,9,11, 8,11,10,        //...
            12,13,15, 12,15,14,
            16,17,19, 16,19,18,
            20,21,23, 20,23,22,
    };


    private ShortBuffer pBuff;

    public GLCube()
    {
        ByteBuffer bBuff = ByteBuffer.allocateDirect(vertices.length*4);
        bBuff.order(ByteOrder.nativeOrder());
        vertBuff = bBuff.asFloatBuffer();
        vertBuff.put(vertices);
        vertBuff.position(0);

        ByteBuffer pbBuff = ByteBuffer.allocateDirect(pIndex.length * 2);
        pbBuff.order(ByteOrder.nativeOrder());
        pBuff =pbBuff.asShortBuffer();
        pBuff.put(pIndex);
        pBuff.position(0);

        bBuff = ByteBuffer.allocateDirect(texture.length * 4);
        bBuff.order(ByteOrder.nativeOrder());
        textureBuffer = bBuff.asFloatBuffer();
        textureBuffer.put(texture);
        textureBuffer.position(0);

    }

    public void draw(GL10 gl)
    {


        gl.glFrontFace(GL10.GL_CCW);
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glCullFace(GL10.GL_BACK);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


        gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertBuff);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);



        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
        gl.glDrawElements(GL10.GL_TRIANGLES,pIndex.length,GL10.GL_UNSIGNED_SHORT, pBuff);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glDisable(GL10.GL_CULL_FACE);

    }


    int Engine_CreateSurfaceTexture(GL10 gl, int width, int height )
    {

        gl.glGenTextures(1, textures, 0);
          if ( textures[0] > 0 ) {

            gl.glBindTexture( GL_TEXTURE_2D, textures[0] );


            gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, null );


            GLES20.glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );

            GLES20.glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

            GLES20.glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

            GLES20.glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

            gl.glBindTexture( GL_TEXTURE_2D, 0 );

        }

        return textures[0];

    }


}

我没有注意到你的线程是lockCanvas,因此你对unlockCanvas的调用可以工作。在上面的onDraw方法中的MainActivity.java中完成所有绘制之后,我已经解锁了画布。是的,但是你的lockCanvas在哪里呢?它在MainActivity.java中作为renderer.surface.lockCanvas