ebiten/internal/graphicsdriver/opengl/context.go

213 lines
5.6 KiB
Go
Raw Normal View History

2016-05-07 12:42:07 +02:00
// Copyright 2016 Hajime Hoshi
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package opengl
import (
2019-02-07 09:19:24 +01:00
"fmt"
"sync"
2019-02-07 09:19:24 +01:00
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
)
type blendFactor int
const (
glDstAlpha blendFactor = 0x304
glDstColor blendFactor = 0x306
glOne blendFactor = 1
glOneMinusDstAlpha blendFactor = 0x305
glOneMinusDstColor blendFactor = 0x307
glOneMinusSrcAlpha blendFactor = 0x303
glOneMinusSrcColor blendFactor = 0x301
glSrcAlpha blendFactor = 0x302
glSrcAlphaSaturate blendFactor = 0x308
glSrcColor blendFactor = 0x300
glZero blendFactor = 0
)
type blendOperation int
const (
glFuncAdd blendOperation = 0x8006
glFuncReverseSubtract blendOperation = 0x800b
glFuncSubtract blendOperation = 0x800a
)
func convertBlendFactor(f graphicsdriver.BlendFactor) blendFactor {
switch f {
case graphicsdriver.BlendFactorZero:
return glZero
case graphicsdriver.BlendFactorOne:
return glOne
case graphicsdriver.BlendFactorSourceColor:
return glSrcColor
case graphicsdriver.BlendFactorOneMinusSourceColor:
return glOneMinusSrcColor
case graphicsdriver.BlendFactorSourceAlpha:
return glSrcAlpha
case graphicsdriver.BlendFactorOneMinusSourceAlpha:
return glOneMinusSrcAlpha
case graphicsdriver.BlendFactorDestinationColor:
return glDstColor
case graphicsdriver.BlendFactorOneMinusDestinationColor:
return glOneMinusDstColor
case graphicsdriver.BlendFactorDestinationAlpha:
return glDstAlpha
case graphicsdriver.BlendFactorOneMinusDestinationAlpha:
return glOneMinusDstAlpha
case graphicsdriver.BlendFactorSourceAlphaSaturated:
return glSrcAlphaSaturate
2018-10-28 12:42:57 +01:00
default:
panic(fmt.Sprintf("opengl: invalid blend factor %d", f))
}
}
func convertBlendOperation(o graphicsdriver.BlendOperation) blendOperation {
switch o {
case graphicsdriver.BlendOperationAdd:
return glFuncAdd
case graphicsdriver.BlendOperationSubtract:
return glFuncSubtract
case graphicsdriver.BlendOperationReverseSubtract:
return glFuncReverseSubtract
default:
panic(fmt.Sprintf("opengl: invalid blend operation %d", o))
2018-10-28 12:42:57 +01:00
}
}
type (
textureNative uint32
renderbufferNative uint32
framebufferNative uint32
shader uint32
program uint32
buffer uint32
)
type (
uniformLocation int32
attribLocation int32
)
const (
invalidFramebuffer = (1 << 32) - 1
invalidUniform = -1
)
type context struct {
ctx gl.Context
2016-05-07 12:42:07 +02:00
locationCache *locationCache
screenFramebuffer framebufferNative // This might not be the default frame buffer '0' (e.g. iOS).
lastFramebuffer framebufferNative
2018-11-04 11:46:20 +01:00
lastTexture textureNative
lastRenderbuffer renderbufferNative
lastViewportWidth int
lastViewportHeight int
lastBlend graphicsdriver.Blend
maxTextureSize int
maxTextureSizeOnce sync.Once
highp bool
highpOnce sync.Once
initOnce sync.Once
contextImpl
2016-05-07 12:42:07 +02:00
}
2016-05-31 19:33:31 +02:00
func (c *context) bindTexture(t textureNative) {
if c.lastTexture == t {
return
}
c.bindTextureImpl(t)
c.lastTexture = t
}
func (c *context) bindRenderbuffer(r renderbufferNative) {
if c.lastRenderbuffer == r {
return
}
c.bindRenderbufferImpl(r)
c.lastRenderbuffer = r
}
func (c *context) bindFramebuffer(f framebufferNative) {
if c.lastFramebuffer == f {
return
}
c.bindFramebufferImpl(f)
c.lastFramebuffer = f
}
func (c *context) setViewport(f *framebuffer) {
c.bindFramebuffer(f.native)
if c.lastViewportWidth != f.width || c.lastViewportHeight != f.height {
2018-11-17 11:29:52 +01:00
// On some environments, viewport size must be within the framebuffer size.
// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
// Use the same size of the framebuffer here.
c.setViewportImpl(f.width, f.height)
2018-11-17 11:29:52 +01:00
// glViewport must be called at least at every frame on iOS.
// As the screen framebuffer is the last render target, next SetViewport should be
// the first call at a frame.
if f.native == c.screenFramebuffer {
c.lastViewportWidth = 0
c.lastViewportHeight = 0
} else {
c.lastViewportWidth = f.width
c.lastViewportHeight = f.height
}
}
2016-05-31 19:33:31 +02:00
}
func (c *context) getScreenFramebuffer() framebufferNative {
return c.screenFramebuffer
}
func (c *context) getMaxTextureSize() int {
c.maxTextureSizeOnce.Do(func() {
c.maxTextureSize = c.maxTextureSizeImpl()
})
return c.maxTextureSize
}
func (c *context) reset() error {
var err1 error
c.initOnce.Do(func() {
// Load OpenGL functions after WGL is initialized especially for Windows (#2452).
if err := c.ctx.LoadFunctions(); err != nil {
err1 = err
return
}
})
if err1 != nil {
return err1
}
c.locationCache = newLocationCache()
c.lastTexture = 0
c.lastFramebuffer = invalidFramebuffer
c.lastViewportWidth = 0
c.lastViewportHeight = 0
c.lastBlend = graphicsdriver.Blend{}
c.ctx.Enable(gl.BLEND)
c.ctx.Enable(gl.SCISSOR_TEST)
c.blend(graphicsdriver.BlendSourceOver)
c.screenFramebuffer = framebufferNative(c.ctx.GetInteger(gl.FRAMEBUFFER_BINDING))
// TODO: Need to update screenFramebufferWidth/Height?
return nil
}