mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
parent
bff760af01
commit
2cc809516f
11
image.go
11
image.go
@ -295,6 +295,13 @@ type Vertex struct {
|
||||
ColorG float32
|
||||
ColorB float32
|
||||
ColorA float32
|
||||
|
||||
// Custom0/Custom1/Custom2/Custom3 represents general-purpose values passed to the shader.
|
||||
// In order to use them, Fragment must have an additional vec4 argument.
|
||||
Custom0 float32
|
||||
Custom1 float32
|
||||
Custom2 float32
|
||||
Custom3 float32
|
||||
}
|
||||
|
||||
var _ [0]byte = [unsafe.Sizeof(Vertex{}) - unsafe.Sizeof(float32(0))*graphics.VertexFloatCount]byte{}
|
||||
@ -668,6 +675,10 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader
|
||||
vs[i*graphics.VertexFloatCount+5] = v.ColorG
|
||||
vs[i*graphics.VertexFloatCount+6] = v.ColorB
|
||||
vs[i*graphics.VertexFloatCount+7] = v.ColorA
|
||||
vs[i*graphics.VertexFloatCount+8] = v.Custom0
|
||||
vs[i*graphics.VertexFloatCount+9] = v.Custom1
|
||||
vs[i*graphics.VertexFloatCount+10] = v.Custom2
|
||||
vs[i*graphics.VertexFloatCount+11] = v.Custom3
|
||||
}
|
||||
|
||||
is := i.ensureTmpIndices(len(indices))
|
||||
|
@ -154,8 +154,8 @@ func imageSrc%[1]dAt(pos vec2) vec4 {
|
||||
shaderSuffix += `
|
||||
var __projectionMatrix mat4
|
||||
|
||||
func __vertex(dstPos vec2, srcPos vec2, color vec4) (vec4, vec2, vec4) {
|
||||
return __projectionMatrix * vec4(dstPos, 0, 1), srcPos, color
|
||||
func __vertex(dstPos vec2, srcPos vec2, color vec4, custom vec4) (vec4, vec2, vec4, vec4) {
|
||||
return __projectionMatrix * vec4(dstPos, 0, 1), srcPos, color, custom
|
||||
}
|
||||
`
|
||||
return shaderSuffix, nil
|
||||
|
@ -39,7 +39,7 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
VertexFloatCount = 8
|
||||
VertexFloatCount = 12
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -345,10 +345,10 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
// Check varying variables.
|
||||
// In testings, there might not be vertex and fragment entry points.
|
||||
if len(vertexOutParams) > 0 && len(fragmentInParams) > 0 {
|
||||
if len(vertexOutParams) != len(fragmentInParams) {
|
||||
cs.addError(0, "the number of vertex entry point's returning values and the number of fragment entry point's params must be the same")
|
||||
}
|
||||
for i, t := range vertexOutParams {
|
||||
if len(fragmentInParams) <= i {
|
||||
break
|
||||
}
|
||||
if !t.Equal(&fragmentInParams[i]) {
|
||||
cs.addError(0, "vertex entry point's returning value types and fragment entry point's param types must match")
|
||||
}
|
||||
@ -373,7 +373,7 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
return
|
||||
}
|
||||
|
||||
// Set attribute varying veraibles.
|
||||
// Set attribute and varying veraibles.
|
||||
cs.ir.Attributes = append(cs.ir.Attributes, vertexInParams...)
|
||||
if len(vertexOutParams) > 0 {
|
||||
// TODO: Check that these params are not arrays or structs
|
||||
@ -820,6 +820,18 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) (function, bool
|
||||
}
|
||||
|
||||
inParams, outParams, returnType := cs.parseFuncParams(block, d.Name.Name, d)
|
||||
if d.Name.Name == cs.fragmentEntry {
|
||||
// The 0th inParams is a special variable for position and is not included in varying variables.
|
||||
if diff := len(cs.ir.Varyings) - (len(inParams) - 1); diff > 0 {
|
||||
// inParams is not enough when the vertex shader has more returning values than the fragment shader's arguments.
|
||||
for i := 0; i < diff; i++ {
|
||||
inParams = append(inParams, variable{
|
||||
name: "_",
|
||||
typ: cs.ir.Varyings[len(inParams)-1+i],
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
b, ok := cs.parseBlock(block, d.Name.Name, d.Body.List, inParams, outParams, returnType, true)
|
||||
if !ok {
|
||||
return function{}, false
|
||||
|
@ -2595,3 +2595,90 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestShaderCustomValues(t *testing.T) {
|
||||
const w, h = 16, 16
|
||||
|
||||
dst := ebiten.NewImage(w, h)
|
||||
s, err := ebiten.NewShader([]byte(`//kage:unit pixels
|
||||
|
||||
package main
|
||||
|
||||
func Fragment(dstPos vec4, srcPos vec2, color vec4, custom vec4) vec4 {
|
||||
return custom
|
||||
}
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
clr := color.RGBA{R: 0x10, G: 0x20, B: 0x30, A: 0x40}
|
||||
dst.DrawTrianglesShader([]ebiten.Vertex{
|
||||
{
|
||||
DstX: 0,
|
||||
DstY: 0,
|
||||
SrcX: 0,
|
||||
SrcY: 0,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
Custom0: float32(clr.R) / 0xff,
|
||||
Custom1: float32(clr.G) / 0xff,
|
||||
Custom2: float32(clr.B) / 0xff,
|
||||
Custom3: float32(clr.A) / 0xff,
|
||||
},
|
||||
{
|
||||
DstX: w,
|
||||
DstY: 0,
|
||||
SrcX: w,
|
||||
SrcY: 0,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
Custom0: float32(clr.R) / 0xff,
|
||||
Custom1: float32(clr.G) / 0xff,
|
||||
Custom2: float32(clr.B) / 0xff,
|
||||
Custom3: float32(clr.A) / 0xff,
|
||||
},
|
||||
{
|
||||
DstX: 0,
|
||||
DstY: h,
|
||||
SrcX: 0,
|
||||
SrcY: h,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
Custom0: float32(clr.R) / 0xff,
|
||||
Custom1: float32(clr.G) / 0xff,
|
||||
Custom2: float32(clr.B) / 0xff,
|
||||
Custom3: float32(clr.A) / 0xff,
|
||||
},
|
||||
{
|
||||
DstX: w,
|
||||
DstY: h,
|
||||
SrcX: w,
|
||||
SrcY: h,
|
||||
ColorR: 1,
|
||||
ColorG: 1,
|
||||
ColorB: 1,
|
||||
ColorA: 1,
|
||||
Custom0: float32(clr.R) / 0xff,
|
||||
Custom1: float32(clr.G) / 0xff,
|
||||
Custom2: float32(clr.B) / 0xff,
|
||||
Custom3: float32(clr.A) / 0xff,
|
||||
},
|
||||
}, []uint16{0, 1, 2, 1, 2, 3}, s, nil)
|
||||
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, j).(color.RGBA)
|
||||
want := clr
|
||||
if !sameColors(got, want, 2) {
|
||||
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user