Skip to content

Commit

Permalink
Fixes build. Closes #15
Browse files Browse the repository at this point in the history
Refresh this package to the new API of the github.com/go-gl/gl package.
It looses dependency on the github/go-gl/glh package.
  • Loading branch information
mibk committed Jun 28, 2015
1 parent c2a8c0a commit e6a1db6
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 27 deletions.
20 changes: 20 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2012 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gltext

import (
"fmt"

"github.com/go-gl/gl/v2.1/gl"
)

// checkGLError returns an opengl error if one exists.
func checkGLError() error {
errno := gl.GetError()
if errno == gl.NO_ERROR {
return nil
}
return fmt.Errorf("GL error: %d", errno)
}
43 changes: 22 additions & 21 deletions font.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@ package gltext

import (
"fmt"
"github.com/go-gl/gl"
"github.com/go-gl/glh"
"image"
"unsafe"

"github.com/go-gl/gl/v2.1/gl"
)

// A Font allows rendering of text to an OpenGL context.
type Font struct {
config *FontConfig // Character set for this font.
texture gl.Texture // Holds the glyph texture id.
listbase uint // Holds the first display list id.
texture uint32 // Holds the glyph texture id.
listbase uint32 // Holds the first display list id.
maxGlyphWidth int // Largest glyph width.
maxGlyphHeight int // Largest glyph height.
}
Expand All @@ -32,20 +33,20 @@ func loadFont(img *image.RGBA, config *FontConfig) (f *Font, err error) {
f.config = config

// Resize image to next power-of-two.
img = glh.Pow2Image(img).(*image.RGBA)
img = Pow2Image(img).(*image.RGBA)
ib := img.Bounds()

// Create the texture itself. It will contain all glyphs.
// Individual glyph-quads display a subset of this texture.
f.texture = gl.GenTexture()
f.texture.Bind(gl.TEXTURE_2D)
gl.GenTextures(1, &f.texture)
gl.BindTexture(gl.TEXTURE_2D, f.texture)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, ib.Dx(), ib.Dy(), 0,
gl.RGBA, gl.UNSIGNED_BYTE, img.Pix)
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(ib.Dx()), int32(ib.Dy()), 0,
gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(img.Pix))

// Create display lists for each glyph.
f.listbase = gl.GenLists(len(config.Glyphs))
f.listbase = gl.GenLists(int32(len(config.Glyphs)))

texWidth := float32(ib.Dx())
texHeight := float32(ib.Dy())
Expand Down Expand Up @@ -73,7 +74,7 @@ func loadFont(img *image.RGBA, config *FontConfig) (f *Font, err error) {
// Advance width (or height if we render top-to-bottom)
adv := float32(glyph.Advance)

gl.NewList(f.listbase+uint(index), gl.COMPILE)
gl.NewList(f.listbase+uint32(index), gl.COMPILE)
{
gl.Begin(gl.QUADS)
{
Expand All @@ -100,7 +101,7 @@ func loadFont(img *image.RGBA, config *FontConfig) (f *Font, err error) {
gl.EndList()
}

err = glh.CheckGLError()
err = checkGLError()
return
}

Expand All @@ -119,8 +120,8 @@ func (f *Font) Glyphs() Charset { return f.config.Glyphs }
// Release releases font resources.
// A font can no longer be used for rendering after this call completes.
func (f *Font) Release() {
f.texture.Delete()
gl.DeleteLists(f.listbase, len(f.config.Glyphs))
gl.DeleteTextures(1, &f.texture)
gl.DeleteLists(f.listbase, int32(len(f.config.Glyphs)))
f.config = nil
}

Expand Down Expand Up @@ -196,7 +197,7 @@ func (f *Font) Printf(x, y float32, fs string, argv ...interface{}) error {
}

var vp [4]int32
gl.GetIntegerv(gl.VIEWPORT, vp[:])
gl.GetIntegerv(gl.VIEWPORT, &vp[0])

gl.PushAttrib(gl.TRANSFORM_BIT)
gl.MatrixMode(gl.PROJECTION)
Expand All @@ -215,11 +216,11 @@ func (f *Font) Printf(x, y float32, fs string, argv ...interface{}) error {

gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE)
f.texture.Bind(gl.TEXTURE_2D)
gl.BindTexture(gl.TEXTURE_2D, f.texture)
gl.ListBase(f.listbase)

var mv [16]float32
gl.GetFloatv(gl.MODELVIEW_MATRIX, mv[:])
gl.GetFloatv(gl.MODELVIEW_MATRIX, &mv[0])

gl.PushMatrix()
{
Expand All @@ -235,19 +236,19 @@ func (f *Font) Printf(x, y float32, fs string, argv ...interface{}) error {
gl.Translatef(x-mgw, float32(vp[3])-y-mgh, 0)
}

gl.MultMatrixf(&mv)
gl.CallLists(len(indices), gl.UNSIGNED_INT, indices)
gl.MultMatrixf(&mv[0])
gl.CallLists(int32(len(indices)), gl.UNSIGNED_INT, unsafe.Pointer(&indices[0]))
}
gl.PopMatrix()
f.texture.Unbind(gl.TEXTURE_2D)
gl.BindTexture(gl.TEXTURE_2D, 0)
}
gl.PopAttrib()

gl.PushAttrib(gl.TRANSFORM_BIT)
gl.MatrixMode(gl.PROJECTION)
gl.PopMatrix()
gl.PopAttrib()
return glh.CheckGLError()
return checkGLError()
}

