func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
	var texture Texture
	if err := c.runOnContextThread(func() error {
		var t uint32
		gl.GenTextures(1, &t)
		// TODO: Use gl.IsTexture
		if t <= 0 {
			return errors.New("opengl: creating texture failed")
		}
		gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4)
		texture = Texture(t)
		return nil
	}); err != nil {
		return 0, err
	}
	if err := c.BindTexture(texture); err != nil {
		return 0, err
	}
	if err := c.runOnContextThread(func() error {
		gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int32(filter))
		gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int32(filter))

		var p interface{}
		if pixels != nil {
			p = pixels
		}
		gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(p))
		return nil
	}); err != nil {
		return 0, err
	}
	return texture, nil
}
Exemple #2
0
func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
	var t uint32
	gl.GenTextures(1, &t)
	if t < 0 {
		return 0, errors.New("glGenTexture failed")
	}
	gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4)
	gl.BindTexture(gl.TEXTURE_2D, t)

	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int32(filter))
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int32(filter))

	var p interface{}
	if pixels != nil {
		p = pixels
	}
	gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(p))

	return Texture(t), nil
}
Exemple #3
0
// PixelStorei sets pixel storage parameters.
//
// http://www.khronos.org/opengles/sdk/docs/man3/html/glPixelStorei.xhtml
func PixelStorei(pname Enum, param int32) {
	gl.PixelStorei(uint32(pname), param)
}
Exemple #4
0
func (stash *Stash) GetGlyph(fnt *Font, codepoint int, isize int16) *Glyph {
	size := float64(isize) / 10

	// Find code point and size.
	h := hashint(uint(codepoint)) & (HASH_LUT_SIZE - 1)
	for i := fnt.lut[h]; i != -1; i = fnt.glyphs[i].next {
		if fnt.glyphs[i].codepoint == codepoint && (fnt.fType == BMFONT || fnt.glyphs[i].size == isize) {
			return fnt.glyphs[i]
		}
	}
	// Could not find glyph.

	// For bitmap fonts: ignore this glyph.
	if fnt.fType == BMFONT {
		return nil
	}

	// For truetype fonts: create this glyph.
	scale := fnt.font.ScaleForPixelHeight(size)
	g := fnt.font.FindGlyphIndex(codepoint)
	if g == 0 {
		// glyph not found
		return nil
	}
	advance, _ := fnt.font.GetGlyphHMetrics(g)
	x0, y0, x1, y1 := fnt.font.GetGlyphBitmapBox(g, scale, scale)
	gw := x1 - x0
	gh := y1 - y0

	// Check if glyph is larger than maximum texture size
	if gw >= stash.tw || gh >= stash.th {
		return nil
	}

	// Find texture and row where the glyph can be fit.
	rh := (int16(gh) + 7) & ^7
	var tt int
	texture := stash.ttTextures[tt]
	var br *Row
	for br == nil {
		for i := range texture.rows {
			if texture.rows[i].h == rh && int(texture.rows[i].x)+gw+1 <= stash.tw {
				br = texture.rows[i]
			}
		}

		// If no row is found, there are 3 possibilities:
		//  - add new row
		//  - try next texture
		//  - create new texture
		if br == nil {
			var py int16
			// Check that there is enough space.
			if len(texture.rows) > 0 {
				py = texture.rows[len(texture.rows)-1].y + texture.rows[len(texture.rows)-1].h + 1
				if int(py+rh) > stash.th {
					if tt < len(stash.ttTextures)-1 {
						tt++
						texture = stash.ttTextures[tt]
					} else {
						// Create new texture
						gl.Enable(gl.TEXTURE_2D)
						texture = &Texture{}
						gl.GenTextures(1, &texture.id)
						gl.BindTexture(gl.TEXTURE_2D, texture.id)
						gl.TexImage2D(gl.TEXTURE_2D, 0, gl.ALPHA,
							int32(stash.tw), int32(stash.th), 0,
							gl.ALPHA, gl.UNSIGNED_BYTE,
							unsafe.Pointer(&stash.emptyData[0]))
						gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
						gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
						gl.Disable(gl.TEXTURE_2D)
						stash.ttTextures = append(stash.ttTextures, texture)
					}
					continue
				}
			}
			// Init and add row
			br = &Row{
				x: 0,
				y: py,
				h: rh,
			}
			texture.rows = append(texture.rows, br)
		}
	}

	// Init glyph.
	glyph := &Glyph{
		codepoint: codepoint,
		size:      isize,
		texture:   texture,
		x0:        int(br.x),
		y0:        int(br.y),
		x1:        int(br.x) + gw,
		y1:        int(br.y) + gh,
		xadv:      scale * float64(advance),
		xoff:      float64(x0),
		yoff:      float64(y0),
		next:      0,
	}
	fnt.glyphs = append(fnt.glyphs, glyph)

	// Advance row location.
	br.x += int16(gw) + 1

	// Insert char to hash lookup.
	glyph.next = fnt.lut[h]
	fnt.lut[h] = len(fnt.glyphs) - 1

	// Rasterize
	bmp := make([]byte, gw*gh)
	bmp = fnt.font.MakeGlyphBitmap(bmp, gw, gh, gw, scale, scale, g)
	if len(bmp) > 0 {
		gl.Enable(gl.TEXTURE_2D)
		// Update texture
		gl.BindTexture(gl.TEXTURE_2D, texture.id)
		gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1)
		gl.TexSubImage2D(gl.TEXTURE_2D, 0, int32(glyph.x0), int32(glyph.y0),
			int32(gw), int32(gh), gl.ALPHA, gl.UNSIGNED_BYTE,
			unsafe.Pointer(&bmp[0]))
		gl.Disable(gl.TEXTURE_2D)
	}

	return glyph
}