您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

238 行
7.3 KiB

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