Skip to content

Instantly share code, notes, and snippets.

@fivemoreminix
Last active June 28, 2018 18:50
Show Gist options
  • Save fivemoreminix/0cca14d941619d17ed13b6c26b51135d to your computer and use it in GitHub Desktop.
Save fivemoreminix/0cca14d941619d17ed13b6c26b51135d to your computer and use it in GitHub Desktop.
A (currently) incomplete 3d terminal renderer.
package main
import (
"github.com/nsf/termbox-go"
)
func DrawPoint(x, y int, color termbox.Attribute) {
termbox.SetCell(x, y, ' ', termbox.ColorDefault, color)
}
func DrawLine(start, end Vec2, color termbox.Attribute) {
xDif, yDif := end[0]-start[0], end[1]-start[1]
rise, run := yDif/xDif, xDif/yDif
curX, curY := start[0], start[1]
//Log(fmt.Sprintf("Rise/Run : %d/%d", rise, run))
for i := 0; i < xDif; i++ {
curX += run
curY += rise / run
DrawPoint(curX, curY, color)
}
}
func ClearText() {
for x := 0; x < _width; x++ {
for y := 0; y < _height; y++ {
DrawPoint(x, y, termbox.ColorDefault)
}
}
}
func Write(message string, pos Vec2, color termbox.Attribute) {
for i := 0; i < len(message); i++ {
termbox.SetCell(pos[0]+i, pos[1], rune(message[i]), color, termbox.ColorDefault)
}
}
var logs [5]string
func UpdateLogs() {
for i := 0; i < len(logs); i++ {
Write(logs[i], Vec2{0, _height - 1 - i}, termbox.ColorWhite)
}
}
func Log(message string) {
if len(logs) > 0 {
var previousString string
for i := 0; i < len(logs); i++ {
var text string
if i == 0 {
text = message
} else {
text = previousString
}
Write(text, Vec2{0, _height - 1 - i}, termbox.ColorWhite)
previousString = logs[i]
logs[i] = text
}
} else {
Write(message, Vec2{0, _height - 1}, termbox.ColorWhite)
logs[0] = message
}
}
var _width, _height int
type Vec2 [2]int
type Vec3 [3]int
var cubeVerts [8]Vec3
var cubeEdges [12]Vec2
func Begin() {
cubeVerts = [8]Vec3{{-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {-1, 1, -1}, {-1, -1, 1}, {1, -1, 1}, {1, 1, 1}, {-1, 1, 1}}
cubeEdges = [12]Vec2{{0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6}, {6, 7}, {7, 4}, {0, 4}, {1, 5}, {2, 6}, {7, 0}}
}
// Update called every frame
func Update(event termbox.Event) {
cx, cy := _width/2, _height/2
// For every vertice ...
for i := 0; i < len(cubeVerts); i++ {
vert := cubeVerts[i]
vert[2] += 10 // Move the cube forward a little
// Depth
f := _width / vert[2]
vert[0], vert[1] = vert[0]*f, vert[1]*f
DrawPoint(vert[0]+cx, vert[1]+cy, termbox.ColorWhite)
}
// For every edge ...
for i := 0; i < len(cubeEdges); i++ {
edge := cubeEdges[i]
points := make([]Vec2, 0, 2)
connectingPoints := [2]Vec3{cubeVerts[edge[0]], cubeVerts[edge[1]]} // Get connecting points
for j := 0; j < len(connectingPoints); j++ {
point := connectingPoints[j]
point[2] += 10 // Move the cube forward a little
// Depth
f := _width / point[2]
point[0], point[1] = point[0]*f, point[1]*f
points = append(points, Vec2{point[0] + cx, point[1] + cy})
}
DrawLine(points[0], points[1], termbox.ColorWhite)
}
}
/*
func Begin() {
}
func Update(event termbox.Event) {
DrawLine(Vec2{2, 2}, Vec2{_width / 2, _height / 2}, termbox.ColorWhite)
Log("Test")
Log("Hello, world!")
Log("These are fun messages!")
Log("Almost five...")
Log("There!")
UpdateLogs()
}
*/
func main() {
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
_width, _height = termbox.Size()
Begin()
mainloop:
for {
ev := termbox.PollEvent()
switch ev.Type {
case termbox.EventKey:
if ev.Key == termbox.KeyEsc {
break mainloop
}
case termbox.EventResize:
_width, _height = ev.Width, ev.Height
}
// Redraw
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
ClearText()
Update(ev)
termbox.Flush()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment