Recent

Author Topic: Flipping after glReadPixels  (Read 17180 times)

gilsonalencar

  • New Member
  • *
  • Posts: 48
Flipping after glReadPixels
« on: July 19, 2012, 02:18:57 pm »
After many efforts, i can to put a OpenGLControl graphics in a bitmap image. But it is inverted from original source, when glReadPixels is used. After weeks searching in the web,  i can´t to find any solution to flip it using gl functions. Anybody knows how to do it? Technics using Canvas.Pixels[X,Y] are very slow.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Flipping after glReadPixels
« Reply #1 on: July 19, 2012, 02:39:17 pm »
What format parameter (5th position) do you give?

gilsonalencar

  • New Member
  • *
  • Posts: 48
Re: Flipping after glReadPixels
« Reply #2 on: July 19, 2012, 03:31:00 pm »
The complet code is here.

Code: [Select]

function BitmapImage(c:TOpenGLControl):TBitmap;
var
  data,rdata: pbyte;
  w,h,s: integer;
  bitMap: TBitmap;

begin
  c.Repaint;
  w := c.Width;
  h := c.Height;
  s := w*h*4;
  result := TBitmap.Create;
  bitMap:=result;   try
    bitMap.SetSize(w,h);
    bitMap.PixelFormat:=pf32bit;
    getMem(data,s);     try
      glPixelStorei(GL_PACK_ALIGNMENT, 4);
      pixel}
      glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, data);     
      rdata := bitMap.RawImage.Data;
      Move(data^,rdata^,bitMap.RawImage.DataSize);
    finally
      freemem(data);
    end;
  except
    bitMap.free;
  end;
end;                             

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Flipping after glReadPixels
« Reply #3 on: July 19, 2012, 03:39:48 pm »
When you say inverted, do you mean the R & B are swapped.

I wrote a routine here that might help ->
http://80.123.225.56/index.php/topic,17383.msg95733.html#msg95733

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Flipping after glReadPixels
« Reply #4 on: July 19, 2012, 03:55:39 pm »
If it's about colors, then this code:
Code: [Select]
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, data);you can switch to GL_BGR.

If it's graphics upside down, then you need to draw then in OpenGL differently. If you use ortho (2D) mode, you should set the screen so that origo (0, 0) is in top left.

Or that may not help at all, who knows. I haven't used glReadPixels, i hear it's slow operation. Even slower than canvas operations.
« Last Edit: July 19, 2012, 03:58:42 pm by User137 »

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Flipping after glReadPixels
« Reply #5 on: July 19, 2012, 04:09:44 pm »
Quote
GL_BGR

I think GL_BGR is an extension, so some video cards might not support it.  Maybe most video cards will have this option now, so it might not be an issue.   :-\

Quote
i hear it's slow operation

I suppose it depends on what your doing, I use it for doing image analysis and for this it seems to work pretty well.  Also if you do use it, one idea is to only grab the area of interest.
« Last Edit: July 19, 2012, 04:11:49 pm by KpjComp »

gilsonalencar

  • New Member
  • *
  • Posts: 48
Re: Flipping after glReadPixels
« Reply #6 on: July 19, 2012, 04:15:12 pm »
Quote
When you say inverted, do you mean the R & B are swapped.

I wrote a routine here that might help ->
http://80.123.225.56/index.php/topic,17383.msg95733.html#msg95733

A 180 degrees inversion in position, not color.

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Flipping after glReadPixels
« Reply #7 on: July 19, 2012, 04:36:18 pm »
Quote
A 180 degrees inversion in position, not color.

One idea is maybe try changing the HandleType to bmDIB, as I think there always top to bottom.  Not sure if this has an effect on Linux.

Another idea is copy Scanlines at a time.

gilsonalencar

  • New Member
  • *
  • Posts: 48
Re: Flipping after glReadPixels
« Reply #8 on: July 19, 2012, 04:37:48 pm »
The image file attached, shows the problem. On the left, the original graphics from OpenGLControl. On the right, the result of bitmap image (3D axis).

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Flipping after glReadPixels
« Reply #9 on: July 19, 2012, 05:02:49 pm »
That is strange, it's not just top to bottom, but left to right.

Are you calling this during your render while the context is still valid, and straight after you do the swapbuffers?

gilsonalencar

  • New Member
  • *
  • Posts: 48
Re: Flipping after glReadPixels
« Reply #10 on: July 19, 2012, 05:27:55 pm »
Quote
That is strange, it's not just top to bottom, but left to right.

Are you calling this during your render while the context is still valid, and straight after you do the swapbuffers?

I'm calling this after do swapbuffers.

KpjComp

  • Hero Member
  • *****
  • Posts: 680
Re: Flipping after glReadPixels
« Reply #11 on: July 19, 2012, 05:50:18 pm »
Quote
I'm calling this after do swapbuffers.

Oh, in that case is there any reason your doing ->
Code: [Select]
c.Repaint;
If your doing this during the Paint Event, then your telling your control to repaint during your paint event, doesn't really make sense.  The way I captured the screen is set a flag to say then next render will be captured, and after the render I would reset.   Not sure if this is your problem though, I'm not an OpenGL expert.

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Flipping after glReadPixels
« Reply #12 on: July 19, 2012, 08:19:44 pm »
Some options:
1) You could try using Canvas.Copyrect() to flip the image to another TBitmap. It should support negative width and height in TRect.

2) Draw them 180 degree rotated when taking screenshot.

3) Same as 1), but copy pixel by pixel to inverse coordinates.

 

TinyPortal © 2005-2018