// GlyphBounds returns the largest width and height for any of the glyphs
Expand Down
94 changes: 94 additions & 0 deletions pow2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2012 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gltext

import (
"fmt"
"image"
"image/color"
)

// Pow2 returns the first power-of-two value >= to n.
// This can be used to create suitable texture dimensions.
func Pow2(x uint32) uint32 {
x--
x |= x >> 1
x |= x >> 2
x |= x >> 4
x |= x >> 8
x |= x >> 16
return x + 1
}

// IsPow2 returns true if the given value is a power-of-two.
func IsPow2(x uint32) bool { return (x & (x - 1)) == 0 }

// Pow2Image returns the given image, scaled to the smallest power-of-two
// dimensions larger or equal to the input dimensions.
// It preserves the image format and contents.
//
// This is useful if an image is to be used as an OpenGL texture.
// These often require image data to have power-of-two dimensions.
func Pow2Image(src image.Image) image.Image {
sb := src.Bounds()
w, h := uint32(sb.Dx()), uint32(sb.Dy())

if IsPow2(w) && IsPow2(h) {
return src // Nothing to do.
}

rect := image.Rect(0, 0, int(Pow2(w)), int(Pow2(h)))

switch src := src.(type) {
case *image.Alpha:
return copyImg(src, image.NewAlpha(rect))

case *image.Alpha16:
return copyImg(src, image.NewAlpha16(rect))

case *image.Gray:
return copyImg(src, image.NewGray(rect))

case *image.Gray16:
return copyImg(src, image.NewGray16(rect))

case *image.NRGBA:
return copyImg(src, image.NewNRGBA(rect))

case *image.NRGBA64:
return copyImg(src, image.NewNRGBA64(rect))

case *image.Paletted:
return copyImg(src, image.NewPaletted(rect, src.Palette))

case *image.RGBA:
return copyImg(src, image.NewRGBA(rect))

case *image.RGBA64:
return copyImg(src, image.NewRGBA64(rect))
}

panic(fmt.Sprintf("Unsupported image format: %T", src))
}

// Why the image.Image interface does not support this,
// I can never understand.
type copyable interface {
image.Image
Set(x, y int, clr color.Color)
}

func copyImg(src, dst copyable) image.Image {
var x, y int
sb := src.Bounds()

for y = 0; y < sb.Dy(); y++ {
for x = 0; x < sb.Dx(); x++ {
dst.Set(x, y, src.At(x, y))
}
}

return dst
}
43 changes: 43 additions & 0 deletions pow2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2012 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gltext

import (
"testing"
)

func TestPow2(t *testing.T) {
tests := [...][2]uint32{
{0, 0}, {1, 1}, {2, 2}, {3, 4},
{4, 4}, {5, 8}, {6, 8}, {7, 8},
{8, 8}, {9, 16}, {10, 16},
}

for i := range tests {
ret := Pow2(tests[i][0])
if ret != tests[i][1] {
t.Fatalf("Pow2(%d): Want %d, Have %d",
tests[i][0], tests[i][1], ret)
}
}
}

func TestIsPow2(t *testing.T) {
tests := [...]struct {
In uint32
Out bool
}{
{1, true}, {2, true}, {3, false}, {4, true}, {5, false},
{6, false}, {7, false}, {8, true}, {9, false}, {10, false},
}

for i := range tests {
ret := IsPow2(tests[i].In)
if ret != tests[i].Out {
t.Fatalf("isPow2(%d): Want %d, Have %d",
tests[i].In, tests[i].Out, ret)
}
}
}
12 changes: 6 additions & 6 deletions truetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
package gltext

import (
"code.google.com/p/freetype-go/freetype"
"code.google.com/p/freetype-go/freetype/truetype"
"github.com/go-gl/glh"
"image"
"io"
"io/ioutil"

"code.google.com/p/freetype-go/freetype"
"code.google.com/p/freetype-go/freetype/truetype"
)

// http://www.freetype.org/freetype2/docs/tutorial/step2.html

// LoadTruetype loads a truetype font from the given stream and
// LoadTruetype loads a truetype font from the given stream and
// applies the given font scale in points.
//
// The low and high values determine the lower and upper rune limits
Expand Down Expand Up @@ -54,8 +54,8 @@ func LoadTruetype(r io.Reader, scale int32, low, high rune, dir Direction) (*Fon
gb := ttf.Bounds(scale)
gw := (gb.XMax - gb.XMin)
gh := (gb.YMax - gb.YMin) + 5
iw := glh.Pow2(uint32(gw * glyphsPerRow))
ih := glh.Pow2(uint32(gh * glyphsPerCol))
iw := Pow2(uint32(gw * glyphsPerRow))
ih := Pow2(uint32(gh * glyphsPerCol))

rect := image.Rect(0, 0, int(iw), int(ih))
img := image.NewRGBA(rect)
Expand Down

0 comments on commit e6a1db6

Please sign in to comment.