mirror of https://github.com/liamg/aminal.git
simplified cursor rendering
This commit is contained in:
parent
54c2aed4a5
commit
e673e72ad9
83
gui/gui.go
83
gui/gui.go
|
@ -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))
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue