internal/graphicsdriver: refactoring: replace Uniform with []float32

Closes #2016
This commit is contained in:
Hajime Hoshi 2022-03-13 03:42:10 +09:00
parent 35a5c88901
commit 7d0f95e9be
11 changed files with 84 additions and 173 deletions

View File

@ -398,13 +398,13 @@ func (i *Image) processSrc(src *Image) {
// 5: Color G
// 6: Color B
// 7: Color Y
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms [][]float32, evenOdd bool) {
backendsM.Lock()
defer backendsM.Unlock()
i.drawTriangles(srcs, vertices, indices, colorm, mode, filter, address, dstRegion, srcRegion, subimageOffsets, shader, uniforms, evenOdd, false)
}
func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool, keepOnAtlas bool) {
func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms [][]float32, evenOdd bool, keepOnAtlas bool) {
if i.disposed {
panic("atlas: the drawing target image must not be disposed (DrawTriangles)")
}

View File

@ -214,7 +214,7 @@ func (i *Image) replacePendingPixels(pix []byte, x, y, width, height int) {
// DrawTriangles draws the src image with the given vertices.
//
// Copying vertices and indices is the caller's responsibility.
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms [][]float32, evenOdd bool) {
for _, src := range srcs {
if i == src {
panic("buffered: Image.DrawTriangles: source images must be different from the receiver")

View File

@ -140,7 +140,7 @@ func mustUseDifferentVertexBuffer(nextNumVertexFloats, nextNumIndices int) bool
}
// EnqueueDrawTrianglesCommand enqueues a drawing-image command.
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, color affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool) {
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, color affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms [][]float32, evenOdd bool) {
if len(indices) > graphics.IndicesNum {
panic(fmt.Sprintf("graphicscommand: len(indices) must be <= graphics.IndicesNum but not at EnqueueDrawTrianglesCommand: len(indices): %d, graphics.IndicesNum: %d", len(indices), graphics.IndicesNum))
}
@ -363,7 +363,7 @@ type drawTrianglesCommand struct {
dstRegion graphicsdriver.Region
srcRegion graphicsdriver.Region
shader *Shader
uniforms []graphicsdriver.Uniform
uniforms [][]float32
evenOdd bool
}

View File

@ -141,7 +141,7 @@ func (i *Image) InternalSize() (int, int) {
//
// If the source image is not specified, i.e., src is nil and there is no image in the uniform variables, the
// elements for the source image are not used.
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, clr affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, clr affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms [][]float32, evenOdd bool) {
if shader == nil {
// Fast path for rendering without a shader (#1355).
img := srcs[0]

View File

@ -39,11 +39,6 @@ type ColorM interface {
Elements(body *[16]float32, translate *[4]float32)
}
type Uniform struct {
Float32 float32
Float32s []float32
}
type Graphics interface {
Begin()
End(present bool)
@ -70,7 +65,7 @@ type Graphics interface {
//
// * float32
// * []float32
DrawTriangles(dst ImageID, srcs [graphics.ShaderImageNum]ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shader ShaderID, indexLen int, indexOffset int, mode CompositeMode, colorM ColorM, filter Filter, address Address, dstRegion, srcRegion Region, uniforms []Uniform, evenOdd bool) error
DrawTriangles(dst ImageID, srcs [graphics.ShaderImageNum]ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shader ShaderID, indexLen int, indexOffset int, mode CompositeMode, colorM ColorM, filter Filter, address Address, dstRegion, srcRegion Region, uniforms [][]float32, evenOdd bool) error
}
// GraphicsNotReady represents that the graphics driver is not ready for recovering from the context lost.

View File

@ -784,7 +784,7 @@ func (g *Graphics) flushRenderCommandEncoderIfNeeded() {
g.lastDst = nil
}
func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion graphicsdriver.Region, srcs [graphics.ShaderImageNum]*Image, indexLen int, indexOffset int, uniforms []graphicsdriver.Uniform, stencilMode stencilMode) error {
func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion graphicsdriver.Region, srcs [graphics.ShaderImageNum]*Image, indexLen int, indexOffset int, uniforms [][]float32, stencilMode stencilMode) error {
// When prepareing a stencil buffer, flush the current render command encoder
// to make sure the stencil buffer is cleared when loading.
// TODO: What about clearing the stencil buffer by vertices?
@ -847,15 +847,8 @@ func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion graph
g.rce.SetVertexBuffer(g.vb, 0, 0)
for i, u := range uniforms {
if len(u.Float32s) == 0 {
v := u.Float32
g.rce.SetVertexBytes(unsafe.Pointer(&v), unsafe.Sizeof(v), i+1)
g.rce.SetFragmentBytes(unsafe.Pointer(&v), unsafe.Sizeof(v), i+1)
} else {
v := u.Float32s
g.rce.SetVertexBytes(unsafe.Pointer(&v[0]), unsafe.Sizeof(v[0])*uintptr(len(v)), i+1)
g.rce.SetFragmentBytes(unsafe.Pointer(&v[0]), unsafe.Sizeof(v[0])*uintptr(len(v)), i+1)
}
g.rce.SetVertexBytes(unsafe.Pointer(&u[0]), unsafe.Sizeof(u[0])*uintptr(len(u)), i+1)
g.rce.SetFragmentBytes(unsafe.Pointer(&u[0]), unsafe.Sizeof(u[0])*uintptr(len(u)), i+1)
}
for i, src := range srcs {
@ -873,7 +866,7 @@ func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion graph
return nil
}
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageNum]graphicsdriver.ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, mode graphicsdriver.CompositeMode, colorM graphicsdriver.ColorM, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, uniforms []graphicsdriver.Uniform, evenOdd bool) error {
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageNum]graphicsdriver.ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, mode graphicsdriver.CompositeMode, colorM graphicsdriver.ColorM, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
dst := g.images[dstID]
if dst.screen {
@ -886,7 +879,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
}
rpss := map[stencilMode]mtl.RenderPipelineState{}
var uniformVars []graphicsdriver.Uniform
var uniformVars [][]float32
if shaderID == graphicsdriver.InvalidShaderID {
if dst.screen && filter == graphicsdriver.FilterScreen {
rpss[noStencil] = g.screenRPS
@ -921,30 +914,18 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
if filter == graphicsdriver.FilterScreen {
scale = float32(dst.width) / float32(srcs[0].width)
}
uniformVars = []graphicsdriver.Uniform{
uniformVars = [][]float32{
{float32(w), float32(h)},
sourceSize,
esBody[:],
esTranslate[:],
{
Float32s: []float32{float32(w), float32(h)},
},
{
Float32s: sourceSize,
},
{
Float32s: esBody[:],
},
{
Float32s: esTranslate[:],
},
{
Float32s: []float32{
srcRegion.X,
srcRegion.Y,
srcRegion.X + srcRegion.Width,
srcRegion.Y + srcRegion.Height,
},
},
{
Float32: scale,
srcRegion.X,
srcRegion.Y,
srcRegion.X + srcRegion.Width,
srcRegion.Y + srcRegion.Height,
},
{scale},
}
} else {
for _, stencil := range []stencilMode{
@ -959,13 +940,11 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
}
}
uniformVars = make([]graphicsdriver.Uniform, graphics.PreservedUniformVariablesNum+len(uniforms))
uniformVars = make([][]float32, graphics.PreservedUniformVariablesNum+len(uniforms))
// Set the destination texture size.
dw, dh := dst.internalSize()
uniformVars[graphics.TextureDestinationSizeUniformVariableIndex] = graphicsdriver.Uniform{
Float32s: []float32{float32(dw), float32(dh)},
}
uniformVars[graphics.TextureDestinationSizeUniformVariableIndex] = []float32{float32(dw), float32(dh)}
// Set the source texture sizes.
usizes := make([]float32, 2*len(srcs))
@ -976,21 +955,15 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
usizes[2*i+1] = float32(h)
}
}
uniformVars[graphics.TextureSourceSizesUniformVariableIndex] = graphicsdriver.Uniform{
Float32s: usizes,
}
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] = graphicsdriver.Uniform{
Float32s: udorigin,
}
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] = graphicsdriver.Uniform{
Float32s: udsize,
}
uniformVars[graphics.TextureDestinationRegionSizeUniformVariableIndex] = udsize
// Set the source offsets.
uoffsets := make([]float32, 2*len(offsets))
@ -998,21 +971,15 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
uoffsets[2*i] = offset[0]
uoffsets[2*i+1] = offset[1]
}
uniformVars[graphics.TextureSourceOffsetsUniformVariableIndex] = graphicsdriver.Uniform{
Float32s: uoffsets,
}
uniformVars[graphics.TextureSourceOffsetsUniformVariableIndex] = uoffsets
// Set the source region's origin of texture0.
usorigin := []float32{float32(srcRegion.X), float32(srcRegion.Y)}
uniformVars[graphics.TextureSourceRegionOriginUniformVariableIndex] = graphicsdriver.Uniform{
Float32s: usorigin,
}
uniformVars[graphics.TextureSourceRegionOriginUniformVariableIndex] = usorigin
// Set the source region's size of texture0.
ussize := []float32{float32(srcRegion.Width), float32(srcRegion.Height)}
uniformVars[graphics.TextureSourceRegionSizeUniformVariableIndex] = graphicsdriver.Uniform{
Float32s: ussize,
}
uniformVars[graphics.TextureSourceRegionSizeUniformVariableIndex] = ussize
// Set the additional uniform variables.
for i, v := range uniforms {

View File

@ -171,7 +171,7 @@ func (g *Graphics) uniformVariableName(idx int) string {
return name
}
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageNum]graphicsdriver.ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, mode graphicsdriver.CompositeMode, colorM graphicsdriver.ColorM, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, uniforms []graphicsdriver.Uniform, evenOdd bool) error {
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageNum]graphicsdriver.ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shaderID graphicsdriver.ShaderID, indexLen int, indexOffset int, mode graphicsdriver.CompositeMode, colorM graphicsdriver.ColorM, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, uniforms [][]float32, evenOdd bool) error {
destination := g.images[dstID]
g.drawCalled = true
@ -197,20 +197,16 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
dw, dh := destination.framebufferSize()
g.uniformVars = append(g.uniformVars, uniformVariable{
name: "viewport_size",
value: graphicsdriver.Uniform{
Float32s: []float32{float32(dw), float32(dh)},
},
typ: shaderir.Type{Main: shaderir.Vec2},
name: "viewport_size",
value: []float32{float32(dw), float32(dh)},
typ: shaderir.Type{Main: shaderir.Vec2},
}, uniformVariable{
name: "source_region",
value: graphicsdriver.Uniform{
Float32s: []float32{
srcRegion.X,
srcRegion.Y,
srcRegion.X + srcRegion.Width,
srcRegion.Y + srcRegion.Height,
},
value: []float32{
srcRegion.X,
srcRegion.Y,
srcRegion.X + srcRegion.Width,
srcRegion.Y + srcRegion.Height,
},
typ: shaderir.Type{Main: shaderir.Vec4},
})
@ -221,39 +217,31 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
var esTranslate [4]float32
colorM.Elements(&esBody, &esTranslate)
g.uniformVars = append(g.uniformVars, uniformVariable{
name: "color_matrix_body",
value: graphicsdriver.Uniform{
Float32s: esBody[:],
},
typ: shaderir.Type{Main: shaderir.Mat4},
name: "color_matrix_body",
value: esBody[:],
typ: shaderir.Type{Main: shaderir.Mat4},
}, uniformVariable{
name: "color_matrix_translation",
value: graphicsdriver.Uniform{
Float32s: esTranslate[:],
},
typ: shaderir.Type{Main: shaderir.Vec4},
name: "color_matrix_translation",
value: esTranslate[:],
typ: shaderir.Type{Main: shaderir.Vec4},
})
}
if filter != graphicsdriver.FilterNearest {
sw, sh := g.images[srcIDs[0]].framebufferSize()
g.uniformVars = append(g.uniformVars, uniformVariable{
name: "source_size",
value: graphicsdriver.Uniform{
Float32s: []float32{float32(sw), float32(sh)},
},
typ: shaderir.Type{Main: shaderir.Vec2},
name: "source_size",
value: []float32{float32(sw), float32(sh)},
typ: shaderir.Type{Main: shaderir.Vec2},
})
}
if filter == graphicsdriver.FilterScreen {
scale := float32(destination.width) / float32(g.images[srcIDs[0]].width)
g.uniformVars = append(g.uniformVars, uniformVariable{
name: "scale",
value: graphicsdriver.Uniform{
Float32: scale,
},
typ: shaderir.Type{Main: shaderir.Float},
name: "scale",
value: []float32{scale},
typ: shaderir.Type{Main: shaderir.Float},
})
}
} else {
@ -271,7 +259,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
const idx = graphics.TextureDestinationSizeUniformVariableIndex
w, h := destination.framebufferSize()
g.uniformVars[idx].name = g.uniformVariableName(idx)
g.uniformVars[idx].value.Float32s = []float32{float32(w), float32(h)}
g.uniformVars[idx].value = []float32{float32(w), float32(h)}
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
}
{
@ -286,7 +274,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
}
const idx = graphics.TextureSourceSizesUniformVariableIndex
g.uniformVars[idx].name = g.uniformVariableName(idx)
g.uniformVars[idx].value.Float32s = sizes
g.uniformVars[idx].value = sizes
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
}
dw, dh := destination.framebufferSize()
@ -294,14 +282,14 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
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.Float32s = origin
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.Float32s = size
g.uniformVars[idx].value = size
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
}
{
@ -312,21 +300,21 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
}
const idx = graphics.TextureSourceOffsetsUniformVariableIndex
g.uniformVars[idx].name = g.uniformVariableName(idx)
g.uniformVars[idx].value.Float32s = voffsets
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.Float32s = origin
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.Float32s = size
g.uniformVars[idx].value = size
g.uniformVars[idx].typ = shader.ir.Uniforms[idx]
}

