Example #1
0
func (s *sheet) compose(pixer chan<- []byte) {
	filename := filepath.Join(s.path, s.name)
	f, err := os.Open(filename)
	if err == nil {
		var length int32
		err := binary.Read(f, binary.LittleEndian, &length)
		if err != nil {
			f.Close()
		} else {
			b := memory.GetBlock(int(length))
			// b := make([]byte, length)
			_, err := f.Read(b)
			f.Close()
			if err == nil {
				pixer <- b
				return
			}
		}
	}
	rect := image.Rect(0, 0, s.dx, s.dy)
	canvas := &image.RGBA{memory.GetBlock(4 * s.dx * s.dy), 4 * s.dx, rect}
	for fid, rect := range s.rects {
		name := s.anim.Node(fid.node).Line(0) + ".png"
		file, err := os.Open(filepath.Join(s.path, fmt.Sprintf("%d", fid.facing), name))
		// if a file isn't there that's ok
		if err != nil {
			continue
		}

		im, _, err := image.Decode(file)
		file.Close()
		// if a file can't be read that is *not* ok, TODO: Log an error or something
		if err != nil {
			continue
		}
		draw.Draw(canvas, image.Rect(rect.X, s.dy-rect.Y, rect.X2, s.dy-rect.Y2), im, image.Point{}, draw.Src)
	}
	f, err = os.Create(filename)
	if err == nil {
		binary.Write(f, binary.LittleEndian, int32(len(canvas.Pix)))
		_, err := f.Write(canvas.Pix)
		f.Close()
		if err != nil {
			os.Remove(filename)
		}
	}
	pixer <- canvas.Pix
}
Example #2
0
func NewGrayAlpha(r image.Rectangle) *GrayAlpha {
	var dx, dy int
	dx = r.Dx()
	// if dx%2 == 1 {
	//   dx++
	// }
	dy = r.Dy()
	return &GrayAlpha{
		Pix:    memory.GetBlock(dx * dy),
		Stride: dx,
		Rect:   r,
	}
}
Example #3
0
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)
			gl.GenTextures(1, (*gl.Uint)(&req.data.texture))
			gl.BindTexture(gl.TEXTURE_2D, req.data.texture)
			gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1)
			gl.TexParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.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 {
			gl.TexImage2D(
				gl.TEXTURE_2D,
				0,
				gl.LUMINANCE_ALPHA,
				gl.Sizei(req.data.dx),
				gl.Sizei(req.data.dy),
				0,
				gl.LUMINANCE_ALPHA,
				gl.BYTE,
				gl.Pointer(&pix[0]))
		} else {
			gl.TexImage2D(
				gl.TEXTURE_2D,
				0,
				gl.RGBA,
				gl.Sizei(req.data.dx),
				gl.Sizei(req.data.dy),
				0,
				gl.RGBA,
				gl.UNSIGNED_BYTE,
				gl.Pointer(&pix[0]))
			// gl.TexImage2D(target, level, internalformat, width, height, border, format, type_, pixels)
			// 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()
		}
	})
}
Example #4
0
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()
		}
	})
}