mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
internal/graphicsdriver/opengl: reduce context functions
This commit is contained in:
parent
4de6da0a50
commit
95b4e67c77
@ -134,7 +134,7 @@ func (c *context) bindTexture(t textureNative) {
|
|||||||
if c.lastTexture == t {
|
if c.lastTexture == t {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.bindTextureImpl(t)
|
c.ctx.BindTexture(gl.TEXTURE_2D, uint32(t))
|
||||||
c.lastTexture = t
|
c.lastTexture = t
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ func (c *context) bindRenderbuffer(r renderbufferNative) {
|
|||||||
if c.lastRenderbuffer == r {
|
if c.lastRenderbuffer == r {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.bindRenderbufferImpl(r)
|
c.ctx.BindRenderbuffer(gl.RENDERBUFFER, uint32(r))
|
||||||
c.lastRenderbuffer = r
|
c.lastRenderbuffer = r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ func (c *context) bindFramebuffer(f framebufferNative) {
|
|||||||
if c.lastFramebuffer == f {
|
if c.lastFramebuffer == f {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.bindFramebufferImpl(f)
|
c.ctx.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
|
||||||
c.lastFramebuffer = f
|
c.lastFramebuffer = f
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ func (c *context) setViewport(f *framebuffer) {
|
|||||||
// On some environments, viewport size must be within the framebuffer size.
|
// On some environments, viewport size must be within the framebuffer size.
|
||||||
// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
|
// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
|
||||||
// Use the same size of the framebuffer here.
|
// Use the same size of the framebuffer here.
|
||||||
c.setViewportImpl(f.width, f.height)
|
c.ctx.Viewport(0, 0, int32(f.width), int32(f.height))
|
||||||
|
|
||||||
// glViewport must be called at least at every frame on iOS.
|
// glViewport must be called at least at every frame on iOS.
|
||||||
// As the screen framebuffer is the last render target, next SetViewport should be
|
// As the screen framebuffer is the last render target, next SetViewport should be
|
||||||
@ -181,7 +181,7 @@ func (c *context) getScreenFramebuffer() framebufferNative {
|
|||||||
|
|
||||||
func (c *context) getMaxTextureSize() int {
|
func (c *context) getMaxTextureSize() int {
|
||||||
c.maxTextureSizeOnce.Do(func() {
|
c.maxTextureSizeOnce.Do(func() {
|
||||||
c.maxTextureSize = c.maxTextureSizeImpl()
|
c.maxTextureSize = c.ctx.GetInteger(gl.MAX_TEXTURE_SIZE)
|
||||||
})
|
})
|
||||||
return c.maxTextureSize
|
return c.maxTextureSize
|
||||||
}
|
}
|
||||||
@ -231,10 +231,6 @@ func (c *context) blend(blend graphicsdriver.Blend) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) scissor(x, y, width, height int) {
|
|
||||||
c.ctx.Scissor(int32(x), int32(y), int32(width), int32(height))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) newTexture(width, height int) (textureNative, error) {
|
func (c *context) newTexture(width, height int) (textureNative, error) {
|
||||||
t := c.ctx.CreateTexture()
|
t := c.ctx.CreateTexture()
|
||||||
if t <= 0 {
|
if t <= 0 {
|
||||||
@ -260,10 +256,6 @@ func (c *context) newTexture(width, height int) (textureNative, error) {
|
|||||||
return textureNative(t), nil
|
return textureNative(t), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) bindFramebufferImpl(f framebufferNative) {
|
|
||||||
c.ctx.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) framebufferPixels(buf []byte, f *framebuffer, x, y, width, height int) error {
|
func (c *context) framebufferPixels(buf []byte, f *framebuffer, x, y, width, height int) error {
|
||||||
if got, want := len(buf), 4*width*height; got != want {
|
if got, want := len(buf), 4*width*height; got != want {
|
||||||
return fmt.Errorf("opengl: len(buf) must be %d but was %d at framebufferPixels", got, want)
|
return fmt.Errorf("opengl: len(buf) must be %d but was %d at framebufferPixels", got, want)
|
||||||
@ -285,14 +277,6 @@ func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width
|
|||||||
c.ctx.BindBuffer(gl.PIXEL_PACK_BUFFER, 0)
|
c.ctx.BindBuffer(gl.PIXEL_PACK_BUFFER, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) activeTexture(idx int) {
|
|
||||||
c.ctx.ActiveTexture(uint32(gl.TEXTURE0 + idx))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) bindTextureImpl(t textureNative) {
|
|
||||||
c.ctx.BindTexture(gl.TEXTURE_2D, uint32(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) deleteTexture(t textureNative) {
|
func (c *context) deleteTexture(t textureNative) {
|
||||||
if !c.ctx.IsTexture(uint32(t)) {
|
if !c.ctx.IsTexture(uint32(t)) {
|
||||||
return
|
return
|
||||||
@ -303,10 +287,6 @@ func (c *context) deleteTexture(t textureNative) {
|
|||||||
c.ctx.DeleteTexture(uint32(t))
|
c.ctx.DeleteTexture(uint32(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) isTexture(t textureNative) bool {
|
|
||||||
return c.ctx.IsTexture(uint32(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) newRenderbuffer(width, height int) (renderbufferNative, error) {
|
func (c *context) newRenderbuffer(width, height int) (renderbufferNative, error) {
|
||||||
r := c.ctx.CreateRenderbuffer()
|
r := c.ctx.CreateRenderbuffer()
|
||||||
if r <= 0 {
|
if r <= 0 {
|
||||||
@ -344,10 +324,6 @@ func (c *context) newRenderbuffer(width, height int) (renderbufferNative, error)
|
|||||||
return renderbuffer, nil
|
return renderbuffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) bindRenderbufferImpl(r renderbufferNative) {
|
|
||||||
c.ctx.BindRenderbuffer(gl.RENDERBUFFER, uint32(r))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) deleteRenderbuffer(r renderbufferNative) {
|
func (c *context) deleteRenderbuffer(r renderbufferNative) {
|
||||||
if !c.ctx.IsRenderbuffer(uint32(r)) {
|
if !c.ctx.IsRenderbuffer(uint32(r)) {
|
||||||
return
|
return
|
||||||
@ -388,10 +364,6 @@ func (c *context) bindStencilBuffer(f framebufferNative, r renderbufferNative) e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) setViewportImpl(width, height int) {
|
|
||||||
c.ctx.Viewport(0, 0, int32(width), int32(height))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) deleteFramebuffer(f framebufferNative) {
|
func (c *context) deleteFramebuffer(f framebufferNative) {
|
||||||
if !c.ctx.IsFramebuffer(uint32(f)) {
|
if !c.ctx.IsFramebuffer(uint32(f)) {
|
||||||
return
|
return
|
||||||
@ -407,14 +379,6 @@ func (c *context) deleteFramebuffer(f framebufferNative) {
|
|||||||
c.ctx.DeleteFramebuffer(uint32(f))
|
c.ctx.DeleteFramebuffer(uint32(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newVertexShader(source string) (shader, error) {
|
|
||||||
return c.newShader(gl.VERTEX_SHADER, source)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) newFragmentShader(source string) (shader, error) {
|
|
||||||
return c.newShader(gl.FRAGMENT_SHADER, source)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) newShader(shaderType uint32, source string) (shader, error) {
|
func (c *context) newShader(shaderType uint32, source string) (shader, error) {
|
||||||
s := c.ctx.CreateShader(shaderType)
|
s := c.ctx.CreateShader(shaderType)
|
||||||
if s == 0 {
|
if s == 0 {
|
||||||
@ -431,10 +395,6 @@ func (c *context) newShader(shaderType uint32, source string) (shader, error) {
|
|||||||
return shader(s), nil
|
return shader(s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) deleteShader(s shader) {
|
|
||||||
c.ctx.DeleteShader(uint32(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
||||||
p := c.ctx.CreateProgram()
|
p := c.ctx.CreateProgram()
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
@ -457,10 +417,6 @@ func (c *context) newProgram(shaders []shader, attributes []string) (program, er
|
|||||||
return program(p), nil
|
return program(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) useProgram(p program) {
|
|
||||||
c.ctx.UseProgram(uint32(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) deleteProgram(p program) {
|
func (c *context) deleteProgram(p program) {
|
||||||
c.locationCache.deleteProgram(p)
|
c.locationCache.deleteProgram(p)
|
||||||
|
|
||||||
@ -470,10 +426,6 @@ func (c *context) deleteProgram(p program) {
|
|||||||
c.ctx.DeleteProgram(uint32(p))
|
c.ctx.DeleteProgram(uint32(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) getUniformLocationImpl(p program, location string) uniformLocation {
|
|
||||||
return uniformLocation(c.ctx.GetUniformLocation(uint32(p), location))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) uniformInt(p program, location string, v int) bool {
|
func (c *context) uniformInt(p program, location string, v int) bool {
|
||||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||||
if l == invalidUniform {
|
if l == invalidUniform {
|
||||||
@ -517,18 +469,6 @@ func (c *context) uniforms(p program, location string, v []uint32, typ shaderir.
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) vertexAttribPointer(index int, size int, stride int, offset int) {
|
|
||||||
c.ctx.VertexAttribPointer(uint32(index), int32(size), gl.FLOAT, false, int32(stride), offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) enableVertexAttribArray(index int) {
|
|
||||||
c.ctx.EnableVertexAttribArray(uint32(index))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) disableVertexAttribArray(index int) {
|
|
||||||
c.ctx.DisableVertexAttribArray(uint32(index))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) newArrayBuffer(size int) buffer {
|
func (c *context) newArrayBuffer(size int) buffer {
|
||||||
b := c.ctx.CreateBuffer()
|
b := c.ctx.CreateBuffer()
|
||||||
c.ctx.BindBuffer(gl.ARRAY_BUFFER, b)
|
c.ctx.BindBuffer(gl.ARRAY_BUFFER, b)
|
||||||
@ -543,14 +483,6 @@ func (c *context) newElementArrayBuffer(size int) buffer {
|
|||||||
return buffer(b)
|
return buffer(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) bindArrayBuffer(b buffer) {
|
|
||||||
c.ctx.BindBuffer(gl.ARRAY_BUFFER, uint32(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) bindElementArrayBuffer(b buffer) {
|
|
||||||
c.ctx.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, uint32(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) arrayBufferSubData(data []float32) {
|
func (c *context) arrayBufferSubData(data []float32) {
|
||||||
s := unsafe.Slice((*byte)(unsafe.Pointer(&data[0])), len(data)*4)
|
s := unsafe.Slice((*byte)(unsafe.Pointer(&data[0])), len(data)*4)
|
||||||
c.ctx.BufferSubData(gl.ARRAY_BUFFER, 0, s)
|
c.ctx.BufferSubData(gl.ARRAY_BUFFER, 0, s)
|
||||||
@ -560,51 +492,3 @@ func (c *context) elementArrayBufferSubData(data []uint16) {
|
|||||||
s := unsafe.Slice((*byte)(unsafe.Pointer(&data[0])), len(data)*2)
|
s := unsafe.Slice((*byte)(unsafe.Pointer(&data[0])), len(data)*2)
|
||||||
c.ctx.BufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, s)
|
c.ctx.BufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) deleteBuffer(b buffer) {
|
|
||||||
c.ctx.DeleteBuffer(uint32(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) drawElements(len int, offsetInBytes int) {
|
|
||||||
c.ctx.DrawElements(gl.TRIANGLES, int32(len), gl.UNSIGNED_SHORT, offsetInBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) maxTextureSizeImpl() int {
|
|
||||||
return c.ctx.GetInteger(gl.MAX_TEXTURE_SIZE)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) flush() {
|
|
||||||
c.ctx.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) texSubImage2D(t textureNative, args []*graphicsdriver.WritePixelsArgs) {
|
|
||||||
c.bindTexture(t)
|
|
||||||
for _, a := range args {
|
|
||||||
c.ctx.TexSubImage2D(gl.TEXTURE_2D, 0, int32(a.X), int32(a.Y), int32(a.Width), int32(a.Height), gl.RGBA, gl.UNSIGNED_BYTE, a.Pixels)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) enableStencilTest() {
|
|
||||||
c.ctx.Enable(gl.STENCIL_TEST)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) disableStencilTest() {
|
|
||||||
c.ctx.Disable(gl.STENCIL_TEST)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) beginStencilWithEvenOddRule() {
|
|
||||||
c.ctx.Clear(gl.STENCIL_BUFFER_BIT)
|
|
||||||
c.ctx.StencilFunc(gl.ALWAYS, 0x00, 0xff)
|
|
||||||
c.ctx.StencilOp(gl.KEEP, gl.KEEP, gl.INVERT)
|
|
||||||
c.ctx.ColorMask(false, false, false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) endStencilWithEvenOddRule() {
|
|
||||||
c.ctx.StencilFunc(gl.NOTEQUAL, 0x00, 0xff)
|
|
||||||
c.ctx.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
|
|
||||||
c.ctx.ColorMask(true, true, true, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *context) isES() bool {
|
|
||||||
return c.ctx.IsES()
|
|
||||||
}
|
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ func (g *Graphics) Begin() error {
|
|||||||
func (g *Graphics) End(present bool) error {
|
func (g *Graphics) End(present bool) error {
|
||||||
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
||||||
// TODO: examples/sprites worked without this. Is this really needed?
|
// TODO: examples/sprites worked without this. Is this really needed?
|
||||||
g.context.flush()
|
g.context.ctx.Flush()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,27 +232,34 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
|||||||
if err := destination.ensureStencilBuffer(); err != nil {
|
if err := destination.ensureStencilBuffer(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
g.context.enableStencilTest()
|
g.context.ctx.Enable(gl.STENCIL_TEST)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dstRegion := range dstRegions {
|
for _, dstRegion := range dstRegions {
|
||||||
g.context.scissor(
|
g.context.ctx.Scissor(
|
||||||
int(dstRegion.Region.X),
|
int32(dstRegion.Region.X),
|
||||||
int(dstRegion.Region.Y),
|
int32(dstRegion.Region.Y),
|
||||||
int(dstRegion.Region.Width),
|
int32(dstRegion.Region.Width),
|
||||||
int(dstRegion.Region.Height),
|
int32(dstRegion.Region.Height),
|
||||||
)
|
)
|
||||||
if evenOdd {
|
if evenOdd {
|
||||||
g.context.beginStencilWithEvenOddRule()
|
g.context.ctx.Clear(gl.STENCIL_BUFFER_BIT)
|
||||||
g.context.drawElements(dstRegion.IndexCount, indexOffset*2)
|
g.context.ctx.StencilFunc(gl.ALWAYS, 0x00, 0xff)
|
||||||
g.context.endStencilWithEvenOddRule()
|
g.context.ctx.StencilOp(gl.KEEP, gl.KEEP, gl.INVERT)
|
||||||
|
g.context.ctx.ColorMask(false, false, false, false)
|
||||||
|
|
||||||
|
g.context.ctx.DrawElements(gl.TRIANGLES, int32(dstRegion.IndexCount), gl.UNSIGNED_SHORT, indexOffset*2)
|
||||||
|
|
||||||
|
g.context.ctx.StencilFunc(gl.NOTEQUAL, 0x00, 0xff)
|
||||||
|
g.context.ctx.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
|
||||||
|
g.context.ctx.ColorMask(true, true, true, true)
|
||||||
}
|
}
|
||||||
g.context.drawElements(dstRegion.IndexCount, indexOffset*2) // 2 is uint16 size in bytes
|
g.context.ctx.DrawElements(gl.TRIANGLES, int32(dstRegion.IndexCount), gl.UNSIGNED_SHORT, indexOffset*2) // 2 is uint16 size in bytes
|
||||||
indexOffset += dstRegion.IndexCount
|
indexOffset += dstRegion.IndexCount
|
||||||
}
|
}
|
||||||
|
|
||||||
if evenOdd {
|
if evenOdd {
|
||||||
g.context.disableStencilTest()
|
g.context.ctx.Disable(gl.STENCIL_TEST)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -270,7 +278,7 @@ func (g *Graphics) NeedsRestoring() bool {
|
|||||||
if runtime.GOOS == "js" {
|
if runtime.GOOS == "js" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return g.context.isES()
|
return g.context.ctx.IsES()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) NeedsClearingScreen() bool {
|
func (g *Graphics) NeedsClearingScreen() bool {
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (g *Graphics) SetGLFWClientAPI() {
|
func (g *Graphics) SetGLFWClientAPI() {
|
||||||
if g.context.isES() {
|
if g.context.ctx.IsES() {
|
||||||
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLESAPI)
|
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLESAPI)
|
||||||
glfw.WindowHint(glfw.ContextVersionMajor, 2)
|
glfw.WindowHint(glfw.ContextVersionMajor, 2)
|
||||||
glfw.WindowHint(glfw.ContextVersionMinor, 0)
|
glfw.WindowHint(glfw.ContextVersionMinor, 0)
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Image struct {
|
type Image struct {
|
||||||
@ -37,7 +38,7 @@ func (i *Image) ID() graphicsdriver.ImageID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) IsInvalidated() bool {
|
func (i *Image) IsInvalidated() bool {
|
||||||
return !i.graphics.context.isTexture(i.texture)
|
return !i.graphics.context.ctx.IsTexture(uint32(i.texture))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Dispose() {
|
func (i *Image) Dispose() {
|
||||||
@ -132,9 +133,14 @@ func (i *Image) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
|||||||
// glFlush is necessary on Android.
|
// glFlush is necessary on Android.
|
||||||
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
|
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
|
||||||
if i.graphics.drawCalled {
|
if i.graphics.drawCalled {
|
||||||
i.graphics.context.flush()
|
i.graphics.context.ctx.Flush()
|
||||||
}
|
}
|
||||||
i.graphics.drawCalled = false
|
i.graphics.drawCalled = false
|
||||||
i.graphics.context.texSubImage2D(i.texture, args)
|
|
||||||
|
i.graphics.context.bindTexture(i.texture)
|
||||||
|
for _, a := range args {
|
||||||
|
i.graphics.context.ctx.TexSubImage2D(gl.TEXTURE_2D, 0, int32(a.X), int32(a.Y), int32(a.Width), int32(a.Height), gl.RGBA, gl.UNSIGNED_BYTE, a.Pixels)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func (c *locationCache) GetUniformLocation(context *context, p program, location
|
|||||||
}
|
}
|
||||||
l, ok := c.uniformLocationCache[p][location]
|
l, ok := c.uniformLocationCache[p][location]
|
||||||
if !ok {
|
if !ok {
|
||||||
l = context.getUniformLocationImpl(p, location)
|
l = uniformLocation(context.ctx.GetUniformLocation(uint32(p), location))
|
||||||
c.uniformLocationCache[p][location] = l
|
c.uniformLocationCache[p][location] = l
|
||||||
}
|
}
|
||||||
return l
|
return l
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,12 +71,12 @@ func (a *arrayBufferLayout) newArrayBuffer(context *context) buffer {
|
|||||||
// enable starts using the array buffer.
|
// enable starts using the array buffer.
|
||||||
func (a *arrayBufferLayout) enable(context *context) {
|
func (a *arrayBufferLayout) enable(context *context) {
|
||||||
for i := range a.parts {
|
for i := range a.parts {
|
||||||
context.enableVertexAttribArray(i)
|
context.ctx.EnableVertexAttribArray(uint32(i))
|
||||||
}
|
}
|
||||||
total := a.totalBytes()
|
total := a.totalBytes()
|
||||||
offset := 0
|
offset := 0
|
||||||
for i, p := range a.parts {
|
for i, p := range a.parts {
|
||||||
context.vertexAttribPointer(i, p.num, total, offset)
|
context.ctx.VertexAttribPointer(uint32(i), int32(p.num), gl.FLOAT, false, int32(total), offset)
|
||||||
offset += floatSizeInBytes * p.num
|
offset += floatSizeInBytes * p.num
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +85,7 @@ func (a *arrayBufferLayout) enable(context *context) {
|
|||||||
func (a *arrayBufferLayout) disable(context *context) {
|
func (a *arrayBufferLayout) disable(context *context) {
|
||||||
// TODO: Disabling should be done in reversed order?
|
// TODO: Disabling should be done in reversed order?
|
||||||
for i := range a.parts {
|
for i := range a.parts {
|
||||||
context.disableVertexAttribArray(i)
|
context.ctx.DisableVertexAttribArray(uint32(i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +135,7 @@ func (s *openGLState) reset(context *context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.lastProgram = 0
|
s.lastProgram = 0
|
||||||
context.useProgram(0)
|
context.ctx.UseProgram(0)
|
||||||
for key := range s.lastUniforms {
|
for key := range s.lastUniforms {
|
||||||
delete(s.lastUniforms, key)
|
delete(s.lastUniforms, key)
|
||||||
}
|
}
|
||||||
@ -143,10 +144,10 @@ func (s *openGLState) reset(context *context) error {
|
|||||||
// and must not be deleted by DeleteBuffer.
|
// and must not be deleted by DeleteBuffer.
|
||||||
if runtime.GOOS != "js" {
|
if runtime.GOOS != "js" {
|
||||||
if s.arrayBuffer != 0 {
|
if s.arrayBuffer != 0 {
|
||||||
context.deleteBuffer(s.arrayBuffer)
|
context.ctx.DeleteBuffer(uint32(s.arrayBuffer))
|
||||||
}
|
}
|
||||||
if s.elementArrayBuffer != 0 {
|
if s.elementArrayBuffer != 0 {
|
||||||
context.deleteBuffer(s.elementArrayBuffer)
|
context.ctx.DeleteBuffer(uint32(s.elementArrayBuffer))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,11 +200,11 @@ func (g *Graphics) textureVariableName(idx int) string {
|
|||||||
// useProgram uses the program (programTexture).
|
// useProgram uses the program (programTexture).
|
||||||
func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textures [graphics.ShaderImageCount]textureVariable) error {
|
func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textures [graphics.ShaderImageCount]textureVariable) error {
|
||||||
if g.state.lastProgram != program {
|
if g.state.lastProgram != program {
|
||||||
g.context.useProgram(program)
|
g.context.ctx.UseProgram(uint32(program))
|
||||||
if g.state.lastProgram == 0 {
|
if g.state.lastProgram == 0 {
|
||||||
theArrayBufferLayout.enable(&g.context)
|
theArrayBufferLayout.enable(&g.context)
|
||||||
g.context.bindArrayBuffer(g.state.arrayBuffer)
|
g.context.ctx.BindBuffer(gl.ARRAY_BUFFER, uint32(g.state.arrayBuffer))
|
||||||
g.context.bindElementArrayBuffer(g.state.elementArrayBuffer)
|
g.context.ctx.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, uint32(g.state.elementArrayBuffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
g.state.lastProgram = program
|
g.state.lastProgram = program
|
||||||
@ -211,7 +212,7 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu
|
|||||||
delete(g.state.lastUniforms, k)
|
delete(g.state.lastUniforms, k)
|
||||||
}
|
}
|
||||||
g.state.lastActiveTexture = 0
|
g.state.lastActiveTexture = 0
|
||||||
g.context.activeTexture(0)
|
g.context.ctx.ActiveTexture(gl.TEXTURE0)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, u := range uniforms {
|
for _, u := range uniforms {
|
||||||
@ -258,7 +259,7 @@ loop:
|
|||||||
})
|
})
|
||||||
g.context.uniformInt(program, g.textureVariableName(i), idx)
|
g.context.uniformInt(program, g.textureVariableName(i), idx)
|
||||||
if g.state.lastActiveTexture != idx {
|
if g.state.lastActiveTexture != idx {
|
||||||
g.context.activeTexture(idx)
|
g.context.ctx.ActiveTexture(uint32(gl.TEXTURE0 + idx))
|
||||||
g.state.lastActiveTexture = idx
|
g.state.lastActiveTexture = idx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/glsl"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/glsl"
|
||||||
)
|
)
|
||||||
@ -54,17 +55,17 @@ func (s *Shader) Dispose() {
|
|||||||
func (s *Shader) compile() error {
|
func (s *Shader) compile() error {
|
||||||
vssrc, fssrc := glsl.Compile(s.ir, s.graphics.context.glslVersion())
|
vssrc, fssrc := glsl.Compile(s.ir, s.graphics.context.glslVersion())
|
||||||
|
|
||||||
vs, err := s.graphics.context.newVertexShader(vssrc)
|
vs, err := s.graphics.context.newShader(gl.VERTEX_SHADER, vssrc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("opengl: vertex shader compile error: %v, source:\n%s", err, vssrc)
|
return fmt.Errorf("opengl: vertex shader compile error: %v, source:\n%s", err, vssrc)
|
||||||
}
|
}
|
||||||
defer s.graphics.context.deleteShader(vs)
|
defer s.graphics.context.ctx.DeleteShader(uint32(vs))
|
||||||
|
|
||||||
fs, err := s.graphics.context.newFragmentShader(fssrc)
|
fs, err := s.graphics.context.newShader(gl.FRAGMENT_SHADER, fssrc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("opengl: fragment shader compile error: %v, source:\n%s", err, fssrc)
|
return fmt.Errorf("opengl: fragment shader compile error: %v, source:\n%s", err, fssrc)
|
||||||
}
|
}
|
||||||
defer s.graphics.context.deleteShader(fs)
|
defer s.graphics.context.ctx.DeleteShader(uint32(fs))
|
||||||
|
|
||||||
p, err := s.graphics.context.newProgram([]shader{vs, fs}, theArrayBufferLayout.names())
|
p, err := s.graphics.context.newProgram([]shader{vs, fs}, theArrayBufferLayout.names())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *context) glslVersion() glsl.GLSLVersion {
|
func (c *context) glslVersion() glsl.GLSLVersion {
|
||||||
if c.isES() {
|
if c.ctx.IsES() {
|
||||||
return glsl.GLSLVersionES100
|
return glsl.GLSLVersionES100
|
||||||
}
|
}
|
||||||
return glsl.GLSLVersionDefault
|
return glsl.GLSLVersionDefault
|
||||||
|
Loading…
Reference in New Issue
Block a user