0

I am trying to create an app, in android using opengl es 2.0, that has a button on pressing which it would take the screenshot and would blurr it using any blur algo (here Fast blur) and would display the blurred screenshot. The sole aim of developing such an app is to try and implement blurring. Using various internet resources i was able to take the screenshot and implement blurring but i dont know how to display the blurred bitmap on the screen in opengl. Can anyone please help me with this? Thanks in advance. Following is my Main activity:

package com.example.ankurtest;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class MainActivity extends Activity {
GLSurfaceView mView;
GLRendererEX myRenderer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //setContentView(mView);
    mView = (MyGLSurfaceview)findViewById(R.id.glSurfaceViewID);
    myRenderer = new GLRendererEX(this);

    mView.setEGLContextClientVersion(2);
    mView.setRenderer(myRenderer);
    myRenderer.queueDoSomethingNextTick(GLRendererEX.DO_THIS);

    findViewById(R.id.buttonID).setOnTouchListener(new OnTouchListener(){

       /* public void onTouch(MotionEvent event){
            myRenderer.queueDoSomethingNextTick(GLRendererEX.DO_THAT);
           // Compiler might complain about myRenderer not being final
        }*/

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_UP){
            myRenderer.queueDoSomethingNextTick(GLRendererEX.DO_THAT);
            return true;
            }
            return false;
        }
});
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    mView.onPause();
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    mView.onResume();
}

    }

Following is my MyGLsurfaceview class:

package com.example.ankurtest;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;

public class MyGLSurfaceview extends GLSurfaceView {

//private final GLRendererEX mRenderer;

public MyGLSurfaceview(Context context) {
    super(context);

    // Create an OpenGL ES 2.0 context.
    //setEGLContextClientVersion(2);

    // Set the Renderer for drawing on the GLSurfaceView
    //mRenderer = new GLRendererEX();
    //setRenderer(mRenderer);

    // Render the view only when there is a change in the drawing data
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
public MyGLSurfaceview(Context context, AttributeSet attrs)
{
  super(context, attrs);

  // Create an OpenGL ES 2.0 context.
  setEGLContextClientVersion(2);

  // Set the Renderer for drawing on the GLSurfaceView
  //mRenderer = new GLRendererEX();
  //setRenderer(mRenderer);
}

}

Following is my Renderer class:

package com.example.ankurtest;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Build;
import android.view.Display;
import android.view.WindowManager;

@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public class GLRendererEX implements Renderer{

private final Context context;

private int command;
public static final int DO_THIS = 1;
public static final int DO_THAT = 2;


public GLRendererEX(Context activitycontext) {
    context = activitycontext;

}


public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    GLES20.glClearColor(0.8f, 0.0f, 0.2f, 1f);

    // TODO Auto-generated method stub

}
@Override
public void onDrawFrame(GL10 gl) {

    if (command==DO_THAT) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        Point size = new Point();
        WindowManager wm = (WindowManager)  context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        //myactivity.getWindowManager().getDefaultDisplay().getSize(size);
        display.getSize(size);
        int width = size.x; // use your favorite width
        int height = size.y; // use your favorite height
        int screenshotSize = width * height;
        ByteBuffer bb = ByteBuffer.allocateDirect(screenshotSize * 4);
        bb.order(ByteOrder.nativeOrder());
        GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, bb);
        int pixelsBuffer[] = new int[screenshotSize];
        bb.asIntBuffer().get(pixelsBuffer);
        bb = null;

        for (int i = 0; i < screenshotSize; ++i) {
            // The alpha and green channels' positions are preserved while the      red and blue are swapped
            pixelsBuffer[i] = ((pixelsBuffer[i] & 0xff00ff00)) |    ((pixelsBuffer[i] & 0x000000ff) << 16) | ((pixelsBuffer[i] & 0x00ff0000) >> 16);
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixelsBuffer, screenshotSize-width, -width, 0, 0, width, height);
Bitmap fast = Fastblur(bitmap,10);
        command = DO_THIS;
    }
    // TODO Auto-generated method stub

}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub

}

