Off screen rendering

Started by mxar, March 04, 2015, 09:38:02 PM

Previous topic - Next topic

EgonOlsen

In theory yes, but i've never tested it. Mainly because a lot of hardware wouldn't be able to deal with it anyway.

mxar


mxar

Hi,

is it possible to do the rendering on a bitmap instead of Texture in MixingExample example?

I need to create a bitmap or ByteBuffer which has the pixels of the screen shown in the MixingExample.

How can i convert the Overlay's texture  to bitmap or a ByteBuffer?

FrameBuffer.getPixels slows down the application.

ITextureEffect can help me?

Thanks in advance

EgonOlsen

No, you can't. At least not without using getPixels(). The rendered image, may it be on or off screen lives on the GPU and a transfer from GPU to CPU is costly...as you have already noticed. What do you need the Bitmap for exactly?

mxar

Thanks,

the bitmap is needed to read the screen image as  feedback.We want to add the option to read back the screen and apply some OpenCV methods to recognize some real objects (e.g texts,the face of a person,...).

Thanks for yout time :)

mxar

Hi,

is it possible to do the rendering but not to show the rendering results on screen?
e.g. the screen is reserved by other activity View?

Something like background rendering.

thanks

EgonOlsen

That's what a render target is actually for. But why would you want that in this context? In which way would that solve your problem? You want to fiddle around with the rendered on a pixel basis in code. For that, you have to transfer data back from the GPU to the main memory. And that is slow no matter what you do.

mxar


Hi,

at last i found a way to read screen pixels with better speed.
Using PixelBuffer the speed was around 42 ms instead of >120 ms.
With PixelBuffer the rendering is done in background.
This worked well if the Jpct-AE was  configured for Opengl 1.x.

But when i configured Jpct-AE to opengl 2.0 the problem was that the shaders couldn't load and compiled.
I think that the problem is that the EGL needs a proper configuration.

A set of EGL method is used to configure EGL:

int[] version = new int[2];
        int[] attribList = new int[] {
            EGL_WIDTH, mWidth,
            EGL_HEIGHT, mHeight,
            EGL_VERSION, 2,
            EGL_NONE
        };

private EGLConfig chooseConfig() {
        int[] attribList = new int[] {   
           EGL_RENDERABLE_TYPE,4, //important   
            EGL_DEPTH_SIZE, 16,
            EGL_STENCIL_SIZE, 0,
            EGL_RED_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_BLUE_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_NONE
        };

   mEGL = (EGL10) EGLContext.getEGL();
        mEGLDisplay = mEGL.eglGetDisplay(EGL_DEFAULT_DISPLAY);
        mEGL.eglInitialize(mEGLDisplay, version);
        mEGLConfig = chooseConfig(); // Choosing a config is a little more complicated
        mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL_NO_CONTEXT, null);
        mEGLSurface = mEGL.eglCreatePbufferSurface(mEGLDisplay, mEGLConfig,  attribList);
        mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);
        mGL = (GL10) mEGLContext.getGL();


Do you have any idea about it?

Thanks for your time.



EgonOlsen

You have to use the FrameBuffer constructor without the GL context for ES 2.0 mode...but I think that you are already doing this or otherwise, it wouldn't try to compile the shaders. What's the exact problem that occurs when compiling the shaders (stacktrace, log output...)?

mxar

Hi,
finally i found out that when i create the frameBuffer then the trace shows that shaders couldn't load and compiled.

The trace is the following:

I/jPCT-AE(10012): Loading file from InputStream
I/jPCT-AE(10012): Text file from InputStream loaded...2416 bytes
I/jPCT-AE(10012): Default vertex shader is: /defaultVertexShader.src
I/jPCT-AE(10012): Loading file from InputStream
I/jPCT-AE(10012): Text file from InputStream loaded...4496 bytes
I/jPCT-AE(10012): Compiling shader program!
E/libEGL(10012): called unimplemented OpenGL ES API
E/libEGL(10012): called unimplemented OpenGL ES API
E/libEGL(10012): called unimplemented OpenGL ES API
E/libEGL(10012): called unimplemented OpenGL ES API
E/libEGL(10012): called unimplemented OpenGL ES API
I/jPCT-AE(10012): Could not compile shader 35633:
E/libEGL(10012): called unimplemented OpenGL ES API
E/jPCT-AE(10012): [ 1427752506957 ] - ERROR: Failed to load and compile vertex shaders!
W/jPCT-AE(10012): [ 1427752506957 ] - WARNING: Unable to load shader!
E/jPCT-AE(10012): [ 1427752506958 ] - ERROR: java.lang.RuntimeException: [ 1427752506957 ] - ERROR: Failed to load and compile vertex shaders!
E/jPCT-AE(10012):    at com.threed.jpct.Logger.log(Logger.java:206)
E/jPCT-AE(10012):    at com.threed.jpct.GLSLShader.loadProgram(GLSLShader.java:1070)
E/jPCT-AE(10012):    at com.threed.jpct.GLSLShader.<init>(GLSLShader.java:265)
E/jPCT-AE(10012):    at com.threed.jpct.GL20.<init>(GL20.java:124)
E/jPCT-AE(10012):    at java.lang.Class.newInstanceImpl(Native Method)
E/jPCT-AE(10012):    at java.lang.Class.newInstance(Class.java:1208)
E/jPCT-AE(10012):    at com.threed.jpct.GLRenderer.init(GLRenderer.java:403)
E/jPCT-AE(10012):    at com.threed.jpct.GLRenderer.init(GLRenderer.java:384)
E/jPCT-AE(10012):    at com.threed.jpct.FrameBuffer.<init>(FrameBuffer.java:94)
E/jPCT-AE(10012):    at com.threed.jpct.FrameBuffer.<init>(FrameBuffer.java:119)


