                             :attributes {:pos-vertex-attribute pos-vertex-attribute
                                          :texture-coords-vertex-attribute texture-coords-vertex-attribute
                                          :fb-pos-vertex-attribute fb-pos-vertex-attribute
-                                         :fb-texture-coords-vertex-attribute fb-texture-coords-vertex-attribute
-}
+                                         :fb-texture-coords-vertex-attribute fb-texture-coords-vertex-attribute}
                             :program-id pgm-id
                             :fb-program-id fb-pgm-id
                             :uniforms {:u-MVMatrix u-MVMatrix

                                    np2-layers  (zutil/next-pow-2 (count (get @layer-group :layers)))]
                                (log/info "creating buffer for bg textures" np2-columns "x" np2-rows) "x" np2-layers
                                (BufferUtils/createByteBuffer (* np2-columns np2-rows 4 np2-layers))))
        glyph-textures      (with-gl-context gl-lock window capabilities
                              (mapv (fn [layer-group glyph-image-data]
                                      (let [np2-columns (zutil/next-pow-2 (get @layer-group :columns))
                                            np2-rows    (zutil/next-pow-2 (get @layer-group :rows))
                                            np2-layers  (zutil/next-pow-2 (count (get @layer-group :layers)))]
                                        (log/info "creating glyph texture" np2-columns "x" np2-rows "x" np2-layers)
                                        (xy-texture-id np2-columns np2-rows np2-layers glyph-image-data)))
                                    (vals group-map)
                                    glyph-image-data))
        fg-textures         (with-gl-context gl-lock window capabilities
                              (mapv (fn [layer-group fg-image-data]
                                      (let [np2-columns (zutil/next-pow-2 (get @layer-group :columns))
                                            np2-rows    (zutil/next-pow-2 (get @layer-group :rows))
                                            np2-layers  (zutil/next-pow-2 (count (get @layer-group :layers)))]
                                        (log/info "creating fg texture" np2-columns "x" np2-rows "x" np2-layers)
                                        (texture-id np2-columns np2-rows np2-layers fg-image-data)))
                                    (vals group-map)
                                    fg-image-data))
        bg-textures         (with-gl-context gl-lock window capabilities
                              (mapv (fn [layer-group bg-image-data]
                                      (let [np2-columns (zutil/next-pow-2 (get @layer-group :columns))
                                            np2-rows    (zutil/next-pow-2 (get @layer-group :rows))
                                            np2-layers  (zutil/next-pow-2 (count (get @layer-group :layers)))]
                                        (log/info "creating bg texture" np2-columns "x" np2-rows "x" np2-layers)
                                        (texture-id np2-columns np2-rows np2-layers bg-image-data)))
                                    (vals group-map)
                                    bg-image-data))
        [fbo-id fbo-texture]
                            (with-gl-context gl-lock window capabilities (fbo-texture framebuffer-width framebuffer-height))
        ; init shaders
        [^int pgm-id
         ^int fb-pgm-id]                   (with-gl-context gl-lock window capabilities (init-shaders (get fx-shader :name)))
        pos-vertex-attribute               (with-gl-context gl-lock window capabilities (GL20/glGetAttribLocation pgm-id "aVertexPosition"))
        texture-coords-vertex-attribute    (with-gl-context gl-lock window capabilities (GL20/glGetAttribLocation pgm-id "aTextureCoord"))
        fb-pos-vertex-attribute            (with-gl-context gl-lock window capabilities (GL20/glGetAttribLocation fb-pgm-id "aVertexPosition"))
        fb-texture-coords-vertex-attribute (with-gl-context gl-lock window capabilities (GL20/glGetAttribLocation fb-pgm-id "aTextureCoord"))

        ;; We just need one vertex buffer, a texture-mapped quad will suffice for drawing the terminal.
        {:keys [vertices-vbo-id
                vertices-count
                texture-coords-vbo-id
                vao-id]}   (with-gl-context gl-lock window capabilities (init-buffers))
        [glyph-tex-dim
         u-MVMatrix
         u-PMatrix

        _                   (log/info "window" window "capabilities" capabilities)
        _                   (log/info "framebuffer size" framebuffer-width "x" framebuffer-height)
        framebuffer-size    (atom [framebuffer-width framebuffer-height])
        monitor-fullscreen-sizes (glfw-fullscreen-sizes)
        _                   (log/info "monitor-fullscreen-sizes" monitor-fullscreen-sizes)

        group->font-texture (into {}
                              (mapv (fn [[k v]]
                                      [k (ref (let [font ((get @v :font) (platform))
                                                    gg   (if (zfont/glyph-graphics? font)
                                                             font
                                                             (zfont/glyph-graphics font))
                                                    font-texture (texture-id-2d (get gg :font-texture-image))]
                                                (log/info "loaded font-texture for" k font-texture (select-keys gg [:font-texture-width :font-texture-height :character-width :character-height]))
                                             (assoc gg :font-texture font-texture)))])
                                 group-map))
        ;; create empty character maps
        layer-character-map-cleared (into {}
                                      (for [[id group-ref] layer-id->group
