package de.tudarmstadt.informatik.hostage.ui.fragment.opengl; import android.content.res.AssetManager; import android.opengl.GLES10; import android.opengl.GLES20; import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity; /** * Created by Fabio Arnold on 13.02.15. */ public class GLFont { private class GlyphMetric { float x0,y0,s0,t0; // top-left float x1,y1,s1,t1; // bottom-right float advance; } private int mTexture; private int mVertexBuffer; private GlyphMetric mMetrics[]; public GLFont(String texFilePath, String metricsFilePath) { AssetManager assets = MainActivity.getInstance().getAssets(); mTexture = ThreatIndicatorGLRenderer.loadTexture(texFilePath); InputStream is = null; try { is = assets.open(metricsFilePath); } catch (IOException e) { e.printStackTrace(); return; } //DataInputStream dis = new DataInputStream(is); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { final int EOF = -1; int len; byte[] buffer = new byte[1 << 12]; while (EOF != (len = is.read(buffer))) out.write(buffer, 0, len); } catch (IOException e) { e.printStackTrace(); return; } //data = ByteBuffer.wrap(out.toByteArray()); // doesn't work data needs to be direct ByteBuffer data = ByteBuffer.allocateDirect(out.size()); data.order(ByteOrder.nativeOrder()); data.put(out.toByteArray()); data.position(0); mMetrics = new GlyphMetric[96]; for (int i = 0; i < 96; i++) { mMetrics[i] = new GlyphMetric(); mMetrics[i].x0 = data.getFloat(); mMetrics[i].y0 = data.getFloat(); mMetrics[i].s0 = data.getFloat(); mMetrics[i].t0 = data.getFloat(); mMetrics[i].x1 = data.getFloat(); mMetrics[i].y1 = data.getFloat(); mMetrics[i].s1 = data.getFloat(); mMetrics[i].t1 = data.getFloat(); mMetrics[i].advance = data.getFloat(); } int buffers[] = new int[1]; GLES20.glGenBuffers(1, buffers, 0); // buffer names mVertexBuffer = buffers[0]; } public float getTextWidth(String text) { float x = 0.0f; for (int i = 0; i < text.length(); i++) { x += mMetrics[(int)text.charAt(i)-32].advance; } return x; } public void drawText(int program, String text, float x, float y) { int vertexCount = text.length() * 6; int vertexSize = (2+2)*4; // size in bytes FloatBuffer buffer = ByteBuffer.allocateDirect(vertexCount * vertexSize).order(ByteOrder.nativeOrder()).asFloatBuffer(); for (int i = 0; i < text.length(); i++) { int glyph = ((int)text.charAt(i))-32; GlyphMetric metric = mMetrics[glyph]; buffer.put(x+metric.x0); buffer.put(y+metric.y0); buffer.put(metric.s0); buffer.put(metric.t1); buffer.put(x+metric.x1); buffer.put(y+metric.y0); buffer.put(metric.s1); buffer.put(metric.t1); buffer.put(x+metric.x1); buffer.put(y+metric.y1); buffer.put(metric.s1); buffer.put(metric.t0); buffer.put(x+metric.x0); buffer.put(y+metric.y0); buffer.put(metric.s0); buffer.put(metric.t1); buffer.put(x+metric.x1); buffer.put(y+metric.y1); buffer.put(metric.s1); buffer.put(metric.t0); buffer.put(x+metric.x0); buffer.put(y+metric.y1); buffer.put(metric.s0); buffer.put(metric.t0); x += metric.advance; } buffer.position(0); // rewind GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer); GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexSize * vertexCount, buffer, GLES20.GL_STREAM_DRAW); int positionIndex = GLES20.glGetAttribLocation(program, "position"); int texCoordIndex = GLES20.glGetAttribLocation(program, "texCoord"); GLES20.glEnableVertexAttribArray(positionIndex); GLES20.glEnableVertexAttribArray(texCoordIndex); GLES20.glVertexAttribPointer(positionIndex, 2, GLES20.GL_FLOAT, false, vertexSize, 0); GLES20.glVertexAttribPointer(texCoordIndex, 2, GLES20.GL_FLOAT, false, vertexSize, 8); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glDisableVertexAttribArray(positionIndex); GLES20.glDisableVertexAttribArray(texCoordIndex); } }