zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

context.go (3367B)


      1 // Copyright 2016 Hajime Hoshi
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package opengl
     16 
     17 import (
     18 	"fmt"
     19 	"sync"
     20 
     21 	"github.com/hajimehoshi/ebiten/v2/internal/driver"
     22 )
     23 
     24 type operation int
     25 
     26 func convertOperation(op driver.Operation) operation {
     27 	switch op {
     28 	case driver.Zero:
     29 		return zero
     30 	case driver.One:
     31 		return one
     32 	case driver.SrcAlpha:
     33 		return srcAlpha
     34 	case driver.DstAlpha:
     35 		return dstAlpha
     36 	case driver.OneMinusSrcAlpha:
     37 		return oneMinusSrcAlpha
     38 	case driver.OneMinusDstAlpha:
     39 		return oneMinusDstAlpha
     40 	case driver.DstColor:
     41 		return dstColor
     42 	default:
     43 		panic(fmt.Sprintf("opengl: invalid operation %d at convertOperation", op))
     44 	}
     45 }
     46 
     47 type context struct {
     48 	locationCache      *locationCache
     49 	screenFramebuffer  framebufferNative // This might not be the default frame buffer '0' (e.g. iOS).
     50 	lastFramebuffer    framebufferNative
     51 	lastTexture        textureNative
     52 	lastRenderbuffer   renderbufferNative
     53 	lastViewportWidth  int
     54 	lastViewportHeight int
     55 	lastCompositeMode  driver.CompositeMode
     56 	maxTextureSize     int
     57 	maxTextureSizeOnce sync.Once
     58 	highp              bool
     59 	highpOnce          sync.Once
     60 
     61 	contextImpl
     62 }
     63 
     64 func (c *context) bindTexture(t textureNative) {
     65 	if c.lastTexture.equal(t) {
     66 		return
     67 	}
     68 	c.bindTextureImpl(t)
     69 	c.lastTexture = t
     70 }
     71 
     72 func (c *context) bindRenderbuffer(r renderbufferNative) {
     73 	if c.lastRenderbuffer.equal(r) {
     74 		return
     75 	}
     76 	c.bindRenderbufferImpl(r)
     77 	c.lastRenderbuffer = r
     78 }
     79 
     80 func (c *context) bindFramebuffer(f framebufferNative) {
     81 	if c.lastFramebuffer.equal(f) {
     82 		return
     83 	}
     84 	c.bindFramebufferImpl(f)
     85 	c.lastFramebuffer = f
     86 }
     87 
     88 func (c *context) setViewport(f *framebuffer) {
     89 	c.bindFramebuffer(f.native)
     90 	if c.lastViewportWidth != f.width || c.lastViewportHeight != f.height {
     91 		// On some environments, viewport size must be within the framebuffer size.
     92 		// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
     93 		// Use the same size of the framebuffer here.
     94 		c.setViewportImpl(f.width, f.height)
     95 
     96 		// glViewport must be called at least at every frame on iOS.
     97 		// As the screen framebuffer is the last render target, next SetViewport should be
     98 		// the first call at a frame.
     99 		if f.native.equal(c.screenFramebuffer) {
    100 			c.lastViewportWidth = 0
    101 			c.lastViewportHeight = 0
    102 		} else {
    103 			c.lastViewportWidth = f.width
    104 			c.lastViewportHeight = f.height
    105 		}
    106 	}
    107 }
    108 
    109 func (c *context) getScreenFramebuffer() framebufferNative {
    110 	return c.screenFramebuffer
    111 }
    112 
    113 func (c *context) getMaxTextureSize() int {
    114 	c.maxTextureSizeOnce.Do(func() {
    115 		c.maxTextureSize = c.maxTextureSizeImpl()
    116 	})
    117 	return c.maxTextureSize
    118 }
    119 
    120 // highpPrecision represents an enough mantissa of float values in a shader.
    121 const highpPrecision = 23
    122 
    123 func (c *context) hasHighPrecisionFloat() bool {
    124 	c.highpOnce.Do(func() {
    125 		c.highp = c.getShaderPrecisionFormatPrecision() >= highpPrecision
    126 	})
    127 	return c.highp
    128 }