simplified cursor rendering

This commit is contained in:
Liam Galvin 2018-08-31 20:24:58 +01:00
parent 54c2aed4a5
commit e673e72ad9
7 changed files with 71 additions and 134 deletions

View File

@ -5,7 +5,7 @@ import (
"runtime"
"time"
"github.com/liamg/glfont"
"gitlab.com/liamg/raft/glfont"
"github.com/go-gl/gl/all-core/gl"
"github.com/go-gl/glfw/v3.2/glfw"
@ -16,30 +16,28 @@ import (
)
type GUI struct {
window *glfw.Window
logger *zap.SugaredLogger
config *config.Config
terminal *terminal.Terminal
width int //window width in pixels
height int //window height in pixels
font *glfont.Font
fontScale int32
renderer Renderer
colourAttr uint32
renderState *RenderState
window *glfw.Window
logger *zap.SugaredLogger
config *config.Config
terminal *terminal.Terminal
width int //window width in pixels
height int //window height in pixels
font *glfont.Font
fontScale int32
renderer Renderer
colourAttr uint32
}
func New(config *config.Config, terminal *terminal.Terminal, logger *zap.SugaredLogger) *GUI {
//logger.
return &GUI{
config: config,
logger: logger,
width: 600,
height: 300,
terminal: terminal,
fontScale: 15.0,
renderState: NewRenderState(),
config: config,
logger: logger,
width: 600,
height: 300,
terminal: terminal,
fontScale: 15.0,
}
}
@ -73,9 +71,6 @@ func (gui *GUI) resize(w *glfw.Window, width int, height int) {
gui.logger.Errorf("Failed to resize terminal to %d cols, %d rows: %s", cols, rows, err)
}
gui.logger.Debugf("Resetting render state...")
gui.renderState.Reset()
gui.logger.Debugf("Setting viewport size...")
gl.Viewport(0, 0, int32(gui.width), int32(gui.height))
@ -192,9 +187,6 @@ func (gui *GUI) Render() error {
defaultCell := buffer.NewBackgroundCell(gui.config.ColourScheme.Background)
var lastCursorX uint
var lastCursorY uint
for !gui.window.ShouldClose() {
dirty := false
@ -210,29 +202,16 @@ func (gui *GUI) Render() error {
default:
}
gl.UseProgram(program)
if dirty || gui.terminal.CheckDirty() {
gl.UseProgram(program)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
if gui.terminal.Modes().ShowCursor {
cx := uint(gui.terminal.GetLogicalCursorX())
cy := uint(gui.terminal.GetLogicalCursorY())
cy = cy + uint(gui.terminal.GetScrollOffset())
if lastCursorX != cx || lastCursorY != cy {
gui.renderState.SetDirty(lastCursorX, lastCursorY)
dirty = true
}
}
lines := gui.terminal.GetVisibleLines()
lineCount := gui.terminal.ActiveBuffer().ViewHeight()
colCount := gui.terminal.ActiveBuffer().ViewWidth()
for y := 0; y < int(lineCount); y++ {
for x := 0; x < int(colCount); x++ {
for x := 0; x < int(colCount); x++ {
for y := 0; y < int(lineCount); y++ {
cell := defaultCell
@ -246,7 +225,27 @@ func (gui *GUI) Render() error {
}
}
gui.renderer.DrawCell(cell, uint(x), uint(y))
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 {
cell = defaultCell
}
}
}
gui.renderer.DrawCellText(cell, uint(x), uint(y))
}
}

View File

@ -5,14 +5,15 @@ import (
"math"
"github.com/go-gl/gl/all-core/gl"
"github.com/liamg/glfont"
"gitlab.com/liamg/raft/buffer"
"gitlab.com/liamg/raft/config"
"gitlab.com/liamg/raft/glfont"
)
type Renderer interface {
SetArea(areaX int, areaY int, areaWidth int, areaHeight int)
DrawCell(cell buffer.Cell, col uint, row uint)
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)
}
@ -89,6 +90,12 @@ func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) *
return rect
}
func (rect *rectangle) Draw() {
gl.UseProgram(rect.prog)
gl.BindVertexArray(rect.vao)
gl.DrawArrays(gl.TRIANGLES, 0, 6)
}
func (rect *rectangle) setColour(colour [3]float32) {
if rect.colour == colour {
return
@ -199,55 +206,44 @@ func (r *OpenGLRenderer) generateRectangle(col uint, line uint) *rectangle {
}
func (r *OpenGLRenderer) DrawCursor(col uint, row uint, colour config.Colour) {
rect, ok := r.rectangles[[2]uint{col, row}]
if !ok { // probably trying to draw during resize - perhaps add a mutex?
return
}
solid := true
mode := uint32(gl.LINE_LOOP) // gl.TRIANGES for solid cursor
points := int32(4)
if solid {
mode = gl.TRIANGLES
points = 6
}
gl.UseProgram(r.program)
rect := r.getRectangle(col, row)
rect.setColour(colour)
gl.BindVertexArray(rect.vao)
//gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
gl.DrawArrays(mode, 0, points)
//gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
rect.Draw()
}
func (r *OpenGLRenderer) DrawCell(cell buffer.Cell, col uint, row uint) {
func (r *OpenGLRenderer) DrawCellBg(cell buffer.Cell, col uint, row uint) {
var fg [3]float32
var bg [3]float32
if cell.Attr().Reverse {
fg = cell.Bg()
bg = cell.Fg()
} else {
fg = cell.Fg()
bg = cell.Bg()
}
if bg != r.config.ColourScheme.Background {
rect := r.getRectangle(col, row)
rect.setColour(bg)
rect.Draw()
}
}
func (r *OpenGLRenderer) DrawCellText(cell buffer.Cell, col uint, row uint) {
var fg [3]float32
if cell.Attr().Reverse {
fg = cell.Bg()
} else {
fg = cell.Fg()
}
pos, ok := r.cellPositions[[2]uint{col, row}]
if !ok {
panic(fmt.Sprintf("Missing position data for cell at %d,%d", col, row))
}
rect := r.getRectangle(col, row)
rect.setColour(bg)
gl.UseProgram(r.program)
gl.BindVertexArray(rect.vao)
gl.DrawArrays(gl.TRIANGLES, 0, 6)
var alpha float32 = 1
if cell.Attr().Dim {
alpha = 0.5

View File

@ -1,58 +0,0 @@
package gui
type RenderState struct {
cells map[[2]uint]RenderedCell
}
func NewRenderState() *RenderState {
return &RenderState{
cells: map[[2]uint]RenderedCell{},
}
}
type RenderedCell struct {
bg [3]float32
fg [3]float32
contents rune
dirty bool
}
func (rs *RenderState) Reset() {
rs.cells = map[[2]uint]RenderedCell{}
}
func (rs *RenderState) SetDirty(x uint, y uint) {
rs.cells[[2]uint{x, y}] = RenderedCell{
bg: [3]float32{0, 0, 0},
fg: [3]float32{0, 0, 0},
contents: 0,
dirty: true,
}
}
func (rs *RenderState) RequiresRender(x uint, y uint, bg [3]float32, fg [3]float32, contents rune, empty bool) bool {
state, found := rs.cells[[2]uint{x, y}]
if !found {
if empty {
//return false
}
rs.cells[[2]uint{x, y}] = RenderedCell{
bg: bg,
fg: fg,
contents: contents,
}
return true
}
if state.bg != bg || state.fg != fg || state.contents != contents || state.dirty {
rs.cells[[2]uint{x, y}] = RenderedCell{
bg: bg,
fg: fg,
contents: contents,
}
return true
}
return false
}