Support single color objects
This commit is contained in:
parent
0a6a5d6404
commit
b72127d3b1
@ -81,9 +81,11 @@ func (fb *SimpleFramebuffer) Get(x uint, y uint) (byte, byte, byte) {
|
|||||||
func (fb *SimpleFramebuffer) GetUv(u float32, v float32) (byte, byte, byte) {
|
func (fb *SimpleFramebuffer) GetUv(u float32, v float32) (byte, byte, byte) {
|
||||||
x := uint(float32(fb.Width)*u) & (fb.Width - 1)
|
x := uint(float32(fb.Width)*u) & (fb.Width - 1)
|
||||||
y := uint(float32(fb.Height)*(1-v)) & (fb.Height - 1)
|
y := uint(float32(fb.Height)*(1-v)) & (fb.Height - 1)
|
||||||
return fb.Data[(x+y*fb.Width)*3],
|
i := (x + y*fb.Width) * 3
|
||||||
fb.Data[(x+y*fb.Width)*3+1],
|
return fb.Data[i], fb.Data[i+1], fb.Data[i+2]
|
||||||
fb.Data[(x+y*fb.Width)*3+2]
|
// return fb.Data[(x+y*fb.Width)*3],
|
||||||
|
// fb.Data[(x+y*fb.Width)*3+1],
|
||||||
|
// fb.Data[(x+y*fb.Width)*3+2]
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSimpleFramebuffer(width uint, height uint) *SimpleFramebuffer {
|
func NewSimpleFramebuffer(width uint, height uint) *SimpleFramebuffer {
|
||||||
|
@ -321,6 +321,14 @@ func (v0 *Vec3f) Sub(v1 *Vec3f) *Vec3f {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v0 *Vec3f) Scale(s float32) *Vec3f {
|
||||||
|
return &Vec3f{
|
||||||
|
X: v0.X * s,
|
||||||
|
Y: v0.Y * s,
|
||||||
|
Z: v0.Z * s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (v0 *Vec3f) CrossProduct(v1 *Vec3f) *Vec3f {
|
func (v0 *Vec3f) CrossProduct(v1 *Vec3f) *Vec3f {
|
||||||
return &Vec3f{
|
return &Vec3f{
|
||||||
X: v0.Y*v1.Z - v0.Z*v1.Y,
|
X: v0.Y*v1.Z - v0.Z*v1.Y,
|
||||||
|
@ -18,17 +18,17 @@ type Vertex struct {
|
|||||||
|
|
||||||
type Facef [3]Vertex
|
type Facef [3]Vertex
|
||||||
|
|
||||||
// struct {
|
|
||||||
// Vertices [3]Vec3f
|
|
||||||
// TextureCoords [3]Vec2i
|
|
||||||
// }
|
|
||||||
|
|
||||||
type ObjModel struct {
|
type ObjModel struct {
|
||||||
Vertices []Vec3f
|
Vertices []Vec3f
|
||||||
VTexture []Vec3f
|
VTexture []Vec3f
|
||||||
Faces []Facef
|
Faces []Facef
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *ObjModel) ClearCachedVertexInfo() {
|
||||||
|
o.Vertices = nil
|
||||||
|
o.VTexture = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Parse an obj file at the given reader. Only handles v and f right now
|
// Parse an obj file at the given reader. Only handles v and f right now
|
||||||
func ParseObj(reader io.Reader) (*ObjModel, error) {
|
func ParseObj(reader io.Reader) (*ObjModel, error) {
|
||||||
result := ObjModel{
|
result := ObjModel{
|
||||||
|
@ -10,6 +10,7 @@ type ObjectDef struct {
|
|||||||
Texture Framebuffer // This needs to go somewhere else eventually!
|
Texture Framebuffer // This needs to go somewhere else eventually!
|
||||||
Pos Vec3f
|
Pos Vec3f
|
||||||
LookVec Vec3f
|
LookVec Vec3f
|
||||||
|
Color Vec3f
|
||||||
Scale float32
|
Scale float32
|
||||||
Lighting bool
|
Lighting bool
|
||||||
}
|
}
|
||||||
@ -67,18 +68,19 @@ func ZClip(v0f Vec3f, v1f Vec3f, v2f Vec3f) bool {
|
|||||||
return maxz < -1 || maxz > 1
|
return maxz < -1 || maxz > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func TriangleFlat(fb *RenderBuffer, color uint, v0f Vec3f, v1f Vec3f, v2f Vec3f) {
|
func TriangleFlat(fb *RenderBuffer, color *Vec3f, v0f Vec3f, v1f Vec3f, v2f Vec3f) {
|
||||||
if ZClip(v0f, v1f, v2f) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
v0 := v0f.ToVec2i()
|
v0 := v0f.ToVec2i()
|
||||||
v1 := v1f.ToVec2i()
|
v1 := v1f.ToVec2i()
|
||||||
v2 := v2f.ToVec2i()
|
v2 := v2f.ToVec2i()
|
||||||
r, g, b := Uint2Col(color)
|
//r, g, b := Uint2Col(color)
|
||||||
boundsTL, boundsBR := ComputeBoundingBox(v0, v1, v2)
|
boundsTL, boundsBR := ComputeBoundingBox(v0, v1, v2)
|
||||||
if boundsBR.X < 0 || boundsBR.Y < 0 || boundsTL.X >= int(fb.Width) || boundsTL.Y >= int(fb.Height) {
|
if boundsBR.X < 0 || boundsBR.Y < 0 || boundsTL.X >= int(fb.Width) || boundsTL.Y >= int(fb.Height) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
parea := EdgeFunctioni(v0, v1, v2)
|
||||||
|
if parea <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
if boundsTL.Y < 0 {
|
if boundsTL.Y < 0 {
|
||||||
boundsTL.Y = 0
|
boundsTL.Y = 0
|
||||||
}
|
}
|
||||||
@ -93,7 +95,6 @@ func TriangleFlat(fb *RenderBuffer, color uint, v0f Vec3f, v1f Vec3f, v2f Vec3f)
|
|||||||
}
|
}
|
||||||
// Where to start our scanning
|
// Where to start our scanning
|
||||||
pstart := Vec2i{boundsTL.X, boundsTL.Y}
|
pstart := Vec2i{boundsTL.X, boundsTL.Y}
|
||||||
parea := EdgeFunctioni(v0, v1, v2)
|
|
||||||
invarea := 1 / float32(parea)
|
invarea := 1 / float32(parea)
|
||||||
w0_y := EdgeFunctioni(v1, v2, pstart)
|
w0_y := EdgeFunctioni(v1, v2, pstart)
|
||||||
w1_y := EdgeFunctioni(v2, v0, pstart)
|
w1_y := EdgeFunctioni(v2, v0, pstart)
|
||||||
@ -101,6 +102,9 @@ func TriangleFlat(fb *RenderBuffer, color uint, v0f Vec3f, v1f Vec3f, v2f Vec3f)
|
|||||||
w0_xi, w0_yi := EdgeIncrementi(v1, v2)
|
w0_xi, w0_yi := EdgeIncrementi(v1, v2)
|
||||||
w1_xi, w1_yi := EdgeIncrementi(v2, v0)
|
w1_xi, w1_yi := EdgeIncrementi(v2, v0)
|
||||||
w2_xi, w2_yi := EdgeIncrementi(v0, v1)
|
w2_xi, w2_yi := EdgeIncrementi(v0, v1)
|
||||||
|
r := byte(255 * color.X)
|
||||||
|
g := byte(255 * color.Y)
|
||||||
|
b := byte(255 * color.Z)
|
||||||
|
|
||||||
for y := uint(boundsTL.Y); y <= uint(boundsBR.Y); y++ {
|
for y := uint(boundsTL.Y); y <= uint(boundsBR.Y); y++ {
|
||||||
w0 := w0_y
|
w0 := w0_y
|
||||||
@ -139,12 +143,8 @@ func TriangleTextured(fb *RenderBuffer, texture Framebuffer, intensity float32,
|
|||||||
v1 := v1v.Pos.ToVec2i()
|
v1 := v1v.Pos.ToVec2i()
|
||||||
v2 := v2v.Pos.ToVec2i()
|
v2 := v2v.Pos.ToVec2i()
|
||||||
parea := EdgeFunctioni(v0, v1, v2)
|
parea := EdgeFunctioni(v0, v1, v2)
|
||||||
// Still draw back faces (assume someone else culls them)
|
// Don't even bother with drawing backfaces or degenerate triangles;
|
||||||
// if parea < 0 {
|
// don't even give the user the option
|
||||||
// log.Print("HEY", parea)
|
|
||||||
// v1, v2 = v2, v1
|
|
||||||
// parea = EdgeFunctioni(v0, v1, v2)
|
|
||||||
// }
|
|
||||||
if parea <= 0 {
|
if parea <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -245,4 +245,6 @@ func PerspectiveAndClip(face Facef, matrix3d *Mat44f) []Facef {
|
|||||||
// TODO: Now that we're here doing it like this, might as well remove faces
|
// 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...
|
// 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
|
// just full rejections. This saves a BIT of processing... though not much
|
||||||
|
// NOTE: Uh no... this is too much effort. Two points could be outside individual
|
||||||
|
// planes and thus still intersect the screen.
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,9 @@ func loadObject(name string) (*hrend.ObjModel, hrend.Framebuffer) {
|
|||||||
o, err := hrend.ParseObj(of)
|
o, err := hrend.ParseObj(of)
|
||||||
must(err)
|
must(err)
|
||||||
|
|
||||||
|
// We also get rid of cached vertex info from the file
|
||||||
|
o.ClearCachedVertexInfo()
|
||||||
|
|
||||||
jf, err := os.Open(tfile)
|
jf, err := os.Open(tfile)
|
||||||
must(err)
|
must(err)
|
||||||
defer jf.Close()
|
defer jf.Close()
|
||||||
@ -185,13 +188,19 @@ 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([]*hrend.ObjectDef, 0)
|
objects := make([]*hrend.ObjectDef, 0)
|
||||||
objects = append(objects, hrend.NewObjectDef(world, wtex))
|
objects = append(objects, hrend.NewObjectDef(world, wtex))
|
||||||
|
worldobj := objects[len(objects)-1]
|
||||||
|
worldobj.Color = hrend.Vec3f{0.0, 1.0, 0.0}
|
||||||
objects = append(objects, hrend.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
|
||||||
|
skyobj.Color = hrend.Vec3f{0.5, 0.5, 1.0}
|
||||||
objects = append(objects, hrend.NewObjectDef(models[1], textures[1]))
|
objects = append(objects, hrend.NewObjectDef(models[1], textures[1]))
|
||||||
objects[len(objects)-1].Pos.Y += 1
|
diabloobj := objects[len(objects)-1]
|
||||||
objects[len(objects)-1].Pos.Z -= 2
|
diabloobj.Pos.Y += 1
|
||||||
|
diabloobj.Pos.Z -= 2
|
||||||
|
diabloobj.Color = hrend.Vec3f{1.0, 0.0, 0.0}
|
||||||
|
//diabloobj.Lighting = false
|
||||||
|
|
||||||
// These don't really change
|
// These don't really change
|
||||||
var projection hrend.Mat44f
|
var projection hrend.Mat44f
|
||||||
@ -254,6 +263,7 @@ 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])
|
||||||
|
//hrend.TriangleFlat(&rb, o.Color.Scale(intensity), sc[0].Pos, sc[1].Pos, sc[2].Pos)
|
||||||
}
|
}
|
||||||
//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)
|
||||||
|
@ -38,12 +38,16 @@ func (fb *RaylibBuffer) Dims() (uint, uint) {
|
|||||||
|
|
||||||
// Sure hope this gets inlined...
|
// Sure hope this gets inlined...
|
||||||
func (fb *RaylibBuffer) Set(x uint, y uint, r byte, g byte, b byte) {
|
func (fb *RaylibBuffer) Set(x uint, y uint, r byte, g byte, b byte) {
|
||||||
if x >= fb.Width || y >= fb.Height {
|
// if x >= fb.Width || y >= fb.Height {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
fb.Data[x+y*fb.Width].R = r
|
// fb.Data[x+y*fb.Width].R = r
|
||||||
fb.Data[x+y*fb.Width].G = g
|
// fb.Data[x+y*fb.Width].G = g
|
||||||
fb.Data[x+y*fb.Width].B = b
|
// fb.Data[x+y*fb.Width].B = b
|
||||||
|
c := &fb.Data[x+y*fb.Width]
|
||||||
|
c.R = r
|
||||||
|
c.G = g
|
||||||
|
c.B = b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fb *RaylibBuffer) Get(x uint, y uint) (byte, byte, byte) {
|
func (fb *RaylibBuffer) Get(x uint, y uint) (byte, byte, byte) {
|
||||||
@ -58,7 +62,9 @@ func (fb *RaylibBuffer) Get(x uint, y uint) (byte, byte, byte) {
|
|||||||
func (fb *RaylibBuffer) GetUv(u float32, v float32) (byte, byte, byte) {
|
func (fb *RaylibBuffer) GetUv(u float32, v float32) (byte, byte, byte) {
|
||||||
x := uint(float32(fb.Width)*u) & (fb.Width - 1)
|
x := uint(float32(fb.Width)*u) & (fb.Width - 1)
|
||||||
y := uint(float32(fb.Height)*(1-v)) & (fb.Height - 1)
|
y := uint(float32(fb.Height)*(1-v)) & (fb.Height - 1)
|
||||||
return fb.Data[x+y*fb.Width].R,
|
c := &fb.Data[x+y*fb.Width]
|
||||||
fb.Data[x+y*fb.Width].G,
|
return c.R, c.G, c.B
|
||||||
fb.Data[x+y*fb.Width].B
|
// fb.Data[x+y*fb.Width].R,
|
||||||
|
// fb.Data[x+y*fb.Width].G,
|
||||||
|
// fb.Data[x+y*fb.Width].B
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user