You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
7.6 KiB

  1. unit uglcArrayBuffer;
  2. { Package: OpenGLCore
  3. Prefix: glc - OpenGL Core
  4. Beschreibung: diese Unit enthält eine Klassen-Kapselung für OpenGL Array Buffer
  5. Beispiel:
  6. type
  7. TVertex = packed record
  8. pos: TgluVector3f; // vertex position
  9. tex: TgluVector2f; // texture coordinates
  10. nor: TgluVector3f; // normal
  11. end;
  12. PVertex = ^TVertex;
  13. var
  14. vBuffer: TglcArrayBuffer;
  15. iBuffer: TglcArrayBuffer;
  16. p: Pointer;
  17. vBuffer := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer);
  18. iBuffer := TglcArrayBuffer.Create(TglcBufferTarget.btElementArrayBuffer);
  19. try
  20. // write vertex data to vertex buffer
  21. vBuffer.Bind;
  22. vBuffer.BufferData(4, SizeOf(TresMeshVertex), TglcBufferUsage.buStaticDraw, nil);
  23. p := vBuffer.MapBuffer(TglcBufferAccess.baWriteOnly);
  24. try
  25. PVertex(p).pos := gluVertex3f(0.0, 0.0, 0.0);
  26. PVertex(p).tex := gluVertex2f(0.0, 0.5);
  27. PVertex(p).nor := gluVertex3f(0.0, 1.0, 0.0);
  28. inc(p, SizeOf(TVertex));
  29. // ...
  30. finally
  31. vBuffer.UnmapBuffer;
  32. vBuffer.Unbind;
  33. end;
  34. // write indices to index buffer
  35. iBuffer.Bind;
  36. iBuffer.BufferData(4, SizeOf(GLuint), TglcBufferUsage.buStaticDraw, nil);
  37. p := iBuffer.MapBuffer(TglcBufferAccess.baWriteOnly);
  38. try
  39. PGLuint(p) := 0;
  40. // ...
  41. finally
  42. iBuffer.UnmapBuffer;
  43. iBuffer.Unbind;
  44. end;
  45. // use array buffers to draw primitive
  46. vBuffer.Bind;
  47. iBuffer.Bind;
  48. glEnableClientState(GL_VERTEX_ARRAY);
  49. glVertexPointer(3, GL_FLOAT, 8, Pointer(0));
  50. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  51. glTexCoordPointer(2, GL_FLOAT, 8, Pointer(3));
  52. glEnableClientState(GL_NORMAL_ARRAY);
  53. glNormalPointer(GL_FLOAT, 8, Pointer(5));
  54. glEnableClientState(GL_INDEX_ARRAY);
  55. glIndexPointer(GL_INT, 0, nil);
  56. glDrawElements(GL_QUADS, iBuffer.DataCount, GL_UNSIGNED_INT, nil);
  57. glDisableClientState(GL_INDEX_ARRAY);
  58. glDisableClientState(GL_VERTEX_ARRAY);
  59. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  60. glDisableClientState(GL_NORMAL_ARRAY);
  61. fIndexBuffer.Unbind;
  62. fVertexBuffer.Unbind;
  63. finally
  64. FreeAndNil(vBuffer);
  65. FreeAndNil(iBuffer);
  66. end; }
  67. {$mode objfpc}{$H+}
  68. interface
  69. uses
  70. {$IFNDEF OPENGL_ES}dglOpenGL{$ELSE}dglOpenGLES{$ENDIF}, sysutils, uglcTypes;
  71. type
  72. EglcArrayBuffer = class(Exception);
  73. TglcArrayBuffer = class(TObject)
  74. private
  75. fID: GLuint;
  76. fTarget: TglcBufferTarget;
  77. fUsage: TglcBufferUsage;
  78. protected
  79. fDataCount: Integer;
  80. fDataSize: Integer;
  81. public
  82. property ID: gluInt read fID;
  83. property Target: TglcBufferTarget read fTarget;
  84. property Usage: TglcBufferUsage read fUsage;
  85. property DataCount: Integer read fDataCount;
  86. property DataSize: Integer read fDataSize;
  87. procedure BufferData(const aDataCount, aDataSize: Cardinal; const aUsage: TglcBufferUsage; const aData: Pointer);
  88. function MapBuffer(const aAccess: TglcBufferAccess): Pointer;
  89. function MapBufferRange(const aOffset: GLintptr; const aSize: GLsizeiptr; const aAccess: TglcBufferAccess): Pointer;
  90. procedure UnmapBuffer;
  91. procedure Bind;
  92. procedure Unbind;
  93. constructor Create(const aTarget: TglcBufferTarget);
  94. destructor Destroy; override;
  95. end;
  96. implementation
  97. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. //TglcArrayBuffer///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  99. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  100. procedure TglcArrayBuffer.BufferData(const aDataCount, aDataSize: Cardinal; const aUsage: TglcBufferUsage; const aData: Pointer);
  101. begin
  102. glGetError(); //clear Errors
  103. Bind;
  104. fDataCount := aDataCount;
  105. fDataSize := aDataSize;
  106. fUsage := aUsage;
  107. glBufferData(GLenum(fTarget), fDataCount * fDataSize, aData, GLenum(fUsage));
  108. glcCheckAndRaiseError;
  109. end;
  110. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  111. function TglcArrayBuffer.MapBuffer(const aAccess: TglcBufferAccess): Pointer;
  112. begin
  113. glGetError();
  114. result := nil;
  115. if (fDataCount * fDataSize) <= 0 then
  116. exit;
  117. {$IFNDEF OPENGL_ES}
  118. result := glMapBuffer(GLenum(fTarget), GLenum(aAccess));
  119. {$ELSE}
  120. if GL_OES_mapbuffer then
  121. result := glMapBufferOES(GLenum(fTarget), GLenum(aAccess))
  122. else
  123. raise EglcArrayBuffer.Create('map buffer is not supported by video card');
  124. {$ENDIF}
  125. glcCheckAndRaiseError;
  126. end;
  127. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  128. function TglcArrayBuffer.MapBufferRange(const aOffset: GLintptr; const aSize: GLsizeiptr; const aAccess: TglcBufferAccess): Pointer;
  129. begin
  130. {$IFNDEF OPENGL_ES}
  131. if not (GL_ARB_map_buffer_range or GL_VERSION_3_0) then
  132. raise EglcArrayBuffer.Create('map buffer range is not supported by video card');
  133. result := glMapBufferRange(GLenum(fTarget), aOffset, aSize, GLenum(aAccess));
  134. {$ELSE}
  135. if GL_VERSION_3_0 then
  136. result := glMapBufferRange(GLenum(fTarget), aOffset, aSize, GLenum(aAccess))
  137. else if GL_EXT_map_buffer_range then
  138. result := glMapBufferRangeEXT(GLenum(fTarget), aOffset, aSize, GLenum(aAccess))
  139. else
  140. raise EglcArrayBuffer.Create('map buffer range is not supported by video card');
  141. {$ENDIF}
  142. end;
  143. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  144. procedure TglcArrayBuffer.UnmapBuffer;
  145. begin
  146. {$IFNDEF OPENGL_ES}
  147. glUnmapBuffer(GLenum(fTarget));
  148. {$ELSE}
  149. if GL_VERSION_3_0 then
  150. glUnmapBuffer(GLenum(fTarget))
  151. else if GL_OES_mapbuffer then
  152. glUnmapBufferOES(GLenum(fTarget))
  153. else
  154. raise EglcArrayBuffer.Create('unmap buffer is not supported by video card');
  155. {$ENDIF}
  156. end;
  157. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  158. procedure TglcArrayBuffer.Bind;
  159. begin
  160. glBindBuffer(GLenum(fTarget), fID);
  161. end;
  162. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  163. procedure TglcArrayBuffer.Unbind;
  164. begin
  165. glBindBuffer(GLenum(fTarget), 0);
  166. end;
  167. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  168. constructor TglcArrayBuffer.Create(const aTarget: TglcBufferTarget);
  169. begin
  170. {$IFNDEF OPENGL_ES}
  171. if not (GL_ARB_Vertex_Buffer_Object or GL_VERSION_2_0) then
  172. raise EglcArrayBuffer.Create('Create - VertexBuffer: not supported');
  173. {$ELSE}
  174. if not GL_VERSION_2_0 then
  175. raise EglcArrayBuffer.Create('Create - VertexBuffer: not supported');
  176. {$ENDIF}
  177. glGetError();
  178. inherited Create;
  179. glGenBuffers(1, @fID);
  180. fDataCount := 0;
  181. fDataSize := 0;
  182. fTarget := aTarget;
  183. glcCheckAndRaiseError;
  184. end;
  185. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
  186. destructor TglcArrayBuffer.Destroy;
  187. begin
  188. glDeleteBuffers(1, @fID);
  189. inherited Destroy;
  190. end;
  191. end.