func NewScene(vertShader, fragShader string, texture *gg.Texture) (*Scene, error) { gg.Enable(gg.DEPTH_TEST) gg.Enable(gg.CULL_FACE) gg.DepthFunc(gg.LESS) gg.Enable(gg.BLEND) gg.BlendFunc(gg.SRC_ALPHA, gg.ONE_MINUS_SRC_ALPHA) // Compile the global shader program vshader, err := gg.CreateShader([]byte(vertShader), gg.VERTEX_SHADER) if err != nil { return nil, err } fshader, err := gg.CreateShader([]byte(fragShader), gg.FRAGMENT_SHADER) if err != nil { return nil, err } program := gg.CreateProgram() gg.AttachShader(program, vshader) gg.AttachShader(program, fshader) if err := gg.LinkProgram(program); err != nil { return nil, err } // Set the global projection matrix gg.UseProgram(program) proj := mgl.Ortho(0, float32(WindowWidth), float32(WindowHeight), 0, 0, 1) projUniform, err := gg.GetUniformLocation(program, "proj") if err != nil { return nil, err } gg.UniformMatrix4fv(projUniform, proj[:]) vertices := []float32{ float32(WindowWidth)/2 - 50, float32(WindowHeight)/2 - 50, 0, float32(WindowWidth)/2 - 50, float32(WindowHeight)/2 + 50, 0, float32(WindowWidth)/2 + 50, float32(WindowHeight)/2 + 50, 0, float32(WindowWidth)/2 + 50, float32(WindowHeight)/2 - 50, 0, } // Initialize sprite sprite, err := NewSprite(vertices, program, texture) if err != nil { return nil, err } return &Scene{sprite: sprite}, nil }
func NewTetris(vertShader, fragShader string) (*Tetris, error) { gg.Enable(gg.BLEND) gg.BlendFunc(gg.SRC_ALPHA, gg.ONE_MINUS_SRC_ALPHA) // Compile the global shader program vshader, err := gg.CreateShader([]byte(vertShader), gg.VERTEX_SHADER) if err != nil { return nil, err } fshader, err := gg.CreateShader([]byte(fragShader), gg.FRAGMENT_SHADER) if err != nil { return nil, err } program := gg.CreateProgram() gg.AttachShader(program, vshader) gg.AttachShader(program, fshader) if err := gg.LinkProgram(program); err != nil { return nil, err } // Set the global projection matrix gg.UseProgram(program) proj := mgl.Ortho(0, float32(WindowWidth), float32(WindowHeight), 0, 0, 1) projUniform, err := gg.GetUniformLocation(program, "proj") if err != nil { return nil, err } gg.UniformMatrix4fv(projUniform, proj[:]) tetris := &Tetris{} tetris.textures, err = LoadTextures() if err != nil { return nil, err } tetris.bg = NewSprite(WindowWidth, WindowHeight, program, tetris.textures["bg"]) tetris.board = NewBoard(WidthCells, HeightCells, program, tetris.textures) tetris.board.x = Padding tetris.board.y = Padding rand.Seed(time.Now().Unix()) tetris.board.current = tetris.board.NewRandomPiece() go func() { t := time.NewTicker(time.Second) for range t.C { tetris.mu.Lock() if tetris.gameOver { return } tetris.mu.Unlock() tetris.HandleInput(inputDown) } }() return tetris, nil }
func newImageTexture(filename string) (*gg.Texture, error) { f, err := os.Open(filename) if err != nil { return nil, err } img, err := png.Decode(f) if err != nil { return nil, err } var buf []byte for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { r, g, b, a := img.At(x, y).RGBA() buf = append(buf, byte(r/256)) buf = append(buf, byte(g/256)) buf = append(buf, byte(b/256)) buf = append(buf, byte(a/256)) } } tex := gg.CreateTexture() gg.ActiveTexture(gg.TEXTURE0) gg.Enable(gg.TEXTURE_2D) gg.BindTexture(gg.TEXTURE_2D, tex) gg.TexImage2D( gg.TEXTURE_2D, 0, gg.RGBA, img.Bounds().Dx(), img.Bounds().Dy(), 0, gg.RGBA, gg.UNSIGNED_BYTE, buf, ) gg.TexParameteri(gg.TEXTURE_2D, gg.TEXTURE_WRAP_S, gg.CLAMP_TO_EDGE) gg.TexParameteri(gg.TEXTURE_2D, gg.TEXTURE_WRAP_T, gg.CLAMP_TO_EDGE) gg.TexParameteri(gg.TEXTURE_2D, gg.TEXTURE_MAG_FILTER, gg.LINEAR) gg.TexParameteri(gg.TEXTURE_2D, gg.TEXTURE_MIN_FILTER, gg.LINEAR) return tex, nil }