graphics: Refactoring: Reduce global variables

This commit is contained in:
Hajime Hoshi 2016-05-15 02:29:54 +09:00
parent e30a12ab6a
commit a3272d0b49
2 changed files with 44 additions and 42 deletions

View File

@ -42,7 +42,7 @@ func drawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
// Let's use them to compare to len(quads) in the future. // Let's use them to compare to len(quads) in the future.
if !shadersInitialized { if !shadersInitialized {
if err := initialize(c); err != nil { if err := theOpenGLState.initialize(c); err != nil {
return err return err
} }
shadersInitialized = true shadersInitialized = true
@ -57,7 +57,8 @@ func drawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
} }
p := programContext{ p := programContext{
program: programTexture, state: &theOpenGLState,
program: theOpenGLState.programTexture,
context: c, context: c,
projectionMatrix: glMatrix(projectionMatrix), projectionMatrix: glMatrix(projectionMatrix),
texture: texture, texture: texture,

View File

@ -20,23 +20,30 @@ import (
"github.com/hajimehoshi/ebiten/internal/graphics/opengl" "github.com/hajimehoshi/ebiten/internal/graphics/opengl"
) )
var ( type openGLState struct {
indexBufferLines opengl.Buffer indexBufferLines opengl.Buffer
indexBufferQuads opengl.Buffer indexBufferQuads opengl.Buffer
)
var (
programTexture opengl.Program programTexture opengl.Program
) lastProgram opengl.Program
lastProjectionMatrix []float32
lastModelviewMatrix []float32
lastColorMatrix []float32
}
const indicesNum = 1 << 16 var theOpenGLState openGLState
const MaxQuads = indicesNum / 6
const (
indicesNum = 1 << 16
MaxQuads = indicesNum / 6
)
// unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS. // unsafe.SizeOf can't be used because unsafe doesn't work with GopherJS.
const int16Size = 2 const (
const float32Size = 4 int16Size = 2
float32Size = 4
)
func initialize(c *opengl.Context) error { func (s *openGLState) initialize(c *opengl.Context) error {
shaderVertexModelviewNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertexModelview)) shaderVertexModelviewNative, err := c.NewShader(c.VertexShader, shader(c, shaderVertexModelview))
if err != nil { if err != nil {
panic(fmt.Sprintf("graphics: shader compiling error:\n%s", err)) panic(fmt.Sprintf("graphics: shader compiling error:\n%s", err))
@ -49,7 +56,7 @@ func initialize(c *opengl.Context) error {
} }
defer c.DeleteShader(shaderFragmentTextureNative) defer c.DeleteShader(shaderFragmentTextureNative)
programTexture, err = c.NewProgram([]opengl.Shader{ s.programTexture, err = c.NewProgram([]opengl.Shader{
shaderVertexModelviewNative, shaderVertexModelviewNative,
shaderFragmentTextureNative, shaderFragmentTextureNative,
}) })
@ -70,13 +77,13 @@ func initialize(c *opengl.Context) error {
indices[6*i+4] = 4*i + 2 indices[6*i+4] = 4*i + 2
indices[6*i+5] = 4*i + 3 indices[6*i+5] = 4*i + 3
} }
indexBufferQuads = c.NewBuffer(c.ElementArrayBuffer, indices, c.StaticDraw) s.indexBufferQuads = c.NewBuffer(c.ElementArrayBuffer, indices, c.StaticDraw)
indices = make([]uint16, indicesNum) indices = make([]uint16, indicesNum)
for i := 0; i < len(indices); i++ { for i := 0; i < len(indices); i++ {
indices[i] = uint16(i) indices[i] = uint16(i)
} }
indexBufferLines = c.NewBuffer(c.ElementArrayBuffer, indices, c.StaticDraw) s.indexBufferLines = c.NewBuffer(c.ElementArrayBuffer, indices, c.StaticDraw)
return nil return nil
} }
@ -93,14 +100,8 @@ func areSameFloat32Array(a, b []float32) bool {
return true return true
} }
var (
lastProgram opengl.Program
lastProjectionMatrix []float32
lastModelviewMatrix []float32
lastColorMatrix []float32
)
type programContext struct { type programContext struct {
state *openGLState
program opengl.Program program opengl.Program
context *opengl.Context context *opengl.Context
projectionMatrix []float32 projectionMatrix []float32
@ -111,21 +112,21 @@ type programContext struct {
func (p *programContext) begin() { func (p *programContext) begin() {
c := p.context c := p.context
if !lastProgram.Equals(p.program) { if !p.state.lastProgram.Equals(p.program) {
c.UseProgram(p.program) c.UseProgram(p.program)
lastProgram = programTexture p.state.lastProgram = p.state.programTexture
lastProjectionMatrix = nil p.state.lastProjectionMatrix = nil
lastModelviewMatrix = nil p.state.lastModelviewMatrix = nil
lastColorMatrix = nil p.state.lastColorMatrix = nil
} }
c.BindElementArrayBuffer(indexBufferQuads) c.BindElementArrayBuffer(p.state.indexBufferQuads)
if !areSameFloat32Array(lastProjectionMatrix, p.projectionMatrix) { if !areSameFloat32Array(p.state.lastProjectionMatrix, p.projectionMatrix) {
c.UniformFloats(p.program, "projection_matrix", p.projectionMatrix) c.UniformFloats(p.program, "projection_matrix", p.projectionMatrix)
if lastProjectionMatrix == nil { if p.state.lastProjectionMatrix == nil {
lastProjectionMatrix = make([]float32, 16) p.state.lastProjectionMatrix = make([]float32, 16)
} }
copy(lastProjectionMatrix, p.projectionMatrix) copy(p.state.lastProjectionMatrix, p.projectionMatrix)
} }
ma := float32(p.geoM.Element(0, 0)) ma := float32(p.geoM.Element(0, 0))
@ -140,12 +141,12 @@ func (p *programContext) begin() {
0, 0, 1, 0, 0, 0, 1, 0,
tx, ty, 0, 1, tx, ty, 0, 1,
} }
if !areSameFloat32Array(lastModelviewMatrix, modelviewMatrix) { if !areSameFloat32Array(p.state.lastModelviewMatrix, modelviewMatrix) {
c.UniformFloats(p.program, "modelview_matrix", modelviewMatrix) c.UniformFloats(p.program, "modelview_matrix", modelviewMatrix)
if lastModelviewMatrix == nil { if p.state.lastModelviewMatrix == nil {
lastModelviewMatrix = make([]float32, 16) p.state.lastModelviewMatrix = make([]float32, 16)
} }
copy(lastModelviewMatrix, modelviewMatrix) copy(p.state.lastModelviewMatrix, modelviewMatrix)
} }
c.UniformInt(p.program, "texture", 0) c.UniformInt(p.program, "texture", 0)
@ -163,12 +164,12 @@ func (p *programContext) begin() {
e[0][2], e[1][2], e[2][2], e[3][2], e[0][2], e[1][2], e[2][2], e[3][2],
e[0][3], e[1][3], e[2][3], e[3][3], e[0][3], e[1][3], e[2][3], e[3][3],
} }
if !areSameFloat32Array(lastColorMatrix, colorMatrix) { if !areSameFloat32Array(p.state.lastColorMatrix, colorMatrix) {
c.UniformFloats(p.program, "color_matrix", colorMatrix) c.UniformFloats(p.program, "color_matrix", colorMatrix)
if lastColorMatrix == nil { if p.state.lastColorMatrix == nil {
lastColorMatrix = make([]float32, 16) p.state.lastColorMatrix = make([]float32, 16)
} }
copy(lastColorMatrix, colorMatrix) copy(p.state.lastColorMatrix, colorMatrix)
} }
colorMatrixTranslation := []float32{ colorMatrixTranslation := []float32{
e[0][4], e[1][4], e[2][4], e[3][4], e[0][4], e[1][4], e[2][4], e[3][4],