better rendering

This commit is contained in:
Liam Galvin 2018-09-02 15:13:33 +01:00
parent be60c1d053
commit 450f9f01bc
3 changed files with 42 additions and 69 deletions

View File

@ -24,7 +24,7 @@ type GUI struct {
height int //window height in pixels height int //window height in pixels
font *glfont.Font font *glfont.Font
fontScale float32 fontScale float32
renderer Renderer renderer *OpenGLRenderer
colourAttr uint32 colourAttr uint32
} }
@ -126,7 +126,6 @@ func (gui *GUI) Render() error {
return fmt.Errorf("Failed to load font: %s", err) return fmt.Errorf("Failed to load font: %s", err)
} }
changeChan := make(chan bool, 1)
titleChan := make(chan bool, 1) titleChan := make(chan bool, 1)
gui.renderer = NewOpenGLRenderer(gui.config, gui.font, 0, 0, gui.width, gui.height, gui.colourAttr, program) gui.renderer = NewOpenGLRenderer(gui.config, gui.font, 0, 0, gui.width, gui.height, gui.colourAttr, program)
@ -137,17 +136,11 @@ func (gui *GUI) Render() error {
gui.window.SetScrollCallback(gui.glfwScrollCallback) gui.window.SetScrollCallback(gui.glfwScrollCallback)
gui.window.SetMouseButtonCallback(gui.mouseButtonCallback) gui.window.SetMouseButtonCallback(gui.mouseButtonCallback)
gui.window.SetRefreshCallback(func(w *glfw.Window) { gui.window.SetRefreshCallback(func(w *glfw.Window) {
select { gui.terminal.SetDirty()
case changeChan <- true:
default:
}
}) })
gui.window.SetFocusCallback(func(w *glfw.Window, focused bool) { gui.window.SetFocusCallback(func(w *glfw.Window, focused bool) {
if focused { if focused {
select { gui.terminal.SetDirty()
case changeChan <- true:
default:
}
} }
}) })
w, h := gui.window.GetSize() w, h := gui.window.GetSize()
@ -180,88 +173,71 @@ func (gui *GUI) Render() error {
) )
gui.terminal.AttachTitleChangeHandler(titleChan) gui.terminal.AttachTitleChangeHandler(titleChan)
gui.terminal.AttachDisplayChangeHandler(changeChan) //gui.terminal.AttachDisplayChangeHandler(changeChan)
ticker := time.NewTicker(time.Second) ticker := time.NewTicker(time.Second)
defer ticker.Stop() defer ticker.Stop()
defaultCell := buffer.NewBackgroundCell(gui.config.ColourScheme.Background) defaultCell := buffer.NewBackgroundCell(gui.config.ColourScheme.Background)
go func() {
for {
<-ticker.C
gui.logger.Sync()
}
}()
for !gui.window.ShouldClose() { for !gui.window.ShouldClose() {
dirty := false
select { select {
case <-ticker.C:
gui.logger.Sync()
case <-changeChan:
dirty = true
case <-titleChan: case <-titleChan:
gui.window.SetTitle(gui.terminal.GetTitle()) gui.window.SetTitle(gui.terminal.GetTitle())
default: default:
//glfw.PollEvents()
glfw.WaitEventsTimeout(0.02) // up to 50fps on no input, otherwise higher
} }
if dirty || gui.terminal.CheckDirty() { if gui.terminal.CheckDirty() {
gl.UseProgram(program) //gl.UseProgram(program)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
lines := gui.terminal.GetVisibleLines() lines := gui.terminal.GetVisibleLines()
lineCount := gui.terminal.ActiveBuffer().ViewHeight() lineCount := int(gui.terminal.ActiveBuffer().ViewHeight())
colCount := gui.terminal.ActiveBuffer().ViewWidth() colCount := int(gui.terminal.ActiveBuffer().ViewWidth())
for x := 0; x < int(colCount); x++ { for y := 0; y < lineCount; y++ {
for y := 0; y < int(lineCount); y++ { for x := 0; x < colCount; x++ {
cell := defaultCell cell := defaultCell
hasText := false
if y < len(lines) { if y < len(lines) {
cells := lines[y].Cells() cells := lines[y].Cells()
if x < len(cells) { if x < len(cells) {
cell = cells[x] cell = cells[x]
//if cell.Rune() == 0 { if cell.Rune() != 0 && cell.Rune() != 32 {
// cell = defaultCell hasText = true
//}
}
}
gui.renderer.DrawCellBg(cell, uint(x), uint(y))
}
}
for x := 0; x < int(colCount); x++ {
for y := 0; y < int(lineCount); y++ {
cell := defaultCell
if y < len(lines) {
cells := lines[y].Cells()
if x < len(cells) {
cell = cells[x]
if cell.Rune() == 0 {
continue
} }
} }
} }
gui.renderer.DrawCellText(cell, uint(x), uint(y)) cursor := false
if gui.terminal.Modes().ShowCursor {
cx := uint(gui.terminal.GetLogicalCursorX())
cy := uint(gui.terminal.GetLogicalCursorY())
cy = cy + uint(gui.terminal.GetScrollOffset())
cursor = cx == uint(x) && cy == uint(y)
}
gui.renderer.DrawCellBg(cell, uint(x), uint(y), cursor)
if hasText {
gui.renderer.DrawCellText(cell, uint(x), uint(y))
}
} }
} }
if gui.terminal.Modes().ShowCursor {
cx := uint(gui.terminal.GetLogicalCursorX())
cy := uint(gui.terminal.GetLogicalCursorY())
cy = cy + uint(gui.terminal.GetScrollOffset())
gui.renderer.DrawCursor(cx, cy, gui.config.ColourScheme.Cursor)
}
gui.window.SwapBuffers() gui.window.SwapBuffers()
} }
//glfw.PollEvents()
glfw.WaitEventsTimeout(0.02) // up to 50fps on no input, otherwise higher
} }
gui.logger.Debugf("Stopping render...") gui.logger.Debugf("Stopping render...")

