androidopengl-esgles20

How to add objects to draw in runtime using GLES20?


In my simple GLES20 app I'm trying to add some objects in runtime to draw. In my Renderer class I have ArrayList of Squares:

private ArrayList<Square> mSquares = new ArrayList<Square>();

Here is my Square class.

Square is drawing well if create it in onSurfaceCreated.

But what I'm actually want to do. I need to add new Square into mSquares in runtime by button clicking and draw squares in onDrawFrame.

In my Renderer class I created AddFigure() method:

public void AddFigure(float x, float y, float z)
{                                                     // color                   coords    angle
    mSquares.add(new Square("Red square", new float[] {1, 0, 0, 1}, new float[] {x, y, z}, 100f));
}

I'm invoking this method by clicking on the button in my Activity:

fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
                mGLRenderer.AddFigure(1f, 1f, 1f);
        }
    });

But it always throwing this exceptions:

E/AndroidRuntime: FATAL EXCEPTION: GLThread 220
    java.util.ConcurrentModificationException

and

E/libEGL: call to OpenGL ES API with no current context (logged once per thread)
E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glEnableVertexAttribArray:741 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16

I'm tried somehow fix it using glBufferData and glBufferSubData, but have no success. Maybe there is an example or wiki how to do it right?


Solution

  • It's ConcurrentModification error, which means you are trying to access the rendering pipeline from a different thread than the OpenGL is rendered on.

    This should be the way to do that:

    glSurfaceView.queueEvent(new Runnable() {
                        @Override
                        public void run() {
                            mGLRenderer.AddFigure(1f, 1f, 1f);
                        }
                    });