I'm currently developing a 3D plane simulator for my bachelor thesis. We've written the engine in LWJGL. We have to provide a GUI, to display some info about the plane that is flying. Like speed, position etc...
We followed a tutorial online from youtuber "Thin Matrix". And now use some TextRenderer. For some reason we can't write text smaller than visible in the provided image.
For 2D games i've experimented with I used the Slick 2D library provided with LWJGL 2, to render text, but I can't use the functions or it throws errors, that those functions are not supported. I guess because we don't use Orthographic projection.
Is there any way to use Slick 2D, or are there other libraries that can be used for easy and smaller text rendering.

Example of our project window

  • 1
    \$\begingroup\$ If it were me, I'd open a separate window and just use the OS-supplied text drawing facilities (or whatever you get by default in Java). Much easier than dealing with 3rd party libraries that have all sorts of dependencies/requirements to get up and running. \$\endgroup\$ Commented Apr 28, 2018 at 21:14

1 Answer 1


LWJGL 3 has stb_true_type. It can generate a texture atlas and the mesh for each character. I'm using it with my engine it requires a projection matrix with top left origin.

Switching to LWJGL 3 will require you to download the jars lwjgl.org or if you're using maven or other build tools to generate a project from there.

For generating the font atlas

this.fontSize = fontSize;
    this.bitmapWidth = bitmapWidth;
    this.bitmapHeight = bitmapHeight;
    try {
        cdata = STBTTBakedChar.malloc(CHAR_AMT);

        ByteBuffer ttf = FileLoader.loadResurce(fontFile);

        STBTTFontinfo info = STBTTFontinfo.create();

        if (!stbtt_InitFont(info, ttf)) {
            throw new IllegalStateException("Failed to initialize font information.");
        ByteBuffer bitmap = BufferUtils.createByteBuffer(bitmapWidth * bitmapHeight);
        stbtt_BakeFontBitmap(ttf, fontSize, bitmap, bitmapWidth, bitmapHeight, 0, cdata);

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        textureId = glGenTextures();
        glBindTexture(GL_TEXTURE_2D, textureId);
        glTexImage2D(GL_TEXTURE_2D, 0, GL11.GL_RED, bitmapWidth, bitmapHeight, 0, GL11.GL_RED, GL_UNSIGNED_BYTE, bitmap);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    } catch (IOException e) {

For generating the mesh for the string.

 int count = text.length() * 4;
    int verticesId = glGenBuffers();
    int textureCoordinates = glGenBuffers();
    try (MemoryStack stack = MemoryStack.stackPush()) {

        FloatBuffer vert = stack.mallocFloat(text.length() * 8);
        FloatBuffer tex = stack.mallocFloat(text.length() * 8);

        float length = 0;
        for (char c : text.toCharArray()) {
            STBTTAlignedQuad stbQuad = STBTTAlignedQuad.create();
            float[] x = new float[1];
            float[] y = new float[1];
            stbtt_GetBakedQuad(cdata, bitmapWidth, bitmapHeight, c, x, y, stbQuad, true);

            float[] vertices = new float[]{
                    length + stbQuad.x0(), stbQuad.y0(),
                    length + stbQuad.x1(), stbQuad.y0(),
                    length + stbQuad.x1(), stbQuad.y1(),
                    length + stbQuad.x0(), stbQuad.y1()

            float[] textures = new float[]{
                    stbQuad.s0(), stbQuad.t0(),
                    stbQuad.s1(), stbQuad.t0(),
                    stbQuad.s1(), stbQuad.t1(),
                    stbQuad.s0(), stbQuad.t1()
            length += x[0];


        glBindBuffer(GL_ARRAY_BUFFER, verticesId);
        glBufferData(GL_ARRAY_BUFFER, vert, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, textureCoordinates);
        glBufferData(GL_ARRAY_BUFFER, tex, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .