Package romcgb.glfontrenderer

Source Code of romcgb.glfontrenderer.FontRenderer

/*
* Copyright 2014 BECKERS romain.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
todo:
    fragment shader -> replace white color with font color
    vertex shader -> render a texture
    ortho view matrix ?
    pass width and height to the vertex shader ?
   
*/
package romcgb.glfontrenderer;

import java.awt.Font;
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.nio.IntBuffer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.BufferUtils;

class Glyph {
    public final int textureId;
    public final int advance;
    public final int height;
    public final int width;
   
    Glyph (int textureId, int advance, int width, int height) {
        this.textureId = textureId;
        this.advance = advance;
        this.width = width;
        this.height = height;
    }
   
    /*
    @Override
    protected void finalize() throws Throwable {
        GL11.glDeleteTextures(this.textureId);
    }
    */
}

public class FontRenderer {
    private Color currentColor;
   
    /*
    private static final String fragmentShaderSource = "";
    private static final String vertexShaderSource = "";
    private static int programId;
    */
    private static boolean initialized = false;
    private boolean disposed;
    private final Glyph[] glyphs;
    private static final int MAX_GLYPH = 127;
   
    FontRenderer (Font font) {
        this.currentColor = java.awt.Color.WHITE;    
        if (!FontRenderer.initialized) {
            FontRenderer.initialize();
        }
        this.disposed = false;
        this.glyphs = new Glyph[MAX_GLYPH];
        buildGlyphs(font);
    }
   
    private static void initialize () {
       /*
        int vertexShaderId = loadShader(
                GL20.GL_VERTEX_SHADER,
                FontRenderer.vertexShaderSource);
        int fragmentShaderId = loadShader(
                GL20.GL_FRAGMENT_SHADER,
                FontRenderer.fragmentShaderSource);
        FontRenderer.programId = loadProgram(vertexShaderId, fragmentShaderId);
        GL20.glDeleteShader(vertexShaderId);
        GL20.glDeleteShader(fragmentShaderId);
        */
        FontRenderer.initialized = true
    }
    /*
    private static int loadShader (int type, String source) {
        int shaderId = GL20.glCreateShader(type);
        if (shaderId == 0) {
            return 0;
        }
        GL20.glShaderSource(shaderId, source);
       
        GL20.glCompileShader(shaderId);
        if (GL20.glGetShaderi(shaderId, GL20.GL_COMPILE_STATUS) == 0) {
            GL20.glDeleteShader(shaderId);
            return 0;
        }
        return shaderId;
    }
   
    private static int loadProgram (int vertexShaderId, int fragmentShaderId) {
        int programId = GL20.glCreateProgram();
        GL20.glAttachShader(programId, vertexShaderId);
        GL20.glAttachShader(programId, fragmentShaderId);
        GL20.glLinkProgram(programId);
        if (GL20.glGetProgrami(programId, GL20.GL_LINK_STATUS)==0) {
            GL20.glDeleteProgram(programId);
            return 0;
        }   
        return programId;
    }
    */
   
    private void buildGlyphs (Font font) {
        int textureId;
        int advance;
        int width;
        int height;
        FontRenderContext frc = new FontRenderContext(font.getTransform(),false,true);
        TextLayout tl;
        BufferedImage image;
        Graphics2D g;
        for (int i = 32; i<MAX_GLYPH; ++i) {
            tl = new TextLayout(String.valueOf((char)i), font, frc);
            width = (int)Math.ceil(tl.getAdvance());
            advance = (int)tl.getAdvance();
            height = (int)Math.ceil(tl.getAscent()+tl.getDescent());
            image =  new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            g = image.createGraphics();
            tl.draw(g, 0, tl.getAscent());
            g.dispose();
            textureId = bufferedImageToTexture(image);
            this.glyphs[i] = new Glyph(textureId, advance, width, height);
        }
    }
     
    private static int bufferedImageToTexture (BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        int[] texels = image.getRGB(0, 0, width, height, null, 0, width);
        IntBuffer buffer = BufferUtils.createIntBuffer(texels.length);
        buffer.put(texels);
        buffer.flip();
        int textureID = GL11.glGenTextures();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D,
                0,
                GL11.GL_RGBA,
                width,
                height,
                0,
                GL12.GL_BGRA,
                GL12.GL_UNSIGNED_INT_8_8_8_8,
                buffer);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
                GL11.GL_TEXTURE_WRAP_S,
                GL12.GL_CLAMP_TO_EDGE);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
                GL11.GL_TEXTURE_WRAP_T,
                GL12.GL_CLAMP_TO_EDGE);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
                GL11.GL_TEXTURE_MIN_FILTER,
                GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D,
                GL11.GL_TEXTURE_MAG_FILTER,
                GL11.GL_LINEAR);
        return textureID;
    }
   
    public void debug () {
        for (Glyph glyph : glyphs) {
            if (glyph==null)
                continue;
            System.out.println(glyph.textureId+" "+glyph.advance);
        }
    }
   
    public void render (int x, int y, String caption) {
        for (char ch : caption.toCharArray()) {
            Glyph glyph = this.glyphs[(int)ch];
            renderGlyph(x, y, glyph);
            x = x + glyph.advance;
        }
    }
   
    public void render (int x, int y, int number) {
        int remainder = 1;
        int num;
        Glyph glyph;
        while (remainder != 0) {
            num = number % 10;
            remainder = num / 10;
            glyph = this.glyphs[48+num];
            renderGlyph(x, y, glyph);
            x = x + glyph.advance;
        }
    }
   
    public void dispose() {
        if (this.disposed)
            return;
        for (Glyph glyph : this.glyphs) {
            if (glyph==null)
                continue;
            GL11.glDeleteTextures(glyph.textureId);
        }
        this.disposed = true;
    }
   
    public boolean isDisposed () {
        return this.disposed;
    }
   
    public void getPixelWidth (String caption) {
        // TODO: not implemented yet
    }
   
    public void setColor (Color color) {
        this.currentColor = color;
    }
   
    public Color getColor () {
        return this.currentColor;
    }
   
   
    //OpenGL 1.1
    private void renderGlyph (int x, int y, Glyph glyph) {
        int right = x+glyph.width;
        int bottom = y+glyph.height;
       
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, glyph.textureId);
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0.0f, 1.0f);
        GL11.glVertex3i(x, y, 0);
        GL11.glTexCoord2f(1.0f, 1.0f);
        GL11.glVertex3i(right, y, 0);
        GL11.glTexCoord2f(1.0f, 0.0f);
        GL11.glVertex3i(right, bottom, 0);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3i(x, bottom, 0);
        GL11.glEnd();
    }
   
   
    /*
    @Override
    protected void finalize() throws Throwable {
        if (!this.disposed) {
            dispose();
        }
        super.finalize();
    }
    */
TOP

Related Classes of romcgb.glfontrenderer.FontRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.