Simplify shaders

This commit is contained in:
Hajime Hoshi 2014-12-22 21:51:58 +09:00
parent a3b0831472
commit 2620414409
5 changed files with 30 additions and 92 deletions

View File

@ -65,9 +65,8 @@ func (i *innerImage) drawImage(image *innerImage, parts []ImagePart, geo Geometr
if i.texture != nil { if i.texture != nil {
targetNativeTexture = i.texture.Native() targetNativeTexture = i.texture.Native()
} }
w2, h2 := i.size()
projectionMatrix := i.renderTarget.ProjectionMatrix() projectionMatrix := i.renderTarget.ProjectionMatrix()
shader.DrawTexture(image.texture.Native(), targetNativeTexture, w2, h2, projectionMatrix, quads, &geo, &color) shader.DrawTexture(image.texture.Native(), targetNativeTexture, projectionMatrix, quads, &geo, &color)
return nil return nil
} }

View File

@ -18,7 +18,6 @@ package shader
import ( import (
"github.com/go-gl/gl" "github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/internal"
"sync" "sync"
) )
@ -39,7 +38,7 @@ type Matrix interface {
} }
// TODO: Use VBO // TODO: Use VBO
func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projectionMatrix [4][4]float64, quads []TextureQuad, geo Matrix, color Matrix) { func DrawTexture(native gl.Texture, target gl.Texture, projectionMatrix [4][4]float64, quads []TextureQuad, geo Matrix, color Matrix) {
once.Do(func() { once.Do(func() {
initialize() initialize()
}) })
@ -50,7 +49,7 @@ func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projec
// TODO: Check performance // TODO: Check performance
program := gl.Program(0) program := gl.Program(0)
if 0 < target { if 0 < target {
program = useProgramColorMatrix(glMatrix(projectionMatrix), width, height, geo, color) program = useProgramColorMatrix(glMatrix(projectionMatrix), geo, color)
} else { } else {
program = useProgramColorFinal(glMatrix(projectionMatrix), geo) program = useProgramColorFinal(glMatrix(projectionMatrix), geo)
} }
@ -64,32 +63,21 @@ func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projec
} }
vertexAttrLocation := getAttributeLocation(program, "vertex") vertexAttrLocation := getAttributeLocation(program, "vertex")
texCoord0AttrLocation := getAttributeLocation(program, "tex_coord0") texCoordAttrLocation := getAttributeLocation(program, "tex_coord")
texCoord1AttrLocation := gl.AttribLocation(0)
if program == programColorMatrix.native {
texCoord1AttrLocation = getAttributeLocation(program, "tex_coord1")
}
gl.EnableClientState(gl.VERTEX_ARRAY) gl.EnableClientState(gl.VERTEX_ARRAY)
gl.EnableClientState(gl.TEXTURE_COORD_ARRAY) gl.EnableClientState(gl.TEXTURE_COORD_ARRAY)
vertexAttrLocation.EnableArray() vertexAttrLocation.EnableArray()
texCoord0AttrLocation.EnableArray() texCoordAttrLocation.EnableArray()
if program == programColorMatrix.native {
texCoord1AttrLocation.EnableArray()
}
defer func() { defer func() {
if program == programColorMatrix.native { texCoordAttrLocation.DisableArray()
texCoord1AttrLocation.DisableArray()
}
texCoord0AttrLocation.DisableArray()
vertexAttrLocation.DisableArray() vertexAttrLocation.DisableArray()
gl.DisableClientState(gl.TEXTURE_COORD_ARRAY) gl.DisableClientState(gl.TEXTURE_COORD_ARRAY)
gl.DisableClientState(gl.VERTEX_ARRAY) gl.DisableClientState(gl.VERTEX_ARRAY)
}() }()
vertices := []float32{} vertices := []float32{}
texCoords0 := []float32{} texCoords := []float32{}
texCoords1 := []float32{}
indicies := []uint32{} indicies := []uint32{}
// TODO: Check len(quads) and gl.MAX_ELEMENTS_INDICES? // TODO: Check len(quads) and gl.MAX_ELEMENTS_INDICES?
for i, quad := range quads { for i, quad := range quads {
@ -107,26 +95,12 @@ func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projec
u1 := quad.TextureCoordU1 u1 := quad.TextureCoordU1
v0 := quad.TextureCoordV0 v0 := quad.TextureCoordV0
v1 := quad.TextureCoordV1 v1 := quad.TextureCoordV1
texCoords0 = append(texCoords0, texCoords = append(texCoords,
u0, v0, u0, v0,
u1, v0, u1, v0,
u0, v1, u0, v1,
u1, v1, u1, v1,
) )
if program == programColorMatrix.native {
w := float32(internal.NextPowerOf2Int(width))
h := float32(internal.NextPowerOf2Int(height))
xx0 := x0 / w
xx1 := x1 / w
yy0 := y0 / h
yy1 := y1 / h
texCoords1 = append(texCoords1,
xx0, yy0,
xx1, yy0,
xx0, yy1,
xx1, yy1,
)
}
base := uint32(i * 4) base := uint32(i * 4)
indicies = append(indicies, indicies = append(indicies,
base, base+1, base+2, base, base+1, base+2,
@ -134,10 +108,7 @@ func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projec
) )
} }
vertexAttrLocation.AttribPointer(2, gl.FLOAT, false, 0, vertices) vertexAttrLocation.AttribPointer(2, gl.FLOAT, false, 0, vertices)
texCoord0AttrLocation.AttribPointer(2, gl.FLOAT, false, 0, texCoords0) texCoordAttrLocation.AttribPointer(2, gl.FLOAT, false, 0, texCoords)
if program == programColorMatrix.native {
texCoord1AttrLocation.AttribPointer(2, gl.FLOAT, false, 0, texCoords1)
}
gl.DrawElements(gl.TRIANGLES, len(indicies), gl.UNSIGNED_INT, indicies) gl.DrawElements(gl.TRIANGLES, len(indicies), gl.UNSIGNED_INT, indicies)
gl.Flush() gl.Flush()

