Setting up render2
This commit is contained in:
parent
c12f5c9218
commit
de0691d28e
@ -12,7 +12,7 @@ const (
|
|||||||
Width = 512
|
Width = 512
|
||||||
Height = 512
|
Height = 512
|
||||||
ObjectFile = "head.obj"
|
ObjectFile = "head.obj"
|
||||||
Repeat = 1_000
|
Repeat = 100_000
|
||||||
)
|
)
|
||||||
|
|
||||||
func must(err error) {
|
func must(err error) {
|
||||||
@ -41,44 +41,45 @@ func main() {
|
|||||||
|
|
||||||
fb := NewFramebuffer(Width, Height)
|
fb := NewFramebuffer(Width, Height)
|
||||||
|
|
||||||
log.Printf("Loading obj %s", ObjectFile)
|
/*
|
||||||
|
log.Printf("Loading obj %s", ObjectFile)
|
||||||
|
|
||||||
of, err := os.Open(ObjectFile)
|
of, err := os.Open(ObjectFile)
|
||||||
must(err)
|
must(err)
|
||||||
defer of.Close()
|
defer of.Close()
|
||||||
o, err := ParseObj(of)
|
o, err := ParseObj(of)
|
||||||
must(err)
|
must(err)
|
||||||
|
*/
|
||||||
|
|
||||||
log.Printf("Running render")
|
log.Printf("Running render")
|
||||||
|
|
||||||
halfwidth := float32(fb.Width / 2)
|
//halfwidth := float32(fb.Width / 2)
|
||||||
halfheight := float32(fb.Height / 2)
|
//halfheight := float32(fb.Height / 2)
|
||||||
|
|
||||||
var x [3]int
|
|
||||||
var y [3]int
|
|
||||||
var hi = int(fb.Height - 1)
|
|
||||||
for range Repeat {
|
for range Repeat {
|
||||||
for _, f := range o.Faces {
|
Triangle1(&fb, 0xFF0000, Vec2i{10, 70}, Vec2i{50, 160}, Vec2i{70, 80})
|
||||||
// Precompute perspective for vertices to save time. Notice Z
|
Triangle1(&fb, 0xFFFFFF, Vec2i{180, 50}, Vec2i{150, 1}, Vec2i{70, 180})
|
||||||
// is not considered: is this orthographic projection? Yeah probably...
|
Triangle1(&fb, 0x00FF00, Vec2i{180, 150}, Vec2i{120, 160}, Vec2i{130, 180})
|
||||||
for i := range 3 { // Triangles, bro
|
|
||||||
x[i] = int((f[i].X + 1) * halfwidth)
|
|
||||||
y[i] = hi - int((f[i].Y+1)*halfheight)
|
|
||||||
}
|
|
||||||
Bresenham2(&fb, 0xFFFFFF, x[0], y[0], x[1], y[1])
|
|
||||||
Bresenham2(&fb, 0xFFFFFF, x[1], y[1], x[2], y[2])
|
|
||||||
Bresenham2(&fb, 0xFFFFFF, x[2], y[2], x[0], y[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just draw a simple line (a million times or something)
|
|
||||||
// // LineDumb5(&fb, 0xFFFFFF, 100, 100, 350, 200)
|
|
||||||
// // LineDumb5(&fb, 0xFF0000, 120, 100, 200, 350)
|
|
||||||
// // LineDumb5(&fb, 0xFF0000, 350, 200, 100, 100) // backward first line
|
|
||||||
// Bresenham2(&fb, 0xFFFFFF, 100, 100, 350, 200)
|
|
||||||
// Bresenham2(&fb, 0xFF0000, 120, 100, 200, 350)
|
|
||||||
// Bresenham2(&fb, 0xFF0000, 350, 200, 100, 100) // backward first line
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
var x [3]int
|
||||||
|
var y [3]int
|
||||||
|
var hi = int(fb.Height - 1)
|
||||||
|
for range Repeat {
|
||||||
|
for _, f := range o.Faces {
|
||||||
|
// Precompute perspective for vertices to save time. Notice Z
|
||||||
|
// is not considered: is this orthographic projection? Yeah probably...
|
||||||
|
for i := range 3 { // Triangles, bro
|
||||||
|
x[i] = int((f[i].X + 1) * halfwidth)
|
||||||
|
y[i] = hi - int((f[i].Y+1)*halfheight)
|
||||||
|
}
|
||||||
|
Bresenham2(&fb, 0xFFFFFF, x[0], y[0], x[1], y[1])
|
||||||
|
Bresenham2(&fb, 0xFFFFFF, x[1], y[1], x[2], y[2])
|
||||||
|
Bresenham2(&fb, 0xFFFFFF, x[2], y[2], x[0], y[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
log.Printf("Exporting ppm to stdout")
|
log.Printf("Exporting ppm to stdout")
|
||||||
fmt.Print(fb.ExportPPM())
|
fmt.Print(fb.ExportPPM())
|
||||||
|
|
||||||
|
@ -13,6 +13,10 @@ type Vec3f struct {
|
|||||||
X, Y, Z float32
|
X, Y, Z float32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Vec2i struct {
|
||||||
|
X, Y int
|
||||||
|
}
|
||||||
|
|
||||||
type Facef [3]Vec3f
|
type Facef [3]Vec3f
|
||||||
|
|
||||||
type ObjModel struct {
|
type ObjModel struct {
|
||||||
|
@ -4,161 +4,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Draw a line using dumb
|
|
||||||
func LineDumb(fb *Framebuffer, color uint, x0 uint, y0 uint, x1 uint, y1 uint) {
|
|
||||||
var t float32
|
|
||||||
for t = 0; t < 1; t += 0.01 {
|
|
||||||
// Very simple interpolation between x and y
|
|
||||||
x := x0 + uint(float32(x1-x0)*t)
|
|
||||||
y := y0 + uint(float32(y1-y0)*t)
|
|
||||||
fb.Set(x, y, color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LineDumb2(fb *Framebuffer, color uint, x0 uint, y0 uint, x1 uint, y1 uint) {
|
|
||||||
for x := x0; x < x1; x++ {
|
|
||||||
// For each pixel across, compute how far across we are and interpolate y
|
|
||||||
t := float32(x-x0) / float32(x1-x0)
|
|
||||||
y := uint(float32(y0)*(1-t) + float32(y1)*t)
|
|
||||||
fb.Set(x, y, color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LineDumb3(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
|
||||||
steep := false
|
|
||||||
// This one makes sure that going pixel by pixel will not make holes in the
|
|
||||||
// other direction by always moving in the less steep direction.
|
|
||||||
if math.Abs(float64(x0-x1)) < math.Abs(float64(y0-y1)) {
|
|
||||||
x0, y0 = y0, x0
|
|
||||||
x1, y1 = y1, x1
|
|
||||||
steep = true
|
|
||||||
}
|
|
||||||
// Don't let lines be invisible, always go left to right
|
|
||||||
if x0 > x1 { // need to be left to right
|
|
||||||
x0, x1 = x1, x0
|
|
||||||
y0, y1 = y1, y0 // Why are we swapping these? I guess because we're swapping the points...
|
|
||||||
}
|
|
||||||
// Same as dumb2, going across pixel by pixel. But "x" here might actually be y
|
|
||||||
// because of the inverted direction
|
|
||||||
for x := x0; x <= x1; x++ {
|
|
||||||
t := float32(x-x0) / float32(x1-x0)
|
|
||||||
y := uint(float32(y0)*(1-t) + float32(y1)*t)
|
|
||||||
if steep {
|
|
||||||
fb.Set(y, uint(x), color)
|
|
||||||
} else {
|
|
||||||
fb.Set(uint(x), y, color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LineDumb4(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
|
||||||
steep := false
|
|
||||||
// This one makes sure that going pixel by pixel will not make holes in the
|
|
||||||
// other direction by always moving in the less steep direction.
|
|
||||||
if math.Abs(float64(x1-x0)) < math.Abs(float64(y1-y0)) {
|
|
||||||
x0, y0 = y0, x0
|
|
||||||
x1, y1 = y1, x1
|
|
||||||
steep = true
|
|
||||||
}
|
|
||||||
// Don't let lines be invisible, always go left to right
|
|
||||||
if x0 > x1 { // need to be left to right
|
|
||||||
x0, x1 = x1, x0
|
|
||||||
y0, y1 = y1, y0 // Why are we swapping these? I guess because we're swapping the points...
|
|
||||||
}
|
|
||||||
dx := x1 - x0 // These MUST be POST calcs
|
|
||||||
dy := y1 - y0
|
|
||||||
// Delta error or something? Basically, as we move in one direction, we get farther
|
|
||||||
// and farther off course if we never move in the OTHER direction. This is the amount
|
|
||||||
// of that per x direction.
|
|
||||||
derror := math.Abs(float64(dy) / float64(dx))
|
|
||||||
y := uint(y0)
|
|
||||||
var err float64
|
|
||||||
// Same as dumb2, going across pixel by pixel. But "x" here might actually be y
|
|
||||||
// because of the inverted direction
|
|
||||||
for x := x0; x <= x1; x++ {
|
|
||||||
if steep {
|
|
||||||
fb.Set(y, uint(x), color)
|
|
||||||
} else {
|
|
||||||
fb.Set(uint(x), y, color)
|
|
||||||
}
|
|
||||||
err += derror
|
|
||||||
if err > 0.5 {
|
|
||||||
if y1 > y0 {
|
|
||||||
y += 1
|
|
||||||
} else {
|
|
||||||
y = y - 1
|
|
||||||
}
|
|
||||||
err -= 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For not-steep lines
|
|
||||||
func BresenhamLow(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
|
||||||
dx := x1 - x0
|
|
||||||
dy := y1 - y0
|
|
||||||
yi := 1 // This is the increment
|
|
||||||
if dy < 0 { // Line moves in opposite vertical direction
|
|
||||||
yi = -1
|
|
||||||
dy = -dy
|
|
||||||
}
|
|
||||||
d := 2*dy - dx
|
|
||||||
// Why minus dx? if slope is 0 then d is -dx. If slope is 1 then d = dy.
|
|
||||||
// I don't know...
|
|
||||||
y := y0
|
|
||||||
x1u := uint(x1)
|
|
||||||
for x := uint(x0); x <= x1u; x++ {
|
|
||||||
fb.Set(x, uint(y), color)
|
|
||||||
if d > 0 {
|
|
||||||
y = y + yi
|
|
||||||
d = d + 2*(dy-dx)
|
|
||||||
} else {
|
|
||||||
d = d + 2*dy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For steep lines
|
|
||||||
func BresenhamHigh(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
|
||||||
dx := x1 - x0
|
|
||||||
dy := y1 - y0
|
|
||||||
xi := 1 // This is the increment
|
|
||||||
if dx < 0 { // Line moves in opposite vertical direction
|
|
||||||
xi = -1
|
|
||||||
dx = -dx
|
|
||||||
}
|
|
||||||
d := 2*dx - dy
|
|
||||||
// Why minus dx? if slope is 0 then d is -dx. If slope is 1 then d = dy.
|
|
||||||
// I don't know...
|
|
||||||
x := x0
|
|
||||||
y1u := uint(y1)
|
|
||||||
for y := uint(y0); y <= y1u; y++ {
|
|
||||||
fb.Set(uint(x), y, color)
|
|
||||||
if d > 0 {
|
|
||||||
x = x + xi
|
|
||||||
d = d + 2*(dx-dy)
|
|
||||||
} else {
|
|
||||||
d = d + 2*dx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Bresenham(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
|
||||||
if math.Abs(float64(y1-y0)) < math.Abs(float64(x1-x0)) { // This is a flatter line
|
|
||||||
if x0 > x1 { // This line is backwards
|
|
||||||
BresenhamLow(fb, color, x1, y1, x0, y0)
|
|
||||||
} else {
|
|
||||||
BresenhamLow(fb, color, x0, y0, x1, y1)
|
|
||||||
}
|
|
||||||
} else { // This is a steep line
|
|
||||||
if y0 > y1 { // This line is backwards
|
|
||||||
BresenhamHigh(fb, color, x1, y1, x0, y0)
|
|
||||||
} else {
|
|
||||||
BresenhamHigh(fb, color, x0, y0, x1, y1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Bresenham2(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
func Bresenham2(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
||||||
dx := int(math.Abs(float64(x1 - x0)))
|
dx := int(math.Abs(float64(x1 - x0)))
|
||||||
sx := -1
|
sx := -1
|
||||||
@ -195,41 +40,12 @@ func Bresenham2(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LineDumb5(fb *Framebuffer, color uint, x0 int, y0 int, x1 int, y1 int) {
|
func line(fb *Framebuffer, color uint, v0 Vec2i, v1 Vec2i) {
|
||||||
steep := false
|
Bresenham2(fb, color, v0.X, v0.Y, v1.X, v1.Y)
|
||||||
// This one makes sure that going pixel by pixel will not make holes in the
|
}
|
||||||
// other direction by always moving in the less steep direction.
|
|
||||||
if math.Abs(float64(x1-x0)) < math.Abs(float64(y1-y0)) {
|
func Triangle1(fb *Framebuffer, color uint, v0 Vec2i, v1 Vec2i, v2 Vec2i) {
|
||||||
x0, y0 = y0, x0
|
line(fb, color, v0, v1)
|
||||||
x1, y1 = y1, x1
|
line(fb, color, v1, v2)
|
||||||
steep = true
|
line(fb, color, v2, v0)
|
||||||
}
|
|
||||||
// Don't let lines be invisible, always go left to right
|
|
||||||
if x0 > x1 { // need to be left to right
|
|
||||||
x0, x1 = x1, x0
|
|
||||||
y0, y1 = y1, y0 // Why are we swapping these? I guess because we're swapping the points...
|
|
||||||
}
|
|
||||||
dx := x1 - x0 // These MUST be POST calcs
|
|
||||||
dy := y1 - y0
|
|
||||||
derror2 := int(math.Abs(float64(dy))) * 2
|
|
||||||
error2 := 0
|
|
||||||
y := y0
|
|
||||||
sy := 1
|
|
||||||
if y1 <= y0 {
|
|
||||||
sy = -1
|
|
||||||
}
|
|
||||||
// Same as dumb2, going across pixel by pixel. But "x" here might actually be y
|
|
||||||
// because of the inverted direction
|
|
||||||
for x := x0; x <= x1; x++ {
|
|
||||||
if steep {
|
|
||||||
fb.Set(uint(y), uint(x), color)
|
|
||||||
} else {
|
|
||||||
fb.Set(uint(x), uint(y), color)
|
|
||||||
}
|
|
||||||
error2 += derror2
|
|
||||||
if error2 > dx {
|
|
||||||
y = y + sy
|
|
||||||
error2 -= dx * 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user