Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

230 řádky
7.0 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); 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);
  155. var
  156. ref: TtsCharRenderRefOpenGL;
  157. begin
  158. if Assigned(aCharRef) and (aCharRef is TtsCharRenderRefOpenGL) then begin
  159. ref := (aCharRef as TtsCharRenderRefOpenGL);
  160. glEnable(GL_TEXTURE_2D);
  161. glBindTexture(GL_TEXTURE_2D, ref.TextureID);
  162. glMatrixMode(GL_TEXTURE);
  163. glPushMatrix;
  164. glLoadIdentity;
  165. glMultMatrixf(@ref.TexMat[0, 0]);
  166. glMatrixMode(GL_MODELVIEW);
  167. glPushMatrix;
  168. glMultMatrixf(@ref.VertMat[0, 0]);
  169. glBindBuffer(GL_ARRAY_BUFFER, fVBO);
  170. glEnableClientState(GL_VERTEX_ARRAY);
  171. glVertexPointer(2, GL_FLOAT, SizeOf(TVertex), Pointer(0));
  172. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  173. glTexCoordPointer(2, GL_FLOAT, SizeOf(TVertex), Pointer(8));
  174. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  175. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  176. glDisableClientState(GL_VERTEX_ARRAY);
  177. glMatrixMode(GL_TEXTURE);
  178. glPopMatrix;
  179. glMatrixMode(GL_MODELVIEW);
  180. glPopMatrix;
  181. end;
  182. end;
  183. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  184. constructor TtsRendererOpenGL.Create(const aContext: TtsContext; const aFormat: TtsFormat);
  185. begin
  186. inherited Create(aContext, aFormat);
  187. fIsRendering := false;
  188. glGenBuffers(1, @fVBO);
  189. glBindBuffer(GL_ARRAY_BUFFER, fVBO);
  190. glBufferData(GL_ARRAY_BUFFER, SizeOf(TVertex) * Length(VBO_DATA), @VBO_DATA[0].pos[0], GL_STATIC_DRAW);
  191. glBindBuffer(GL_ARRAY_BUFFER, 0);
  192. end;
  193. destructor TtsRendererOpenGL.Destroy;
  194. begin
  195. glDeleteBuffers(1, @fVBO);
  196. inherited Destroy;
  197. end;
  198. end.