add support for Picture slicing (Batch and Window)

This commit is contained in:
faiface 2017-01-14 16:07:51 +01:00
parent 3b39cc60e9
commit c9f445787e
3 changed files with 53 additions and 10 deletions

View File

@ -13,6 +13,7 @@ import (
// object.Draw(batch)
type Batch struct {
cont TrianglesDrawer
fixpic *Picture
pic *Picture
mat mgl32.Mat3
@ -28,7 +29,7 @@ type Batch struct {
func NewBatch(pic *Picture, container Triangles) *Batch {
return &Batch{
cont: TrianglesDrawer{Triangles: container},
pic: pic,
fixpic: pic,
}
}
@ -39,7 +40,7 @@ func (b *Batch) Clear() {
// Draw draws all objects that are currently in the Batch onto another Target.
func (b *Batch) Draw(t Target) {
t.SetPicture(b.pic)
t.SetPicture(b.fixpic)
b.cont.Draw(t)
}
@ -52,15 +53,16 @@ func (b *Batch) MakeTriangles(t Triangles) Triangles {
}
}
// SetPicture only checks, whether the supplied Picture has the same underlying Picture as the fixed
// Picture of this Batch. If that is not true, this method panics.
// SetPicture sets the current Picture that will be used with the following draws. The underlying
// Texture of this Picture must be same as the underlying Texture of the Batch's Picture.
func (b *Batch) SetPicture(p *Picture) {
if p == nil {
return
}
if p.Texture() != b.pic.Texture() {
panic("batch: attempted to draw with a different Picture")
if p.Texture() != b.fixpic.Texture() {
panic("batch: attempted to draw with a different underlying Picture")
}
b.pic = p
}
// SetTransform sets transforms used in the following draws onto the Batch.
@ -96,7 +98,9 @@ func (bt *batchTriangles) Draw() {
})
bt.data[i].Position = V(float64(transPos.X()), float64(transPos.Y()))
bt.data[i].Color = bt.data[i].Color.Mul(bt.batch.col)
//TODO: texture
if bt.batch.pic != nil && bt.data[i].Texture != V(-1, -1) {
bt.data[i].Texture = pictureBounds(bt.batch.pic, bt.data[i].Texture)
}
}
bt.trans.Update(&bt.data)
bt.batch.cont.Append(bt.trans)

19
util.go
View File

@ -12,6 +12,17 @@ func clamp(x, low, high float64) float64 {
return x
}
func lerp(x float64, a, b Vec) Vec {
return a.Scaled(1-x) + b.Scaled(x)
}
func lerp2d(x, a, b Vec) Vec {
return V(
lerp(x.X(), a, b).X(),
lerp(x.Y(), a, b).Y(),
)
}
func transformToMat(t ...Transform) mgl32.Mat3 {
mat := mgl32.Ident3()
for i := range t {
@ -19,3 +30,11 @@ func transformToMat(t ...Transform) mgl32.Mat3 {
}
return mat
}
func pictureBounds(p *Picture, v Vec) Vec {
w, h := float64(p.Texture().Width()), float64(p.Texture().Height())
a := p.Bounds().Pos
b := p.Bounds().Pos + p.Bounds().Size
u := lerp2d(v, a, b)
return V(u.X()/w, u.Y()/h)
}

View File

@ -66,6 +66,7 @@ type Window struct {
pic *Picture
mat mgl32.Mat3
col mgl32.Vec4
bnd mgl32.Vec4
// need to save these to correctly restore a fullscreen window
restore struct {
@ -374,12 +375,14 @@ func (wt *windowTriangles) Draw() {
pic := wt.w.pic // avoid
mat := wt.w.mat // race
col := wt.w.col // condition
bnd := wt.w.bnd
pixelgl.DoNoBlock(func() {
wt.w.begin()
wt.w.shader.SetUniformAttr(transformMat3, mat)
wt.w.shader.SetUniformAttr(maskColorVec4, col)
wt.w.shader.SetUniformAttr(boundsVec4, bnd)
if pic != nil {
pic.Texture().Begin()
@ -514,6 +517,14 @@ func (w *Window) MakeTriangles(t Triangles) Triangles {
// SetPicture sets a Picture that will be used in subsequent drawings onto the window.
func (w *Window) SetPicture(p *Picture) {
if p != nil {
min := pictureBounds(p, V(0, 0))
max := pictureBounds(p, V(1, 1))
w.bnd = mgl32.Vec4{
float32(min.X()), float32(min.Y()),
float32(max.X()), float32(max.Y()),
}
}
w.pic = p
}
@ -552,11 +563,13 @@ var defaultVertexFormat = pixelgl.AttrFormat{
const (
maskColorVec4 int = iota
transformMat3
boundsVec4
)
var defaultUniformFormat = pixelgl.AttrFormat{
{Name: "maskColor", Type: pixelgl.Vec4},
{Name: "transform", Type: pixelgl.Mat3},
{Name: "bounds", Type: pixelgl.Vec4},
}
var defaultVertexShader = `
@ -587,13 +600,20 @@ in vec2 Texture;
out vec4 color;
uniform vec4 maskColor;
uniform vec4 bounds;
uniform sampler2D tex;
void main() {
vec2 boundsMin = bounds.xy;
vec2 boundsMax = bounds.zw;
float tx = boundsMin.x * (1 - Texture.x) + boundsMax.x * Texture.x;
float ty = boundsMin.y * (1 - Texture.y) + boundsMax.y * Texture.y;
if (Texture == vec2(-1, -1)) {
color = maskColor * Color;
} else {
color = maskColor * Color * texture(tex, vec2(Texture.x, 1 - Texture.y));
color = maskColor * Color * texture(tex, vec2(tx, 1 - ty));
}
}
`