func (s *sheet) makeTexture(pixer <-chan []byte) { gl.Enable(gl.TEXTURE_2D) s.texture = gl.GenTexture() s.texture.Bind(gl.TEXTURE_2D) gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) data := <-pixer glu.Build2DMipmaps(gl.TEXTURE_2D, 4, s.dx, s.dy, gl.RGBA, data) memory.FreeBlock(data) }
func handleLoadRequest(req loadRequest) { f, _ := os.Open(req.path) im, _, err := image.Decode(f) f.Close() if err != nil { return } gray := true dx := im.Bounds().Dx() dy := im.Bounds().Dy() for i := 0; i < dx; i++ { for j := 0; j < dy; j++ { r, g, b, _ := im.At(i, j).RGBA() if r != g || g != b { gray = false break } } if !gray { break } } var canvas draw.Image var pix []byte if gray { ga := NewGrayAlpha(im.Bounds()) pix = ga.Pix canvas = ga } else { pix = memory.GetBlock(4 * req.data.dx * req.data.dy) canvas = &image.RGBA{pix, 4 * req.data.dx, im.Bounds()} } draw.Draw(canvas, im.Bounds(), im, image.Point{}, draw.Src) load_mutex.Lock() load_count += len(pix) manual_unlock := false // This prevents us from trying to send too much to opengl in a single // frame. If we go over the threshold then we hold the lock until we're // done sending data to opengl, then other requests will be free to // queue up and they will run on the next frame. if load_count < load_threshold { load_mutex.Unlock() } else { manual_unlock = true } render.Queue(func() { { gl.Enable(gl.TEXTURE_2D) req.data.texture = gl.GenTexture() req.data.texture.Bind(gl.TEXTURE_2D) gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) } if gray { glu.Build2DMipmaps(gl.TEXTURE_2D, gl.LUMINANCE_ALPHA, req.data.dx, req.data.dy, gl.LUMINANCE_ALPHA, pix) } else { glu.Build2DMipmaps(gl.TEXTURE_2D, gl.RGBA, req.data.dx, req.data.dy, gl.RGBA, pix) } memory.FreeBlock(pix) if manual_unlock { load_count = 0 load_mutex.Unlock() } }) }