www.jpct.net

jPCT-AE - a 3d engine for Android => Support => Topic started by: haijin on May 27, 2011, 09:38:36 pm

Title: framebuffer getPixels()
Post by: haijin on May 27, 2011, 09:38:36 pm
Hi,

I am having trouble getting the right colors to generate a bitmap from the framebuffer.getPixels() method. My thought was that fb would return ints with 24bits, 1 byte per color and that, depending on the Config when creating bitmap and some previos manipulation I would get the right result. I've tried different options but none has been succesful so, I thought I better ask instead of banging my head on this...
first I tried for Config.RGB_565, doing the following conversion (and other bitwise operations combos):

                            int[] tmpPixels = fb.getPixels();
                            for (int i = 0; i < tmpPixels.length; i++){
                                int tmpInt = ((tmpPixels & 0xf8) >> 3);
                                tmpInt += ((tmpPixels & 0xfc00) >> 5);
                                tmpInt += ((tmpPixels & 0xf80000) >> 11);
                                tmpPixels = tmpInt;
                            }
                            lastImage = Bitmap.createBitmap(tmpPixels, fb.getWidth(), fb.getHeight(), Config.RGB_565);

got nice unintended predator style views, playing with that :)
also tried with a more comfortable format, Config.ARGB_8888, only adding opaque alpha:

                            int[] tmpPixels = fb.getPixels();
                            for (int i = 0; i < tmpPixels.length; i++)
                                tmpPixels = tmpPixels + 0xff000000;
                            lastImage = Bitmap.createBitmap(tmpPixels, fb.getWidth(), fb.getHeight(), Config.ARGB_8888);

and this got me a blueish tint (closer but not quite)... which actually I have also seen in some screenshot taking software... which requires to tick an option to invert red and blue... so I also tried inverting R and B (resulting in a  predator/hello kitty effect):

                            int[] tmpPixels = fb.getPixels();
                            for (int i = 0; i < tmpPixels.length; i++){
                                int tmpInt = tmpPixels + 0xff000000;
                                tmpInt &= 0xff00ff00;//remove r and b
                                int inv = ~(tmpPixels & 0x00ff00ff);//invert r and b
                                tmpInt += inv;//add r and b
                                tmpPixels = tmpInt;
                            }
                            lastImage = Bitmap.createBitmap(tmpPixels, fb.getWidth(), fb.getHeight(), Config.ARGB_8888);

any suggestions/ideas/piece of code with the solution?

cheers!
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 27, 2011, 09:58:32 pm
I'm not sure...I've never used this method on Android. Have you tried to put alpha at the end, i.e. rgba or bgra?
Title: Re: framebuffer getPixels()
Post by: haijin on May 27, 2011, 11:19:27 pm
the alpha was in the right place, but not so the red and blue. Switching those generated the desired result:

                            int[] tmpPixels = fb.getPixels();
                            for (int i = 0; i < tmpPixels.length; i++){
                                int tmpInt = tmpPixels + 0xff000000;
                                int red = (tmpInt & 0x00ff0000)>>16;
                                int blue = (tmpInt & 0x000000ff)<<16;
                                tmpInt &= 0xff00ff00;
                                tmpInt += red + blue;
                                tmpPixels = tmpInt;
                            }
                            lastImage = Bitmap.createBitmap(tmpPixels, fb.getWidth(), fb.getHeight(), Config.ARGB_8888);
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 24, 2012, 06:05:13 pm
the alpha was in the right place, but not so the red and blue. Switching those generated the desired result:

                            int[] tmpPixels = fb.getPixels();
                            for (int i = 0; i < tmpPixels.length; i++){
                                int tmpInt = tmpPixels + 0xff000000;
                                int red = (tmpInt & 0x00ff0000)>>16;
                                int blue = (tmpInt & 0x000000ff)<<16;
                                tmpInt &= 0xff00ff00;
                                tmpInt += red + blue;
                                tmpPixels = tmpInt;
                            }
                            lastImage = Bitmap.createBitmap(tmpPixels, fb.getWidth(), fb.getHeight(), Config.ARGB_8888);
