mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/graphicscommand: refactoring: add preserved uniform variables at the graphicscommand package
This is a preparation to skip setting unnecessary uniform variables like dstRegion. Updates #2232
This commit is contained in:
parent
72bdd690a1
commit
a5993f09a2
@ -108,22 +108,12 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
|||||||
q.tmpNumVertexFloats += len(vertices)
|
q.tmpNumVertexFloats += len(vertices)
|
||||||
q.tmpNumIndices += len(indices)
|
q.tmpNumIndices += len(indices)
|
||||||
|
|
||||||
if srcs[0] != nil {
|
uniforms = prependPreservedUniforms(uniforms, dst, srcs, offsets, dstRegion, srcRegion)
|
||||||
w, h := srcs[0].InternalSize()
|
|
||||||
srcRegion.X /= float32(w)
|
|
||||||
srcRegion.Y /= float32(h)
|
|
||||||
srcRegion.Width /= float32(w)
|
|
||||||
srcRegion.Height /= float32(h)
|
|
||||||
for i := range offsets {
|
|
||||||
offsets[i][0] /= float32(w)
|
|
||||||
offsets[i][1] /= float32(h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: If dst is the screen, reorder the command to be the last.
|
// TODO: If dst is the screen, reorder the command to be the last.
|
||||||
if !split && 0 < len(q.commands) {
|
if !split && 0 < len(q.commands) {
|
||||||
if last, ok := q.commands[len(q.commands)-1].(*drawTrianglesCommand); ok {
|
if last, ok := q.commands[len(q.commands)-1].(*drawTrianglesCommand); ok {
|
||||||
if last.CanMergeWithDrawTrianglesCommand(dst, srcs, vertices, blend, dstRegion, srcRegion, shader, uniforms, evenOdd) {
|
if last.CanMergeWithDrawTrianglesCommand(dst, srcs, vertices, blend, dstRegion, shader, uniforms, evenOdd) {
|
||||||
last.setVertices(q.lastVertices(len(vertices) + last.numVertices()))
|
last.setVertices(q.lastVertices(len(vertices) + last.numVertices()))
|
||||||
last.addNumIndices(len(indices))
|
last.addNumIndices(len(indices))
|
||||||
return
|
return
|
||||||
@ -134,12 +124,10 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
|||||||
c := q.drawTrianglesCommandPool.get()
|
c := q.drawTrianglesCommandPool.get()
|
||||||
c.dst = dst
|
c.dst = dst
|
||||||
c.srcs = srcs
|
c.srcs = srcs
|
||||||
c.offsets = offsets
|
|
||||||
c.vertices = q.lastVertices(len(vertices))
|
c.vertices = q.lastVertices(len(vertices))
|
||||||
c.nindices = len(indices)
|
c.nindices = len(indices)
|
||||||
c.blend = blend
|
c.blend = blend
|
||||||
c.dstRegion = dstRegion
|
c.dstRegion = dstRegion
|
||||||
c.srcRegion = srcRegion
|
|
||||||
c.shader = shader
|
c.shader = shader
|
||||||
c.uniforms = uniforms
|
c.uniforms = uniforms
|
||||||
c.evenOdd = evenOdd
|
c.evenOdd = evenOdd
|
||||||
@ -258,12 +246,10 @@ func FlushCommands(graphicsDriver graphicsdriver.Graphics, endFrame bool) error
|
|||||||
type drawTrianglesCommand struct {
|
type drawTrianglesCommand struct {
|
||||||
dst *Image
|
dst *Image
|
||||||
srcs [graphics.ShaderImageCount]*Image
|
srcs [graphics.ShaderImageCount]*Image
|
||||||
offsets [graphics.ShaderImageCount - 1][2]float32
|
|
||||||
vertices []float32
|
vertices []float32
|
||||||
nindices int
|
nindices int
|
||||||
blend graphicsdriver.Blend
|
blend graphicsdriver.Blend
|
||||||
dstRegion graphicsdriver.Region
|
dstRegion graphicsdriver.Region
|
||||||
srcRegion graphicsdriver.Region
|
|
||||||
shader *Shader
|
shader *Shader
|
||||||
uniforms [][]float32
|
uniforms [][]float32
|
||||||
evenOdd bool
|
evenOdd bool
|
||||||
@ -317,7 +303,7 @@ func (c *drawTrianglesCommand) Exec(graphicsDriver graphicsdriver.Graphics, inde
|
|||||||
imgs[i] = src.image.ID()
|
imgs[i] = src.image.ID()
|
||||||
}
|
}
|
||||||
|
|
||||||
return graphicsDriver.DrawTriangles(c.dst.image.ID(), imgs, c.offsets, c.shader.shader.ID(), c.nindices, indexOffset, c.blend, c.dstRegion, c.srcRegion, c.uniforms, c.evenOdd)
|
return graphicsDriver.DrawTriangles(c.dst.image.ID(), imgs, c.shader.shader.ID(), c.nindices, indexOffset, c.blend, c.dstRegion, c.uniforms, c.evenOdd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *drawTrianglesCommand) numVertices() int {
|
func (c *drawTrianglesCommand) numVertices() int {
|
||||||
@ -338,7 +324,7 @@ func (c *drawTrianglesCommand) addNumIndices(n int) {
|
|||||||
|
|
||||||
// CanMergeWithDrawTrianglesCommand returns a boolean value indicating whether the other drawTrianglesCommand can be merged
|
// CanMergeWithDrawTrianglesCommand returns a boolean value indicating whether the other drawTrianglesCommand can be merged
|
||||||
// with the drawTrianglesCommand c.
|
// with the drawTrianglesCommand c.
|
||||||
func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, blend graphicsdriver.Blend, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms [][]float32, evenOdd bool) bool {
|
func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, blend graphicsdriver.Blend, dstRegion graphicsdriver.Region, shader *Shader, uniforms [][]float32, evenOdd bool) bool {
|
||||||
if c.shader != shader {
|
if c.shader != shader {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -367,9 +353,6 @@ func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs
|
|||||||
if c.dstRegion != dstRegion {
|
if c.dstRegion != dstRegion {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if c.srcRegion != srcRegion {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if c.evenOdd || evenOdd {
|
if c.evenOdd || evenOdd {
|
||||||
if c.evenOdd && evenOdd {
|
if c.evenOdd && evenOdd {
|
||||||
return !mightOverlapDstRegions(c.vertices, vertices)
|
return !mightOverlapDstRegions(c.vertices, vertices)
|
||||||
@ -572,3 +555,61 @@ func MaxImageSize(graphicsDriver graphicsdriver.Graphics) int {
|
|||||||
})
|
})
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prependPreservedUniforms(uniforms [][]float32, dst *Image, srcs [graphics.ShaderImageCount]*Image, offsets [graphics.ShaderImageCount - 1][2]float32, dstRegion, srcRegion graphicsdriver.Region) [][]float32 {
|
||||||
|
uniforms = append(make([][]float32, graphics.PreservedUniformVariablesCount), uniforms...)
|
||||||
|
|
||||||
|
// Set the destination texture size.
|
||||||
|
dw, dh := dst.InternalSize()
|
||||||
|
uniforms[graphics.TextureDestinationSizeUniformVariableIndex] = []float32{float32(dw), float32(dh)}
|
||||||
|
|
||||||
|
// Set the source texture sizes.
|
||||||
|
usizes := make([]float32, 2*len(srcs))
|
||||||
|
for i, src := range srcs {
|
||||||
|
if src != nil {
|
||||||
|
w, h := src.InternalSize()
|
||||||
|
usizes[2*i] = float32(w)
|
||||||
|
usizes[2*i+1] = float32(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uniforms[graphics.TextureSourceSizesUniformVariableIndex] = usizes
|
||||||
|
|
||||||
|
// Set the destination region.
|
||||||
|
// TODO: Set them only when the shader refers this (#2232).
|
||||||
|
uniforms[graphics.TextureDestinationRegionOriginUniformVariableIndex] = []float32{float32(dstRegion.X) / float32(dw), float32(dstRegion.Y) / float32(dh)}
|
||||||
|
uniforms[graphics.TextureDestinationRegionSizeUniformVariableIndex] = []float32{float32(dstRegion.Width) / float32(dw), float32(dstRegion.Height) / float32(dh)}
|
||||||
|
|
||||||
|
if srcs[0] != nil {
|
||||||
|
w, h := srcs[0].InternalSize()
|
||||||
|
srcRegion.X /= float32(w)
|
||||||
|
srcRegion.Y /= float32(h)
|
||||||
|
srcRegion.Width /= float32(w)
|
||||||
|
srcRegion.Height /= float32(h)
|
||||||
|
for i := range offsets {
|
||||||
|
offsets[i][0] /= float32(w)
|
||||||
|
offsets[i][1] /= float32(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the source offsets.
|
||||||
|
uoffsets := make([]float32, 2*len(offsets))
|
||||||
|
for i, offset := range offsets {
|
||||||
|
uoffsets[2*i] = offset[0]
|
||||||
|
uoffsets[2*i+1] = offset[1]
|
||||||
|
}
|
||||||
|
uniforms[graphics.TextureSourceOffsetsUniformVariableIndex] = uoffsets
|
||||||
|
|
||||||
|
// Set the source region of texture0.
|
||||||
|
// TODO: Set them only when the shader refers this (#2232).
|
||||||
|
uniforms[graphics.TextureSourceRegionOriginUniformVariableIndex] = []float32{float32(srcRegion.X), float32(srcRegion.Y)}
|
||||||
|
uniforms[graphics.TextureSourceRegionSizeUniformVariableIndex] = []float32{float32(srcRegion.Width), float32(srcRegion.Height)}
|
||||||
|
|
||||||
|
uniforms[graphics.ProjectionMatrixUniformVariableIndex] = []float32{
|
||||||
|
2 / float32(dw), 0, 0, 0,
|
||||||
|
0, 2 / float32(dh), 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
-1, -1, 0, 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
return uniforms
|
||||||
|
}
|
||||||
|
@ -1168,7 +1168,7 @@ func (g *Graphics) NewShader(program *shaderir.Program) (graphicsdriver.Shader,
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.ShaderImageCount]graphicsdriver.ImageID, offsets [graphics.ShaderImageCount - 1][2]float32, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, blend graphicsdriver.Blend, dstRegion, srcRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
|
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, blend graphicsdriver.Blend, dstRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
|
||||||
if shaderID == graphicsdriver.InvalidShaderID {
|
if shaderID == graphicsdriver.InvalidShaderID {
|
||||||
return fmt.Errorf("directx: shader ID is invalid")
|
return fmt.Errorf("directx: shader ID is invalid")
|
||||||
}
|
}
|
||||||
@ -1217,45 +1217,15 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.Sh
|
|||||||
|
|
||||||
shader := g.shaders[shaderID]
|
shader := g.shaders[shaderID]
|
||||||
|
|
||||||
// TODO: This logic is very similar to Metal's. Let's unify them.
|
// In DirectX, the NDC's Y direction (upward) and the framebuffer's Y direction (downward) don't
|
||||||
dw, dh := dst.internalSize()
|
// match. Then, the Y direction must be inverted.
|
||||||
us := make([][]float32, graphics.PreservedUniformVariablesCount+len(uniforms))
|
const idx = graphics.ProjectionMatrixUniformVariableIndex
|
||||||
us[graphics.TextureDestinationSizeUniformVariableIndex] = []float32{float32(dw), float32(dh)}
|
uniforms[idx][1] *= -1
|
||||||
usizes := make([]float32, 2*len(srcs))
|
uniforms[idx][5] *= -1
|
||||||
for i, src := range srcImages {
|
uniforms[idx][9] *= -1
|
||||||
if src != nil {
|
uniforms[idx][13] *= -1
|
||||||
w, h := src.internalSize()
|
|
||||||
usizes[2*i] = float32(w)
|
|
||||||
usizes[2*i+1] = float32(h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
us[graphics.TextureSourceSizesUniformVariableIndex] = usizes
|
|
||||||
udorigin := []float32{float32(dstRegion.X) / float32(dw), float32(dstRegion.Y) / float32(dh)}
|
|
||||||
us[graphics.TextureDestinationRegionOriginUniformVariableIndex] = udorigin
|
|
||||||
udsize := []float32{float32(dstRegion.Width) / float32(dw), float32(dstRegion.Height) / float32(dh)}
|
|
||||||
us[graphics.TextureDestinationRegionSizeUniformVariableIndex] = udsize
|
|
||||||
uoffsets := make([]float32, 2*len(offsets))
|
|
||||||
for i, offset := range offsets {
|
|
||||||
uoffsets[2*i] = offset[0]
|
|
||||||
uoffsets[2*i+1] = offset[1]
|
|
||||||
}
|
|
||||||
us[graphics.TextureSourceOffsetsUniformVariableIndex] = uoffsets
|
|
||||||
usorigin := []float32{float32(srcRegion.X), float32(srcRegion.Y)}
|
|
||||||
us[graphics.TextureSourceRegionOriginUniformVariableIndex] = usorigin
|
|
||||||
ussize := []float32{float32(srcRegion.Width), float32(srcRegion.Height)}
|
|
||||||
us[graphics.TextureSourceRegionSizeUniformVariableIndex] = ussize
|
|
||||||
us[graphics.ProjectionMatrixUniformVariableIndex] = []float32{
|
|
||||||
2 / float32(dw), 0, 0, 0,
|
|
||||||
0, -2 / float32(dh), 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
-1, 1, 0, 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, u := range uniforms {
|
flattenUniforms := shader.uniformsToFloat32s(uniforms)
|
||||||
us[graphics.PreservedUniformVariablesCount+i] = u
|
|
||||||
}
|
|
||||||
|
|
||||||
flattenUniforms := shader.uniformsToFloat32s(us)
|
|
||||||
|
|
||||||
w, h := dst.internalSize()
|
w, h := dst.internalSize()
|
||||||
g.needFlushDrawCommandList = true
|
g.needFlushDrawCommandList = true
|
||||||
|
@ -52,7 +52,7 @@ type Graphics interface {
|
|||||||
NewShader(program *shaderir.Program) (Shader, error)
|
NewShader(program *shaderir.Program) (Shader, error)
|
||||||
|
|
||||||
// DrawTriangles draws an image onto another image with the given parameters.
|
// DrawTriangles draws an image onto another image with the given parameters.
|
||||||
DrawTriangles(dst ImageID, srcs [graphics.ShaderImageCount]ImageID, offsets [graphics.ShaderImageCount - 1][2]float32, shader ShaderID, indexLen int, indexOffset int, blend Blend, dstRegion, srcRegion Region, uniforms [][]float32, evenOdd bool) error
|
DrawTriangles(dst ImageID, srcs [graphics.ShaderImageCount]ImageID, shader ShaderID, indexLen int, indexOffset int, blend Blend, dstRegion Region, uniforms [][]float32, evenOdd bool) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphicsNotReady represents that the graphics driver is not ready for recovering from the context lost.
|
// GraphicsNotReady represents that the graphics driver is not ready for recovering from the context lost.
|
||||||
|
@ -503,7 +503,7 @@ func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion graph
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, offsets [graphics.ShaderImageCount - 1][2]float32, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, blend graphicsdriver.Blend, dstRegion, srcRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
|
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, blend graphicsdriver.Blend, dstRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
|
||||||
if shaderID == graphicsdriver.InvalidShaderID {
|
if shaderID == graphicsdriver.InvalidShaderID {
|
||||||
return fmt.Errorf("metal: shader ID is invalid")
|
return fmt.Errorf("metal: shader ID is invalid")
|
||||||
}
|
}
|
||||||
@ -519,58 +519,20 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
|||||||
srcs[i] = g.images[srcID]
|
srcs[i] = g.images[srcID]
|
||||||
}
|
}
|
||||||
|
|
||||||
uniformVars := make([][]float32, graphics.PreservedUniformVariablesCount+len(uniforms))
|
uniformVars := make([][]float32, len(uniforms))
|
||||||
|
|
||||||
// Set the destination texture size.
|
|
||||||
dw, dh := dst.internalSize()
|
|
||||||
uniformVars[graphics.TextureDestinationSizeUniformVariableIndex] = []float32{float32(dw), float32(dh)}
|
|
||||||
|
|
||||||
// Set the source texture sizes.
|
|
||||||
usizes := make([]float32, 2*len(srcs))
|
|
||||||
for i, src := range srcs {
|
|
||||||
if src != nil {
|
|
||||||
w, h := src.internalSize()
|
|
||||||
usizes[2*i] = float32(w)
|
|
||||||
usizes[2*i+1] = float32(h)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uniformVars[graphics.TextureSourceSizesUniformVariableIndex] = usizes
|
|
||||||
|
|
||||||
// Set the destination region's origin.
|
|
||||||
udorigin := []float32{float32(dstRegion.X) / float32(dw), float32(dstRegion.Y) / float32(dh)}
|
|
||||||
uniformVars[graphics.TextureDestinationRegionOriginUniformVariableIndex] = udorigin
|
|
||||||
|
|
||||||
// Set the destination region's size.
|
|
||||||
udsize := []float32{float32(dstRegion.Width) / float32(dw), float32(dstRegion.Height) / float32(dh)}
|
|
||||||
uniformVars[graphics.TextureDestinationRegionSizeUniformVariableIndex] = udsize
|
|
||||||
|
|
||||||
// Set the source offsets.
|
|
||||||
uoffsets := make([]float32, 2*len(offsets))
|
|
||||||
for i, offset := range offsets {
|
|
||||||
uoffsets[2*i] = offset[0]
|
|
||||||
uoffsets[2*i+1] = offset[1]
|
|
||||||
}
|
|
||||||
uniformVars[graphics.TextureSourceOffsetsUniformVariableIndex] = uoffsets
|
|
||||||
|
|
||||||
// Set the source region's origin of texture0.
|
|
||||||
usorigin := []float32{float32(srcRegion.X), float32(srcRegion.Y)}
|
|
||||||
uniformVars[graphics.TextureSourceRegionOriginUniformVariableIndex] = usorigin
|
|
||||||
|
|
||||||
// Set the source region's size of texture0.
|
|
||||||
ussize := []float32{float32(srcRegion.Width), float32(srcRegion.Height)}
|
|
||||||
uniformVars[graphics.TextureSourceRegionSizeUniformVariableIndex] = ussize
|
|
||||||
|
|
||||||
uniformVars[graphics.ProjectionMatrixUniformVariableIndex] = []float32{
|
|
||||||
2 / float32(dw), 0, 0, 0,
|
|
||||||
0, -2 / float32(dh), 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
-1, 1, 0, 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the additional uniform variables.
|
// Set the additional uniform variables.
|
||||||
for i, v := range uniforms {
|
for i, v := range uniforms {
|
||||||
const offset = graphics.PreservedUniformVariablesCount
|
if i == graphics.ProjectionMatrixUniformVariableIndex {
|
||||||
t := g.shaders[shaderID].ir.Uniforms[offset+i]
|
// In Metal, the NDC's Y direction (upward) and the framebuffer's Y direction (downward) don't
|
||||||
|
// match. Then, the Y direction must be inverted.
|
||||||
|
v[1] *= -1
|
||||||
|
v[5] *= -1
|
||||||
|
v[9] *= -1
|
||||||
|
v[13] *= -1
|
||||||
|
}
|
||||||
|
|
||||||
|
t := g.shaders[shaderID].ir.Uniforms[i]
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case shaderir.Mat3:
|
case shaderir.Mat3:
|
||||||
// float3x3 requires 16-byte alignment (#2036).
|
// float3x3 requires 16-byte alignment (#2036).
|
||||||
@ -578,7 +540,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
|||||||
copy(v1[0:3], v[0:3])
|
copy(v1[0:3], v[0:3])
|
||||||
copy(v1[4:7], v[3:6])
|
copy(v1[4:7], v[3:6])
|
||||||
copy(v1[8:11], v[6:9])
|
copy(v1[8:11], v[6:9])
|
||||||
uniformVars[offset+i] = v1
|
uniformVars[i] = v1
|
||||||
case shaderir.Array:
|
case shaderir.Array:
|
||||||
switch t.Sub[0].Main {
|
switch t.Sub[0].Main {
|
||||||
case shaderir.Mat3:
|
case shaderir.Mat3:
|
||||||
@ -590,12 +552,12 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
|||||||
copy(v1[offset1+4:offset1+7], v[offset0+3:offset0+6])
|
copy(v1[offset1+4:offset1+7], v[offset0+3:offset0+6])
|
||||||
copy(v1[offset1+8:offset1+11], v[offset0+6:offset0+9])
|
copy(v1[offset1+8:offset1+11], v[offset0+6:offset0+9])
|
||||||
}
|
}
|
||||||
uniformVars[offset+i] = v1
|
uniformVars[i] = v1
|
||||||
default:
|
default:
|
||||||
uniformVars[offset+i] = v
|
uniformVars[i] = v
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
uniformVars[offset+i] = v
|
uniformVars[i] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ func (g *Graphics) uniformVariableName(idx int) string {
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, offsets [graphics.ShaderImageCount - 1][2]float32, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, blend graphicsdriver.Blend, dstRegion, srcRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
|
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, blend graphicsdriver.Blend, dstRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
|
||||||
if shaderID == graphicsdriver.InvalidShaderID {
|
if shaderID == graphicsdriver.InvalidShaderID {
|
||||||
return fmt.Errorf("opengl: shader ID is invalid")
|
return fmt.Errorf("opengl: shader ID is invalid")
|
||||||
}
|
}
|
||||||
@ -203,101 +203,26 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
|||||||
shader := g.shaders[shaderID]
|
shader := g.shaders[shaderID]
|
||||||
program := shader.p
|
program := shader.p
|
||||||
|
|
||||||
ulen := graphics.PreservedUniformVariablesCount + len(uniforms)
|
ulen := len(uniforms)
|
||||||
if cap(g.uniformVars) < ulen {
|
if cap(g.uniformVars) < ulen {
|
||||||
g.uniformVars = make([]uniformVariable, ulen)
|
g.uniformVars = make([]uniformVariable, ulen)
|
||||||
} else {
|
} else {
|
||||||
g.uniformVars = g.uniformVars[:ulen]
|
g.uniformVars = g.uniformVars[:ulen]
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
const idx = graphics.TextureDestinationSizeUniformVariableIndex
|
|
||||||
w, h := destination.framebufferSize()
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
g.uniformVars[idx].value = []float32{float32(w), float32(h)}
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
sizes := make([]float32, 2*len(srcIDs))
|
|
||||||
for i, srcID := range srcIDs {
|
|
||||||
if img := g.images[srcID]; img != nil {
|
|
||||||
w, h := img.framebufferSize()
|
|
||||||
sizes[2*i] = float32(w)
|
|
||||||
sizes[2*i+1] = float32(h)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
const idx = graphics.TextureSourceSizesUniformVariableIndex
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
g.uniformVars[idx].value = sizes
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
dw, dh := destination.framebufferSize()
|
|
||||||
{
|
|
||||||
origin := []float32{float32(dstRegion.X) / float32(dw), float32(dstRegion.Y) / float32(dh)}
|
|
||||||
const idx = graphics.TextureDestinationRegionOriginUniformVariableIndex
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
g.uniformVars[idx].value = origin
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size := []float32{float32(dstRegion.Width) / float32(dw), float32(dstRegion.Height) / float32(dh)}
|
|
||||||
const idx = graphics.TextureDestinationRegionSizeUniformVariableIndex
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
g.uniformVars[idx].value = size
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
voffsets := make([]float32, 2*len(offsets))
|
|
||||||
for i, o := range offsets {
|
|
||||||
voffsets[2*i] = o[0]
|
|
||||||
voffsets[2*i+1] = o[1]
|
|
||||||
}
|
|
||||||
const idx = graphics.TextureSourceOffsetsUniformVariableIndex
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
g.uniformVars[idx].value = voffsets
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
origin := []float32{float32(srcRegion.X), float32(srcRegion.Y)}
|
|
||||||
const idx = graphics.TextureSourceRegionOriginUniformVariableIndex
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
g.uniformVars[idx].value = origin
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
size := []float32{float32(srcRegion.Width), float32(srcRegion.Height)}
|
|
||||||
const idx = graphics.TextureSourceRegionSizeUniformVariableIndex
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
g.uniformVars[idx].value = size
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const idx = graphics.ProjectionMatrixUniformVariableIndex
|
|
||||||
g.uniformVars[idx].name = g.uniformVariableName(idx)
|
|
||||||
if destination.screen {
|
|
||||||
g.uniformVars[idx].value = []float32{
|
|
||||||
2 / float32(dw), 0, 0, 0,
|
|
||||||
0, -2 / float32(dh), 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
-1, 1, 0, 1,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g.uniformVars[idx].value = []float32{
|
|
||||||
2 / float32(dw), 0, 0, 0,
|
|
||||||
0, 2 / float32(dh), 0, 0,
|
|
||||||
0, 0, 1, 0,
|
|
||||||
-1, -1, 0, 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range uniforms {
|
for i, v := range uniforms {
|
||||||
const offset = graphics.PreservedUniformVariablesCount
|
g.uniformVars[i].name = g.uniformVariableName(i)
|
||||||
g.uniformVars[i+offset].name = g.uniformVariableName(i + offset)
|
g.uniformVars[i].value = v
|
||||||
g.uniformVars[i+offset].value = v
|
g.uniformVars[i].typ = shader.ir.Uniforms[i]
|
||||||
g.uniformVars[i+offset].typ = shader.ir.Uniforms[i+offset]
|
}
|
||||||
|
|
||||||
|
// In OpenGL, the NDC's Y direction (upward), so flip the Y direction for the final framebuffer.
|
||||||
|
if destination.screen {
|
||||||
|
const idx = graphics.ProjectionMatrixUniformVariableIndex
|
||||||
|
g.uniformVars[idx].value[1] *= -1
|
||||||
|
g.uniformVars[idx].value[5] *= -1
|
||||||
|
g.uniformVars[idx].value[9] *= -1
|
||||||
|
g.uniformVars[idx].value[13] *= -1
|
||||||
}
|
}
|
||||||
|
|
||||||
var imgs [graphics.ShaderImageCount]textureVariable
|
var imgs [graphics.ShaderImageCount]textureVariable
|
||||||
|
Loading…
Reference in New Issue
Block a user