View File

@ -18,7 +18,6 @@ package shader
import ( import (
"github.com/go-gl/gl" "github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/internal"
) )
type program struct { type program struct {
@ -31,7 +30,7 @@ var programColorMatrix = program{
} }
var programColorFinal = program{ var programColorFinal = program{
shaderIds: []shaderId{shaderVertexFinal, shaderColorFinal}, shaderIds: []shaderId{shaderVertex, shaderColorFinal},
} }
func (p *program) create() { func (p *program) create() {
@ -73,7 +72,7 @@ func getUniformLocation(program gl.Program, name string) gl.UniformLocation {
var lastProgram gl.Program = 0 var lastProgram gl.Program = 0
func useProgramColorMatrix(projectionMatrix [16]float32, width, height int, geo Matrix, color Matrix) gl.Program { func useProgramColorMatrix(projectionMatrix [16]float32, geo Matrix, color Matrix) gl.Program {
if lastProgram != programColorMatrix.native { if lastProgram != programColorMatrix.native {
programColorMatrix.native.Use() programColorMatrix.native.Use()
lastProgram = programColorMatrix.native lastProgram = programColorMatrix.native
@ -97,18 +96,7 @@ func useProgramColorMatrix(projectionMatrix [16]float32, width, height int, geo
} }
getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix) getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix)
txn := tx / float32(internal.NextPowerOf2Int(width)) getUniformLocation(program.native, "texture").Uniform1i(0)
tyn := ty / float32(internal.NextPowerOf2Int(height))
glModelviewMatrixN := [...]float32{
a, c, 0, 0,
b, d, 0, 0,
0, 0, 1, 0,
txn, tyn, 0, 1,
}
getUniformLocation(program.native, "modelview_matrix_n").UniformMatrix4fv(false, glModelviewMatrixN)
getUniformLocation(program.native, "texture0").Uniform1i(0)
getUniformLocation(program.native, "texture1").Uniform1i(1)
e := [4][5]float32{} e := [4][5]float32{}
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
@ -156,7 +144,7 @@ func useProgramColorFinal(projectionMatrix [16]float32, geo Matrix) gl.Program {
} }
getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix) getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix)
getUniformLocation(program.native, "texture0").Uniform1i(0) getUniformLocation(program.native, "texture").Uniform1i(0)
return program.native return program.native
} }

