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{
glContext: c,
defaultR: &innerImage{f, nil},
screen: screen,
screenScale: screenScale,
@ -43,6 +44,7 @@ func newGraphicsContext(c *opengl.Context, screenWidth, screenHeight, screenScal
}
type graphicsContext struct {
glContext *opengl.Context
screen *innerImage
defaultR *innerImage
screenScale int
@ -70,7 +72,7 @@ func (c *graphicsContext) postUpdate() error {
options := &DrawImageOptions{
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 nil

View File

@ -48,7 +48,7 @@ func (i *innerImage) Fill(clr color.Color) error {
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 {
options = &DrawImageOptions{}
}
@ -66,7 +66,7 @@ func (i *innerImage) drawImage(img *innerImage, options *DrawImageOptions) error
clr := options.ColorM
w, h := img.size()
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 {
@ -152,7 +152,7 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
func (i *Image) drawImage(image *innerImage, option *DrawImageOptions) (err error) {
i.pixels = nil
i.syncer.Sync(func() {
err = i.inner.drawImage(image, option)
err = i.inner.drawImage(currentUI.glContext, image, option)
})
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)
}
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 {
return err
}
projectionMatrix := f.projectionMatrix()
// 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 (
"github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/internal/opengl"
)
func glMatrix(m [4][4]float64) [16]float32 {
@ -46,11 +47,11 @@ const size = 10000
const uint16Size = 2
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?
const stride = 4 * 4
if !initialized {
if err := initialize(); err != nil {
if err := initialize(c); err != nil {
return err
}

View File

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

View File

@ -15,14 +15,12 @@
package shader
import (
"errors"
"fmt"
"github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/internal/opengl"
)
type shader struct {
native gl.Shader
shaderType gl.GLenum
native opengl.Shader
source string
}
@ -35,7 +33,6 @@ const (
var shaders = map[shaderId]*shader{
shaderVertex: {
shaderType: gl.VERTEX_SHADER,
source: `
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
@ -50,7 +47,6 @@ void main(void) {
`,
},
shaderColorMatrix: {
shaderType: gl.FRAGMENT_SHADER,
source: `
uniform sampler2D texture;
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() {
s.native.Delete()
gl.Shader(s.native).Delete()
}

View File

@ -27,10 +27,12 @@ const (
filterLinear = gl.LINEAR
)
type Context struct {
Nearest Filter
Linear Filter
}
type ShaderType int
const (
shaderTypeVertex ShaderType = gl.VERTEX_SHADER
shaderTypeFragment = gl.FRAGMENT_SHADER
)
type Texture gl.Texture
@ -76,10 +78,31 @@ func (f Framebuffer) 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 {
c := &Context{
Nearest: filterNearest,
Linear: filterLinear,
VertexShader: shaderTypeVertex,
FragmentShader: shaderTypeFragment,
}
c.init()
return c
@ -121,3 +144,39 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
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
}