func GrabCursor() { if sdl.GetRelativeMouseMode() { sdl.SetRelativeMouseMode(false) } else { sdl.SetRelativeMouseMode(true) } }
// SetRelativeMode sets whether relative mode is enabled for the mouse. func SetRelativeMode(isvisible bool) { sdl.SetRelativeMouseMode(isvisible) }
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 } } }