public void queueDoSomethingNextTick(int command){

    this.command = command;

}

}

Herein Fastblur() method is used to blur the screenshot and it returns the blurred screenshot. Now, my question is how to display the bitmap returned by Fastblur() using opengl?

genpfault
  • 51,148
  • 11
  • 85
  • 139
ankur
  • 5
  • 4
  • Draw a textured quad (sprite) consisting of 2 triangles with [orthographic projection](http://en.wikipedia.org/wiki/Orthographic_projection) or use any sprite drawing wrapper you like. – Ivan Aksamentov - Drop Mar 22 '14 at 10:32

1 Answers1

0

The common method to display a full sized image is to use an orthogonal projection matrix:

(example using fixed functionality)

GLES20.glViewport(0, 0, windowWidth, windowHeight);
GLES20.glMatrixMode(GL_PROJECTION);
GLES20.glLoadIdentity();
GLES20.glOrtho(-1, 1, -1, 1, 1, -1);

than draw a fullscreen quad with your image bound as texture2D.

basic texture tutorial here.

basic quad tutorial here.

set quad coordinate as follow:

static float squareCoords[] = {
        -1f, -1f, 0.0f,   // top left
        -1f, 1f, 0.0f,   // bottom left
         1f, 1f, 0.0f,   // bottom right
         1f, -1f, 0.0f }; // top right
j-p
  • 1,622
  • 10
  • 18
  • [Fixed function](http://en.wikipedia.org/wiki/Fixed-function) is common method? In a [stone age](http://en.wikipedia.org/wiki/Stone_Age)? – Ivan Aksamentov - Drop Mar 22 '14 at 10:29
  • @Drop where do you see fixed function? if he wants to had a shader there's no problem, but seeing the level of it's code, he's maybe not ready for blurring in fragment shader... – j-p Mar 22 '14 at 10:42
  • `glMatrixMode()`, `glLoadIdentity()`, `glOrtho()` is a matrix stack functionality which is a part of fixed function pipeline, which was obsolete for a several years. It is not common anymore in any way. That is just what I want to say. – Ivan Aksamentov - Drop Mar 22 '14 at 11:07
  • the fact that fixed pipeline use those matrix doesn't mean that using them in a simpler vertex buffer is obsolete. Using them gives you access to default shader variables that doesn't impact performances (example: gl_ModelViewProjectionMatrix), at least that's what I guess... – j-p Mar 22 '14 at 11:13
  • @Drop ok, you are right, but for simple example and tutorial, they are priceless! – j-p Mar 22 '14 at 11:27
  • I don't think that it's worth loosing time learning things that could be removed from API any time soon (or was already removed). ([Click](https://www.opengl.org/wiki/Fixed_Function_Pipeline)). – Ivan Aksamentov - Drop Mar 22 '14 at 11:30
  • throwing an eye on the code the OP supplied lead me to gives the simplest example, without shadder (if he knew something about glsl, his blurring algo would surely not look like it is). the shortest path to what he wants is the one I gave. – j-p Mar 22 '14 at 11:42
  • Thanks a lot for the help. One more thing i wanted to ask you is that is there any workaround for displaying bitmap in this scenario besides using opengl, if yes then what is it and which one should i prefer. Please bear with the poor coding and trivial questions, i am new to android. Thanks again. – ankur Mar 22 '14 at 16:28
  • Having your GL context, (makes a long time since I dev with android) you should start a new activity for your bitmap display i guess, which appear an extra work since you already have a context for imaging. I can only point some good [tutorial](http://developer.android.com/training/displaying-bitmaps/display-bitmap.html). OpenGL and Android are two distinct technologies, choose one, and start learning. Maybe you should learn android basis first. For opengl you could learn using simpler framework like OpenTK in c#, using fixed pipeline for simplicity and than extending your learning to shadder. – j-p Mar 23 '14 at 01:04