driver: Add (Graphics).HasHighPrecisionFlaot

This enables to determine whether vertices should be adjusted or
not.

Fixes #879
This commit is contained in:
Hajime Hoshi 2019-06-22 04:47:48 +09:00
parent cddb93b9f6
commit 9bff33472a
8 changed files with 49 additions and 7 deletions

View File

@ -35,6 +35,7 @@ type Graphics interface {
VDirection() VDirection
NeedsRestoring() bool
IsGL() bool
HasHighPrecisionFloat() bool
}
type Image interface {

View File

@ -183,13 +183,14 @@ func (q *commandQueue) Flush() {
fmt.Println("--")
}
// Adjust texels.
// TODO: texelAdjustmentFactor can vary depends on the highp precisions (#879).
const texelAdjustmentFactor = 1.0 / 512.0
for i := 0; i < q.nvertices/graphics.VertexFloatNum; i++ {
s := q.dstSizes[i]
vs[i*graphics.VertexFloatNum+6] -= 1.0 / s.width * texelAdjustmentFactor
vs[i*graphics.VertexFloatNum+7] -= 1.0 / s.height * texelAdjustmentFactor
if theGraphicsDriver.HasHighPrecisionFloat() {
// Adjust texels.
const texelAdjustmentFactor = 1.0 / 512.0
for i := 0; i < q.nvertices/graphics.VertexFloatNum; i++ {
s := q.dstSizes[i]
vs[i*graphics.VertexFloatNum+6] -= 1.0 / s.width * texelAdjustmentFactor
vs[i*graphics.VertexFloatNum+7] -= 1.0 / s.height * texelAdjustmentFactor
}
}
theGraphicsDriver.Begin()

View File

@ -703,6 +703,10 @@ func (d *Driver) IsGL() bool {
return false
}
func (d *Driver) HasHighPrecisionFloat() bool {
return true
}
type Image struct {
driver *Driver
width int

View File

@ -16,6 +16,7 @@ package opengl
import (
"fmt"
"sync"
"github.com/hajimehoshi/ebiten/internal/graphics"
"github.com/hajimehoshi/ebiten/internal/thread"
@ -49,6 +50,8 @@ type context struct {
lastViewportHeight int
lastCompositeMode graphics.CompositeMode
maxTextureSize int
highp bool
highpOnce sync.Once
t *thread.Thread
@ -102,3 +105,13 @@ func (c *context) getMaxTextureSize() int {
}
return c.maxTextureSize
}
// highpPrecision represents an enough mantissa of float values in a shader.
const highpPrecision = 23
func (c *context) hasHighPrecisionFloat() bool {
c.highpOnce.Do(func() {
c.highp = c.getShaderPrecisionFormatPrecision() >= highpPrecision
})
return c.highp
}

View File

@ -493,6 +493,12 @@ func (c *context) maxTextureSizeImpl() int {
return size
}
func (c *context) getShaderPrecisionFormatPrecision() int {
// glGetShaderPrecisionFormat is not defined at OpenGL 2.0. Assume that desktop environments always have
// enough highp precision.
return highpPrecision
}
func (c *context) flush() {
_ = c.t.Call(func() error {
gl.Flush()

View File

@ -73,6 +73,7 @@ var (
framebuffer_ = contextPrototype.Get("FRAMEBUFFER")
framebufferBinding = contextPrototype.Get("FRAMEBUFFER_BINDING")
framebufferComplete = contextPrototype.Get("FRAMEBUFFER_COMPLETE")
highFloat = contextPrototype.Get("HIGH_FLOAT")
linkStatus = contextPrototype.Get("LINK_STATUS")
maxTextureSize = contextPrototype.Get("MAX_TEXTURE_SIZE")
nearest = contextPrototype.Get("NEAREST")
@ -451,6 +452,12 @@ func (c *context) maxTextureSizeImpl() int {
return gl.Call("getParameter", maxTextureSize).Int()
}
func (c *context) getShaderPrecisionFormatPrecision() int {
c.ensureGL()
gl := c.gl
return gl.Call("getShaderPrecisionFormat", js.ValueOf(int(fragmentShader)), highFloat).Get("precision").Int()
}
func (c *context) flush() {
c.ensureGL()
gl := c.gl

View File

@ -377,6 +377,12 @@ func (c *context) maxTextureSizeImpl() int {
return gl.GetInteger(mgl.MAX_TEXTURE_SIZE)
}
func (c *context) getShaderPrecisionFormatPrecision() int {
gl := c.gl
_, _, p := gl.GetShaderPrecisionFormat(mgl.FRAGMENT_SHADER, mgl.HIGH_FLOAT)
return p
}
func (c *context) flush() {
gl := c.gl
gl.Flush()

View File

@ -138,3 +138,7 @@ func (d *Driver) NeedsRestoring() bool {
func (d *Driver) IsGL() bool {
return true
}
func (d *Driver) HasHighPrecisionFloat() bool {
return d.context.hasHighPrecisionFloat()
}