Actually working oh wow
This commit is contained in:
parent
123ebc83df
commit
4a399c7bb7
@ -42,22 +42,40 @@ func (m *Mat44f) SetIdentity() {
|
||||
// instead of creating a new one all the time (garbage collection)
|
||||
|
||||
// Compute the projection matrix, filling the given matrix. FOV is in degrees
|
||||
func (m *Mat44f) SetProjection(fov float32, near float32, far float32) {
|
||||
func (m *Mat44f) SetProjection(fov float32, aspect float32, near float32, far float32) {
|
||||
// Projection matrix is (ROW MAJOR!)
|
||||
// S 0 0 0
|
||||
// 0 S 0 0
|
||||
// 0 0 -f/(f-n) -1
|
||||
// 0 0 -fn/(f-n) 0
|
||||
// where S (scale) is 1 / tan(fov / 2) (assuming fov is radians)
|
||||
// NOTE: -1 there is actually -1/c, where c is distance from viewer to
|
||||
// projection plane. We fix it at 1 for now but...
|
||||
// // NOTE: -1 there is actually -1/c, where c is distance from viewer to
|
||||
// // projection plane. We fix it at 1 for now but...
|
||||
// m.ZeroFill()
|
||||
// scale := float32(1 / math.Tan(float64(fov)*0.5*math.Pi/180))
|
||||
// m.Set(0, 0, scale)
|
||||
// m.Set(1, 1, scale)
|
||||
// m.Set(2, 2, -far/(far-near))
|
||||
// m.Set(3, 2, -1)
|
||||
// m.Set(2, 3, -far*near/(far-near))
|
||||
// OK apparently I suck, let's use somebody else's projection matrix:
|
||||
m.ZeroFill()
|
||||
scale := float32(1 / math.Tan(float64(fov)*0.5*math.Pi/180))
|
||||
m.Set(0, 0, scale)
|
||||
m.Set(1, 1, scale)
|
||||
m.Set(2, 2, -far/(far-near))
|
||||
|
||||
DEG2RAD := math.Acos(-1.0) / 180.0
|
||||
tangent := math.Tan(float64(fov/2.0) * DEG2RAD) // tangent of half fovY
|
||||
top := near * float32(tangent) // half height of near plane
|
||||
right := top * aspect // half width of near plane
|
||||
// Column major maybe???
|
||||
// n/r 0 0 0
|
||||
// 0 n/t 0 0
|
||||
// 0 0 -(f+n)/(f-n) -1
|
||||
// 0 0 -(2fn)/(f-n) 0
|
||||
|
||||
m.Set(0, 0, near/right)
|
||||
m.Set(1, 1, near/top)
|
||||
m.Set(2, 2, -(far+near)/(far-near))
|
||||
m.Set(3, 2, -1)
|
||||
m.Set(2, 3, -far*near/(far-near))
|
||||
m.Set(2, 3, -(2*far*near)/(far-near))
|
||||
}
|
||||
|
||||
func (m *Mat44f) SetTranslation(x, y, z float32) {
|
||||
|
@ -42,6 +42,9 @@ func TriangleFlat(fb *RenderBuffer, color uint, v0f Vec3f, v1f Vec3f, v2f Vec3f)
|
||||
v2 := v2f.ToVec2i()
|
||||
r, g, b := Uint2Col(color)
|
||||
boundsTL, boundsBR := ComputeBoundingBox(v0, v1, v2)
|
||||
if boundsBR.Y < 0 || boundsBR.X < 0 || boundsTL.X >= int(fb.Width) || boundsTL.Y >= int(fb.Height) {
|
||||
return
|
||||
}
|
||||
if boundsTL.Y < 0 {
|
||||
boundsTL.Y = 0
|
||||
}
|
||||
|
@ -2,11 +2,14 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"image"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"renderer1/hrend"
|
||||
"runtime/pprof" // For performance profiling (unnecessary)
|
||||
"time"
|
||||
|
||||
_ "image/jpeg"
|
||||
|
||||
@ -20,7 +23,9 @@ const (
|
||||
FarClip = 100
|
||||
FOV = 90.0
|
||||
ZOffset = -1.5
|
||||
ObjectFile = "head.obj"
|
||||
Movement = 1.0
|
||||
Fps = 60
|
||||
ObjectFile = "../head.obj"
|
||||
TextureFile = "../head.jpg"
|
||||
)
|
||||
|
||||
@ -73,38 +78,98 @@ func main() {
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
fb := NewRaylibBuffer(Width, Height)
|
||||
rb := hrend.NewRenderbuffer(fb, Width, Height)
|
||||
o, texture := loadDefault()
|
||||
|
||||
light := hrend.Vec3f{0, 0, -1}
|
||||
|
||||
var projection, worldToCamera, viewport hrend.Mat44f
|
||||
|
||||
rl.InitWindow(Width, Height, "Simple renderer with raylib")
|
||||
defer rl.CloseWindow()
|
||||
|
||||
rl.SetTargetFPS(60)
|
||||
rl.SetTargetFPS(Fps)
|
||||
|
||||
fb := NewRaylibBuffer(Width, Height)
|
||||
defer rl.UnloadTexture(fb.Texture)
|
||||
defer rl.UnloadImageColors(fb.Data)
|
||||
defer rl.UnloadImage(fb.Image)
|
||||
|
||||
rb := hrend.NewRenderbuffer(fb, Width, Height)
|
||||
o, texture := loadDefault()
|
||||
|
||||
light := hrend.Vec3f{
|
||||
X: 0,
|
||||
Y: 0,
|
||||
Z: -1,
|
||||
}
|
||||
|
||||
var thing hrend.Vec2i
|
||||
log.Print(thing)
|
||||
|
||||
var projection, worldToCamera, viewport hrend.Mat44f
|
||||
|
||||
// These don't really change
|
||||
projection.SetProjection(float32(FOV), float32(Width)/float32(Height), NearClip, FarClip)
|
||||
viewport.SetViewportSimple(int(fb.Width), int(fb.Height), 1) //65535)
|
||||
|
||||
log.Printf("Starting raylib loop")
|
||||
|
||||
frameSum := 0.0
|
||||
frameCount := 0
|
||||
frameAverage := 0.0
|
||||
|
||||
xofs := float32(0.0)
|
||||
yofs := float32(0.0)
|
||||
zofs := float32(ZOffset)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
rl.BeginDrawing()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
if rl.IsKeyDown(rl.KeyD) {
|
||||
xofs += Movement / Fps
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyA) {
|
||||
xofs -= Movement / Fps
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyW) {
|
||||
zofs += Movement / Fps
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyS) {
|
||||
zofs -= Movement / Fps
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeySpace) {
|
||||
yofs -= Movement / Fps
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyLeftShift) {
|
||||
yofs += Movement / Fps
|
||||
}
|
||||
|
||||
// This might (thought not currently)
|
||||
worldToCamera.SetTranslation(xofs, yofs, zofs)
|
||||
|
||||
screenmat := worldToCamera.Multiply(&projection)
|
||||
screenmat = screenmat.Multiply(&viewport)
|
||||
|
||||
for i := 0; i < Width*Height; i++ {
|
||||
fb.Data[i].R = 0
|
||||
fb.Data[i].G = 0
|
||||
fb.Data[i].B = 0
|
||||
}
|
||||
//rl.ImageDrawRectangle(fb.Image, 0, 0, Width, Height, rl.Black)
|
||||
//rl.ImageClearBackground(fb.Image, rl.Black)
|
||||
|
||||
var sc [3]hrend.Vertex
|
||||
rb.ResetZBuffer()
|
||||
for _, f := range o.Faces {
|
||||
// Precompute perspective for vertices to save time. Notice Z
|
||||
// is not considered: is this orthographic projection? Yeah probably...
|
||||
var fpt [3]hrend.Vec3f
|
||||
maxz := float32(-math.MaxFloat32)
|
||||
for i := range 3 { // Triangles, bro
|
||||
sc[i] = f[i]
|
||||
sc[i].Pos = screenmat.MultiplyPoint3(f[i].Pos)
|
||||
fpt[i] = worldToCamera.MultiplyPoint3(f[i].Pos)
|
||||
maxz = max(maxz, sc[i].Pos.Z)
|
||||
}
|
||||
|
||||
if maxz < 0 || maxz > 1 {
|
||||
//log.Printf("Clipping %f %f %f", sc[0].Pos.Z, sc[1].Pos.Z, sc[2].Pos.Z)
|
||||
continue
|
||||
}
|
||||
|
||||
l1 := fpt[2].Sub(fpt[0])
|
||||
@ -113,12 +178,24 @@ func main() {
|
||||
intensity := n.MultSimp(&light)
|
||||
if intensity > 0 {
|
||||
hrend.TriangleTextured(&rb, texture, intensity, sc[0], sc[1], sc[2])
|
||||
//hrend.TriangleFlat(&rb, hrend.Col2Uint(byte(255*intensity), byte(255*intensity), byte(255*intensity)), sc[0].Pos, sc[1].Pos, sc[2].Pos)
|
||||
}
|
||||
}
|
||||
|
||||
rl.UpdateTexture(fb.Texture, fb.Data)
|
||||
|
||||
frameSum += time.Since(start).Seconds()
|
||||
frameCount += 1
|
||||
if frameCount&0x7 == 0 {
|
||||
frameAverage = frameSum / float64(frameCount)
|
||||
frameSum = 0
|
||||
frameCount = 0
|
||||
}
|
||||
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.RayWhite)
|
||||
rl.DrawText("Congrats! You created your first window!", 190, 200, 20, rl.LightGray)
|
||||
|
||||
rl.DrawTexture(fb.Texture, 0, 0, rl.White)
|
||||
rl.DrawText(fmt.Sprintf("Frame: %fms", frameAverage*1000), 5, 5, 20, rl.Red)
|
||||
rl.EndDrawing()
|
||||
}
|
||||
}
|
||||
|
@ -2,17 +2,31 @@ package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
"log"
|
||||
)
|
||||
|
||||
type RaylibBuffer struct {
|
||||
Data []rl.Color
|
||||
Image *rl.Image
|
||||
Texture rl.Texture2D
|
||||
Width uint
|
||||
Height uint
|
||||
}
|
||||
|
||||
func NewRaylibBuffer(width uint, height uint) *RaylibBuffer {
|
||||
log.Printf("Creating new raylib framebuffer using texture + image")
|
||||
//rl.NewTexture2D(1, Width, Height, 0, )
|
||||
rlimage := rl.GenImageColor(Width, Height, rl.Black)
|
||||
rl.ImageFormat(rlimage, rl.UncompressedR8g8b8a8)
|
||||
log.Printf("Generated baseline image: %v", rlimage)
|
||||
rltexture := rl.LoadTextureFromImage(rlimage)
|
||||
log.Printf("Generated texture from image")
|
||||
data := rl.LoadImageColors(rlimage)
|
||||
log.Printf("Generated pixel data from image")
|
||||
return &RaylibBuffer{
|
||||
Data: make([]rl.Color, width*height),
|
||||
Data: data,
|
||||
Image: rlimage,
|
||||
Texture: rltexture,
|
||||
Width: width,
|
||||
Height: height,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user