OpenGL ES 2.0 Context in Android

15,369

The problem may be this line:

Square square = new Square();

Because it gets initialized before the call to "setRenderer". The constructor for Square calls GLES20 methods, which could be causing the problem. Try instantiating it after the call to "setRenderer(render);" or inside the "onSurfaceCreated" method.

Share:
15,369
Christopher Francisco
Author by

Christopher Francisco

Updated on June 04, 2022

Comments

  • Christopher Francisco
    Christopher Francisco about 2 years

    I'm new to OpenGL on Android and I have read heavily documented samples, and I kinda understand it. But before trying to do anything complex, I want to draw a simple 2D white rectangle on a black bacground. Nothing else.

    I'm stuck at this error: call to OpenGL ES API with no current context, which seems to be that I'm calling something from the non-OpenGL Thread. The thing is that I'm not sure what is called from the OpenGL Thread. So here's my code

    //============== Activity ==================//

    public class MainActivity extends Activity {
    
    public static String TAG = MainActivity.class.getSimpleName();
    
    MyGLSurfaceView surface;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
        );
    
        surface = new MyGLSurfaceView(this);
        setContentView(surface);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        surface.onPause();
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        surface.onResume();
    }
    
    }
    

    //==================== GLSurfaceView ========================//

    public class MyGLSurfaceView extends GLSurfaceView {
    
    MyGLSurfaceRenderer renderer;
    
    public MyGLSurfaceView(Context context) {
        super(context);
    
        setEGLContextClientVersion(2);
    
        renderer = new MyGLSurfaceRenderer(this);
        setRenderer(renderer);
    }
    
    }
    

    //================== Renderer ==========================//

    public class MyGLSurfaceRenderer implements GLSurfaceView.Renderer {
    
    Square square = new Square();
    
    public MyGLSurfaceRenderer(MyGLSurfaceView surface) {
    
    }
    
    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        square.draw();
    }
    
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
    }
    
    }
    

    //==================== Square ========================//

    public class Square {
    
    private FloatBuffer vertexBuffer;
    private ShortBuffer drawListBuffer;
    
    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // top left
                                    -0.5f, -0.5f, 0.0f,   // bottom left
                                     0.5f, -0.5f, 0.0f,   // bottom right
                                     0.5f,  0.5f, 0.0f }; // top right
    
    private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
    
    
    private final String vertexShaderCode =
            "attribute vec4 vPosition;" +
            "void main() {" +
            "  gl_Position = vPosition;" +
            "}";
    
    private final String fragmentShaderCode =
        "precision mediump float;" +
        "uniform vec4 vColor;" +
        "void main() {" +
        "  gl_FragColor = vColor;" +
        "}";
    
    int mProgram;
    
    static final int vertexStride = COORDS_PER_VERTEX * 4;
    static final int vertexCount = 4;
    
    public Square() {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); // (# of coordinate values * 4 bytes per float)
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareCoords);
        vertexBuffer.position(0);
    
        // initialize byte buffer for the draw list
        ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); // (# of coordinate values * 2 bytes per short)
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);
    
    
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = 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);                  // creates OpenGL ES program executables
    }
    
    public static int loadShader(int type, String shaderCode){
    
        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);
    
        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);
    
        return shader;
    }
    
    public void draw() {
        // Add program to OpenGL ES environment 
        GLES20.glUseProgram(mProgram);
    
        // get handle to vertex shader's vPosition member
        int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    
        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(mPositionHandle);
    
        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                     GLES20.GL_FLOAT, false,
                                     vertexStride, vertexBuffer);
    
        // get handle to fragment shader's vColor member
        int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
    
        // Set color for drawing the triangle
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);
    
        // Draw the triangle
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
    
        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
    }
    
  • Christopher Francisco
    Christopher Francisco almost 11 years
    Yep, that was the problem. Thanks