View File

@ -42,31 +42,12 @@ var shaders = map[shaderId]*shader{
source: ` source: `
uniform mat4 projection_matrix; uniform mat4 projection_matrix;
uniform mat4 modelview_matrix; uniform mat4 modelview_matrix;
uniform mat4 modelview_matrix_n;
attribute vec2 vertex; attribute vec2 vertex;
attribute vec2 tex_coord0; attribute vec2 tex_coord;
attribute vec2 tex_coord1; varying vec2 vertex_out_tex_coord;
varying vec2 vertex_out_tex_coord0;
varying vec2 vertex_out_tex_coord1;
void main(void) { void main(void) {
vertex_out_tex_coord0 = tex_coord0; vertex_out_tex_coord = tex_coord;
vertex_out_tex_coord1 = (modelview_matrix_n * vec4(tex_coord1, 0, 1)).xy;
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1);
}
`,
},
shaderVertexFinal: {
shaderType: gl.VERTEX_SHADER,
source: `
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
attribute vec2 vertex;
attribute vec2 tex_coord0;
varying vec2 vertex_out_tex_coord0;
void main(void) {
vertex_out_tex_coord0 = tex_coord0;
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1); gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1);
} }
`, `,
@ -74,37 +55,33 @@ void main(void) {
shaderColorMatrix: { shaderColorMatrix: {
shaderType: gl.FRAGMENT_SHADER, shaderType: gl.FRAGMENT_SHADER,
source: ` source: `
uniform sampler2D texture0; uniform sampler2D texture;
uniform sampler2D texture1;
uniform mat4 color_matrix; uniform mat4 color_matrix;
uniform vec4 color_matrix_translation; uniform vec4 color_matrix_translation;
varying vec2 vertex_out_tex_coord0; varying vec2 vertex_out_tex_coord;
varying vec2 vertex_out_tex_coord1;
void main(void) { void main(void) {
vec4 color0 = texture2D(texture0, vertex_out_tex_coord0); vec4 color = texture2D(texture, vertex_out_tex_coord);
vec4 color1 = texture2D(texture1, vertex_out_tex_coord1);
// Un-premultiply alpha // Un-premultiply alpha
color0.rgb /= color0.a; color.rgb /= color.a;
// Apply the color matrix // Apply the color matrix
color0 = (color_matrix * color0) + color_matrix_translation; color = (color_matrix * color) + color_matrix_translation;
// Premultiply alpha // Premultiply alpha
color0 = clamp(color0, 0.0, 1.0); color = clamp(color, 0.0, 1.0);
color0.rgb *= color0.a; color.rgb *= color.a;
gl_FragColor = color0 + (1.0 - color0.a) * color1; gl_FragColor = color;
} }
`, `,
}, },
shaderColorFinal: { shaderColorFinal: {
shaderType: gl.FRAGMENT_SHADER, shaderType: gl.FRAGMENT_SHADER,
source: ` source: `
uniform sampler2D texture0; uniform sampler2D texture;
varying vec2 vertex_out_tex_coord0; varying vec2 vertex_out_tex_coord;
void main(void) { void main(void) {
vec4 color0 = texture2D(texture0, vertex_out_tex_coord0); gl_FragColor = texture2D(texture, vertex_out_tex_coord);
gl_FragColor = color0;
} }
`, `,
}, },

3
ui.go
View File

@ -52,6 +52,9 @@ func init() {
currentUI.use(func() { currentUI.use(func() {
gl.Init() gl.Init()
gl.Enable(gl.TEXTURE_2D) gl.Enable(gl.TEXTURE_2D)
// Textures' pixel formats are alpha premultiplied.
gl.Enable(gl.BLEND)
gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
}) })
} }