Back to rendering somewhat properly again
This commit is contained in:
parent
27874d042f
commit
48366274c3
@ -132,10 +132,8 @@ func (m *Mat44f) SetProjection(fov float32, aspect float32, near float32, far fl
|
|||||||
m.Set(0, 0, near/right)
|
m.Set(0, 0, near/right)
|
||||||
m.Set(1, 1, near/top)
|
m.Set(1, 1, near/top)
|
||||||
m.Set(2, 2, -(far+near)/(far-near))
|
m.Set(2, 2, -(far+near)/(far-near))
|
||||||
//m.Set(2, 2, -(far)/(far-near))
|
|
||||||
m.Set(3, 2, -1)
|
m.Set(3, 2, -1)
|
||||||
m.Set(2, 3, -(2*far*near)/(far-near))
|
m.Set(2, 3, -(2*far*near)/(far-near))
|
||||||
//m.Set(2, 3, -(far*near)/(far-near))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mat44f) SetViewport(tl Vec3f, br Vec3f) { //width, height, depth int) {
|
func (m *Mat44f) SetViewport(tl Vec3f, br Vec3f) { //width, height, depth int) {
|
||||||
@ -237,8 +235,25 @@ func (m *Mat44f) SetLookAt(from *Vec3f, to *Vec3f, up *Vec3f) {
|
|||||||
m.Set(2, 3, from.Z)
|
m.Set(2, 3, from.Z)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply the given point by our vector. Remember this is row-major order
|
// Multiply the given point by our vector. Remember this is row-major order.
|
||||||
func (m *Mat44f) MultiplyPoint3(p Vec3f) Vec3f {
|
// Point is NOT scaled back
|
||||||
|
func (m *Mat44f) MultiplyPoint3(p Vec3f) (Vec3f, float32) {
|
||||||
|
var out Vec3f
|
||||||
|
// We hope very much that Go will optimize the function calls for us,
|
||||||
|
// along with computing the constants.
|
||||||
|
out.X = p.X*m.Get(0, 0) + p.Y*m.Get(0, 1) + p.Z*m.Get(0, 2) + m.Get(0, 3)
|
||||||
|
out.Y = p.X*m.Get(1, 0) + p.Y*m.Get(1, 1) + p.Z*m.Get(1, 2) + m.Get(1, 3)
|
||||||
|
out.Z = p.X*m.Get(2, 0) + p.Y*m.Get(2, 1) + p.Z*m.Get(2, 2) + m.Get(2, 3)
|
||||||
|
w := p.X*m.Get(3, 0) + p.Y*m.Get(3, 1) + p.Z*m.Get(3, 2) + m.Get(3, 3)
|
||||||
|
// out.X /= w
|
||||||
|
// if w != 1 {
|
||||||
|
// out.Y /= w
|
||||||
|
// out.Z /= w
|
||||||
|
// }
|
||||||
|
return out, w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mat44f) MultiplyPoint3Conventional(p Vec3f) Vec3f {
|
||||||
var out Vec3f
|
var out Vec3f
|
||||||
// We hope very much that Go will optimize the function calls for us,
|
// We hope very much that Go will optimize the function calls for us,
|
||||||
// along with computing the constants.
|
// along with computing the constants.
|
||||||
|
@ -2,8 +2,29 @@ package hrend
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
// "log"
|
// "log"
|
||||||
|
// "math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ObjectDef struct {
|
||||||
|
Model *ObjModel
|
||||||
|
Texture Framebuffer // This needs to go somewhere else eventually!
|
||||||
|
Pos Vec3f
|
||||||
|
LookVec Vec3f
|
||||||
|
Scale float32
|
||||||
|
Lighting bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewObjectDef(model *ObjModel, texture Framebuffer) *ObjectDef {
|
||||||
|
result := ObjectDef{
|
||||||
|
Model: model,
|
||||||
|
Texture: texture,
|
||||||
|
LookVec: Vec3f{X: 0, Y: 0, Z: -1},
|
||||||
|
Scale: 1,
|
||||||
|
Lighting: true,
|
||||||
|
}
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out the minimum bounding box for a triangle defined by
|
// Figure out the minimum bounding box for a triangle defined by
|
||||||
// these vertices. Returns the top left and bottom right points,
|
// these vertices. Returns the top left and bottom right points,
|
||||||
// inclusive
|
// inclusive
|
||||||
@ -117,10 +138,10 @@ func TriangleTextured(fb *RenderBuffer, texture Framebuffer, intensity float32,
|
|||||||
//boundsBRf.Z < 0 || boundsTLf.Z > 1 {
|
//boundsBRf.Z < 0 || boundsTLf.Z > 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if boundsBRf.Z < 0 || boundsTLf.Z > 1 {
|
// if boundsBRf.Z < 0 || boundsTLf.Z > 1 {
|
||||||
//log.Print(boundsTLf, boundsBRf)
|
// //log.Print(boundsTLf, boundsBRf)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
v0 := v0v.Pos.ToVec2i()
|
v0 := v0v.Pos.ToVec2i()
|
||||||
v1 := v1v.Pos.ToVec2i()
|
v1 := v1v.Pos.ToVec2i()
|
||||||
v2 := v2v.Pos.ToVec2i()
|
v2 := v2v.Pos.ToVec2i()
|
||||||
@ -212,3 +233,103 @@ func TriangleTextured(fb *RenderBuffer, texture Framebuffer, intensity float32,
|
|||||||
w2_y += w2_yi
|
w2_y += w2_yi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//func PerspectiveAndClip(//o * ObjectDef, screenmat *Mat44f, width int, height int) {
|
||||||
|
|
||||||
|
// Return true if the face should be culled
|
||||||
|
func BackfaceCull(v1, v2, v3 Vec3f) bool {
|
||||||
|
return (v1.X-v2.X)*(v3.Y-v2.Y)-(v1.Y-v2.Y)*(v3.X-v2.X) >= 0
|
||||||
|
// This is what it essentially is
|
||||||
|
// e1 := v1.Sub(&v2)
|
||||||
|
// e2 := v1.Sub(&v3)
|
||||||
|
// // If viewing front face, it should be pointing in the positive z direction
|
||||||
|
// return e1.CrossProduct(e2).Z <= 0
|
||||||
|
// But we know we can just use x and y since this is post projection
|
||||||
|
|
||||||
|
//l1 := f[2].Pos.Sub(&f[0].Pos)
|
||||||
|
//n := l1.CrossProduct(f[1].Pos.Sub(&f[0].Pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
// func TriangleTextured(fb *RenderBuffer, texture Framebuffer, intensity float32, v0v Vertex, v1v Vertex, v2v Vertex) {
|
||||||
|
// func PerspectiveAndClip(infaces []Facef, matrix3d *Mat44f, outfaces []Facef) {
|
||||||
|
func PerspectiveAndClip(face Facef, matrix3d *Mat44f) []Facef { //, outfaces []Facef) {
|
||||||
|
//var facei = 0
|
||||||
|
outfaces := make([]Facef, 0, 2)
|
||||||
|
var sc Facef
|
||||||
|
var w [3]float32
|
||||||
|
var d [3]float32
|
||||||
|
outers := make([]int, 0, 3)
|
||||||
|
// miny := float32(math.MaxFloat32)
|
||||||
|
// minyx := float32(math.MaxFloat32)
|
||||||
|
// minyi := 0
|
||||||
|
//var modelmat Mat44f
|
||||||
|
//var intensity float32
|
||||||
|
//modelmat.SetLookAt(&o.Pos, o.Pos.Add(&o.LookVec), &camup)
|
||||||
|
//modelmat.ScaleSelf(o.Scale)
|
||||||
|
//matrix3d := modelmat.Multiply(screenmat)
|
||||||
|
//for _, f := range infaces {
|
||||||
|
for i := range 3 {
|
||||||
|
sc[i] = face[i]
|
||||||
|
sc[i].Pos, w[i] = matrix3d.MultiplyPoint3(face[i].Pos)
|
||||||
|
d[i] = sc[i].Pos.Z + w[i]
|
||||||
|
if d[i] < 0 {
|
||||||
|
outers = append(outers, i)
|
||||||
|
}
|
||||||
|
// if sc[i].Pos.Y < miny || sc[i].Pos.Y < {
|
||||||
|
// miny = sc[i].Pos.Y
|
||||||
|
// minyi = i
|
||||||
|
// }
|
||||||
|
//miny = min(miny, sc[i].Pos.Y)
|
||||||
|
//minz = min(minz, sc[i].Pos.Z)
|
||||||
|
//maxz = max(maxz, sc[i].Pos.Z)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just to test: reject any that have points outside. We don't clip
|
||||||
|
if len(outers) > 0 {
|
||||||
|
return outfaces
|
||||||
|
} else {
|
||||||
|
for i := range 3 {
|
||||||
|
//sc[i]
|
||||||
|
if w[i] != 1 {
|
||||||
|
sc[i].Pos.X /= w[i]
|
||||||
|
sc[i].Pos.Y /= w[i]
|
||||||
|
sc[i].Pos.Z /= w[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Backface culling: no need to do anything with triangles facing the wrong way
|
||||||
|
if !BackfaceCull(sc[0].Pos, sc[1].Pos, sc[2].Pos) {
|
||||||
|
outfaces = append(outfaces, sc)
|
||||||
|
}
|
||||||
|
//outfaces[facei] = sc
|
||||||
|
//facei += 1
|
||||||
|
return outfaces
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Now that we're here doing it like this, might as well remove faces
|
||||||
|
// that are fully outside the other clipping zones. No need to do actual clipping...
|
||||||
|
// just full rejections. This saves a BIT of processing... though not much
|
||||||
|
|
||||||
|
// log.Print(o.Model.Faces[0][0].Pos, o.Model.Faces[0][1].Pos, o.Model.Faces[0][2].Pos)
|
||||||
|
// log.Print(sc[0].Pos, sc[1].Pos, sc[2].Pos)
|
||||||
|
// log.Print(matrix3d)
|
||||||
|
// for i := range 3 {
|
||||||
|
// // Perspective divide (?) and screen coord
|
||||||
|
// sc[i].Pos.ViewportSelf(width, height)
|
||||||
|
// }
|
||||||
|
// //log.Print(sc[0].Pos, sc[1].Pos, sc[2].Pos, matrix3d)
|
||||||
|
// if o.Lighting {
|
||||||
|
// l1 := f[2].Pos.Sub(&f[0].Pos)
|
||||||
|
// n := l1.CrossProduct(f[1].Pos.Sub(&f[0].Pos))
|
||||||
|
// n = n.Normalize()
|
||||||
|
// // light = lookvec // use this for weird things
|
||||||
|
// intensity = n.MultSimp(&light)
|
||||||
|
// if intensity < 0 {
|
||||||
|
// intensity = 0
|
||||||
|
// }
|
||||||
|
// intensity = (intensity + float32(*minlight)) / (1 + float32(*minlight))
|
||||||
|
// } else {
|
||||||
|
// intensity = 1.0
|
||||||
|
// }
|
||||||
|
// TriangleTextured(&rb, o.Texture, intensity, sc[0], sc[1], sc[2])
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
@ -32,25 +32,25 @@ func must(err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ObjectDef struct {
|
// type ObjectDef struct {
|
||||||
Model *hrend.ObjModel
|
// Model *hrend.ObjModel
|
||||||
Texture hrend.Framebuffer // This needs to go somewhere else eventually!
|
// Texture hrend.Framebuffer // This needs to go somewhere else eventually!
|
||||||
Pos hrend.Vec3f
|
// Pos hrend.Vec3f
|
||||||
LookVec hrend.Vec3f
|
// LookVec hrend.Vec3f
|
||||||
Scale float32
|
// Scale float32
|
||||||
Lighting bool
|
// Lighting bool
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func NewObjectDef(model *hrend.ObjModel, texture hrend.Framebuffer) *ObjectDef {
|
// func NewObjectDef(model *hrend.ObjModel, texture hrend.Framebuffer) *ObjectDef {
|
||||||
result := ObjectDef{
|
// result := ObjectDef{
|
||||||
Model: model,
|
// Model: model,
|
||||||
Texture: texture,
|
// Texture: texture,
|
||||||
LookVec: hrend.Vec3f{X: 0, Y: 0, Z: -1},
|
// LookVec: hrend.Vec3f{X: 0, Y: 0, Z: -1},
|
||||||
Scale: 1,
|
// Scale: 1,
|
||||||
Lighting: true,
|
// Lighting: true,
|
||||||
}
|
// }
|
||||||
return &result
|
// return &result
|
||||||
}
|
// }
|
||||||
|
|
||||||
func loadObject(name string) (*hrend.ObjModel, hrend.Framebuffer) {
|
func loadObject(name string) (*hrend.ObjModel, hrend.Framebuffer) {
|
||||||
ofile := filepath.Join("../", name+".obj")
|
ofile := filepath.Join("../", name+".obj")
|
||||||
@ -126,7 +126,7 @@ func CameraInput(yaw, pitch float32) (float32, float32, hrend.Vec3f) {
|
|||||||
// translate the new camera movement based on the yaw
|
// translate the new camera movement based on the yaw
|
||||||
var moverot hrend.Mat44f
|
var moverot hrend.Mat44f
|
||||||
moverot.SetRotationY(-yaw)
|
moverot.SetRotationY(-yaw)
|
||||||
newcamtrans = moverot.MultiplyPoint3(newcamtrans)
|
newcamtrans = moverot.MultiplyPoint3Conventional(newcamtrans)
|
||||||
|
|
||||||
return yaw, pitch, newcamtrans
|
return yaw, pitch, newcamtrans
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ func main() {
|
|||||||
// Generate world
|
// Generate world
|
||||||
wtexraw := Checkerboard([]color.Color{color.RGBA{R: 0, G: 255, B: 0, A: 255}, color.RGBA{R: 50, G: 150, B: 0, A: 255}}, 32)
|
wtexraw := Checkerboard([]color.Color{color.RGBA{R: 0, G: 255, B: 0, A: 255}, color.RGBA{R: 50, G: 150, B: 0, A: 255}}, 32)
|
||||||
wtex := hrend.NewTexture(wtexraw, 1)
|
wtex := hrend.NewTexture(wtexraw, 1)
|
||||||
world := FlatTerrain(1)
|
world := FlatTerrain(10)
|
||||||
|
|
||||||
// Generate skybox
|
// Generate skybox
|
||||||
skyraw := Gradient1px(color.RGBA{R: 100, G: 100, B: 255, A: 255}, color.RGBA{R: 255, G: 255, B: 255, A: 255}, 32)
|
skyraw := Gradient1px(color.RGBA{R: 100, G: 100, B: 255, A: 255}, color.RGBA{R: 255, G: 255, B: 255, A: 255}, 32)
|
||||||
@ -199,13 +199,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And the actual objects for the scene. We also put the world in there
|
// And the actual objects for the scene. We also put the world in there
|
||||||
objects := make([]*ObjectDef, 0)
|
objects := make([]*hrend.ObjectDef, 0)
|
||||||
objects = append(objects, NewObjectDef(world, wtex))
|
objects = append(objects, hrend.NewObjectDef(world, wtex))
|
||||||
objects = append(objects, NewObjectDef(sky, skytex)) // the actual skybox
|
objects = append(objects, hrend.NewObjectDef(sky, skytex)) // the actual skybox
|
||||||
skyobj := objects[len(objects)-1]
|
skyobj := objects[len(objects)-1]
|
||||||
skyobj.Scale = 50
|
skyobj.Scale = 50
|
||||||
skyobj.Lighting = false
|
skyobj.Lighting = false
|
||||||
objects = append(objects, NewObjectDef(models[1], textures[1]))
|
objects = append(objects, hrend.NewObjectDef(models[1], textures[1]))
|
||||||
objects[len(objects)-1].Pos.Y += 1
|
objects[len(objects)-1].Pos.Y += 1
|
||||||
objects[len(objects)-1].Pos.Z -= 2
|
objects[len(objects)-1].Pos.Z -= 2
|
||||||
|
|
||||||
@ -243,26 +243,27 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sc [3]hrend.Vertex
|
//var faces []hrend.Facef //[3]hrend.Vertex
|
||||||
var modelmat hrend.Mat44f
|
var modelmat hrend.Mat44f
|
||||||
var intensity float32
|
var intensity float32
|
||||||
var minz = float32(math.MaxFloat32)
|
//var minz = float32(math.MaxFloat32)
|
||||||
var maxz = float32(-math.MaxFloat32)
|
//var maxz = float32(-math.MaxFloat32)
|
||||||
for _, o := range objects {
|
for _, o := range objects {
|
||||||
// Create the final matrix
|
// Create the final matrix
|
||||||
modelmat.SetLookAt(&o.Pos, o.Pos.Add(&o.LookVec), &camup)
|
modelmat.SetLookAt(&o.Pos, o.Pos.Add(&o.LookVec), &camup)
|
||||||
modelmat.ScaleSelf(o.Scale)
|
modelmat.ScaleSelf(o.Scale)
|
||||||
matrix3d := modelmat.Multiply(screenmat)
|
matrix3d := modelmat.Multiply(screenmat)
|
||||||
for _, f := range o.Model.Faces {
|
for _, f := range o.Model.Faces {
|
||||||
for i := range 3 {
|
for _, sc := range hrend.PerspectiveAndClip(f, matrix3d) {
|
||||||
sc[i] = f[i]
|
// for i := range 3 {
|
||||||
sc[i].Pos = matrix3d.MultiplyPoint3(f[i].Pos)
|
// sc[i] = f[i]
|
||||||
minz = min(minz, sc[i].Pos.Z)
|
// sc[i].Pos = matrix3d.MultiplyPoint3(f[i].Pos)
|
||||||
maxz = max(maxz, sc[i].Pos.Z)
|
// minz = min(minz, sc[i].Pos.Z)
|
||||||
}
|
// maxz = max(maxz, sc[i].Pos.Z)
|
||||||
log.Print(o.Model.Faces[0][0].Pos, o.Model.Faces[0][1].Pos, o.Model.Faces[0][2].Pos)
|
// }
|
||||||
log.Print(sc[0].Pos, sc[1].Pos, sc[2].Pos)
|
// log.Print(o.Model.Faces[0][0].Pos, o.Model.Faces[0][1].Pos, o.Model.Faces[0][2].Pos)
|
||||||
log.Print(matrix3d)
|
// log.Print(sc[0].Pos, sc[1].Pos, sc[2].Pos)
|
||||||
|
// log.Print(matrix3d)
|
||||||
for i := range 3 {
|
for i := range 3 {
|
||||||
// Perspective divide (?) and screen coord
|
// Perspective divide (?) and screen coord
|
||||||
sc[i].Pos.ViewportSelf(*width, *height)
|
sc[i].Pos.ViewportSelf(*width, *height)
|
||||||
@ -282,10 +283,11 @@ func main() {
|
|||||||
intensity = 1.0
|
intensity = 1.0
|
||||||
}
|
}
|
||||||
hrend.TriangleTextured(&rb, o.Texture, intensity, sc[0], sc[1], sc[2])
|
hrend.TriangleTextured(&rb, o.Texture, intensity, sc[0], sc[1], sc[2])
|
||||||
break // only render one face
|
}
|
||||||
|
//break // only render one face
|
||||||
//hrend.TriangleFlat(&rb, hrend.Col2Uint(byte(255*intensity), byte(255*intensity), byte(255*intensity)), sc[0].Pos, sc[1].Pos, sc[2].Pos)
|
//hrend.TriangleFlat(&rb, hrend.Col2Uint(byte(255*intensity), byte(255*intensity), byte(255*intensity)), sc[0].Pos, sc[1].Pos, sc[2].Pos)
|
||||||
}
|
}
|
||||||
break // only render one object
|
//break // only render one object
|
||||||
}
|
}
|
||||||
//log.Print(minz, maxz)
|
//log.Print(minz, maxz)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user