func loadTree(file string) error { pal := palette.Plan9 rawPal := make([]byte, 4*256) treeFp, err := os.Open(file) if err != nil { return err } defer treeFp.Close() log.Println("loading octree:", file) tree, vpa, err := trace.LoadOctree(treeFp) if err != nil { return err } loadedTree.maxDepth = trace.TreeWidthToDepth(vpa) loadedTree.tree = tree paletteFile := file + ".png" paletteFp, err := os.Open(paletteFile) if err == nil { src, _, err := image.Decode(paletteFp) if err == nil { size := src.Bounds().Max if size.X == 16 && size.Y == 16 { log.Println("loading palette:", paletteFile) pal = make([]color.Color, 256) for y := 0; y < 16; y++ { for x := 0; x < 16; x++ { r, g, b, _ := src.At(x, y).RGBA() pal[y*16+x] = color.RGBA{uint8(r), uint8(g), uint8(b), 0xFF} } } } } } paletteFp.Close() for i, c := range pal { r, g, b, _ := c.RGBA() rawPal[i*4] = byte(r) rawPal[i*4+1] = byte(g) rawPal[i*4+2] = byte(b) rawPal[i*4+3] = 0xFF } loadedTree.pal = pal loadedTree.rawPal = rawPal return nil }
func loadTree(file string) error { treeFp, err := os.Open(file) if err != nil { return err } defer treeFp.Close() log.Println("loading octree:", file) tree, vpa, err := trace.LoadOctree(treeFp) if err != nil { return err } loadedTree.maxDepth = trace.TreeWidthToDepth(vpa) loadedTree.tree = tree return nil }
func main() { flag.Parse() fmt.Sscanf(arguments.windowSize, "%d,%d", &screenWidth, &screenHeight) fmt.Sscanf(arguments.resolution, "%d,%d", &resolutionX, &resolutionY) fp, err := os.Open(arguments.inputFile) if err != nil { fmt.Fprintln(os.Stderr, err) return } defer fp.Close() tree, vpa, err := trace.LoadOctree(fp) if err != nil { panic(err) } maxDepth := trace.TreeWidthToDepth(vpa) sdl.Init(sdl.INIT_EVERYTHING) defer sdl.Quit() title := "AJ's Raytracer" window, err := sdl.CreateWindow(title, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, screenWidth, screenHeight, sdl.WINDOW_SHOWN) if err != nil { panic(err) } defer window.Destroy() sdl.SetRelativeMouseMode(true) renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) if err != nil { panic(err) } defer renderer.Destroy() sdl.SetHint(sdl.HINT_RENDER_SCALE_QUALITY, arguments.scaleFilter) renderer.SetLogicalSize(resolutionX, resolutionY) renderer.SetDrawColor(0, 0, 0, 255) rect := image.Rect(0, 0, resolutionX, resolutionY) if arguments.enableJitter { rect.Max.X /= 2 } surfaces := [2]*image.RGBA{image.NewRGBA(rect), image.NewRGBA(rect)} backBuffer := image.NewRGBA(image.Rect(0, 0, resolutionX, resolutionY)) texture, err := renderer.CreateTexture(sdl.PIXELFORMAT_ABGR8888, sdl.TEXTUREACCESS_STREAMING, resolutionX, resolutionY) if err != nil { panic(err) } defer texture.Destroy() var pos [3]float32 fmt.Sscanf(arguments.treePosition, "%f,%f,%f", &pos[0], &pos[1], &pos[2]) cfg := trace.Config{ FieldOfView: float32(arguments.fieldOfView), TreeScale: float32(arguments.treeScale), TreePosition: pos, ViewDist: float32(arguments.viewDistance), Images: surfaces, Jitter: arguments.enableJitter, MultiThreaded: arguments.multiThreaded, Depth: enableDepthTest, } raytracer := trace.NewRaytracer(cfg) defer raytracer.Close() camera := trace.FreeFlightCamera{XRot: 0, YRot: 0} nf := 0 dt := time.Duration(1000 / 60) ft := time.Duration(nf) if arguments.pprof { go func() { fmt.Fprintln(os.Stderr, http.ListenAndServe("localhost:6060", nil)) }() fp, err := os.Create("raytracer.pprof") if err != nil { panic(err) } defer fp.Close() pprof.StartCPUProfile(fp) defer pprof.StopCPUProfile() } for { t := time.Now() dtf := float32(dt / time.Millisecond) for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { switch t := event.(type) { case *sdl.QuitEvent: return case *sdl.MouseMotionEvent: if enableInput { camera.XRot -= dtf * float32(t.XRel) * mouseSpeed camera.YRot -= dtf * float32(t.YRel) * mouseSpeed } case *sdl.KeyUpEvent: switch t.Keysym.Sym { case sdl.K_ESCAPE: return case sdl.K_f: toggleFullscreen(window) case sdl.K_c: if !arguments.ppm { fmt.Println("Camera:", camera) } case sdl.K_SPACE: enableInput = !enableInput sdl.SetRelativeMouseMode(enableInput) } } } renderer.Clear() if enableInput || arguments.ppm || arguments.pprof { if enableInput { moveCamera(&camera, dtf) window.WarpMouseInWindow(screenWidth/2, screenHeight/2) } if enableDepthTest { raytracer.ClearDepth(raytracer.Frame()) } raytracer.Trace(&camera, tree, maxDepth) } if arguments.enableJitter { if err := trace.Reconstruct(raytracer.Image(0), raytracer.Image(1), backBuffer); err != nil { panic(err) } } else { backBuffer = surfaces[0] } texture.Update(nil, unsafe.Pointer(&backBuffer.Pix[0]), backBuffer.Stride) renderer.Copy(texture, nil, nil) renderer.Present() if arguments.ppm { writePPM(backBuffer) } dt = time.Since(t) ft += dt nf++ if ft >= time.Second { window.SetTitle(fmt.Sprintf("%v - fps: %v, dt: %vms", title, nf, int(ft/time.Millisecond)/nf)) nf = 0 ft = 0 } } }