Sorry for the bump, but Im having a bit of a problem with this, as the background is completely black
Any chance you can tell me how you fixed it?
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 24, 2012, 08:57:47 pm
i don't think that you can grab the camera image that way, because this grabs only the image created in the gl context. There has to be another way to get a screen shot of both combined...i guess. Worst case would be to grab the camera image in another way and combine both in your code.
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 25, 2012, 12:00:10 am
i don't think that you can grab the camera image that way, because this grabs only the image created in the gl context. There has to be another way to get a screen shot of both combined...i guess. Worst case would be to grab the camera image in another way and combine both in your code.
Sorry, wasn't talking about the camera preview, already got that.
Im grabbing both and merging them with a canvas. But the frameBuffer.getPixels() is returning all black where it should be transparent after running the:
Code: [Select]
int[] tmpPixels = fb.getPixels();
                            for (int i = 0; i < tmpPixels.length; i++){
                                int tmpInt = tmpPixels[i] + 0xff000000;
                                int red = (tmpInt & 0x00ff0000)>>16;
                                int blue = (tmpInt & 0x000000ff)<<16;
                                tmpInt &= 0xff00ff00;
                                tmpInt += red + blue;
                                tmpPixels[i] = tmpInt;
                            }
                            lastImage = Bitmap.createBitmap(tmpPixels, fb.getWidth(), fb.getHeight(), Config.ARGB_8888);

Replacing "tmpInt &= 0xff00ff00" with " tmpInt &= 0x7f00ff00" makes the frameBuffer image semi-transparent.
Im not too shabby with the hex codes, but Im guessing that the alpha is overwritten. I've tried replacing the "ff"'s with "00"'s a few places to see if that did it, but to no avail
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 25, 2012, 12:03:53 am
At first glance, this...

Code: [Select]
int tmpInt = tmpPixels[i] + 0xff000000;

seems to set the alpha to ff for all pixels. Try something like

Code: [Select]
int tmpInt = tmpPixels[i];

instead.
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 25, 2012, 09:39:30 am
At first glance, this...

Code: [Select]
int tmpInt = tmpPixels[i] + 0xff000000;

seems to set the alpha to ff for all pixels. Try something like

Code: [Select]
int tmpInt = tmpPixels[i];

