|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- unit uglcArrayBuffer;
-
- { Package: OpenGLCore
- Prefix: glc - OpenGL Core
- Beschreibung: diese Unit enthält eine Klassen-Kapselung für OpenGL Array Buffer
- Beispiel:
- type
- TVertex = packed record
- pos: TgluVector3f; // vertex position
- tex: TgluVector2f; // texture coordinates
- nor: TgluVector3f; // normal
- end;
- PVertex = ^TVertex;
-
- var
- vBuffer: TglcArrayBuffer;
- iBuffer: TglcArrayBuffer;
- p: Pointer;
-
- vBuffer := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer);
- iBuffer := TglcArrayBuffer.Create(TglcBufferTarget.btElementArrayBuffer);
- try
- // write vertex data to vertex buffer
- vBuffer.Bind;
- vBuffer.BufferData(4, SizeOf(TresMeshVertex), TglcBufferUsage.buStaticDraw, nil);
- p := vBuffer.MapBuffer(TglcBufferAccess.baWriteOnly);
- try
- PVertex(p).pos := gluVertex3f(0.0, 0.0, 0.0);
- PVertex(p).tex := gluVertex2f(0.0, 0.5);
- PVertex(p).nor := gluVertex3f(0.0, 1.0, 0.0);
- inc(p, SizeOf(TVertex));
- // ...
- finally
- vBuffer.UnmapBuffer;
- vBuffer.Unbind;
- end;
-
- // write indices to index buffer
- iBuffer.Bind;
- iBuffer.BufferData(4, SizeOf(GLuint), TglcBufferUsage.buStaticDraw, nil);
- p := iBuffer.MapBuffer(TglcBufferAccess.baWriteOnly);
- try
- PGLuint(p) := 0;
- // ...
- finally
- iBuffer.UnmapBuffer;
- iBuffer.Unbind;
- end;
-
- // use array buffers to draw primitive
- vBuffer.Bind;
- iBuffer.Bind;
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 8, Pointer(0));
-
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 8, Pointer(3));
-
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(GL_FLOAT, 8, Pointer(5));
-
- glEnableClientState(GL_INDEX_ARRAY);
- glIndexPointer(GL_INT, 0, nil);
-
- glDrawElements(GL_QUADS, iBuffer.DataCount, GL_UNSIGNED_INT, nil);
-
- glDisableClientState(GL_INDEX_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
-
- fIndexBuffer.Unbind;
- fVertexBuffer.Unbind;
- finally
- FreeAndNil(vBuffer);
- FreeAndNil(iBuffer);
- end; }
-
- {$mode objfpc}{$H+}
-
- interface
-
- uses
- {$IFNDEF OPENGL_ES}dglOpenGL{$ELSE}dglOpenGLES{$ENDIF}, sysutils, uglcTypes;
-
- type
- EglcArrayBuffer = class(Exception);
- TglcArrayBuffer = class(TObject)
- private
- fID: GLuint;
- fTarget: TglcBufferTarget;
- fUsage: TglcBufferUsage;
- protected
- fDataCount: Integer;
- fDataSize: Integer;
- public
- property ID: gluInt read fID;
- property Target: TglcBufferTarget read fTarget;
- property Usage: TglcBufferUsage read fUsage;
- property DataCount: Integer read fDataCount;
- property DataSize: Integer read fDataSize;
-
- procedure BufferData(const aDataCount, aDataSize: Cardinal; const aUsage: TglcBufferUsage; const aData: Pointer);
- function MapBuffer(const aAccess: TglcBufferAccess): Pointer;
- function MapBufferRange(const aOffset: GLintptr; const aSize: GLsizeiptr; const aAccess: TglcBufferAccess): Pointer;
- procedure UnmapBuffer;
- procedure Bind;
- procedure Unbind;
- constructor Create(const aTarget: TglcBufferTarget);
- destructor Destroy; override;
- end;
-
- implementation
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TglcArrayBuffer///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- procedure TglcArrayBuffer.BufferData(const aDataCount, aDataSize: Cardinal; const aUsage: TglcBufferUsage; const aData: Pointer);
- begin
- glGetError(); //clear Errors
- Bind;
- fDataCount := aDataCount;
- fDataSize := aDataSize;
- fUsage := aUsage;
- glBufferData(GLenum(fTarget), fDataCount * fDataSize, aData, GLenum(fUsage));
- glcCheckAndRaiseError;
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- function TglcArrayBuffer.MapBuffer(const aAccess: TglcBufferAccess): Pointer;
- begin
- glGetError();
- result := nil;
- if (fDataCount * fDataSize) <= 0 then
- exit;
- {$IFNDEF OPENGL_ES}
- result := glMapBuffer(GLenum(fTarget), GLenum(aAccess));
- {$ELSE}
- if GL_OES_mapbuffer then
- result := glMapBufferOES(GLenum(fTarget), GLenum(aAccess))
- else
- raise EglcArrayBuffer.Create('map buffer is not supported by video card');
- {$ENDIF}
- glcCheckAndRaiseError;
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- function TglcArrayBuffer.MapBufferRange(const aOffset: GLintptr; const aSize: GLsizeiptr; const aAccess: TglcBufferAccess): Pointer;
- begin
- {$IFNDEF OPENGL_ES}
- if not (GL_ARB_map_buffer_range or GL_VERSION_3_0) then
- raise EglcArrayBuffer.Create('map buffer range is not supported by video card');
- result := glMapBufferRange(GLenum(fTarget), aOffset, aSize, GLenum(aAccess));
- {$ELSE}
- if GL_VERSION_3_0 then
- result := glMapBufferRange(GLenum(fTarget), aOffset, aSize, GLenum(aAccess))
- else if GL_EXT_map_buffer_range then
- result := glMapBufferRangeEXT(GLenum(fTarget), aOffset, aSize, GLenum(aAccess))
- else
- raise EglcArrayBuffer.Create('map buffer range is not supported by video card');
- {$ENDIF}
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- procedure TglcArrayBuffer.UnmapBuffer;
- begin
- {$IFNDEF OPENGL_ES}
- glUnmapBuffer(GLenum(fTarget));
- {$ELSE}
- if GL_VERSION_3_0 then
- glUnmapBuffer(GLenum(fTarget))
- else if GL_OES_mapbuffer then
- glUnmapBufferOES(GLenum(fTarget))
- else
- raise EglcArrayBuffer.Create('unmap buffer is not supported by video card');
- {$ENDIF}
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- procedure TglcArrayBuffer.Bind;
- begin
- glBindBuffer(GLenum(fTarget), fID);
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- procedure TglcArrayBuffer.Unbind;
- begin
- glBindBuffer(GLenum(fTarget), 0);
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- constructor TglcArrayBuffer.Create(const aTarget: TglcBufferTarget);
- begin
- {$IFNDEF OPENGL_ES}
- if not (GL_ARB_Vertex_Buffer_Object or GL_VERSION_2_0) then
- raise EglcArrayBuffer.Create('Create - VertexBuffer: not supported');
- {$ELSE}
- if not GL_VERSION_2_0 then
- raise EglcArrayBuffer.Create('Create - VertexBuffer: not supported');
- {$ENDIF}
- glGetError();
- inherited Create;
- glGenBuffers(1, @fID);
- fDataCount := 0;
- fDataSize := 0;
- fTarget := aTarget;
- glcCheckAndRaiseError;
- end;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
- destructor TglcArrayBuffer.Destroy;
- begin
- glDeleteBuffers(1, @fID);
- inherited Destroy;
- end;
-
- end.
-
|