Ignore:
Timestamp:
Mar 20, 2011, 7:18:27 PM (14 years ago)
Author:
george
Message:
  • Added: OpenGL PBO method.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest/UDrawMethod.pas

    r211 r212  
    88  Classes, SysUtils, StdCtrls, ExtCtrls, UPlatform, UFastBitmap, Graphics,
    99  LCLType, IntfGraphics, fpImage, GraphType, BGRABitmap, BGRABitmapTypes,
    10   LclIntf, GL, OpenGLContext;
     10  LclIntf, GL, GLExt, OpenGLContext;
    1111
    1212type
     
    3030    OpenGLControl: TOpenGLControl;
    3131    TextureId: GLuint;
     32    procedure Init; virtual;
    3233    constructor Create; virtual;
    3334    destructor Destroy; override;
     
    102103    procedure SetBitmap(const AValue: TBitmap); override;
    103104    constructor Create; override;
     105    procedure Init; override;
    104106    destructor Destroy; override;
    105107    procedure DrawFrame(FastBitmap: TFastBitmap); override;
    106108  end;
    107109
     110  { TOpenGLPBOMethod }
     111
     112  TOpenGLPBOMethod = class(TDrawMethod)
     113    pboIds: array[0..1] of GLuint;
     114    Index, NextIndex: Integer;
     115    procedure SetBitmap(const AValue: TBitmap); override;
     116    procedure Init; override;
     117    constructor Create; override;
     118    destructor Destroy; override;
     119    procedure DrawFrame(FastBitmap: TFastBitmap); override;
     120  end;
    108121
    109122const
    110   DrawMethodClasses: array[0..7] of TDrawMethodClass = (
     123  DrawMethodClasses: array[0..8] of TDrawMethodClass = (
    111124    TCanvasPixels, TCanvasPixelsUpdateLock, TLazIntfImageColorsCopy,
    112125    TLazIntfImageColorsNoCopy, TBitmapRawImageData, TBitmapRawImageDataPaintBox,
    113     TBGRABitmapPaintBox, TOpenGLMethod);
     126    TBGRABitmapPaintBox, TOpenGLMethod, TOpenGLPBOMethod);
    114127
    115128implementation
     129
     130{ TOpenGLPBOMethod }
     131
     132procedure TOpenGLPBOMethod.SetBitmap(const AValue: TBitmap);
     133begin
     134  inherited SetBitmap(AValue);
     135end;
     136
     137//procedure glGenBuffersARB2 : procedure(n : GLsizei; buffers : PGLuint); extdecl;
     138
     139procedure TOpenGLPBOMethod.Init;
     140var
     141  DataSize: Integer;
     142  glExtensions: string;
     143begin
     144  OpenGLControl.MakeCurrent;
     145  DataSize := OpenGLControl.Width * OpenGLControl.Height * SizeOf(Integer);
     146//  glGenBuffersARB(Length(pboIds), PGLuint(pboIds));
     147  //if glext_LoadExtension('GL_ARB_pixel_buffer_object') then
     148  if Load_GL_ARB_vertex_buffer_object then begin
     149    glGenBuffersARB(2, @pboIds);
     150    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[0]);
     151    glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, DataSize, Pointer(0), GL_STREAM_READ_ARB);
     152    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[1]);
     153    glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, DataSize, Pointer(0), GL_STREAM_READ_ARB);
     154
     155  end else raise Exception.Create('GL_ARB_pixel_buffer_object not supported');
     156
     157  glEnable(GL_TEXTURE_2D);
     158  glBindTexture(GL_TEXTURE_2D, TextureId);
     159    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     160    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     161    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     162    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     163    glTexImage2D(GL_TEXTURE_2D, 0, 4, OpenGLControl.Width, OpenGLControl.Height,
     164      0, GL_RGBA, GL_UNSIGNED_BYTE, OpenGLBitmap);
     165end;
     166
     167constructor TOpenGLPBOMethod.Create;
     168begin
     169  inherited Create;
     170  Caption := 'OpenGL PBO';
     171  PaintObject := poOpenGL;
     172//  SetLength(pboIds, 2);
     173  Index := 0;
     174  NextIndex := 1;
     175end;
     176
     177destructor TOpenGLPBOMethod.Destroy;
     178begin
     179  inherited Destroy;
     180end;
     181
     182procedure TOpenGLPBOMethod.DrawFrame(FastBitmap: TFastBitmap);
     183var
     184  X, Y: Integer;
     185  P: PInteger;
     186  R: PInteger;
     187  Ptr: ^GLubyte;
     188  TextureShift: TPoint;
     189  TextureShift2: TPoint;
     190const
     191  GL_CLAMP_TO_EDGE = $812F;
     192begin
     193  // "index" is used to read pixels from framebuffer to a PBO
     194  // "nextIndex" is used to update pixels in the other PBO
     195  Index := (Index + 1) mod 2;
     196  NextIndex := (Index + 1) mod 2;
     197
     198  glLoadIdentity;
     199
     200  glBindTexture(GL_TEXTURE_2D, TextureId);
     201    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     202    //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     203    //glTexImage2D(GL_TEXTURE_2D, 0, 4, OpenGLControl.Width, OpenGLControl.Height,
     204    //  0, GL_RGBA, GL_UNSIGNED_BYTE, OpenGLBitmap);
     205    //glTexImage2D(GL_TEXTURE_2D, 0, 4, 512, 256,
     206    //0, GL_RGBA, GL_UNSIGNED_BYTE, OpenGLBitmap);
     207
     208  // bind the texture and PBO
     209  //glBindTexture(GL_TEXTURE_2D, textureId);
     210  glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboIds[index]);
     211
     212  // copy pixels from PBO to texture object
     213  // Use offset instead of ponter.
     214  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, OpenGLControl.Width, OpenGLControl.Height,
     215    GL_BGRA, GL_UNSIGNED_BYTE, Pointer(0));
     216
     217
     218  // bind PBO to update texture source
     219  glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboIds[nextIndex]);
     220
     221  // Note that glMapBufferARB() causes sync issue.
     222  // If GPU is working with this buffer, glMapBufferARB() will wait(stall)
     223  // until GPU to finish its job. To avoid waiting (idle), you can call
     224  // first glBufferDataARB() with NULL pointer before glMapBufferARB().
     225  // If you do that, the previous data in PBO will be discarded and
     226  // glMapBufferARB() returns a new allocated pointer immediately
     227  // even if GPU is still working with the previous data.
     228  glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, OpenGLControl.Width * OpenGLControl.Height * SizeOf(Integer), Pointer(0), GL_STREAM_DRAW_ARB);
     229
     230  // map the buffer object into client's memory
     231  ptr := glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
     232  if Assigned(ptr) then begin
     233    // update data directly on the mapped buffer
     234    P := PInteger(Ptr);
     235    with FastBitmap do
     236    for Y := 0 to Size.Y - 2 do begin
     237      R := P;
     238      for X := 0 to Size.X - 1 do begin
     239        R^ := NoSwapBRComponent(Pixels[X, Y]) or $ff000000;
     240        Inc(R);
     241      end;
     242      Inc(P, Size.X);
     243    end;
     244    glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
     245  end;
     246
     247  // it is good idea to release PBOs with ID 0 after use.
     248  // Once bound with 0, all pixel operations are back to normal ways.
     249  glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
     250
     251  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
     252  //glRotatef(30.0, 0, 0, 1.0);
     253  glTranslatef(-OpenGLControl.Width / 2, -OpenGLControl.Height / 2, 0.0);
     254  glBindTexture(GL_TEXTURE_2D, TextureId);
     255
     256  TextureShift := Point(0, 0);
     257  TextureShift2 := Point(0, 0);
     258  glBegin(GL_QUADS);
     259    glColor3ub(255, 255, 255);
     260    glTexCoord2f(TextureShift.X, TextureShift.Y);
     261    glVertex3f(TextureShift2.X, TextureShift2.Y, 0);
     262    glTexCoord2f(TextureShift.X + OpenGLControl.Width div 2, TextureShift.Y);
     263    glVertex3f(TextureShift2.X + OpenGLControl.Width, TextureShift2.Y, 0);
     264    glTexCoord2f(TextureShift.X + OpenGLControl.Width div 2, TextureShift.Y + OpenGLControl.Height div 2);
     265    glVertex3f(TextureShift2.X + OpenGLControl.Width, TextureShift2.Y + OpenGLControl.Height, 0);
     266    glTexCoord2f(TextureShift.X, TextureShift.Y + OpenGLControl.Height div 2);
     267    glVertex3f(TextureShift2.X, TextureShift2.Y + OpenGLControl.Height, 0);
     268  glEnd();
     269
     270  OpenGLControl.SwapBuffers;
     271end;
    116272
    117273{ TOpenGLMethod }
     
    127283  Caption := 'OpenGL';
    128284  PaintObject := poOpenGL;
     285end;
     286
     287procedure TOpenGLMethod.Init;
     288begin
     289  inherited Init;
     290  //OpenGLControl.MakeCurrent;
    129291end;
    130292
     
    142304  GL_CLAMP_TO_EDGE = $812F;
    143305begin
    144 (*  glEnable(GL_TEXTURE_2D);          // enables 2d textures
    145     glClearColor(0.0,0.0,0.0,1.0);    // sets background color
    146     glClearDepth(1.0);
    147     glDepthFunc(GL_LEQUAL);           // the type of depth test to do
    148     glEnable(GL_DEPTH_TEST);          // enables depth testing
    149     glShadeModel(GL_SMOOTH);          // enables smooth color shading
    150     {blending}
    151     glColor4f(1.0,1.0,1.0,0.5);       // Full Brightness, 50% Alpha ( NEW )
    152     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    153     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
    154 *)
    155 
     306  glLoadIdentity;
    156307  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    157308  //glLoadIdentity;             { clear the matrix }
    158309  //glTranslatef(0.0, 0.0, -3.0);  // -2.5); { viewing transformation }
    159 
    160   //glLoadIdentity;             { clear the matrix }
    161310
    162311  P := OpenGLBitmap;
     
    172321  end;
    173322
    174     glLoadIdentity;
    175323    //glRotatef(30.0, 0, 0, 1.0);
    176324    glTranslatef(-OpenGLControl.Width div 2, -OpenGLControl.Height div 2, 0.0);
     
    459607end;
    460608
     609procedure TDrawMethod.Init;
     610begin
     611
     612end;
     613
    461614constructor TDrawMethod.Create;
    462615begin
Note: See TracChangeset for help on using the changeset viewer.