Add opengl.Context.NewShader

This commit is contained in:
Hajime Hoshi 2014-12-31 16:12:13 +09:00
parent a4a4c91eb1
commit dc6a153c65
7 changed files with 94 additions and 55 deletions

View File

@ -35,6 +35,7 @@ func newGraphicsContext(c *opengl.Context, screenWidth, screenHeight, screenScal
} }
gc := &graphicsContext{ gc := &graphicsContext{
glContext: c,
defaultR: &innerImage{f, nil}, defaultR: &innerImage{f, nil},
screen: screen, screen: screen,
screenScale: screenScale, screenScale: screenScale,
@ -43,6 +44,7 @@ func newGraphicsContext(c *opengl.Context, screenWidth, screenHeight, screenScal
} }
type graphicsContext struct { type graphicsContext struct {
glContext *opengl.Context
screen *innerImage screen *innerImage
defaultR *innerImage defaultR *innerImage
screenScale int screenScale int
@ -70,7 +72,7 @@ func (c *graphicsContext) postUpdate() error {
options := &DrawImageOptions{ options := &DrawImageOptions{
GeoM: ScaleGeo(scale, scale), GeoM: ScaleGeo(scale, scale),
} }
if err := c.defaultR.drawImage(c.screen, options); err != nil { if err := c.defaultR.drawImage(c.glContext, c.screen, options); err != nil {
return err return err
} }
return nil return nil

View File

@ -48,7 +48,7 @@ func (i *innerImage) Fill(clr color.Color) error {
return i.framebuffer.Fill(r, g, b, a) return i.framebuffer.Fill(r, g, b, a)
} }
func (i *innerImage) drawImage(img *innerImage, options *DrawImageOptions) error { func (i *innerImage) drawImage(c *opengl.Context, img *innerImage, options *DrawImageOptions) error {
if options == nil { if options == nil {
options = &DrawImageOptions{} options = &DrawImageOptions{}
} }
@ -66,7 +66,7 @@ func (i *innerImage) drawImage(img *innerImage, options *DrawImageOptions) error
clr := options.ColorM clr := options.ColorM
w, h := img.size() w, h := img.size()
quads := &textureQuads{parts, w, h} quads := &textureQuads{parts, w, h}
return i.framebuffer.DrawTexture(img.texture, quads, geo, clr) return i.framebuffer.DrawTexture(c, img.texture, quads, geo, clr)
} }
func u(x float64, width int) float32 { func u(x float64, width int) float32 {
@ -152,7 +152,7 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
func (i *Image) drawImage(image *innerImage, option *DrawImageOptions) (err error) { func (i *Image) drawImage(image *innerImage, option *DrawImageOptions) (err error) {
i.pixels = nil i.pixels = nil
i.syncer.Sync(func() { i.syncer.Sync(func() {
err = i.inner.drawImage(image, option) err = i.inner.drawImage(currentUI.glContext, image, option)
}) })
return return
} }

View File

@ -107,11 +107,11 @@ func (f *Framebuffer) Fill(r, g, b, a float64) error {
return f.framebuffer.Fill(r, g, b, a) return f.framebuffer.Fill(r, g, b, a)
} }
func (f *Framebuffer) DrawTexture(t *Texture, quads TextureQuads, geo, clr Matrix) error { func (f *Framebuffer) DrawTexture(c *opengl.Context, t *Texture, quads TextureQuads, geo, clr Matrix) error {
if err := f.setAsViewport(); err != nil { if err := f.setAsViewport(); err != nil {
return err return err
} }
projectionMatrix := f.projectionMatrix() projectionMatrix := f.projectionMatrix()
// TODO: Define texture.Draw() // TODO: Define texture.Draw()
return shader.DrawTexture(gl.Texture(t.native), projectionMatrix, quads, geo, clr) return shader.DrawTexture(c, gl.Texture(t.native), projectionMatrix, quads, geo, clr)
} }

View File

@ -16,6 +16,7 @@ package shader
import ( import (
"github.com/go-gl/gl" "github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/internal/opengl"
) )
func glMatrix(m [4][4]float64) [16]float32 { func glMatrix(m [4][4]float64) [16]float32 {
@ -46,11 +47,11 @@ const size = 10000
const uint16Size = 2 const uint16Size = 2
const float32Size = 4 const float32Size = 4
func DrawTexture(native gl.Texture, projectionMatrix [4][4]float64, quads TextureQuads, geo Matrix, color Matrix) error { func DrawTexture(c *opengl.Context, native gl.Texture, projectionMatrix [4][4]float64, quads TextureQuads, geo Matrix, color Matrix) error {
// TODO: Check len(quads) and gl.MAX_ELEMENTS_INDICES? // TODO: Check len(quads) and gl.MAX_ELEMENTS_INDICES?
const stride = 4 * 4 const stride = 4 * 4
if !initialized { if !initialized {
if err := initialize(); err != nil { if err := initialize(c); err != nil {
return err return err
} }

View File

@ -17,6 +17,7 @@ package shader
import ( import (
"errors" "errors"
"github.com/go-gl/gl" "github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/internal/opengl"
) )
type program struct { type program struct {
@ -35,7 +36,7 @@ func (p *program) create() error {
} }
for _, shaderId := range p.shaderIds { for _, shaderId := range p.shaderIds {
p.native.AttachShader(shaders[shaderId].native) p.native.AttachShader(gl.Shader(shaders[shaderId].native))
} }
p.native.Link() p.native.Link()
if p.native.Get(gl.LINK_STATUS) == gl.FALSE { if p.native.Get(gl.LINK_STATUS) == gl.FALSE {
@ -44,17 +45,19 @@ func (p *program) create() error {
return nil return nil
} }
func initialize() error { func initialize(c *opengl.Context) error {
for _, shader := range shaders { var err error
if err := shader.compile(); err != nil { shaders[shaderVertex].native, err = c.NewShader(c.VertexShader, shaders[shaderVertex].source)
if err != nil {
return err return err
} }
defer shaders[shaderVertex].delete()
shaders[shaderColorMatrix].native, err = c.NewShader(c.FragmentShader, shaders[shaderColorMatrix].source)
if err != nil {
return err
} }
defer func() { defer shaders[shaderColorMatrix].delete()
for _, shader := range shaders {
shader.delete()
}
}()
return programColorMatrix.create() return programColorMatrix.create()
} }

View File

@ -15,14 +15,12 @@
package shader package shader
import ( import (
"errors"
"fmt"
"github.com/go-gl/gl" "github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/internal/opengl"
) )
type shader struct { type shader struct {
native gl.Shader native opengl.Shader
shaderType gl.GLenum
source string source string
} }
@ -35,7 +33,6 @@ const (
var shaders = map[shaderId]*shader{ var shaders = map[shaderId]*shader{
shaderVertex: { shaderVertex: {
shaderType: gl.VERTEX_SHADER,
source: ` source: `
uniform mat4 projection_matrix; uniform mat4 projection_matrix;
uniform mat4 modelview_matrix; uniform mat4 modelview_matrix;
@ -50,7 +47,6 @@ void main(void) {
`, `,
}, },
shaderColorMatrix: { shaderColorMatrix: {
shaderType: gl.FRAGMENT_SHADER,
source: ` source: `
uniform sampler2D texture; uniform sampler2D texture;
uniform mat4 color_matrix; uniform mat4 color_matrix;
@ -76,28 +72,6 @@ void main(void) {
}, },
} }
func (s *shader) compile() error {
s.native = gl.CreateShader(s.shaderType)
if s.native == 0 {
return errors.New("glCreateShader failed")
}
s.native.Source(s.source)
s.native.Compile()
if s.native.Get(gl.COMPILE_STATUS) == gl.FALSE {
return errors.New(fmt.Sprintf("shader compile failed: %s", s.shaderLog()))
}
return nil
}
func (s *shader) shaderLog() string {
if s.native.Get(gl.INFO_LOG_LENGTH) == 0 {
return ""
}
return s.native.GetInfoLog()
}
func (s *shader) delete() { func (s *shader) delete() {
s.native.Delete() gl.Shader(s.native).Delete()
} }

View File

@ -27,10 +27,12 @@ const (
filterLinear = gl.LINEAR filterLinear = gl.LINEAR
) )
type Context struct { type ShaderType int
Nearest Filter
Linear Filter const (
} shaderTypeVertex ShaderType = gl.VERTEX_SHADER
shaderTypeFragment = gl.FRAGMENT_SHADER
)
type Texture gl.Texture type Texture gl.Texture
@ -76,10 +78,31 @@ func (f Framebuffer) Delete() {
gl.Framebuffer(f).Delete() gl.Framebuffer(f).Delete()
} }
type Shader gl.Shader
type Program gl.Program
func (p Program) GetAttribLocation(name string) int {
return int(p.GetAttribLocation(name))
}
func (p Program) GetUniformLocation(name string) int {
return int(p.GetUniformLocation(name))
}
type Context struct {
Nearest Filter
Linear Filter
VertexShader ShaderType
FragmentShader ShaderType
}
func NewContext() *Context { func NewContext() *Context {
c := &Context{ c := &Context{
Nearest: filterNearest, Nearest: filterNearest,
Linear: filterLinear, Linear: filterLinear,
VertexShader: shaderTypeVertex,
FragmentShader: shaderTypeFragment,
} }
c.init() c.init()
return c return c
@ -121,3 +144,39 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
return Framebuffer(f), nil return Framebuffer(f), nil
} }
func (c *Context) NewShader(shaderType ShaderType, source string) (Shader, error) {
s := gl.CreateShader(gl.GLenum(shaderType))
if s == 0 {
println(gl.GetError())
return 0, errors.New("glCreateShader failed")
}
s.Source(source)
s.Compile()
if s.Get(gl.COMPILE_STATUS) == gl.FALSE {
log := ""
if s.Get(gl.INFO_LOG_LENGTH) != 0 {
log = s.GetInfoLog()
}
return 0, errors.New(fmt.Sprintf("shader compile failed: %s", log))
}
return Shader(s), nil
}
func (c *Context) NewProgram() (Program, error) {
p := gl.CreateProgram()
if p == 0 {
return 0, errors.New("glCreateProgram failed")
}
/*for _, shaderId := range p.shaderIds {
p.native.AttachShader(shaders[shaderId].native)
}
p.native.Link()
if p.native.Get(gl.LINK_STATUS) == gl.FALSE {
return errors.New("program error")
}*/
return Program(p), nil
}