View File

@ -9,16 +9,6 @@ import (
"gitlab.com/liamg/raft/glfont" "gitlab.com/liamg/raft/glfont"
) )
type Renderer interface {
SetArea(areaX int, areaY int, areaWidth int, areaHeight int)
DrawCellBg(cell buffer.Cell, col uint, row uint)
DrawCellText(cell buffer.Cell, col uint, row uint)
DrawCursor(col uint, row uint, colour config.Colour)
GetTermSize() (uint, uint)
CellWidth() float32
CellHeight() float32
}
type OpenGLRenderer struct { type OpenGLRenderer struct {
font *glfont.Font font *glfont.Font
areaWidth int areaWidth int
@ -200,11 +190,13 @@ func (r *OpenGLRenderer) DrawCursor(col uint, row uint, colour config.Colour) {
rect.Draw() rect.Draw()
} }
func (r *OpenGLRenderer) DrawCellBg(cell buffer.Cell, col uint, row uint) { func (r *OpenGLRenderer) DrawCellBg(cell buffer.Cell, col uint, row uint, cursor bool) {
var bg [3]float32 var bg [3]float32
if cell.Attr().Reverse { if cursor {
bg = r.config.ColourScheme.Cursor
} else if cell.Attr().Reverse {
bg = cell.Fg() bg = cell.Fg()
} else { } else {
bg = cell.Bg() bg = cell.Bg()

View File

@ -89,6 +89,7 @@ func New(pty *os.File, logger *zap.SugaredLogger, config *config.Config) *Termin
ShowCursor: true, ShowCursor: true,
}, },
} }
} }
func (terminal *Terminal) CheckDirty() bool { func (terminal *Terminal) CheckDirty() bool {
@ -97,6 +98,10 @@ func (terminal *Terminal) CheckDirty() bool {
return d return d
} }
func (terminal *Terminal) SetDirty() {
terminal.isDirty = true
}
func (terminal *Terminal) IsApplicationCursorKeysModeEnabled() bool { func (terminal *Terminal) IsApplicationCursorKeysModeEnabled() bool {
return terminal.modes.ApplicationCursorKeys return terminal.modes.ApplicationCursorKeys
} }