Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Locking a VBO in OpenGL

  1. #1

    Locking a VBO in OpenGL

    :arrow:System: Windows Vista, Pentium D 2.66GHz, GeForce 7600 GS
    :arrow:Compiler/IDE: Delphi 2007 for Win32
    :arrow:API: OpenGL

    Hello everyone!

    I have a little problem with my VBOs. One friend asked me to make a OpenGL version of his VBO implementation in OpenGL. And I'm stuck, I don't really know how to do it. Can you please take a look at the two codes and tell me what's wrong?

    HIS VERSION (DX)
    [pascal]
    TBVertexBufforDx9 = class(TBVertexBuffor)
    private
    VBuffor : IDIRECT3DVERTEXBUFFER9;
    fscreen : TBScreenDx9;
    public
    procedure UnInit; override;
    procedure CreateVertexBuffor(size : integer; sizevertex : integer; FVF : DWORD; Pool : TBPOOL = BPOOL_MANAGED; Usage : TBUsage = BUSAGE_WRITEONLY); override;
    procedure Render(typ : TBShapetype; count : DWORD); override;

    function Lock(start, count : DWORD) : pointer; override;
    procedure UnLock; override;

    destructor Destroy; override;
    end;

    function BUageToDxUsage(const usage : TBUsage) : cardinal; inline;
    begin
    case usage of
    BUSAGE_RENDERTARGET: result := D3DUSAGE_RENDERTARGET;
    BUSAGE_DYNAMIC: result := D3DUSAGE_DYNAMIC;
    BUSAGE_WRITEONLY: result := D3DUSAGE_WRITEONLY;
    end;
    end;

    procedure TBVertexBufforDx9.CreateVertexBuffor(size : integer; sizevertex : integer; FVF : DWORD; Pool : TBPOOL = BPOOL_MANAGED; Usage : TBUsage = BUSAGE_WRITEONLY);
    var hr : HRESULT;
    begin
    if fscreen.device=nil then
    raise EBNotInit.Create('screen not init');
    hr := fscreen.Device.CreateVertexBuffer( size * sizevertex,
    BUageToDxUsage(Usage), BFVF_CUSTOMVERTEX,
    _D3DPOOL(Pool), VBuffor,nil );
    if FAILED(hr) then //D3DPOOL_MANAGED
    begin // D3DUSAGE_WRITEONLY
    {$IFOPT D+}
    if TheLoger<>nil then TheLoger.Write('Render Init ', DXGetErrorString9A(hr) , LogFatalError);
    {$ENDIF}
    raise EBNotInit.Create('Nie mo¬øna zainicjowa?¶ Rendera');
    end;
    fFVF := FVF;
    fsizeVertex := sizevertex;
    end;

    procedure TBVertexBufforDx9.Render(typ : TBShapetype; count : DWORD);
    begin
    fscreen.Device.SetStreamSource( 0, VBuffor, 0, fsizeVertex );
    fscreen.Device.SetFVF(fFVF);
    fscreen.Device.DrawPrimitive( _D3DPRIMITIVETYPE(typ), 0, count );
    end;

    function TBVertexBufforDx9.Lock(start, count : DWORD) : pointer;
    var s : dword;
    begin
    s := start*fsizeVertex;
    VBuffor.Lock(s,s+fsizeVertex*count,result,0);
    end;

    procedure TBVertexBufforDx9.UnLock;
    begin
    VBuffor.Unlock;
    end;

    procedure TBVertexBufforDx9.UnInit;
    begin
    VBuffor := nil;
    end;

    destructor TBVertexBufforDx9.Destroy;
    begin
    UnInit;
    inherited;
    end;
    [/pascal]

    MY VERSION (OGL)
    [pascal]
    { .: TBVertexBufforOGL :. }
    TBVertexBufforOGL = class(TBVertexBuffor)
    private
    { Private declarations }
    VBuffor: GLuint;
    FScreen: TBScreenOGL;
    public
    { Public declarations }
    destructor Destroy(); override;

    procedure UnInit(); override;
    procedure CreateVertexBuffor(Size: Integer; SizeVertex: Integer;
    FVF: DWORD; Pool: TBPOOL = BPOOL_MANAGED;
    Usage: TBUsage = BUSAGE_WRITEONLY); override;

    procedure Render(Typ: TBShapetype; Count: DWORD); override;

    function Lock(Start, Count: DWORD): Pointer; override;
    procedure UnLock(); override;
    end;

    { TBVertexBufforOGL }

    { .: BUsageToOGLUsage :. }
    function BUsageToOGLUsage(const Usage: TBUsage): GLuint; inline;
    begin
    case Usage of
    BUSAGE_RENDERTARGET: Result := GL_STATIC_DRAW_ARB;
    BUSAGE_DYNAMIC: Result := GL_DYNAMIC_DRAW_ARB;
    BUSAGE_WRITEONLY: Result := GL_WRITE_ONLY_ARB;
    end;
    end;

    procedure TBVertexBufforOGL.CreateVertexBuffor(Size, SizeVertex: Integer;
    FVF: DWORD; Pool: TBPOOL; Usage: TBUsage);
    begin
    glGenBuffersARB(1, @VBuffor);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBuffor);
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, Size * SizeVertex, nil,
    BUsageToOGLUsage(Usage));

    FSizeVertex := SizeVertex;
    end;

    destructor TBVertexBufforOGL.Destroy;
    begin
    UnInit();

    inherited Destroy();
    end;

    function TBVertexBufforOGL.Lock(Start, Count: DWORD): Pointer;
    begin
    Result := glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
    end;

    procedure TBVertexBufforOGL.Render(Typ: TBShapetype; Count: DWORD);
    var
    TheType: GLuint;
    begin
    glEnableClientState(GL_VERTEX_ARRAY);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBuffor);
    case Typ of
    BPOINTLIST: TheType := GL_POINTS;
    BLINELIST: TheType := GL_LINES;
    BLINESTRIP: TheType := GL_LINE_STRIP;
    BTRIANGLELIST: TheType := GL_TRIANGLES;
    BTRIANGLESTRIP: TheType := GL_TRIANGLE_STRIP;
    BTRIANGLEFAN: TheType := GL_TRIANGLE_FAN;
    end;
    glDrawElements(TheType, Count, GL_UNSIGNED_INT,
    Pointer(Count * SizeOf(DWORD)));
    end;

    procedure TBVertexBufforOGL.UnInit;
    begin
    glDeleteBuffersARB(1, @VBuffor);
    end;

    procedure TBVertexBufforOGL.UnLock;
    begin
    glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
    end;
    [/pascal]

    Everytime I execute this code, I get an AV. What's wrong? :? I think it has something to do with Lock and UnLock method, but I'm not sure.

    Thank you in advance.

  2. #2

    Locking a VBO in OpenGL

    Generaly, this kind of problem can be solved using breakpoints and stepping through your code. Have you done that? :?

    I might have missed it, but what code do you use to utilise this class? You can expiriment with that a little bit. Just create the VBO and lock/unlock it without moving data. If that works, you can try to move data. If that works, it's probably the render method that bugs.

    I alway's use these techniques to isolate bugs. Just make a simple testbed and call the routines you want to test.

    Good luck!
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  3. #3

    Locking a VBO in OpenGL

    I experimented with arrays before, topic's here:
    http://www.pascalgamedevelopment.com...pic.php?t=4785
    See if there's some differences. Though same program does raw rendering, displaylists, vertexarrays and vertexbuffer objects, it is commented well.

  4. #4

    Locking a VBO in OpenGL

    Dumb question: Are you 100% certain that the relevant extensions have been loaded when you use these functions?
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  5. #5

    Locking a VBO in OpenGL

    @JSoftware: Good one! because calling an uninitialized procvar result's in an AV.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  6. #6

    Locking a VBO in OpenGL

    Quote Originally Posted by JSoftware
    Dumb question: Are you 100% certain that the relevant extensions have been loaded when you use these functions?
    Yip, I'm 100% sure.

    Quote Originally Posted by User137
    I experimented with arrays before, topic's here:
    http://www.pascalgamedevelopment.com...pic.php?t=4785
    See if there's some differences. Though same program does raw rendering, displaylists, vertexarrays and vertexbuffer objects, it is commented well.
    I tried your code, but I can't really make it work with my class. :? The problem is that I still get an AV.

    Quote Originally Posted by chronozphere
    I might have missed it, but what code do you use to utilise this class? You can expiriment with that a little bit. Just create the VBO and lock/unlock it without moving data. If that works, you can try to move data. If that works, it's probably the render method that bugs.
    I don't understand. How to lock and unlock a VBO?

  7. #7

    Locking a VBO in OpenGL

    Lol... the DirectX routines for this are called lock/unlock. These allow you to temporarly gain acces to the Vertexdata so you can modify it. The title of your thread mentions "locking" so i thought you would understand.

    The openGL equalivents are:
    glMapBufferARB
    glUnmapBufferARB

    Hope this helps.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  8. #8

    Locking a VBO in OpenGL

    Okay, but when I use them, I get an AV. :-/ Dunno what's wrong... :? This is the code that uses Lock procedure:
    [pascal]
    function TBRender.BeginRender(typ : TBShapeType; size : word; ile : word; BlendMode : TBBlendMode) : pointer;
    var pvertex : pointer;
    s : dword;
    begin
    if fsize+size>=PBUFSIZE then
    Render;

    if (typ = BTRIANGLESTRIP) or (typ=BTRIANGLEFAN) or (typ=BLINESTRIP) then
    render
    else if typ<>fType then
    render;
    if BlendMode<>fBlendMode then
    begin
    render;
    fBlendMode := BlendMode;
    end;
    ftype := typ;
    s:= fsize*sizeof(TBVertex2D);
    pvertex := fbuffor.Lock(s,s+sizeof(TBVertex2D)*size) ;
    inc(files, ile);
    inc(fsize, size);
    result := pvertex;
    end;
    [/pascal]

    But it isn't executed, I get AV. Anyone knows why? What could be wrong?

  9. #9

    Locking a VBO in OpenGL

    Ok 1 more thing

    [pascal]glDrawElements(TheType, Count, GL_UNSIGNED_INT,
    Pointer(Count * SizeOf(DWORD))); [/pascal]

    Make sure your int type is accurate. GL_UNSIGNED_INT is propably 32 bit where your data must also be 32 bit. So AV can occur if glDrawElements tries to read out of your memory.

  10. #10

    Locking a VBO in OpenGL

    Still the same. I even tried glDrawArrays instead, but I still get that god-damn AV. :?

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •