mirror of https://github.com/liamg/aminal.git
Improve font rendering performance, eliminate excessive memory usage
This commit is contained in:
parent
070f29ad13
commit
961bc1134a
|
@ -17,17 +17,19 @@ const DPI = 72
|
||||||
|
|
||||||
// A Font allows rendering of text to an OpenGL context.
|
// A Font allows rendering of text to an OpenGL context.
|
||||||
type Font struct {
|
type Font struct {
|
||||||
characters map[rune]*character
|
characters map[rune]*character
|
||||||
vao uint32
|
vao uint32
|
||||||
vbo uint32
|
vbo uint32
|
||||||
program uint32
|
program uint32
|
||||||
texture uint32 // Holds the glyph texture id.
|
uniformLocationResolution int32
|
||||||
color color
|
uniformLocationTextColor int32
|
||||||
ttf *truetype.Font
|
texture uint32 // Holds the glyph texture id.
|
||||||
ttfFace font.Face
|
color color
|
||||||
scale float32
|
ttf *truetype.Font
|
||||||
linePadding float32
|
ttfFace font.Face
|
||||||
lineHeight float32
|
scale float32
|
||||||
|
linePadding float32
|
||||||
|
lineHeight float32
|
||||||
}
|
}
|
||||||
|
|
||||||
type color struct {
|
type color struct {
|
||||||
|
@ -46,15 +48,14 @@ func LoadFont(reader io.Reader, scale float32, windowWidth int, windowHeight int
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate corresponding render state
|
font, err := LoadTrueTypeFont(program, reader, scale)
|
||||||
gl.UseProgram(program)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
//set screen resolution
|
font.UpdateResolution(windowWidth, windowHeight)
|
||||||
resUniform := gl.GetUniformLocation(program, gl.Str("resolution\x00"))
|
|
||||||
gl.Uniform2f(resUniform, float32(windowWidth), float32(windowHeight))
|
|
||||||
gl.UseProgram(0)
|
|
||||||
|
|
||||||
return LoadTrueTypeFont(program, reader, scale)
|
return font, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Font) Free() {
|
func (f *Font) Free() {
|
||||||
|
@ -82,10 +83,8 @@ func (f *Font) SetColor(red float32, green float32, blue float32, alpha float32)
|
||||||
|
|
||||||
func (f *Font) UpdateResolution(windowWidth int, windowHeight int) {
|
func (f *Font) UpdateResolution(windowWidth int, windowHeight int) {
|
||||||
gl.UseProgram(f.program)
|
gl.UseProgram(f.program)
|
||||||
resUniform := gl.GetUniformLocation(f.program, gl.Str("resolution\x00"))
|
gl.Uniform2f(f.uniformLocationResolution, float32(windowWidth), float32(windowHeight))
|
||||||
gl.Uniform2f(resUniform, float32(windowWidth), float32(windowHeight))
|
|
||||||
gl.UseProgram(0)
|
gl.UseProgram(0)
|
||||||
//f.characters = map[rune]*character{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Font) LineHeight() float32 {
|
func (f *Font) LineHeight() float32 {
|
||||||
|
@ -112,13 +111,11 @@ func (f *Font) Print(x, y float32, text string) error {
|
||||||
// Activate corresponding render state
|
// Activate corresponding render state
|
||||||
gl.UseProgram(f.program)
|
gl.UseProgram(f.program)
|
||||||
//set text color
|
//set text color
|
||||||
gl.Uniform4f(gl.GetUniformLocation(f.program, gl.Str("textColor\x00")), f.color.r, f.color.g, f.color.b, f.color.a)
|
gl.Uniform4f(f.uniformLocationTextColor, f.color.r, f.color.g, f.color.b, f.color.a)
|
||||||
//set screen resolution
|
|
||||||
//resUniform := gl.GetUniformLocation(f.program, gl.Str("resolution\x00"))
|
|
||||||
//gl.Uniform2f(resUniform, float32(2560), float32(1440))
|
|
||||||
|
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
gl.BindVertexArray(f.vao)
|
gl.BindVertexArray(f.vao)
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, f.vbo)
|
||||||
|
|
||||||
// Iterate through all characters in string
|
// Iterate through all characters in string
|
||||||
for i := range indices {
|
for i := range indices {
|
||||||
|
@ -145,7 +142,7 @@ func (f *Font) Print(x, y float32, text string) error {
|
||||||
var y2 = ypos + h
|
var y2 = ypos + h
|
||||||
|
|
||||||
//setup quad array
|
//setup quad array
|
||||||
var vertices = []float32{
|
var vertices = [...]float32{
|
||||||
// X, Y, Z, U, V
|
// X, Y, Z, U, V
|
||||||
// Front
|
// Front
|
||||||
x1, y1, 0.0, 0.0,
|
x1, y1, 0.0, 0.0,
|
||||||
|
@ -153,25 +150,24 @@ func (f *Font) Print(x, y float32, text string) error {
|
||||||
x1, y2, 0.0, 1.0,
|
x1, y2, 0.0, 1.0,
|
||||||
x1, y2, 0.0, 1.0,
|
x1, y2, 0.0, 1.0,
|
||||||
x2, y1, 1.0, 0.0,
|
x2, y1, 1.0, 0.0,
|
||||||
x2, y2, 1.0, 1.0}
|
x2, y2, 1.0, 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
// Render glyph texture over quad
|
// Render glyph texture over quad
|
||||||
gl.BindTexture(gl.TEXTURE_2D, ch.textureID)
|
gl.BindTexture(gl.TEXTURE_2D, ch.textureID)
|
||||||
// Update content of VBO memory
|
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, f.vbo)
|
|
||||||
|
|
||||||
//BufferSubData(target Enum, offset int, data []byte)
|
// Update content of VBO memory
|
||||||
gl.BufferSubData(gl.ARRAY_BUFFER, 0, len(vertices)*4, gl.Ptr(vertices)) // Be sure to use glBufferSubData and not glBufferData
|
gl.NamedBufferSubData(f.vbo, 0, len(vertices)*4, gl.Ptr(&vertices[0])) // Be sure to use glBufferSubData and not glBufferData
|
||||||
|
|
||||||
// Render quad
|
// Render quad
|
||||||
gl.DrawArrays(gl.TRIANGLES, 0, 24)
|
gl.DrawArrays(gl.TRIANGLES, 0, 24)
|
||||||
|
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
|
||||||
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
||||||
x += float32((ch.advance >> 6)) // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
x += float32((ch.advance >> 6)) // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear opengl textures and programs
|
//clear opengl textures and programs
|
||||||
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, 0)
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
gl.UseProgram(0)
|
gl.UseProgram(0)
|
||||||
|
@ -308,6 +304,7 @@ func (f *Font) GetRune(r rune) (*character, error) {
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(rgba.Rect.Dx()), int32(rgba.Rect.Dy()), 0,
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(rgba.Rect.Dx()), int32(rgba.Rect.Dy()), 0,
|
||||||
gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix))
|
gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix))
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
|
|
||||||
char.textureID = texture
|
char.textureID = texture
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ func LoadTrueTypeFont(program uint32, r io.Reader, scale float32) (*Font, error)
|
||||||
f.scale = scale
|
f.scale = scale
|
||||||
f.characters = map[rune]*character{}
|
f.characters = map[rune]*character{}
|
||||||
f.program = program //set shader program
|
f.program = program //set shader program
|
||||||
|
f.uniformLocationResolution = gl.GetUniformLocation(program, gl.Str("resolution\x00"))
|
||||||
|
f.uniformLocationTextColor = gl.GetUniformLocation(program, gl.Str("textColor\x00"))
|
||||||
|
|
||||||
// Read the truetype font.
|
// Read the truetype font.
|
||||||
f.ttf, err = truetype.Parse(data)
|
f.ttf, err = truetype.Parse(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -47,3 +47,7 @@ func (gui *GUI) loadFonts(actualWidth int, actualHeight int) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *GUI) updateFontsResolution(actualWidth int, actualHeight int) {
|
||||||
|
gui.fontMap.UpdateResolution(actualWidth, actualHeight)
|
||||||
|
}
|
||||||
|
|
|
@ -321,7 +321,7 @@ func (gui *GUI) resize(w *glfw.Window, width int, height int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.logger.Debugf("Updating font resolutions...")
|
gui.logger.Debugf("Updating font resolutions...")
|
||||||
gui.loadFonts(gui.width, gui.height)
|
gui.updateFontsResolution(gui.width, gui.height)
|
||||||
|
|
||||||
gui.logger.Debugf("Setting renderer area...")
|
gui.logger.Debugf("Setting renderer area...")
|
||||||
gui.renderer.SetArea(0, 0, gui.width-vScrollbarWidth, gui.height)
|
gui.renderer.SetArea(0, 0, gui.width-vScrollbarWidth, gui.height)
|
||||||
|
|
Loading…
Reference in New Issue