Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

243 linhas
7.5 KiB

  1. unit utsRendererOpenGL;
  2. {$IFDEF FPC}
  3. {$mode objfpc}{$H+}
  4. {$ENDIF}
  5. interface
  6. uses
  7. Classes, SysUtils, dglOpenGL,
  8. utsOpenGLUtils, utsTypes, utsContext, utsImage;
  9. type
  10. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  11. TtsRendererOpenGL = class(TtsBaseOpenGL)
  12. private
  13. fVBO: GLuint;
  14. fIsRendering: Boolean;
  15. protected
  16. function CreateNewTexture: PtsFontTexture; override;
  17. procedure FreeTexture(var aTexture: PtsFontTexture); override;
  18. procedure UploadTexData(const aCharRef: TtsOpenGLRenderRef; const aCharImage: TtsImage; const X, Y: Integer); override;
  19. procedure BeginRender; override;
  20. procedure EndRender; override;
  21. procedure SetDrawPos(const aValue: TtsPosition); override;
  22. procedure MoveDrawPos(const aOffset: TtsPosition); override;
  23. procedure SetColor(const aValue: TtsColor4f); override;
  24. procedure Render(const aRenderRef: TtsRenderRef; const aForcedWidth: Integer = 0); override;
  25. public
  26. constructor Create(const aContext: TtsContext; const aFormat: TtsFormat);
  27. destructor Destroy; override;
  28. end;
  29. implementation
  30. uses
  31. utsUtils;
  32. type
  33. TVertex = packed record
  34. pos: array[0..1] of GLfloat;
  35. tex: array[0..1] of GLfloat;
  36. end;
  37. const
  38. FORMAT_TYPES: array[TtsFormat] of packed record
  39. InternalFormat: GLenum;
  40. Format: GLenum;
  41. DataFormat: GLenum;
  42. end = (
  43. ( //tsFormatEmpty
  44. InternalFormat: 0;
  45. Format: 0;
  46. DataFormat: 0),
  47. ( //tsFormatRGBA8
  48. InternalFormat: GL_RGBA8;
  49. Format: GL_RGBA;
  50. DataFormat: GL_UNSIGNED_BYTE),
  51. ( //tsFormatLumAlpha8
  52. InternalFormat: GL_LUMINANCE8_ALPHA8;
  53. Format: GL_LUMINANCE_ALPHA;
  54. DataFormat: GL_UNSIGNED_BYTE),
  55. ( //tsFormatAlpha8
  56. InternalFormat: GL_ALPHA8;
  57. Format: GL_ALPHA;
  58. DataFormat: GL_UNSIGNED_BYTE),
  59. ( //tsFormatAlpha8
  60. InternalFormat: GL_LUMINANCE8;
  61. Format: GL_LUMINANCE;
  62. DataFormat: GL_UNSIGNED_BYTE)
  63. );
  64. VBO_DATA: array[0..3] of TVertex = (
  65. (pos: (0.0, 0.0); tex: (0.0, 0.0)),
  66. (pos: (0.0, 1.0); tex: (0.0, 1.0)),
  67. (pos: (1.0, 0.0); tex: (1.0, 0.0)),
  68. (pos: (1.0, 1.0); tex: (1.0, 1.0))
  69. );
  70. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. //TtsRendererOpenGL/////////////////////////////////////////////////////////////////////////////////////////////////////
  72. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. function TtsRendererOpenGL.CreateNewTexture: PtsFontTexture;
  74. begin
  75. new(result);
  76. try
  77. FillChar(result^, SizeOf(result^), #0);
  78. new(result^.Usage);
  79. FillChar(result^.Usage^, SizeOf(result^.Usage^), #0);
  80. result^.Size := TextureSize;
  81. glGenTextures(1, @result^.ID);
  82. glBindTexture(GL_TEXTURE_2D, result^.ID);
  83. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  84. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  85. glTexImage2D(
  86. GL_TEXTURE_2D,
  87. 0,
  88. FORMAT_TYPES[Format].InternalFormat,
  89. result^.Size,
  90. result^.Size,
  91. 0,
  92. FORMAT_TYPES[Format].Format,
  93. FORMAT_TYPES[Format].DataFormat,
  94. nil);
  95. PushTexture(result);
  96. except
  97. if Assigned(result^.Usage) then
  98. Dispose(result^.Usage);
  99. Dispose(result);
  100. end;
  101. end;
  102. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  103. procedure TtsRendererOpenGL.FreeTexture(var aTexture: PtsFontTexture);
  104. begin
  105. if Assigned(aTexture) then
  106. glDeleteTextures(1, @aTexture^.ID);
  107. inherited FreeTexture(aTexture);
  108. end;
  109. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  110. procedure TtsRendererOpenGL.UploadTexData(const aCharRef: TtsOpenGLRenderRef; const aCharImage: TtsImage; const X,
  111. Y: Integer);
  112. begin
  113. glBindTexture(GL_TEXTURE_2D, aCharRef.TextureID);
  114. glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  115. glTexSubImage2D(GL_TEXTURE_2D, 0,
  116. x, y, aCharImage.Width, aCharImage.Height,
  117. FORMAT_TYPES[aCharImage.Format].Format,
  118. FORMAT_TYPES[aCharImage.Format].DataFormat,
  119. aCharImage.Data);
  120. end;
  121. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  122. procedure TtsRendererOpenGL.BeginRender;
  123. begin
  124. inherited BeginRender;
  125. fIsRendering := true;
  126. glPushMatrix;
  127. glColor4fv(@Color.arr[0]);
  128. glBindBuffer(GL_ARRAY_BUFFER, fVBO);
  129. glEnableClientState(GL_VERTEX_ARRAY);
  130. glVertexPointer(2, GL_FLOAT, SizeOf(TVertex), Pointer(0));
  131. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  132. glTexCoordPointer(2, GL_FLOAT, SizeOf(TVertex), Pointer(8));
  133. end;
  134. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  135. procedure TtsRendererOpenGL.EndRender;
  136. begin
  137. if fIsRendering then begin
  138. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  139. glDisableClientState(GL_VERTEX_ARRAY);
  140. glBindBuffer(GL_ARRAY_BUFFER, 0);
  141. glPopMatrix;
  142. fIsRendering := false;
  143. end;
  144. end;
  145. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146. procedure TtsRendererOpenGL.SetDrawPos(const aValue: TtsPosition);
  147. begin
  148. inherited SetDrawPos(aValue);
  149. glPopMatrix;
  150. glPushMatrix;
  151. glTranslatef(aValue.x, aValue.y, 0);
  152. end;
  153. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  154. procedure TtsRendererOpenGL.MoveDrawPos(const aOffset: TtsPosition);
  155. begin
  156. inherited MoveDrawPos(aOffset);
  157. glTranslatef(aOffset.x, aOffset.y, 0);
  158. end;
  159. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  160. procedure TtsRendererOpenGL.SetColor(const aValue: TtsColor4f);
  161. begin
  162. inherited SetColor(aValue);
  163. glColor4fv(@Color.arr[0]);
  164. end;
  165. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  166. procedure TtsRendererOpenGL.Render(const aRenderRef: TtsRenderRef; const aForcedWidth: Integer);
  167. var
  168. ref: TtsOpenGLRenderRef;
  169. m: TtsMatrix4f;
  170. begin
  171. if Assigned(aRenderRef) then begin
  172. ref := TtsOpenGLRenderRef(aRenderRef);
  173. glEnable(GL_TEXTURE_2D);
  174. glBindTexture(GL_TEXTURE_2D, ref.TextureID);
  175. glMatrixMode(GL_TEXTURE);
  176. glPushMatrix;
  177. glLoadIdentity;
  178. glMultMatrixf(@ref.TexMat[0, 0]);
  179. glMatrixMode(GL_MODELVIEW);
  180. glPushMatrix;
  181. if (aForcedWidth > 0) then begin
  182. m := ref.VertMat;
  183. m[0] := tsVector4f(aForcedWidth, 0, 0, 0);
  184. glMultMatrixf(@m[0, 0]);
  185. end else
  186. glMultMatrixf(@ref.VertMat[0, 0]);
  187. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  188. glMatrixMode(GL_TEXTURE);
  189. glPopMatrix;
  190. glMatrixMode(GL_MODELVIEW);
  191. glPopMatrix;
  192. end;
  193. end;
  194. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  195. constructor TtsRendererOpenGL.Create(const aContext: TtsContext; const aFormat: TtsFormat);
  196. begin
  197. inherited Create(aContext, aFormat);
  198. fIsRendering := false;
  199. glGenBuffers(1, @fVBO);
  200. glBindBuffer(GL_ARRAY_BUFFER, fVBO);
  201. glBufferData(GL_ARRAY_BUFFER, SizeOf(TVertex) * Length(VBO_DATA), @VBO_DATA[0].pos[0], GL_STATIC_DRAW);
  202. glBindBuffer(GL_ARRAY_BUFFER, 0);
  203. end;
  204. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  205. destructor TtsRendererOpenGL.Destroy;
  206. begin
  207. glDeleteBuffers(1, @fVBO);
  208. inherited Destroy;
  209. end;
  210. end.