: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.