0

This is the first time I am trying to render the Camera Preview using OpenGL ES 2.0. I am into some issues with the code. Here goes the code below --

MainActivity.java

public class MainActivity extends AppCompatActivity implements SurfaceTexture.OnFrameAvailableListener {

private Camera mCamera;
private GLSurfaceView glSurfaceView;
Bitmap bitmap;
FrameLayout frameLayout;
DrawOnTop drawOnTop;
FrameLayout.LayoutParams layoutParams;
private SurfaceTexture surface;
MyGLRenderer renderer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    frameLayout = (FrameLayout)findViewById(R.id.camera_preview);
    drawOnTop = null;
}

public void onCamViewButtonClicked (View view)
{
    glSurfaceView = new MyGLSurfaceView(this);
    renderer = MyGLSurfaceView.getRenderer();
    frameLayout.addView(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)
    {
        ioe.printStackTrace();
    }
}

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

public void onOverlayImageButtonClicked(View view)
{
    if(glSurfaceView == null)
    {
        Toast.makeText(getApplicationContext(),"Preview is not available now!",Toast.LENGTH_LONG).show();
        return;
    }
    else {
        if(drawOnTop != null)
        {
            frameLayout.removeView(drawOnTop);
            drawOnTop = null;
        }
        else
        {
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.internetothings);
            drawOnTop = new DrawOnTop(this, bitmap);
            layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
            frameLayout.addView(drawOnTop, layoutParams);
            Toast.makeText(getApplicationContext(),"Click again to remove!",Toast.LENGTH_LONG).show();
        }
    }
}

public void onPause()
{
    super.onPause();
    mCamera.stopPreview();
    mCamera.release();
}
}

MyGLSurfaceView.java

public class MyGLSurfaceView extends GLSurfaceView{
static MyGLRenderer myGLRenderer;

public MyGLSurfaceView(Context c)
{
    super(c);
    setEGLContextClientVersion(2);
    myGLRenderer = new MyGLRenderer((MainActivity)c);
    setRenderer(myGLRenderer);
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}

public static MyGLRenderer getRenderer()
{
    return myGLRenderer;
}
}

MyGLRenderer.java

public class MyGLRenderer implements GLSurfaceView.Renderer{
int texture;
private SurfaceTexture surfaceTexture;
MainActivity mainActivity;

public MyGLRenderer(MainActivity main)
{
    mainActivity = main;
}

public void onSurfaceCreated(GL10 unused, javax.microedition.khronos.egl.EGLConfig config)
{
    texture = createTexture();
    GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    mainActivity.startCamera(texture);
}

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

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

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)
{
    surfaceTexture = _surface;
}
}

Issue 1: After all this, I am getting a Grey texture instead of a Camera Preview. As a reference I have checked this post. Please help me to identify what went wrong over here.

Issue 2: While investigating Issue 1, I feel (not sure though) that in MyGLSurfaceView.java, declaring myGLRenderer as static could be a problem. Also I have declared the method getRenderer() as static as well which might cause the issue. So I removed the static keyword as below --

public class MyGLSurfaceView extends GLSurfaceView {
MyGLRenderer myGLRenderer;

public MyGLSurfaceView(Context c)
{
    super(c);
    setEGLContextClientVersion(2);
    myGLRenderer = new MyGLRenderer((MainActivity)c);
    setRenderer(myGLRenderer);
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}

public MyGLRenderer getRenderer()
{
    return myGLRenderer;
}
}

But then I run into a very weird issue in this line --

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

It says "Cannot resolve method getRenderer()".

Can anybody please help me get over these two issues? Thanks in advance!

Community
  • 1
  • 1
Saumik Bhattacharya
  • 891
  • 1
  • 12
  • 28

1 Answers1

0

You can try various options: I had the issue null point exception: MainActivity.startCamera.

First, I would say check your device settings: Settings --> Apps --> (Your App) --> permissions and change it to camera.

Second, you can try changing your startCamera() because we need to release the camera after we performed the event. Modified as follows:

 public void startCamera(int texture) {

    releaseCameraAndPreview();
    surface = new SurfaceTexture(texture);
    surface.setOnFrameAvailableListener(this);
    renderer.setSurface(surface);

    mCamera = Camera.open();
    Camera.Parameters parameters = mCamera.getParameters();
    mCamera.setParameters(parameters);

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

just add releaseCameraAndPreview() at the bottom of MainActivity()

private void releaseCameraAndPreview() {
    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }
}

Try that and let us know. There can be other options too, eg. changing in the manifest file : Add the following

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

Hope this helps

Sdembla
  • 1,629
  • 13
  • 13