GLFont.java 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package de.tudarmstadt.informatik.hostage.ui.fragment.opengl;
  2. import android.content.res.AssetManager;
  3. import android.opengl.GLES10;
  4. import android.opengl.GLES20;
  5. import android.util.Log;
  6. import java.io.ByteArrayOutputStream;
  7. import java.io.DataInputStream;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.nio.ByteBuffer;
  11. import java.nio.ByteOrder;
  12. import java.nio.FloatBuffer;
  13. import java.nio.IntBuffer;
  14. import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
  15. /**
  16. * Created by Fabio Arnold on 13.02.15.
  17. */
  18. public class GLFont {
  19. private class GlyphMetric {
  20. float x0,y0,s0,t0; // top-left
  21. float x1,y1,s1,t1; // bottom-right
  22. float advance;
  23. }
  24. private int mTexture;
  25. private int mVertexBuffer;
  26. private GlyphMetric mMetrics[];
  27. public GLFont(String texFilePath, String metricsFilePath) {
  28. AssetManager assets = MainActivity.getInstance().getAssets();
  29. mTexture = ThreatIndicatorGLRenderer.loadTexture(texFilePath);
  30. InputStream is = null;
  31. try {
  32. is = assets.open(metricsFilePath);
  33. } catch (IOException e) {
  34. e.printStackTrace();
  35. return;
  36. }
  37. //DataInputStream dis = new DataInputStream(is);
  38. ByteArrayOutputStream out = new ByteArrayOutputStream();
  39. try {
  40. final int EOF = -1;
  41. int len;
  42. byte[] buffer = new byte[1 << 12];
  43. while (EOF != (len = is.read(buffer)))
  44. out.write(buffer, 0, len);
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. return;
  48. }
  49. //data = ByteBuffer.wrap(out.toByteArray()); // doesn't work data needs to be direct
  50. ByteBuffer data = ByteBuffer.allocateDirect(out.size());
  51. data.order(ByteOrder.nativeOrder());
  52. data.put(out.toByteArray());
  53. data.position(0);
  54. mMetrics = new GlyphMetric[96];
  55. for (int i = 0; i < 96; i++) {
  56. mMetrics[i] = new GlyphMetric();
  57. mMetrics[i].x0 = data.getFloat();
  58. mMetrics[i].y0 = data.getFloat();
  59. mMetrics[i].s0 = data.getFloat();
  60. mMetrics[i].t0 = data.getFloat();
  61. mMetrics[i].x1 = data.getFloat();
  62. mMetrics[i].y1 = data.getFloat();
  63. mMetrics[i].s1 = data.getFloat();
  64. mMetrics[i].t1 = data.getFloat();
  65. mMetrics[i].advance = data.getFloat();
  66. }
  67. int buffers[] = new int[1];
  68. GLES20.glGenBuffers(1, buffers, 0); // buffer names
  69. mVertexBuffer = buffers[0];
  70. }
  71. public float getTextWidth(String text) {
  72. float x = 0.0f;
  73. for (int i = 0; i < text.length(); i++) {
  74. x += mMetrics[(int)text.charAt(i)-32].advance;
  75. }
  76. return x;
  77. }
  78. public void drawText(int program, String text, float x, float y) {
  79. int vertexCount = text.length() * 6;
  80. int vertexSize = (2+2)*4; // size in bytes
  81. FloatBuffer buffer = ByteBuffer.allocateDirect(vertexCount * vertexSize).order(ByteOrder.nativeOrder()).asFloatBuffer();
  82. for (int i = 0; i < text.length(); i++) {
  83. int glyph = ((int)text.charAt(i))-32;
  84. GlyphMetric metric = mMetrics[glyph];
  85. buffer.put(x+metric.x0); buffer.put(y+metric.y0);
  86. buffer.put(metric.s0); buffer.put(metric.t1);
  87. buffer.put(x+metric.x1); buffer.put(y+metric.y0);
  88. buffer.put(metric.s1); buffer.put(metric.t1);
  89. buffer.put(x+metric.x1); buffer.put(y+metric.y1);
  90. buffer.put(metric.s1); buffer.put(metric.t0);
  91. buffer.put(x+metric.x0); buffer.put(y+metric.y0);
  92. buffer.put(metric.s0); buffer.put(metric.t1);
  93. buffer.put(x+metric.x1); buffer.put(y+metric.y1);
  94. buffer.put(metric.s1); buffer.put(metric.t0);
  95. buffer.put(x+metric.x0); buffer.put(y+metric.y1);
  96. buffer.put(metric.s0); buffer.put(metric.t0);
  97. x += metric.advance;
  98. }
  99. buffer.position(0); // rewind
  100. GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture);
  101. GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
  102. GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexSize * vertexCount, buffer, GLES20.GL_STREAM_DRAW);
  103. int positionIndex = GLES20.glGetAttribLocation(program, "position");
  104. int texCoordIndex = GLES20.glGetAttribLocation(program, "texCoord");
  105. GLES20.glEnableVertexAttribArray(positionIndex);
  106. GLES20.glEnableVertexAttribArray(texCoordIndex);
  107. GLES20.glVertexAttribPointer(positionIndex, 2, GLES20.GL_FLOAT, false, vertexSize, 0);
  108. GLES20.glVertexAttribPointer(texCoordIndex, 2, GLES20.GL_FLOAT, false, vertexSize, 8);
  109. GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
  110. GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
  111. GLES20.glDisableVertexAttribArray(positionIndex);
  112. GLES20.glDisableVertexAttribArray(texCoordIndex);
  113. }
  114. }