mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
graphicsutil: Add MipmapLevel
This commit is contained in:
parent
b8ab1363d2
commit
0956ca0ea6
24
image.go
24
image.go
@ -251,12 +251,18 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
|
|||||||
|
|
||||||
a, b, c, d, tx, ty := geom.elements()
|
a, b, c, d, tx, ty := geom.elements()
|
||||||
|
|
||||||
level := uint(0)
|
level := 0
|
||||||
if filter == graphics.FilterLinear {
|
if filter == graphics.FilterLinear {
|
||||||
det := math.Abs(float64(geom.det()))
|
det := geom.det()
|
||||||
for det < 0.25 {
|
if det == 0 {
|
||||||
level++
|
return
|
||||||
det *= 4
|
}
|
||||||
|
if math.IsNan(det) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
level = graphicsutil.MipmapLevel(det)
|
||||||
|
if level < 0 {
|
||||||
|
panic("not reached")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if level > 6 {
|
if level > 6 {
|
||||||
@ -264,7 +270,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if level > 0 {
|
if level > 0 {
|
||||||
s := 1 << level
|
s := 1 << uint(level)
|
||||||
a *= float32(s)
|
a *= float32(s)
|
||||||
b *= float32(s)
|
b *= float32(s)
|
||||||
c *= float32(s)
|
c *= float32(s)
|
||||||
@ -276,8 +282,8 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
w, h = img.shareableImages[len(img.shareableImages)-1].Size()
|
w, h = img.shareableImages[len(img.shareableImages)-1].Size()
|
||||||
for uint(len(img.shareableImages)) < level+1 {
|
for len(img.shareableImages) < level+1 {
|
||||||
lastl := uint(len(img.shareableImages)) - 1
|
lastl := len(img.shareableImages) - 1
|
||||||
src := img.shareableImages[lastl]
|
src := img.shareableImages[lastl]
|
||||||
w2 := int(math.Ceil(float64(w) / 2.0))
|
w2 := int(math.Ceil(float64(w) / 2.0))
|
||||||
h2 := int(math.Ceil(float64(h) / 2.0))
|
h2 := int(math.Ceil(float64(h) / 2.0))
|
||||||
@ -298,7 +304,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
|
|||||||
h = h2
|
h = h2
|
||||||
}
|
}
|
||||||
|
|
||||||
if level < uint(len(img.shareableImages)) {
|
if level < len(img.shareableImages) {
|
||||||
src := img.shareableImages[level]
|
src := img.shareableImages[level]
|
||||||
vs := src.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, options.ColorM.impl)
|
vs := src.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, options.ColorM.impl)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
|
41
internal/graphicsutil/mipmap.go
Normal file
41
internal/graphicsutil/mipmap.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2018 The Ebiten Authors
|
||||||
|
//
|
||||||
|
// 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 graphicsutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MipmapLevel returns an appropriate mipmap level for the given determinant of a geometry matrix.
|
||||||
|
//
|
||||||
|
// MipmapLevel returns -1 if det is 0.
|
||||||
|
//
|
||||||
|
// MipmapLevel panics if det is NaN.
|
||||||
|
func MipmapLevel(det float32) int {
|
||||||
|
if math.IsNaN(float64(det)) {
|
||||||
|
panic("graphicsutil: det must be finite")
|
||||||
|
}
|
||||||
|
if det == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
d := math.Abs(float64(det))
|
||||||
|
level := 0
|
||||||
|
for d < 0.25 {
|
||||||
|
level++
|
||||||
|
d *= 4
|
||||||
|
}
|
||||||
|
return level
|
||||||
|
}
|
64
internal/graphicsutil/mipmap_test.go
Normal file
64
internal/graphicsutil/mipmap_test.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2018 The Ebiten Authors
|
||||||
|
//
|
||||||
|
// 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 graphicsutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/hajimehoshi/ebiten/internal/graphicsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMipmapLevel(t *testing.T) {
|
||||||
|
inf := float32(math.Inf(1))
|
||||||
|
cases := []struct {
|
||||||
|
In float32
|
||||||
|
Out int
|
||||||
|
}{
|
||||||
|
{0, -1},
|
||||||
|
{1, 0},
|
||||||
|
{-1, 0},
|
||||||
|
{2, 0},
|
||||||
|
{-2, 0},
|
||||||
|
{100, 0},
|
||||||
|
{-100, 0},
|
||||||
|
{1.0 / 2.0, 0},
|
||||||
|
{-1.0 / 2.0, 0},
|
||||||
|
{1.0 / 4.0, 0},
|
||||||
|
{-1.0 / 4.0, 0},
|
||||||
|
{math.Nextafter32(1.0/4.0, 0), 1},
|
||||||
|
{math.Nextafter32(-1.0/4.0, 0), 1},
|
||||||
|
{1.0 / 8.0, 1},
|
||||||
|
{-1.0 / 8.0, 1},
|
||||||
|
{1.0 / 16.0, 1},
|
||||||
|
{-1.0 / 16.0, 1},
|
||||||
|
{math.Nextafter32(1.0/16.0, 0), 2},
|
||||||
|
{math.Nextafter32(-1.0/16.0, 0), 2},
|
||||||
|
{math.Nextafter32(1.0/256.0, 0), 4},
|
||||||
|
{math.Nextafter32(-1.0/256.0, 0), 4},
|
||||||
|
{math.SmallestNonzeroFloat32, 74},
|
||||||
|
{-math.SmallestNonzeroFloat32, 74},
|
||||||
|
{inf, 0},
|
||||||
|
{-inf, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
got := MipmapLevel(c.In)
|
||||||
|
want := c.Out
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("MipmapLevel(%v): got %v, want %v", c.In, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user