add support for Picture slicing (Batch and Window)
This commit is contained in:
parent
3b39cc60e9
commit
c9f445787e
18
batch.go
18
batch.go
|
@ -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
19
util.go
|
@ -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)
|
||||
}
|
||||
|
|
22
window.go
22
window.go
|
@ -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));
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
Loading…
Reference in New Issue