i call the opengl version 2: fb = new FrameBuffer(width, height);


Before creating the FrameBuffer i try to create EGLContext compatible with Opengl 2.

I believe that i dont config correctly the EGLContext,perhaps the EGLContext i created is not compatible with openGL 2.

I use the following code to config the EGLContext:


int[] version = new int[2];
        int[] attribList = new int[] {
            EGL_WIDTH, width,
            EGL_HEIGHT, height,
            EGL_NONE
        };
       
       
        mEGL = (EGL10) EGLContext.getEGL();
       
       
        mEGLDisplay = mEGL.eglGetDisplay(EGL_DEFAULT_DISPLAY);
        mEGL.eglInitialize(mEGLDisplay, version);
     
        mEGLConfig = chooseConfig(); // Choosing a config is a little more complicated

        int EGL_CONTEXT_CLIENT_VERSION = 0x3098;

        int[] list = {EGL_CONTEXT_CLIENT_VERSION, (int) 2,EGL10.EGL_NONE };
               
        mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL_NO_CONTEXT, list); //null);
               
        mEGLSurface = mEGL.eglCreatePbufferSurface(mEGLDisplay, mEGLConfig,  attribList);
        mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);
        mGL = (GL10) mEGLContext.getGL();



  private EGLConfig chooseConfig() {
        int[] attribList = new int[] { 
              EGL_DEPTH_SIZE, 16,
            EGL_STENCIL_SIZE, 8,
            EGL_RED_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_BLUE_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_NONE
        };
   

        // No error checking performed, minimum required code to elucidate logic
        // Expand on this logic to be more selective in choosing a configuration
        int[] numConfig = new int[1];
        mEGL.eglChooseConfig(mEGLDisplay, attribList, null, 0, numConfig);
        int configSize = numConfig[0];
        mEGLConfigs = new EGLConfig[configSize];
        mEGL.eglChooseConfig(mEGLDisplay, attribList, mEGLConfigs, configSize, numConfig);

        if (LIST_CONFIGS) {
            listConfig();
        }

        return mEGLConfigs[0];  // Best match is probably the first configuration
    }
   
    private void listConfig() {
        Log.i(TAG, "Config List {");

        for (EGLConfig config : mEGLConfigs) {
            int d, s, r, g, b, a;
                   
            // Expand on this logic to dump other attributes       
            d = getConfigAttrib(config, EGL_DEPTH_SIZE);
            s = getConfigAttrib(config, EGL_STENCIL_SIZE);
            r = getConfigAttrib(config, EGL_RED_SIZE);
            g = getConfigAttrib(config, EGL_GREEN_SIZE);
            b = getConfigAttrib(config, EGL_BLUE_SIZE);
            a = getConfigAttrib(config, EGL_ALPHA_SIZE);               
            Log.i(TAG, "    <d,s,r,g,b,a> = <" + d + "," + s + "," +
                r + "," + g + "," + b + "," + a + ">");
        }

        Log.i(TAG, "}");
    }
       
    private int getConfigAttrib(EGLConfig config, int attribute) {
        int[] value = new int[1];
        return mEGL.eglGetConfigAttrib(mEGLDisplay, config,
                        attribute, value)? value[0] : 0;
    }
       
Right after this code i create the frameBuffer but then the default shaders cannot loaded and compiled.


Thanks for your time.


EgonOlsen

You are not in ES 2.0 mode then, hence the undefined function errors. Have you tried to request 2.0 just like the examples do in addition to your config-code?

mxar


Thanks for the reply.

Is there an example which configs ES 2.0 mode?

Where can I find one?

Can you help me?

Thanks in advance


mxar


EgonOlsen

Just out of interest: How are you reading the pixels now? By the normal getPixels() method or are you doing something else?