mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +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()
|
||||
|
||||
level := uint(0)
|
||||
level := 0
|
||||
if filter == graphics.FilterLinear {
|
||||
det := math.Abs(float64(geom.det()))
|
||||
for det < 0.25 {
|
||||
level++
|
||||
det *= 4
|
||||
det := geom.det()
|
||||
if det == 0 {
|
||||
return
|
||||
}
|
||||
if math.IsNan(det) {
|
||||
return
|
||||
}
|
||||
level = graphicsutil.MipmapLevel(det)
|
||||
if level < 0 {
|
||||
panic("not reached")
|
||||
}
|
||||
}
|
||||
if level > 6 {
|
||||
@ -264,7 +270,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
|
||||
}
|
||||
|
||||
if level > 0 {
|
||||
s := 1 << level
|
||||
s := 1 << uint(level)
|
||||
a *= float32(s)
|
||||
b *= 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()
|
||||
for uint(len(img.shareableImages)) < level+1 {
|
||||
lastl := uint(len(img.shareableImages)) - 1
|
||||
for len(img.shareableImages) < level+1 {
|
||||
lastl := len(img.shareableImages) - 1
|
||||
src := img.shareableImages[lastl]
|
||||
w2 := int(math.Ceil(float64(w) / 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
|
||||
}
|
||||
|
||||
if level < uint(len(img.shareableImages)) {
|
||||
if level < len(img.shareableImages) {
|
||||
src := img.shareableImages[level]
|
||||
vs := src.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, options.ColorM.impl)
|
||||
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