package main import ( "fmt" "strings" ) // Convert rgb to uint func Col2Uint(r, g, b byte) uint { return (uint(r) << 16) | (uint(g) << 8) | uint(b) } // Convert uint to rgb (in that order) func Uint2Col(col uint) (byte, byte, byte) { return byte((col >> 16) & 0xFF), byte((col >> 8) & 0xFF), byte(col & 0xFF) } // Color is in ARGB (alpha not used right now) type Framebuffer struct { Data []uint Width uint Height uint } // Create a new framebuffer for the given width and height. func NewFramebuffer(width uint, height uint) Framebuffer { return Framebuffer{ Data: make([]uint, width*height), Width: width, Height: height, } } // Sure hope this gets inlined... func (fb *Framebuffer) Set(x uint, y uint, color uint) { fb.Data[x+y*fb.Width] = color } // Given some image data, return a string that is the ppm of it func (fb *Framebuffer) ExportPPM() string { var result strings.Builder result.WriteString(fmt.Sprintf("P3\n%d %d\n255\n", fb.Width, fb.Height)) for y := range fb.Height { for x := range fb.Width { r, g, b := Uint2Col(fb.Data[x+y*fb.Width]) result.WriteString(fmt.Sprintf("%d %d %d\t", r, g, b)) } result.WriteRune('\n') } return result.String() }