View File

@ -132,7 +132,7 @@ type openGLState struct {
programs map[programKey]program
lastProgram program
lastUniforms map[string]graphicsdriver.Uniform
lastUniforms map[string][]float32
lastActiveTexture int
}
@ -242,7 +242,7 @@ func areSameFloat32Array(a, b []float32) bool {
type uniformVariable struct {
name string
value graphicsdriver.Uniform
value []float32
typ shaderir.Type
}
@ -282,41 +282,22 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu
}
for _, u := range uniforms {
if len(u.value.Float32s) == 0 {
if u.typ.Main != shaderir.Float {
expected := &shaderir.Type{Main: shaderir.Float}
got := u.typ
return fmt.Errorf("opengl: uniform variable %s type doesn't match: expected %s but %s", u.name, expected.String(), got.String())
}
cached, ok := g.state.lastUniforms[u.name]
if ok && cached.Float32 == u.value.Float32 {
continue
}
// TODO: Remember whether the location is available or not.
g.context.uniformFloat(program, u.name, u.value.Float32)
if g.state.lastUniforms == nil {
g.state.lastUniforms = map[string]graphicsdriver.Uniform{}
}
g.state.lastUniforms[u.name] = u.value
} else {
if got, expected := len(u.value.Float32s), u.typ.FloatNum(); got != expected {
// Copy a shaderir.Type value once. Do not pass u.typ directly to fmt.Errorf arguments, or
// the value u would be allocated on heap.
typ := u.typ
return fmt.Errorf("opengl: length of a uniform variables %s (%s) doesn't match: expected %d but %d", u.name, typ.String(), expected, got)
}
cached, ok := g.state.lastUniforms[u.name]
if ok && areSameFloat32Array(cached.Float32s, u.value.Float32s) {
continue
}
g.context.uniformFloats(program, u.name, u.value.Float32s, u.typ)
if g.state.lastUniforms == nil {
g.state.lastUniforms = map[string]graphicsdriver.Uniform{}
}
g.state.lastUniforms[u.name] = u.value
if got, expected := len(u.value), u.typ.FloatNum(); got != expected {
// Copy a shaderir.Type value once. Do not pass u.typ directly to fmt.Errorf arguments, or
// the value u would be allocated on heap.
typ := u.typ
return fmt.Errorf("opengl: length of a uniform variables %s (%s) doesn't match: expected %d but %d", u.name, typ.String(), expected, got)
}
cached, ok := g.state.lastUniforms[u.name]
if ok && areSameFloat32Array(cached, u.value) {
continue
}
g.context.uniformFloats(program, u.name, u.value, u.typ)
if g.state.lastUniforms == nil {
g.state.lastUniforms = map[string][]float32{}
}
g.state.lastUniforms[u.name] = u.value
}
var idx int

View File

@ -91,7 +91,7 @@ func (m *Mipmap) Pixels(x, y, width, height int) ([]byte, error) {
return m.orig.Pixels(x, y, width, height)
}
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageNum]*Mipmap, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool, canSkipMipmap bool) {
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageNum]*Mipmap, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, subimageOffsets [graphics.ShaderImageNum - 1][2]float32, shader *Shader, uniforms [][]float32, evenOdd bool, canSkipMipmap bool) {
if len(indices) == 0 {
return
}

View File

@ -76,7 +76,7 @@ type drawTrianglesHistoryItem struct {
dstRegion graphicsdriver.Region
srcRegion graphicsdriver.Region
shader *Shader
uniforms []graphicsdriver.Uniform
uniforms [][]float32
evenOdd bool
}
@ -365,7 +365,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
// 5: Color G
// 6: Color B
// 7: Color Y
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms [][]float32, evenOdd bool) {
if i.priority {
panic("restorable: DrawTriangles cannot be called on a priority image")
}
@ -410,7 +410,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [gra
}
// appendDrawTrianglesHistory appends a draw-image history item to the image.
func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms []graphicsdriver.Uniform, evenOdd bool) {
func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, colorm affine.ColorM, mode graphicsdriver.CompositeMode, filter graphicsdriver.Filter, address graphicsdriver.Address, dstRegion, srcRegion graphicsdriver.Region, shader *Shader, uniforms [][]float32, evenOdd bool) {
if i.stale || i.volatile || i.screen {
return
}

View File

@ -23,7 +23,6 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
"github.com/hajimehoshi/ebiten/v2/internal/graphicscommand"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
"github.com/hajimehoshi/ebiten/v2/internal/mipmap"
"github.com/hajimehoshi/ebiten/v2/internal/shader"
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
@ -186,7 +185,7 @@ func (s *Shader) Dispose() {
s.shader = nil
}
func (s *Shader) convertUniforms(uniforms map[string]interface{}) []graphicsdriver.Uniform {
func (s *Shader) convertUniforms(uniforms map[string]interface{}) [][]float32 {
type index struct {
resultIndex int
shaderUniformIndex int
@ -205,18 +204,14 @@ func (s *Shader) convertUniforms(uniforms map[string]interface{}) []graphicsdriv
idx++
}
us := make([]graphicsdriver.Uniform, len(names))
us := make([][]float32, len(names))
for name, idx := range names {
if v, ok := uniforms[name]; ok {
switch v := v.(type) {
case float32:
us[idx.resultIndex] = graphicsdriver.Uniform{
Float32: v,
}
us[idx.resultIndex] = []float32{v}
case []float32:
us[idx.resultIndex] = graphicsdriver.Uniform{
Float32s: v,
}
us[idx.resultIndex] = v
default:
panic(fmt.Sprintf("ebiten: unexpected uniform value type: %s, %T", name, v))
}
@ -224,25 +219,10 @@ func (s *Shader) convertUniforms(uniforms map[string]interface{}) []graphicsdriv
}
t := s.uniformTypes[idx.shaderUniformIndex]
us[idx.resultIndex] = zeroUniformValue(name, t)
us[idx.resultIndex] = make([]float32, t.FloatNum())
}
// TODO: Panic if uniforms include an invalid name
return us
}
func zeroUniformValue(name string, t shaderir.Type) graphicsdriver.Uniform {
switch t.Main {
case shaderir.Float:
return graphicsdriver.Uniform{
Float32: 0,
}
case shaderir.Array, shaderir.Vec2, shaderir.Vec3, shaderir.Vec4, shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
return graphicsdriver.Uniform{
Float32s: make([]float32, t.FloatNum()),
}
default:
panic(fmt.Sprintf("ebiten: unexpected uniform variable type: %s, %s", name, t.String()))
}
}