Improve glyph API

This commit is contained in:
bloeys
2022-07-01 10:33:37 +04:00
parent 224f33bf9f
commit 0d2792c82e
2 changed files with 55 additions and 36 deletions

View File

@ -1,7 +1,6 @@
package glyphs
import (
"math/rand"
"os"
"unicode"
@ -24,6 +23,9 @@ type GlyphRend struct {
GlyphCount int32
GlyphVBO []float32
ScreenWidth int32
ScreenHeight int32
}
//getGlyphRanges returns a list of ranges, each range is: [i][0]<=range<[i][1]
@ -74,10 +76,10 @@ func getGlyphsFromRanges(ranges [][2]rune) []rune {
return out
}
func (gr *GlyphRend) DrawTextOpenGL(text string, startPos *gglm.Vec3, winWidth, winHeight int32) {
func (gr *GlyphRend) DrawTextOpenGL(text string, screenPos *gglm.Vec3, color *gglm.Vec4) {
//The projection matrix fits the screen size. This is needed so we can size and position characters correctly.
projMtx := gglm.Ortho(0, float32(winWidth), float32(winHeight), 0, 0.1, 10)
projMtx := gglm.Ortho(0, float32(gr.ScreenWidth), float32(gr.ScreenHeight), 0, 0.1, 10)
viewMtx := gglm.LookAt(gglm.NewVec3(0, 0, -1), gglm.NewVec3(0, 0, 0), gglm.NewVec3(0, 1, 0))
projViewMtx := projMtx.Clone().Mul(viewMtx)
@ -89,19 +91,15 @@ func (gr *GlyphRend) DrawTextOpenGL(text string, startPos *gglm.Vec3, winWidth,
rs := []rune(text)
const floatsPerGlyph = 18
rCol := rand.Float32()
gCol := rand.Float32()
bCol := rand.Float32()
pos := startPos.Clone()
pos := screenPos.Clone()
instancedData := make([]float32, 0, len(rs)*floatsPerGlyph) //This a larger approximation than needed because we don't count spaces etc
for i := 0; i < len(rs); i++ {
r := rs[i]
g := gr.Atlas.Glyphs[r]
if r == '\n' {
startPos.SetY(startPos.Y() - float32(gr.Atlas.LineHeight))
pos = startPos.Clone()
screenPos.SetY(screenPos.Y() - float32(gr.Atlas.LineHeight))
pos = screenPos.Clone()
continue
}
gr.GlyphCount++
@ -125,7 +123,7 @@ func (gr *GlyphRend) DrawTextOpenGL(text string, startPos *gglm.Vec3, winWidth,
g.U, g.V + g.SizeV,
g.U + g.SizeU, g.V + g.SizeV,
rCol, gCol, bCol, 1, //Color
color.R(), color.G(), color.B(), color.A(), //Color
drawPos.X(), drawPos.Y(), drawPos.Z(), //Model pos
scale.X(), scale.Y(), scale.Z(), //Model scale
}...)
@ -165,7 +163,12 @@ func (gr *GlyphRend) SetFontFromFile(fontFile string, fontOptions *truetype.Opti
return nil
}
func NewGlyphRend(fontFile string, fontOptions *truetype.Options) (*GlyphRend, error) {
func (gr *GlyphRend) SetScreenSize(screenWidth, screenHeight int32) {
gr.ScreenWidth = screenWidth
gr.ScreenHeight = screenHeight
}
func NewGlyphRend(fontFile string, fontOptions *truetype.Options, screenWidth, screenHeight int32) (*GlyphRend, error) {
atlas, err := NewFontAtlasFromFile(fontFile, fontOptions)
if err != nil {
@ -293,5 +296,8 @@ func NewGlyphRend(fontFile string, fontOptions *truetype.Options) (*GlyphRend, e
GlyphCount: 0,
GlyphVBO: make([]float32, 0),
ScreenWidth: screenWidth,
ScreenHeight: screenHeight,
}, nil
}

61
main.go
View File

@ -2,7 +2,6 @@ package main
import (
"fmt"
"sync"
"time"
"github.com/bloeys/gglm/gglm"
@ -22,6 +21,9 @@ type program struct {
win *engine.Window
rend *rend3dgl.Rend3DGL
imguiInfo nmageimgui.ImguiInfo
FontSize uint32
GlyphRend *glyphs.GlyphRend
}
//nMage TODO:
@ -30,6 +32,7 @@ type program struct {
// * Move SetAttribute away from material struct
// * Fix FPS counter
// * Allow texture loading without cache
// * Reduce/remove Game interface
func main() {
@ -51,18 +54,28 @@ func main() {
win: win,
rend: rend,
imguiInfo: nmageimgui.NewImGUI(),
FontSize: 32,
}
p.win.EventCallbacks = append(p.win.EventCallbacks, func(e sdl.Event) {
switch e := e.(type) {
case *sdl.WindowEvent:
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
p.handleWindowResize()
}
}
})
engine.Run(p)
}
var fontPointSize uint = 32
var glyphRend *glyphs.GlyphRend
func (p *program) Init() {
w, h := p.win.SDLWin.GetSize()
var err error
glyphRend, err = glyphs.NewGlyphRend("./res/fonts/Consolas.ttf", &truetype.Options{Size: float64(fontPointSize), DPI: 72})
p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/Consolas.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: 72}, w, h)
if err != nil {
panic("Failed to create atlas from font file. Err: " + err.Error())
}
@ -87,52 +100,47 @@ func (p *program) Update() {
fontSizeChanged := false
if input.KeyClicked(sdl.K_KP_PLUS) {
fontPointSize += 2
p.FontSize += 2
fontSizeChanged = true
} else if input.KeyClicked(sdl.K_KP_MINUS) {
fontPointSize -= 2
p.FontSize -= 2
fontSizeChanged = true
}
if fontSizeChanged {
glyphRend.SetFace(&truetype.Options{Size: float64(fontPointSize), DPI: 72})
p.GlyphRend.SetFace(&truetype.Options{Size: float64(p.FontSize), DPI: 72})
}
}
var gg = sync.Once{}
func (p *program) Render() {
w, h := p.win.SDLWin.GetSize()
textColor := gglm.NewVec4(1, 1, 1, 1)
//Draw FPS
var fps float32
if frameTime.Milliseconds() > 0 {
fps = 1 / float32(frameTime.Milliseconds()) * 1000
}
startFromTop := float32(h) - float32(glyphRend.Atlas.LineHeight)
glyphRend.DrawTextOpenGL(fmt.Sprintf("FPS=%f", fps), gglm.NewVec3(float32(w)*0.7, startFromTop, 0), w, h)
startFromTop := float32(h) - float32(p.GlyphRend.Atlas.LineHeight)
p.GlyphRend.DrawTextOpenGL(fmt.Sprintf("FPS=%f", fps), gglm.NewVec3(float32(w)*0.7, startFromTop, 0), textColor)
//Draw point and texture sizes
startFromTop -= float32(glyphRend.Atlas.LineHeight)
glyphRend.DrawTextOpenGL(fmt.Sprintf("Point size=%d", fontPointSize), gglm.NewVec3(float32(w)*0.7, startFromTop, 0), w, h)
startFromTop -= float32(p.GlyphRend.Atlas.LineHeight)
p.GlyphRend.DrawTextOpenGL(fmt.Sprintf("Point size=%d", p.FontSize), gglm.NewVec3(float32(w)*0.7, startFromTop, 0), textColor)
startFromTop -= float32(glyphRend.Atlas.LineHeight)
glyphRend.DrawTextOpenGL(fmt.Sprintf("Texture size=%d*%d", glyphRend.Atlas.Img.Rect.Max.X, glyphRend.Atlas.Img.Rect.Max.Y), gglm.NewVec3(float32(w)*0.7, startFromTop, 0), w, h)
startFromTop -= float32(p.GlyphRend.Atlas.LineHeight)
p.GlyphRend.DrawTextOpenGL(fmt.Sprintf("Texture size=%d*%d", p.GlyphRend.Atlas.Img.Rect.Max.X, p.GlyphRend.Atlas.Img.Rect.Max.Y), gglm.NewVec3(float32(w)*0.7, startFromTop, 0), textColor)
//Draw all other
count := 1000
startFromBot := float32(glyphRend.Atlas.LineHeight)
startFromBot := float32(p.GlyphRend.Atlas.LineHeight)
for i := 0; i < count; i++ {
glyphRend.DrawTextOpenGL("Hello friend, how are you?\n", gglm.NewVec3(0, startFromBot, 0), w, h)
startFromBot += float32(glyphRend.Atlas.LineHeight) * 2
p.GlyphRend.DrawTextOpenGL("Hello friend, how are you?\n", gglm.NewVec3(0, startFromBot, 0), textColor)
startFromBot += float32(p.GlyphRend.Atlas.LineHeight) * 2
}
gg.Do(func() {
fmt.Printf("Drawn chars: %d\n", glyphRend.GlyphCount)
})
glyphRend.Draw()
p.GlyphRend.Draw()
}
func (p *program) FrameEnd() {
@ -154,3 +162,8 @@ func (p *program) ShouldRun() bool {
func (p *program) Deinit() {
}
func (p *program) handleWindowResize() {
w, h := p.win.SDLWin.GetSize()
p.GlyphRend.SetScreenSize(w, h)
}