instead.
That was my first thought as well, but that made the image 100% transparent ^^
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 25, 2012, 09:47:25 am
...looks like i'm nulling the alpha values in the code that flips the image after grabbing it from the frame buffer. I'll upload a fixed version later today.
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 25, 2012, 10:02:13 am
...looks like i'm nulling the alpha values in the code that flips the image after grabbing it from the frame buffer. I'll upload a fixed version later today.
Thanks!
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 25, 2012, 02:17:18 pm
...looks like i'm nulling the alpha values in the code that flips the image after grabbing it from the frame buffer. I'll upload a fixed version later today.
Not to rush you or anything, but do you know when today you might be able to look at it?
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 25, 2012, 02:31:37 pm
Maybe 6 hours from now. I'm still at work...
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 25, 2012, 02:36:36 pm
An easy hacky "fix" for now, would be to set alpha according to the background color. I.e. all black pixels are transparent, all others opaque.
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 25, 2012, 02:41:24 pm
An easy hacky "fix" for now, would be to set alpha according to the background color. I.e. all black pixels are transparent, all others opaque.
True. Ill try it and see how it looks.
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 25, 2012, 02:56:37 pm
An easy hacky "fix" for now, would be to set alpha according to the background color. I.e. all black pixels are transparent, all others opaque.
True. Ill try it and see how it looks.
Looks horrible :P
(http://i.imgur.com/3uAXN.png)
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 25, 2012, 03:16:12 pm
Yes, or course. But i thought it might be better than nothing...
Title: Re: framebuffer getPixels()
Post by: MrAdam on May 25, 2012, 03:17:33 pm
Yes, or course. But i thought it might be better than nothing...
It certainly is :P
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on May 25, 2012, 05:45:36 pm
I managed to make the change a bit ealier than expected. Please try this jar: http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)
Title: Re: framebuffer getPixels()
Post by: MrAdam on June 02, 2012, 05:39:15 pm
I managed to make the change a bit ealier than expected. Please try this jar: http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)
Sorry for the late response :-/ Had a bit of a stressing few days lately, we just completed the project.
Anyways, we have been getting reports from users using the Galaxy SII having a completely black car:
(http://i.imgur.com/CUCk1.jpg)

I believe this might be due to the phones GPU having a different OpenGL implementation.
Do you have any idea what might cause this?
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on June 02, 2012, 08:36:52 pm
The S2 uses a Mali GPU. It's most likely that the custom shader does something that either the gpu (unlikely) or the driver's shader compiler doesn't like. But it's hard to tell and debug without access to an actual device (which i don't have...). If possible, get a device and try to use the default shaders instead (i.e. don't use your custom ones). That should look ok. If that's the case, try to debug your shader by wild guessing and taking desperate actions...at least that's what i did to get the default shaders working on almost any device that i know of.
In general, shader compiler quality differs largely from one gpu manufacturer to another...the order from bad to good is roughly:

Adreno->Mali->PowerVR->Nvidia

Feel free to post the current shader code you are using. Maybe i can spot something based on bad experience with my own shaders...
Title: Re: framebuffer getPixels()
Post by: MrAdam on June 04, 2012, 11:05:35 am
Disabling the shader certainly helped. Its no longer in nightrider mode ^^
(http://i.imgur.com/TbUih.png)
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on June 04, 2012, 11:24:06 am
...so it's some problem with the shader code or (more likely) the shader compiler creating stupid code...
Title: Re: framebuffer getPixels()
Post by: MrAdam on June 04, 2012, 11:31:59 am
...so it's some problem with the shader code or (more likely) the shader compiler creating stupid code...
I don't think Im gonna find a solution to this, it's most likely a crappy driver.
Updating the phone to 4.x solves the problem ^^
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on June 06, 2012, 10:40:18 pm
When will this app actually be available to the public?
Title: Re: framebuffer getPixels()
Post by: MrAdam on June 20, 2012, 11:57:39 am
Sorry, I forgot to enable notifications, didn't see your post until now
The app is available here: https://play.google.com/store/apps/details?id=bmw.makeityours

Although, I still haven't been able to fix the black model problem. It appears only on Galaxy S II and S III devices.
I know it's the GPU, we had the same problem with the old engine (jMonkeyEngine) but it got fixed in an update.

Got a video illustrating it: http://vimeo.com/44378417
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on June 20, 2012, 08:09:19 pm
I tried it on my Nexus S...it worked fine for the most parts. I couldn't enter this "scan your code" (whatever that is) part, because it exitied in Android's Camera class. You should have received some bug reports about this. The other problem is with generating the actual add. While everything looks fine in the live view where i place the car, the end result after taking the picture looks strange. Look at this example screen shot. The car was looking fine with proper scale. It properly rested on the top of that hut. But in the final picture, the car looks slightly misplaced, fuzzy and distorted...

(http://jpct.de/pix/somehow_wrong.jpg)

Edit: Another example...this is the live view:

(http://jpct.de/pix/bmw1.png)

and this the result

(http://jpct.de/pix/bmw2.png)
Title: Re: framebuffer getPixels()
Post by: MrAdam on July 03, 2012, 11:11:52 am
Again.. sorry for the delay. Been busy with a new project.
Anyways, I know there's problems with the scaling, and parts of the app crashes due to memory limit being reached.

But the main problem is the black car. It won't work on the Galaxy S III either.
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on July 03, 2012, 11:20:50 am
Have you tried to revert to jPCT's default shaders on these devices? Does that render correctly?
Title: Re: framebuffer getPixels()
Post by: MrAdam on July 03, 2012, 11:44:08 am
Have you tried to revert to jPCT's default shaders on these devices? Does that render correctly?
I tried that, yes. The car is still 100% black like in the video. And 100% lit up like a cone light when it gets very close to one light.
Title: Re: framebuffer getPixels()
Post by: Thomas. on July 03, 2012, 11:51:03 am
I have Galaxy S3, if you need any testing let me know ;)
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on July 03, 2012, 12:15:15 pm
I'm not sure if i'm still able to follow...



It that correct?
Title: Re: framebuffer getPixels()
Post by: MrAdam on July 03, 2012, 01:01:04 pm
I'm not sure if i'm still able to follow...

  • S2 and S3 both render black cars when using the custom shader
  • S2 problem goes away if you don't use the custom shader but the default ones of jPCT-AE
  • S3 problem doesn't go away when you disable the shader (100% sure?)
  • S2 problem goes away when updating to Android x.y (which?)


It that correct?

S3 is always black, no matter what shader is used/not used.
S2 is always black, no matter what shader is used/not used, except on some versions of Android.
I haven't been able to confirm which versions though :-/
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on July 03, 2012, 01:07:41 pm
S2 is always black, no matter what shader is used/not used, except on some versions of Android.
But then i don't understand this post: http://www.jpct.net/forum2/index.php/topic,2088.msg20457.html#msg20457 (http://www.jpct.net/forum2/index.php/topic,2088.msg20457.html#msg20457)  ???
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on July 03, 2012, 01:12:38 pm
And please try to add

Code: [Select]
precision highp float;

to the fragment and the vertex shader to see if that changes anything...
Title: Re: framebuffer getPixels()
Post by: MrAdam on July 03, 2012, 01:49:51 pm
And please try to add

Code: [Select]
precision highp float;

to the fragment and the vertex shader to see if that changes anything...
Already tried that when you suggested it in the other thread ;-)
Didn't make a difference
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on July 03, 2012, 02:16:09 pm
Could you please try to disable all custom shaders AND the light sources (and maybe adjust the ambient light)? I never got any reports that the default shaders have problems on Mali GPUs, so find it hard to believe that they should also suffer from this problem.
I also would like to know (as posted above), how this fits into the whole issue: http://www.jpct.net/forum2/index.php/topic,2088.msg20457.html#msg20457 (http://www.jpct.net/forum2/index.php/topic,2088.msg20457.html#msg20457)
 
If everything fails, i would try to disable GL20 support and revert to 1.1 to see if that helps.
Title: Re: framebuffer getPixels()
Post by: mxar on September 24, 2014, 10:59:49 pm
Hi,

can anybody help me?

I call the following code :

int[] tmpPixels = frameBuffer.getPixels();

renderImage = Bitmap.createBitmap(tmpPixels, frameBuffer.getWidth(), frameBuffer.getHeight(), Config.ARGB_8888);

When i try to load the renderImage Bitmap in ImageView ( calling imageView.setImageBitmap(renderImage))

i see only a black rectangular.


Thanks in advance



Title: Re: framebuffer getPixels()
Post by: EgonOlsen on September 25, 2014, 08:20:47 am
At which stage are you grabbing the pixels and which render mode are you using (OpenGL ES 1.x or 2.0)? And which device?
Title: Re: framebuffer getPixels()
Post by: mxar on September 25, 2014, 09:03:13 am

Hi,

I use opengle 1.x

I use the following code to build a bitmap from FrameBuffer:

The FrameBuffer is resized to  128x128.

The Bitmap renderImage  is used as a bitmap for an ImageView view.


   public void onDrawFrame(GL10 gl) {
      
      coinObject3D.rotateY((float) (Math.PI/180.0f));
      cube.rotateY((float) (Math.PI/180.0f) * -1);
      
      //cube.translate(x, y, z)
      prevXRot  = xrot;
      prevYRot  = yrot;
      prevZRot  = zrot;
      
            
      fb.clear(back);
      int w = fb.getWidth();
          int h = fb.getHeight();
      
    
       world.renderScene(fb);
      
       int[] tmpPixels = fb.getPixels();
      
       
        renderImage = Bitmap.createBitmap(tmpPixels, fb.getWidth(), fb.getHeight(), Config.RGB_565);

       Log.d("TAG", "width = "  + fb.getWidth());
      Log.d("TAG", "height = " + fb.getHeight());
      
      world.draw(fb);
      
      //fb.runPostProcessors();
      fb.display();
      
      

      if (System.currentTimeMillis() - time >= 1000) {
         Logger.log(fps + "fps");
         fps = 0;
         time = System.currentTimeMillis();
      }
      
      fps++;
   }


Thanks in advance

Title: Re: framebuffer getPixels()
Post by: mxar on September 25, 2014, 09:05:30 am

Sorry,

I forgot to say that i use NEXUS 5.
Title: Re: framebuffer getPixels()
Post by: EgonOlsen on September 25, 2014, 10:08:18 am
That's too early... move the call to after the call to display and try again.
Title: Re: framebuffer getPixels()
Post by: mxar on September 25, 2014, 11:22:37 am

it works.

thanks