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.

236 lines
7.3 KiB

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