168 lines
4.3 KiB
Go
168 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
"runtime"
|
|
"runtime/pprof"
|
|
|
|
gl "github.com/go-gl/gl/v3.1/gles2"
|
|
"github.com/go-gl/mathgl/mgl32"
|
|
"github.com/veandco/go-sdl2/sdl"
|
|
|
|
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/breakout"
|
|
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/game_window"
|
|
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/gl_objects"
|
|
)
|
|
|
|
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
|
|
|
const GameTitle = "Carpy Breakout"
|
|
const LogFile = "output.log"
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
if *cpuprofile != "" {
|
|
f, err := os.Create(*cpuprofile)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
pprof.StartCPUProfile(f)
|
|
defer pprof.StopCPUProfile()
|
|
}
|
|
|
|
setupLogging()
|
|
|
|
// TODO can potentially rework stuff to not need LockOSThread()
|
|
// here. SDL has the built-in sdl.Do(), but I would need to create
|
|
// my own similar thing for OpenGL. Essentially they both need to
|
|
// be locked to the main thread, but anything else can be in a
|
|
// goroutine.
|
|
runtime.LockOSThread()
|
|
|
|
runOpenGL()
|
|
}
|
|
|
|
func runOpenGL() {
|
|
var sdlInitFlags uint32 = sdl.INIT_TIMER | sdl.INIT_AUDIO | sdl.INIT_VIDEO | sdl.INIT_EVENTS | sdl.INIT_JOYSTICK | sdl.INIT_HAPTIC | sdl.INIT_GAMECONTROLLER // ignore sensor subsystem
|
|
err := sdl.Init(sdlInitFlags)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer sdl.Quit()
|
|
|
|
sdlSettings()
|
|
|
|
gameWindow, err := game_window.NewGameWindow(GameTitle)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer gameWindow.Destroy()
|
|
|
|
// GL Init requires an active OpenGL context (e.g. the game window)
|
|
err = gl.Init()
|
|
if err != nil {
|
|
log.Fatalf("Failed to initialize OpenGL: %v", err)
|
|
}
|
|
glVersion := gl.GetString(gl.VERSION)
|
|
if glVersion == nil {
|
|
log.Printf("Error getting OpenGL version.\n")
|
|
}
|
|
log.Printf("OpenGL Version: %v\n", gl.GoStr(glVersion))
|
|
|
|
// Then we can setup the OpenGL specific stuff in the game window
|
|
gameWindow.GLInit()
|
|
|
|
sunLight := gl_objects.NewPointLight(mgl32.Vec3{-10, 10, 30})
|
|
sunLight.GLInit(gameWindow.GLProgram)
|
|
|
|
camera := gl_objects.NewCamera(gameWindow.GLProgram)
|
|
camera.Position = mgl32.Vec3{0, 0, 30}
|
|
gameWindow.SetCamera(camera)
|
|
gameWindow.AddObject(camera)
|
|
|
|
// textureId, err := gl_helpers.NewTexture("square.png")
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
|
|
// Brick Targets
|
|
targets := breakout.NewTargets(4, 5, mgl32.Vec3{0, 6, 0})
|
|
targets.GLInit(gameWindow.GLProgram)
|
|
for _, brick := range targets.Bricks {
|
|
gameWindow.AddObject(brick)
|
|
}
|
|
positiveBoundary := targets.TopRight
|
|
negativeBoundary := positiveBoundary.Mul(-1)
|
|
gameWindow.PositiveBoundary = positiveBoundary
|
|
gameWindow.NegativeBoundary = negativeBoundary
|
|
|
|
// Bounding Box
|
|
boundingBoxMaterial := gl_objects.NewMaterial()
|
|
boundingBoxMaterial.Color = mgl32.Vec4{0.3, 0.3, 0.3, 1}
|
|
boundingBox := breakout.NewBoundingBox(negativeBoundary, positiveBoundary, boundingBoxMaterial)
|
|
|
|
// Paddle
|
|
paddleMaterial := gl_objects.NewMaterial()
|
|
paddleMaterial.Color = mgl32.Vec4{0, 1, 0, 1}
|
|
paddle := gl_objects.NewBox(6.0, 1.0, 4.0, mgl32.Vec3{0, -6, 0}, paddleMaterial)
|
|
paddle.GLInit(gameWindow.GLProgram)
|
|
gameWindow.AddObject(paddle)
|
|
gameWindow.SetPaddle(paddle)
|
|
|
|
// Ball
|
|
ballMaterial := gl_objects.NewMaterial()
|
|
ballMaterial.Color = mgl32.Vec4{1, 1, 1, 1}
|
|
ball := gl_objects.NewBox(1, 1, 1, mgl32.Vec3{-8, 0, 0}, ballMaterial)
|
|
ball.GLInit(gameWindow.GLProgram)
|
|
gameWindow.AddObject(ball)
|
|
|
|
glSettings()
|
|
for gameWindow.IsRunning() {
|
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
|
|
|
gameWindow.Update()
|
|
gameWindow.GLDraw()
|
|
|
|
gameWindow.SDLWindow.GLSwap()
|
|
|
|
gameWindow.HandleEvents()
|
|
sdl.Delay(16)
|
|
}
|
|
}
|
|
|
|
func setupLogging() {
|
|
// file, err := os.OpenFile(LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
|
|
// log.SetOutput(file)
|
|
log.Println("=== START ===")
|
|
}
|
|
|
|
func glSettings() {
|
|
// Global options after setup is all done
|
|
gl.ClearColor(0.0, 0.0, 0.0, 1.0)
|
|
gl.Enable(gl.DEPTH_TEST)
|
|
gl.DepthFunc(gl.LESS)
|
|
gl.LineWidth(2.0)
|
|
}
|
|
|
|
func sdlSettings() {
|
|
// Smooth
|
|
sdl.GLSetAttribute(sdl.GL_MULTISAMPLEBUFFERS, 1)
|
|
sdl.GLSetAttribute(sdl.GL_MULTISAMPLESAMPLES, 4)
|
|
|
|
// Disable the Linux compositor flicker.
|
|
// https://github.com/mosra/magnum/issues/184#issuecomment-425952900
|
|
sdl.SetHint(sdl.HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0")
|
|
|
|
sdl.DisableScreenSaver()
|
|
|
|
// Capture the mouse for movement
|
|
sdl.SetRelativeMouseMode(true)
|
|
}
|