func main() { sdl.SetHint(sdl.HINT_RENDER_VSYNC, "1") check(sdl.Init(sdl.INIT_EVERYTHING)) defer sdl.Quit() check(mix.Init(mix.INIT_OGG)) defer mix.Quit() check(mix.OpenAudio(44100, mix.DEFAULT_FORMAT, 1, 512)) defer mix.CloseAudio() if img.Init(img.INIT_PNG)&img.INIT_PNG == 0 { panic("error init png") } defer img.Quit() window, renderer, err := sdl.CreateWindowAndRenderer( 640, 480, sdl.WINDOW_RESIZABLE, ) check(err) defer renderer.Destroy() defer window.Destroy() window.SetTitle("Gophette's Adventures") window.SetSize(800, 600) sdl.ShowCursor(0) window.SetFullscreen(sdl.WINDOW_FULLSCREEN_DESKTOP) fullscreen := true camera := newWindowCamera(window.GetSize()) assetLoader := newSDLAssetLoader(camera, renderer) defer assetLoader.close() // charIndex selects which character is being controlled by the user, for // the final game this must be 0 but for creating the "AI" for Barney, set // this to 1 and delete the recorded inputs so they are not applied // additionally to the user controls var charIndex int const recordingAI = false // NOTE switch for development mode if !recordingAI { charIndex = 0 } else { charIndex = 1 recordedInputs = recordedInputs[:0] recordingInput = true } game := NewGame( assetLoader, &sdlGraphics{renderer, camera}, camera, charIndex, ) frameTime := time.Second / 65 lastUpdate := time.Now().Add(-frameTime) music, err := mix.LoadMUS("./rsc/background_music.ogg") if err != nil { fmt.Println("error loading music:", err) } else { defer music.Free() music.FadeIn(-1, 500) } for game.Running() { for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() { switch event := e.(type) { case *sdl.KeyDownEvent: if event.Repeat == 0 { switch event.Keysym.Sym { case sdl.K_LEFT: game.HandleInput(InputEvent{GoLeft, true, charIndex}) case sdl.K_RIGHT: game.HandleInput(InputEvent{GoRight, true, charIndex}) case sdl.K_UP: game.HandleInput(InputEvent{Jump, true, charIndex}) case sdl.K_ESCAPE: game.HandleInput(InputEvent{QuitGame, true, charIndex}) } } case *sdl.KeyUpEvent: switch event.Keysym.Sym { case sdl.K_LEFT: game.HandleInput(InputEvent{GoLeft, false, charIndex}) case sdl.K_RIGHT: game.HandleInput(InputEvent{GoRight, false, charIndex}) case sdl.K_UP: game.HandleInput(InputEvent{Jump, false, charIndex}) case sdl.K_F11: if fullscreen { window.SetFullscreen(0) } else { window.SetFullscreen(sdl.WINDOW_FULLSCREEN_DESKTOP) } fullscreen = !fullscreen case sdl.K_ESCAPE: game.HandleInput(InputEvent{QuitGame, false, charIndex}) } case *sdl.WindowEvent: if event.Event == sdl.WINDOWEVENT_SIZE_CHANGED { width, height := int(event.Data1), int(event.Data2) camera.setWindowSize(width, height) } case *sdl.QuitEvent: game.HandleInput(InputEvent{QuitGame, true, charIndex}) } } now := time.Now() dt := now.Sub(lastUpdate) if dt > frameTime { game.Update() lastUpdate = now } check(renderer.SetDrawColor(0, 95, 83, 255)) check(renderer.Clear()) game.Render() renderer.Present() } }
func main() { fmt.Print() sdl.SetHint(sdl.HINT_RENDER_VSYNC, "1") check(sdl.Init(sdl.INIT_EVERYTHING)) defer sdl.Quit() window, r, err := sdl.CreateWindowAndRenderer( 640, 480, sdl.WINDOW_RESIZABLE, ) check(err) renderer = r defer renderer.Destroy() defer window.Destroy() window.SetTitle("Gophette's Adventures - Level Editor") window.SetPosition(50, 50) window.SetSize(1800, 900) window.SetFullscreen(sdl.WINDOW_FULLSCREEN_DESKTOP) renderer.SetDrawBlendMode(sdl.BLENDMODE_BLEND) if len(LevelImages) == 0 { for i, id := range []string{ "grass left", "grass right", "grass center 1", "grass center 2", "grass center 3", "small tree", } { images = append(images, image{id, loadImage(id), 0, i * 50}) } } else { for i := range LevelImages { id := LevelImages[i].ID x, y := LevelImages[i].X, LevelImages[i].Y img := loadImage(id) images = append(images, image{id, img, x, y}) } } leftDown := false middleDown := false rightDown := false selectedImage := -1 selectedObject := -1 var lastX, lastY int moveImage := func(dx, dy int) { if selectedImage != -1 { images[selectedImage].x += dx images[selectedImage].y += dy } } stretchObject := func(dx, dy int) { if selectedObject != -1 { if sdl.GetKeyboardState()[sdl.SCANCODE_LCTRL] != 0 { dx *= 20 dy *= 20 } obj := &LevelObjects[selectedObject] obj.W += dx obj.H += dy } } running := true for running { for e := sdl.PollEvent(); e != nil; e = sdl.PollEvent() { switch event := e.(type) { case *sdl.QuitEvent: running = false case *sdl.MouseButtonEvent: if event.Button == sdl.BUTTON_LEFT { leftDown = event.State == sdl.PRESSED if !leftDown { draggingImage = false draggingObject = false } else { selectedObject = -1 selectedImage = -1 for i := range images { if images[i].contains( int(event.X)-cameraX, int(event.Y)-cameraY, ) { draggingImage = true selectedImage = i } } if selectedImage == -1 { for i := range LevelObjects { if contains(LevelObjects[i], int(event.X)-cameraX, int(event.Y)-cameraY, ) { draggingObject = true selectedObject = i } } } } } if event.Button == sdl.BUTTON_MIDDLE { middleDown = event.State == sdl.PRESSED } if event.Button == sdl.BUTTON_RIGHT { rightDown = event.State == sdl.PRESSED LevelObjects = append(LevelObjects, LevelObject{ int(event.X) - cameraX, int(event.Y) - cameraY, 0, 0, true, }) selectedObject = -1 } case *sdl.MouseMotionEvent: dx, dy := int(event.X)-lastX, int(event.Y)-lastY if selectedImage != -1 && draggingImage { img := &images[selectedImage] img.x += dx img.y += dy } if selectedObject != -1 && draggingObject { obj := &LevelObjects[selectedObject] obj.X += dx obj.Y += dy } lastX, lastY = int(event.X), int(event.Y) if middleDown { cameraX += dx cameraY += dy } if rightDown { last := &LevelObjects[len(LevelObjects)-1] last.W += dx last.H += dy } case *sdl.KeyDownEvent: switch event.Keysym.Sym { case sdl.K_ESCAPE: running = false case sdl.K_LEFT: cameraX += 100 case sdl.K_RIGHT: cameraX -= 100 case sdl.K_UP: cameraY += 100 case sdl.K_DOWN: cameraY -= 100 case sdl.K_a: moveImage(-1, 0) case sdl.K_d: moveImage(1, 0) case sdl.K_w: moveImage(0, -1) case sdl.K_s: moveImage(0, 1) case sdl.K_j: stretchObject(-1, 0) case sdl.K_l: stretchObject(1, 0) case sdl.K_i: stretchObject(0, -1) case sdl.K_k: stretchObject(0, 1) case sdl.K_MINUS: if selectedImage != -1 && selectedImage != 0 { images = append(append( []image{images[selectedImage]}, images[0:selectedImage]...), images[selectedImage+1:]..., ) selectedImage = 0 } case sdl.K_PLUS: last := len(images) - 1 fmt.Println("last", last, len(images)) fmt.Println("selectedImage", selectedImage) if selectedImage != -1 && selectedImage != last { images = append(append( images[0:selectedImage], images[selectedImage+1:]...), images[selectedImage], ) selectedImage = last fmt.Println("selectedImage after", selectedImage) } case sdl.K_SPACE: if selectedObject != -1 { obj := &LevelObjects[selectedObject] obj.Solid = !obj.Solid } case sdl.K_c: if selectedImage != -1 { copy := images[selectedImage] copy.x += 10 copy.y += 10 images = append(images, copy) } case sdl.K_DELETE: if selectedImage != -1 { images = append(images[:selectedImage], images[selectedImage+1:]...) selectedImage = -1 } else if selectedObject != -1 { LevelObjects = append( LevelObjects[:selectedObject], LevelObjects[selectedObject+1:]..., ) selectedObject = -1 } case sdl.K_F3: saveLevel() } } } renderer.SetDrawColor(backColor[0], backColor[1], backColor[2], 255) renderer.Clear() for i, img := range images { img.render(i == selectedImage) } for i, obj := range LevelObjects { var g uint8 = 0 var a uint8 = 100 if i == selectedObject { g = 255 } renderer.SetDrawColor(0, g, 0, a) if obj.Solid { renderer.SetDrawColor(0, g, 255, a) } obj.X += cameraX obj.Y += cameraY r := sdl.Rect{int32(obj.X), int32(obj.Y), int32(obj.W), int32(obj.H)} renderer.FillRect(&r) } renderer.Present() } }
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 } } }