From 0d2792c82eab08c47fa7a4b1af127c08823d6923 Mon Sep 17 00:00:00 2001 From: bloeys Date: Fri, 1 Jul 2022 10:33:37 +0400 Subject: [PATCH] Improve glyph API --- glyphs/glyphs.go | 30 ++++++++++++++---------- main.go | 61 +++++++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/glyphs/glyphs.go b/glyphs/glyphs.go index 697e4c1..0d5dd85 100755 --- a/glyphs/glyphs.go +++ b/glyphs/glyphs.go @@ -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 } diff --git a/main.go b/main.go index dcaa068..a869270 100755 --- a/main.go +++ b/main.go @@ -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) +}