public float getWidth(String text){ float w = 0; FloatBuffer xbuf = BufferUtils.createFloatBuffer(1); FloatBuffer ybuf = BufferUtils.createFloatBuffer(1); STBTTAlignedQuad q = STBTTAlignedQuad.malloc(); for(char c : text.toCharArray()){ if(c == '\n'){ continue; }else if(c < 32 || c > 128){ continue; } STBTruetype.stbtt_GetBakedQuad(cdata, 512, 512, (int)(c - 32), xbuf, ybuf, q, true); w += q.x1() - q.x0(); } return w; }
/** * The constructor that creates the font from the given file at the given height. * * @param filePath - The path to file including the file type * @param fontHeight - The height (size) of the font */ public TrueTypeFont(String filePath, int fontHeight) { this.fontHeight = fontHeight; long startTime = 0L; if (Debug.enabled) startTime = System.nanoTime(); textureID = glGenTextures(); cdata = STBTTBakedChar.mallocBuffer(96); try { ByteBuffer ttf = IOUtil.ioResourceToByteBuffer(filePath, 160 * 1024); ByteBuffer bitmap = BufferUtils.createByteBuffer(BITMAP_W * BITMAP_H); STBTruetype.stbtt_BakeFontBitmap(ttf, fontHeight, bitmap, BITMAP_W, BITMAP_H, 32, cdata); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_W, BITMAP_H, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } catch (IOException e) { throw new RuntimeException(e); } xbuf = BufferUtils.createFloatBuffer(1); ybuf = BufferUtils.createFloatBuffer(1); quad = STBTTAlignedQuad.malloc(); if (Debug.enabled) { long endTime = System.nanoTime(); Debug.println(" Loaded font: " + filePath + "\n\tFont height: " + fontHeight + "px" + "\n\tLoad time: " + Debug.noNotation.format((endTime - startTime) / 1000000000.0) + "s", Debug.ANSI_CYAN); } }
public void print(float x, float y, String text){ GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId); FloatBuffer xbuf = BufferUtils.createFloatBuffer(1); FloatBuffer ybuf = BufferUtils.createFloatBuffer(1); xbuf.put(x); ybuf.put(Window.instance.getHeight() - y); xbuf.flip(); ybuf.flip(); STBTTAlignedQuad q = STBTTAlignedQuad.malloc(); GL11.glBegin(GL11.GL_QUADS); for(char c : text.toCharArray()){ if(c == '\n'){ ybuf.put(0, ybuf.get(0) + fontHeight); xbuf.put(0, x); continue; }else if(c < 32 || c > 128){ continue; } STBTruetype.stbtt_GetBakedQuad(cdata, 512, 512, (int)(c - 32), xbuf, ybuf, q, true); GL11.glTexCoord2f(q.s0(), q.t0()); GL11.glVertex2f(q.x0(), q.y0()); GL11.glTexCoord2f(q.s1(), q.t0()); GL11.glVertex2f(q.x1(), q.y0()); GL11.glTexCoord2f(q.s1(), q.t1()); GL11.glVertex2f(q.x1(), q.y1()); GL11.glTexCoord2f(q.s0(), q.t1()); GL11.glVertex2f(q.x0(), q.y1()); } GL11.glEnd(); }
public void draw(){ try ( MemoryStack stack = stackPush() ) { FloatBuffer x = stack.floats(0.0f); FloatBuffer y = stack.floats(0.0f); STBTTAlignedQuad q = STBTTAlignedQuad.mallocStack(stack); for ( int i = 0; i < text.length(); i++ ) { char c = text.charAt(i); if ( c == '\n' ) { y.put(0, y.get(0) + ttf.getFontSize()); x.put(0, 0.0f); continue; } else if ( c < 32 || 128 <= c ) continue; stbtt_GetBakedQuad(ttf.getCData(), ttf.getBitmapSize(), ttf.getBitmapSize(), c - 32, x, y, q, true); Mesh mesh = new Mesh(); ArrayList<Vertex> verts2 = new ArrayList<Vertex>(); verts2.add(new Vertex(new Vector3f(q.x0(), -q.y0(), 0), null, null, new Vector2f( q.s0(), q.t0()))); verts2.add(new Vertex(new Vector3f(q.x1(), -q.y0(), 0), null, null, new Vector2f( q.s1(), q.t0()))); verts2.add(new Vertex(new Vector3f(q.x1(), -q.y1(), 0), null, null, new Vector2f( q.s1(), q.t1()))); verts2.add(new Vertex(new Vector3f(q.x0(), -q.y1(), 0), null, null, new Vector2f( q.s0(), q.t1()))); mesh.loadVertices(verts2); Integer[] index_array2 = { 3, 1, 0, 3, 2, 1 }; ArrayList<Integer> indices2 = new ArrayList(Arrays.asList(index_array2)); mesh.loadIndices(indices2); if (ttf.getVDO().getVBO() != null) ttf.getVDO().getVBO().delete(); ttf.getVDO().loadVBO(mesh, ttf.getShader()); if (ttf.getVDO().getEBO() != null) ttf.getVDO().getEBO().delete(); ttf.getVDO().loadEBO(mesh); float ratio = 1; //Matrix4f model = new Matrix4f(); Matrix4f projection = Matrix4f.orthographic(0, 960, 0, 540, -1, 1); Drawable t = new Drawable(ttf.getShader(), ttf.getVDO()); ttf.getShader().setMVP(getMatrix(), new Matrix4f(), projection); t.draw(); } } }
/** * Draws The specified text on screen. Not suitable for drawing text into a 3D world yet. * * Note: 0, 0 is the bottom left of the window. */ public void draw(float xpos, float ypos, String text) { Tessellator ts = Engine.tessellator; glDisable(GL_CULL_FACE); Shader s = getShader("sprite"); glBindTexture(GL_TEXTURE_2D, texID); s.bind(); s.uniformMat4("model", mat4().translate(vec3(-(Settings.WINDOW_WIDTH / 2) + xpos, -(Settings.WINDOW_HEIGHT / 2) +ypos, 0))); s.uniformMat4("view", mat4()); float w = Settings.WINDOW_WIDTH / 2; float h = Settings.WINDOW_HEIGHT / 2; s.uniformMat4("projection", Mat4.orthographic(-w, w, -h, h, -100, 100)); s.uniformVec3("color", vec3(1f, 1f, 1f)); try ( MemoryStack stack = stackPush() ) { FloatBuffer x = stack.floats(0.0f); FloatBuffer y = stack.floats(0.0f); STBTTAlignedQuad q = STBTTAlignedQuad.mallocStack(stack); ts.begin(GL_QUADS); for ( int i = 0; i < text.length(); i++ ) { char c = text.charAt(i); if ( c == '\n' ) { y.put(0, y.get(0) + size); x.put(0, 0.0f); continue; } else if ( c < 32 || 128 <= c ) continue; stbtt_GetBakedQuad(cdata, BITMAP_W, BITMAP_H, c - 32, x, y, q, true); ts.vertex(q.x0(), 1-q.y0(), 0, q.s0(), q.t0()); ts.vertex(q.x1(), 1-q.y0(), 0, q.s1(), q.t0()); ts.vertex(q.x1(), 1-q.y1(), 0, q.s1(), q.t1()); ts.vertex(q.x0(), 1-q.y1(), 0, q.s0(), q.t1()); } ts.end(); } }