From d23e833b54d2d8ae665d588741c5d975dbd0e7b2 Mon Sep 17 00:00:00 2001 From: bloeys Date: Wed, 6 Jul 2022 17:53:55 +0400 Subject: [PATCH] Use texelFetch+debug grid in atlas --- glyphs/font_atlas.go | 47 ++++++++++++++++++++++++++++++++++++------ glyphs/glyphs.go | 4 ++-- main.go | 6 ++---- res/shaders/glyph.glsl | 3 ++- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/glyphs/font_atlas.go b/glyphs/font_atlas.go index d2a74ee..ded0068 100755 --- a/glyphs/font_atlas.go +++ b/glyphs/font_atlas.go @@ -3,6 +3,7 @@ package glyphs import ( "errors" "image" + "image/color" "image/draw" "image/png" "math" @@ -118,7 +119,7 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo } //Create atlas - atlasSizeXF32 := float32(atlasSizeX) + // atlasSizeXF32 := float32(atlasSizeX) atlasSizeYF32 := float32(atlasSizeY) atlas := &FontAtlas{ Font: f, @@ -127,7 +128,8 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo Advance: charAdv - charPaddingX, LineHeight: lineHeight, - SizeUV: *gglm.NewVec2(float32(charAdv-charPaddingX)/atlasSizeXF32, float32(lineHeight)/atlasSizeYF32), + SizeUV: *gglm.NewVec2(float32(charAdv-charPaddingX), float32(lineHeight)), + // SizeUV: *gglm.NewVec2(float32(charAdv-charPaddingX)/atlasSizeXF32, float32(lineHeight)/atlasSizeYF32), } //Clear background to black @@ -144,6 +146,9 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo charsOnLine := 0 drawer.Dot = fixed.P(atlas.Advance+charPaddingX, lineHeight) + + drawHorizontalLines := true + drawVerticalLines := true for _, g := range glyphs { gBounds, _, _ := face.GlyphBounds(g) @@ -152,8 +157,10 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo bearingX := absFixedI26_6(gBounds.Min.X) atlas.Glyphs[g] = FontAtlasGlyph{ - U: float32((drawer.Dot.X).Floor()) / atlasSizeXF32, - V: (atlasSizeYF32 - float32((drawer.Dot.Y).Ceil())) / atlasSizeYF32, + U: float32((drawer.Dot.X).Floor()), + V: (atlasSizeYF32 - float32((drawer.Dot.Y).Ceil())), + // U: float32((drawer.Dot.X).Floor()) / atlasSizeXF32, + // V: (atlasSizeYF32 - float32((drawer.Dot.Y).Ceil())) / atlasSizeYF32, Ascent: float32(ascent.Ceil()), Descent: float32(descent.Ceil()), @@ -162,20 +169,48 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo //Get glyph to draw but undo any applied descent so that the glyph is drawn sitting on the line exactly. //Bearing will be applied correctly but descent will be the responsibility of the positioning code - imgRect, mask, maskp, gAdvanceFixed, _ := face.Glyph(drawer.Dot, g) + imgRect, mask, maskp, _, _ := face.Glyph(drawer.Dot, g) if imgRect.Max.Y > drawer.Dot.Y.Ceil() { diff := imgRect.Max.Y - drawer.Dot.Y.Ceil() imgRect.Min.Y -= diff imgRect.Max.Y -= diff } + if drawVerticalLines { + rectCopy := imgRect + rectCopy.Min.Y = 0 + rectCopy.Max.Y = drawer.Dst.Bounds().Max.Y + rectCopy.Max.X = rectCopy.Min.X + 1 + oldPos := drawer.Dot + drawer.Dot.Y = 0 + // fmt.Printf("Drawing with maskP %s\n", maskp.String()) + draw.Draw(drawer.Dst, rectCopy, image.NewUniform(color.NRGBA{G: 255, A: 255}), image.Point{}, draw.Over) + drawer.Dot = oldPos + } + //Draw glyph and advance dot draw.DrawMask(drawer.Dst, imgRect, drawer.Src, image.Point{}, mask, maskp, draw.Over) - drawer.Dot.X += fixed.I(gAdvanceFixed.Ceil()) + charPaddingXFixed + drawer.Dot.X += fixed.I(atlas.Advance) + charPaddingXFixed charsOnLine++ if charsOnLine == charsPerLine { + if drawHorizontalLines { + rectCopy := imgRect + rectCopy.Min.X = 0 + rectCopy.Max.X = drawer.Dst.Bounds().Max.X + + // rectCopy.Min.Y += (lineHeightFixed + charPaddingYFixed).Floor() * 1 + rectCopy.Max.Y = rectCopy.Min.Y + 1 + + oldPos := drawer.Dot + drawer.Dot.X = 0 + draw.Draw(drawer.Dst, rectCopy, image.NewUniform(color.NRGBA{G: 255, A: 255}), image.Point{}, draw.Over) + drawer.Dot = oldPos + + drawVerticalLines = false + } + charsOnLine = 0 drawer.Dot.X = fixed.I(atlas.Advance) + charPaddingXFixed drawer.Dot.Y += lineHeightFixed + charPaddingYFixed diff --git a/glyphs/glyphs.go b/glyphs/glyphs.go index ae39e83..a52562f 100755 --- a/glyphs/glyphs.go +++ b/glyphs/glyphs.go @@ -137,8 +137,8 @@ func (gr *GlyphRend) DrawTextOpenGLAbs(text string, screenPos *gglm.Vec3, color gr.GlyphVBO[buffIndex+5] = color.A() //Model Pos - gr.GlyphVBO[buffIndex+6] = roundF32(drawPos.X()) - gr.GlyphVBO[buffIndex+7] = roundF32(drawPos.Y()) + gr.GlyphVBO[buffIndex+6] = drawPos.X() + gr.GlyphVBO[buffIndex+7] = drawPos.Y() gr.GlyphVBO[buffIndex+8] = drawPos.Z() //Model Scale diff --git a/main.go b/main.go index ea73721..4157194 100755 --- a/main.go +++ b/main.go @@ -90,7 +90,7 @@ func (p *program) Init() { fmt.Printf("DPI: %f, font size: %d\n", dpi, p.FontSize) w, h := p.win.SDLWin.GetSize() - p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/KawkabMono-Regular.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h) + p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/Consolas.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h) if err != nil { panic("Failed to create atlas from font file. Err: " + err.Error()) } @@ -175,8 +175,6 @@ var b = rand.Float32() func (p *program) Render() { - // println("Will profile with pprof...") - defer p.GlyphRend.Draw() if p.shouldDrawGrid { @@ -201,7 +199,7 @@ func (p *program) Render() { textColor := gglm.NewVec4(r, g, b, 1) // str := "مرحبا بك my friend" - str := " hello there يا friend. أسمي عمر wow" + str := " hello there يا friend. سمي عمر wow" // str := " ijojo\n\n Hello there, friend|. pq?\n ABCDEFG\tHIJKLMNOPQRSTUVWXYZ\nمرحبا بك" // str := " ijojo\n\n Hello there, friend|. pq?\n ABCDEFG\tHIJKLMNOPQRSTUVWXYZ" diff --git a/res/shaders/glyph.glsl b/res/shaders/glyph.glsl index 17bc197..8dbf9cf 100755 --- a/res/shaders/glyph.glsl +++ b/res/shaders/glyph.glsl @@ -45,7 +45,8 @@ uniform sampler2D diffTex; void main() { - vec4 texColor = texture(diffTex, v2fUV0); + vec4 texColor = texelFetch(diffTex, ivec2(v2fUV0), 0); + // vec4 texColor = texture(diffTex, v2fUV0); // if (texColor.r == 0) // { // fragColor = vec4(0,1,0,0.25);