@@ -3,25 +3,42 @@ // hellotriangle is an example Metal program that renders a single frame with a triangle. // It writes the frame to a triangle.png file in current working directory. package main import ( "flag" "fmt" "image" "image/png" "log" "os" "unsafe" "dmitri.shuralyov.com/gpu/mtl" "golang.org/x/image/math/f32" ) func usage() { fmt.Fprintln(os.Stderr, "Usage: hellotriangle") flag.PrintDefaults() } func main() { device, err := mtl.CreateSystemDefaultDevice() flag.Usage = usage flag.Parse() err := run() if err != nil { log.Fatalln(err) } } func run() error { device, err := mtl.CreateSystemDefaultDevice() if err != nil { return err } // Create a render pipeline state. const source = `#include <metal_stdlib> using namespace metal; @@ -42,28 +59,27 @@ fragment float4 FragmentShader(Vertex in [[stage_in]]) { return in.color; } ` lib, err := device.MakeLibrary(source, mtl.CompileOptions{}) if err != nil { log.Fatalln(err) return err } vs, err := lib.MakeFunction("VertexShader") if err != nil { log.Fatalln(err) return err } fs, err := lib.MakeFunction("FragmentShader") if err != nil { log.Fatalln(err) return err } var rpld mtl.RenderPipelineDescriptor rpld.VertexFunction = vs rpld.FragmentFunction = fs rpld.ColorAttachments[0].PixelFormat = mtl.PixelFormatRGBA8UNorm rps, err := device.MakeRenderPipelineState(rpld) if err != nil { log.Fatalln(err) return err } // Create a vertex buffer. type Vertex struct { Position f32.Vec4 @@ -114,13 +130,11 @@ fragment float4 FragmentShader(Vertex in [[stage_in]]) { region := mtl.RegionMake2D(0, 0, texture.Width, texture.Height) texture.GetBytes(&img.Pix[0], uintptr(bytesPerRow), region, 0) // Write output image to a PNG file. err = writePNG("triangle.png", img) if err != nil { log.Fatalln(err) } return err } // writePNG encodes the image m to a named file, in PNG format. func writePNG(name string, m image.Image) error { f, err := os.Create(name)