mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
Bug fix: the default framebuffer can't bind a texture
This commit is contained in:
parent
b50e82f49d
commit
df35a0ce1e
@ -72,7 +72,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := ebiten.Run(g.Update, screenWidth, screenHeight, 2, "Perspective (Ebiten Demo)"); err != nil {
|
if err := ebiten.Run(g.Update, screenWidth, screenHeight, 2, "Alpha Blending (Ebiten Demo)"); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
|
func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
|
||||||
r, t, err := opengl.NewZeroRenderTarget(screenWidth*screenScale, screenHeight*screenScale, true)
|
r, err := opengl.NewZeroRenderTarget(screenWidth*screenScale, screenHeight*screenScale)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -32,18 +32,14 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &graphicsContext{
|
c := &graphicsContext{
|
||||||
currents: make([]*RenderTarget, 1),
|
currents: make([]*RenderTarget, 1),
|
||||||
defaultR: &RenderTarget{r, &Texture{t}},
|
defaultR: &RenderTarget{r, nil},
|
||||||
screen: screen,
|
screen: screen,
|
||||||
screenWidth: screenWidth,
|
screenWidth: screenWidth,
|
||||||
screenHeight: screenHeight,
|
screenHeight: screenHeight,
|
||||||
screenScale: screenScale,
|
screenScale: screenScale,
|
||||||
}
|
}
|
||||||
|
|
||||||
idsInstance.fillRenderTarget(c.screen, color.RGBA{0, 0, 0, 0})
|
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,17 +88,18 @@ func (c *graphicsContext) PopRenderTarget() {
|
|||||||
func (c *graphicsContext) preUpdate() {
|
func (c *graphicsContext) preUpdate() {
|
||||||
c.currents = c.currents[0:1]
|
c.currents = c.currents[0:1]
|
||||||
c.currents[0] = c.defaultR
|
c.currents[0] = c.defaultR
|
||||||
|
|
||||||
c.PushRenderTarget(c.screen)
|
c.PushRenderTarget(c.screen)
|
||||||
c.Fill(color.RGBA{0, 0, 0, 0xff})
|
c.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) postUpdate() {
|
func (c *graphicsContext) postUpdate() {
|
||||||
c.PopRenderTarget()
|
c.PopRenderTarget()
|
||||||
c.Clear()
|
|
||||||
|
|
||||||
scale := float64(c.screenScale)
|
scale := float64(c.screenScale)
|
||||||
geo := ScaleGeometry(scale, scale)
|
geo := ScaleGeometry(scale, scale)
|
||||||
DrawWholeTexture(c, c.screen.texture, geo, ColorMatrixI())
|
clr := ColorMatrixI()
|
||||||
|
DrawWholeTexture(c, c.screen.texture, geo, clr)
|
||||||
|
|
||||||
gl.Flush()
|
gl.Flush()
|
||||||
}
|
}
|
||||||
|
7
ids.go
7
ids.go
@ -49,6 +49,7 @@ func (i *ids) createRenderTarget(width, height int, filter int) (*RenderTarget,
|
|||||||
texture := &Texture{glTexture}
|
texture := &Texture{glTexture}
|
||||||
// TODO: Is |texture| necessary?
|
// TODO: Is |texture| necessary?
|
||||||
renderTarget := &RenderTarget{glRenderTarget, texture}
|
renderTarget := &RenderTarget{glRenderTarget, texture}
|
||||||
|
i.fillRenderTarget(renderTarget, color.RGBA{0, 0, 0, 0})
|
||||||
|
|
||||||
return renderTarget, nil
|
return renderTarget, nil
|
||||||
}
|
}
|
||||||
@ -72,7 +73,11 @@ func (i *ids) drawTexture(target *RenderTarget, texture *Texture, parts []Textur
|
|||||||
projectionMatrix := target.glRenderTarget.ProjectionMatrix()
|
projectionMatrix := target.glRenderTarget.ProjectionMatrix()
|
||||||
quads := textureQuads(parts, glTexture.Width(), glTexture.Height())
|
quads := textureQuads(parts, glTexture.Width(), glTexture.Height())
|
||||||
w, h := target.Size()
|
w, h := target.Size()
|
||||||
shader.DrawTexture(glTexture.Native(), target.texture.glTexture.Native(), w, h, projectionMatrix, quads, &geo, &color)
|
targetNativeTexture := gl.Texture(0)
|
||||||
|
if target.texture != nil {
|
||||||
|
targetNativeTexture = target.texture.glTexture.Native()
|
||||||
|
}
|
||||||
|
shader.DrawTexture(glTexture.Native(), targetNativeTexture, w, h, projectionMatrix, quads, &geo, &color)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,30 +48,39 @@ func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projec
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO: Check performance
|
// TODO: Check performance
|
||||||
shaderProgram := use(glMatrix(projectionMatrix), width, height, geo, color)
|
program := gl.Program(0)
|
||||||
|
if 0 < target {
|
||||||
|
program = useProgramColorMatrix(glMatrix(projectionMatrix), width, height, geo, color)
|
||||||
|
} else {
|
||||||
|
program = useProgramColorFinal(glMatrix(projectionMatrix), geo)
|
||||||
|
}
|
||||||
|
|
||||||
gl.ActiveTexture(gl.TEXTURE0)
|
gl.ActiveTexture(gl.TEXTURE0)
|
||||||
native.Bind(gl.TEXTURE_2D)
|
native.Bind(gl.TEXTURE_2D)
|
||||||
|
|
||||||
|
if 0 < target {
|
||||||
gl.ActiveTexture(gl.TEXTURE1)
|
gl.ActiveTexture(gl.TEXTURE1)
|
||||||
target.Bind(gl.TEXTURE_2D)
|
target.Bind(gl.TEXTURE_2D)
|
||||||
|
}
|
||||||
|
|
||||||
texture0UniformLocation := getUniformLocation(shaderProgram, "texture0")
|
vertexAttrLocation := getAttributeLocation(program, "vertex")
|
||||||
texture1UniformLocation := getUniformLocation(shaderProgram, "texture1")
|
texCoord0AttrLocation := getAttributeLocation(program, "tex_coord0")
|
||||||
texture0UniformLocation.Uniform1i(0)
|
texCoord1AttrLocation := gl.AttribLocation(0)
|
||||||
texture1UniformLocation.Uniform1i(1)
|
if program == programColorMatrix.native {
|
||||||
|
texCoord1AttrLocation = getAttributeLocation(program, "tex_coord1")
|
||||||
vertexAttrLocation := getAttributeLocation(shaderProgram, "vertex")
|
}
|
||||||
texCoord0AttrLocation := getAttributeLocation(shaderProgram, "tex_coord0")
|
|
||||||
texCoord1AttrLocation := getAttributeLocation(shaderProgram, "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()
|
texCoord0AttrLocation.EnableArray()
|
||||||
|
if program == programColorMatrix.native {
|
||||||
texCoord1AttrLocation.EnableArray()
|
texCoord1AttrLocation.EnableArray()
|
||||||
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
|
if program == programColorMatrix.native {
|
||||||
texCoord1AttrLocation.DisableArray()
|
texCoord1AttrLocation.DisableArray()
|
||||||
|
}
|
||||||
texCoord0AttrLocation.DisableArray()
|
texCoord0AttrLocation.DisableArray()
|
||||||
vertexAttrLocation.DisableArray()
|
vertexAttrLocation.DisableArray()
|
||||||
gl.DisableClientState(gl.TEXTURE_COORD_ARRAY)
|
gl.DisableClientState(gl.TEXTURE_COORD_ARRAY)
|
||||||
@ -104,6 +113,7 @@ func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projec
|
|||||||
u1, v2,
|
u1, v2,
|
||||||
u2, v2,
|
u2, v2,
|
||||||
)
|
)
|
||||||
|
if program == programColorMatrix.native {
|
||||||
w := float32(internal.AdjustSizeForTexture(width))
|
w := float32(internal.AdjustSizeForTexture(width))
|
||||||
h := float32(internal.AdjustSizeForTexture(height))
|
h := float32(internal.AdjustSizeForTexture(height))
|
||||||
xx1 := x1 / w
|
xx1 := x1 / w
|
||||||
@ -116,6 +126,7 @@ func DrawTexture(native gl.Texture, target gl.Texture, width, height int, projec
|
|||||||
xx1, yy2,
|
xx1, yy2,
|
||||||
xx2, yy2,
|
xx2, yy2,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
base := uint32(i * 4)
|
base := uint32(i * 4)
|
||||||
indicies = append(indicies,
|
indicies = append(indicies,
|
||||||
base, base+1, base+2,
|
base, base+1, base+2,
|
||||||
@ -124,7 +135,9 @@ 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)
|
texCoord0AttrLocation.AttribPointer(2, gl.FLOAT, false, 0, texCoords0)
|
||||||
|
if program == programColorMatrix.native {
|
||||||
texCoord1AttrLocation.AttribPointer(2, gl.FLOAT, false, 0, texCoords1)
|
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()
|
||||||
|
@ -30,6 +30,10 @@ var programColorMatrix = program{
|
|||||||
shaderIds: []shaderId{shaderVertex, shaderColorMatrix},
|
shaderIds: []shaderId{shaderVertex, shaderColorMatrix},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var programColorFinal = program{
|
||||||
|
shaderIds: []shaderId{shaderVertexFinal, shaderColorFinal},
|
||||||
|
}
|
||||||
|
|
||||||
func (p *program) create() {
|
func (p *program) create() {
|
||||||
p.native = gl.CreateProgram()
|
p.native = gl.CreateProgram()
|
||||||
if p.native == 0 {
|
if p.native == 0 {
|
||||||
@ -56,32 +60,24 @@ func initialize() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
programColorMatrix.create()
|
programColorMatrix.create()
|
||||||
programColorMatrix.native.Use()
|
programColorFinal.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: This caches are now used only for programColorMatrix
|
|
||||||
var attribLocationCache = map[string]gl.AttribLocation{}
|
|
||||||
var uniformLocationCache = map[string]gl.UniformLocation{}
|
|
||||||
|
|
||||||
func getAttributeLocation(program gl.Program, name string) gl.AttribLocation {
|
func getAttributeLocation(program gl.Program, name string) gl.AttribLocation {
|
||||||
if location, ok := attribLocationCache[name]; ok {
|
return program.GetAttribLocation(name)
|
||||||
return location
|
|
||||||
}
|
|
||||||
location := program.GetAttribLocation(name)
|
|
||||||
attribLocationCache[name] = location
|
|
||||||
return location
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUniformLocation(program gl.Program, name string) gl.UniformLocation {
|
func getUniformLocation(program gl.Program, name string) gl.UniformLocation {
|
||||||
if location, ok := uniformLocationCache[name]; ok {
|
return program.GetUniformLocation(name)
|
||||||
return location
|
|
||||||
}
|
|
||||||
location := program.GetUniformLocation(name)
|
|
||||||
uniformLocationCache[name] = location
|
|
||||||
return location
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func use(projectionMatrix [16]float32, width, height int, geo Matrix, color Matrix) gl.Program {
|
var lastProgram gl.Program = 0
|
||||||
|
|
||||||
|
func useProgramColorMatrix(projectionMatrix [16]float32, width, height int, geo Matrix, color Matrix) gl.Program {
|
||||||
|
if lastProgram != programColorMatrix.native {
|
||||||
|
programColorMatrix.native.Use()
|
||||||
|
lastProgram = programColorMatrix.native
|
||||||
|
}
|
||||||
// TODO: Check the performance.
|
// TODO: Check the performance.
|
||||||
program := programColorMatrix
|
program := programColorMatrix
|
||||||
|
|
||||||
@ -100,6 +96,7 @@ func use(projectionMatrix [16]float32, width, height int, geo Matrix, color Matr
|
|||||||
tx, ty, 0, 1,
|
tx, ty, 0, 1,
|
||||||
}
|
}
|
||||||
getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix)
|
getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix)
|
||||||
|
|
||||||
txn := tx / float32(internal.AdjustSizeForTexture(width))
|
txn := tx / float32(internal.AdjustSizeForTexture(width))
|
||||||
tyn := ty / float32(internal.AdjustSizeForTexture(height))
|
tyn := ty / float32(internal.AdjustSizeForTexture(height))
|
||||||
glModelviewMatrixN := [...]float32{
|
glModelviewMatrixN := [...]float32{
|
||||||
@ -110,7 +107,8 @@ func use(projectionMatrix [16]float32, width, height int, geo Matrix, color Matr
|
|||||||
}
|
}
|
||||||
getUniformLocation(program.native, "modelview_matrix_n").UniformMatrix4fv(false, glModelviewMatrixN)
|
getUniformLocation(program.native, "modelview_matrix_n").UniformMatrix4fv(false, glModelviewMatrixN)
|
||||||
|
|
||||||
getUniformLocation(program.native, "texture").Uniform1i(0)
|
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++ {
|
||||||
@ -133,3 +131,32 @@ func use(projectionMatrix [16]float32, width, height int, geo Matrix, color Matr
|
|||||||
|
|
||||||
return program.native
|
return program.native
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func useProgramColorFinal(projectionMatrix [16]float32, geo Matrix) gl.Program {
|
||||||
|
if lastProgram != programColorFinal.native {
|
||||||
|
programColorFinal.native.Use()
|
||||||
|
lastProgram = programColorFinal.native
|
||||||
|
}
|
||||||
|
|
||||||
|
program := programColorFinal
|
||||||
|
|
||||||
|
getUniformLocation(program.native, "projection_matrix").UniformMatrix4fv(false, projectionMatrix)
|
||||||
|
|
||||||
|
a := float32(geo.Element(0, 0))
|
||||||
|
b := float32(geo.Element(0, 1))
|
||||||
|
c := float32(geo.Element(1, 0))
|
||||||
|
d := float32(geo.Element(1, 1))
|
||||||
|
tx := float32(geo.Element(0, 2))
|
||||||
|
ty := float32(geo.Element(1, 2))
|
||||||
|
glModelviewMatrix := [...]float32{
|
||||||
|
a, c, 0, 0,
|
||||||
|
b, d, 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
tx, ty, 0, 1,
|
||||||
|
}
|
||||||
|
getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix)
|
||||||
|
|
||||||
|
getUniformLocation(program.native, "texture0").Uniform1i(0)
|
||||||
|
|
||||||
|
return program.native
|
||||||
|
}
|
||||||
|
@ -31,9 +31,9 @@ type shaderId int
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
shaderVertex shaderId = iota
|
shaderVertex shaderId = iota
|
||||||
shaderFragment
|
shaderVertexFinal
|
||||||
shaderColorMatrix
|
shaderColorMatrix
|
||||||
shaderSolidColor
|
shaderColorFinal
|
||||||
)
|
)
|
||||||
|
|
||||||
var shaders = map[shaderId]*shader{
|
var shaders = map[shaderId]*shader{
|
||||||
@ -54,6 +54,21 @@ void main(void) {
|
|||||||
vertex_out_tex_coord1 = (modelview_matrix_n * vec4(tex_coord1, 0, 1)).xy;
|
vertex_out_tex_coord1 = (modelview_matrix_n * vec4(tex_coord1, 0, 1)).xy;
|
||||||
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1);
|
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);
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
shaderColorMatrix: {
|
shaderColorMatrix: {
|
||||||
@ -74,6 +89,19 @@ void main(void) {
|
|||||||
gl_FragColor.a = color0.a + color1.a - color0.a * color1.a;
|
gl_FragColor.a = color0.a + color1.a - color0.a * color1.a;
|
||||||
gl_FragColor.rgb = (color0.a * color0.rgb + (1.0 - color0.a) * color1.a * color1.rgb) / gl_FragColor.a;
|
gl_FragColor.rgb = (color0.a * color0.rgb + (1.0 - color0.a) * color1.a * color1.rgb) / gl_FragColor.a;
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
shaderColorFinal: {
|
||||||
|
shaderType: gl.FRAGMENT_SHADER,
|
||||||
|
source: `
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
varying vec2 vertex_out_tex_coord0;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec4 color0 = texture2D(texture0, vertex_out_tex_coord0);
|
||||||
|
gl_FragColor.rgb = color0.a * color0.rgb;
|
||||||
|
gl_FragColor.a = 1.0;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -44,23 +44,13 @@ type RenderTarget struct {
|
|||||||
flipY bool
|
flipY bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZeroRenderTarget(width, height int, flipY bool) (*RenderTarget, *Texture, error) {
|
func NewZeroRenderTarget(width, height int) (*RenderTarget, error) {
|
||||||
r := &RenderTarget{
|
r := &RenderTarget{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
flipY: flipY,
|
flipY: true,
|
||||||
}
|
}
|
||||||
// The framebuffer 0 can't be enlarged, so any filter is acceptable.
|
return r, nil
|
||||||
t, err := NewTexture(width, height, gl.NEAREST)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
// TODO: Does this affect the current rendering target?
|
|
||||||
gl.Framebuffer(0).Bind()
|
|
||||||
if err := framebufferTexture(t.native); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return r, t, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRenderTargetFromTexture(texture *Texture) (*RenderTarget, error) {
|
func NewRenderTargetFromTexture(texture *Texture) (*RenderTarget, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user