mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
graphics: Add geometry matrix info to vertices
This commit is contained in:
parent
8d550a4007
commit
ebf7f0df00
@ -128,7 +128,7 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
||||
}
|
||||
}
|
||||
w, h := image.impl.restorable.Size()
|
||||
vs := vertices(parts, w, h)
|
||||
vs := vertices(parts, w, h, &options.GeoM)
|
||||
if len(vs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ func v(y, height2p int) int16 {
|
||||
return int16(math.MaxInt16 * y / height2p)
|
||||
}
|
||||
|
||||
func vertices(parts ImageParts, width, height int) []uint8 {
|
||||
func vertices(parts ImageParts, width, height int, geo *GeoM) []uint8 {
|
||||
// TODO: This function should be in graphics package?
|
||||
totalSize := graphics.QuadVertexSizeInBytes()
|
||||
oneSize := totalSize / 4
|
||||
l := parts.Len()
|
||||
@ -86,6 +87,12 @@ func vertices(parts ImageParts, width, height int) []uint8 {
|
||||
height2p := graphics.NextPowerOf2Int(height)
|
||||
n := 0
|
||||
vs := make([]int16, 16)
|
||||
geoBytes := floatBytes(geo.Element(0, 0),
|
||||
geo.Element(0, 1),
|
||||
geo.Element(1, 0),
|
||||
geo.Element(1, 1),
|
||||
geo.Element(0, 2),
|
||||
geo.Element(1, 2))
|
||||
for i := 0; i < l; i++ {
|
||||
dx0, dy0, dx1, dy1 := parts.Dst(i)
|
||||
if dx0 == dx1 || dy0 == dy1 {
|
||||
@ -114,15 +121,21 @@ func vertices(parts ImageParts, width, height int) []uint8 {
|
||||
vs[14] = u1
|
||||
vs[15] = v1
|
||||
// Use direct assign here. `append` function might be slow on browsers.
|
||||
if endian.IsLittle() {
|
||||
for i, v := range vs {
|
||||
vertices[totalSize*n+oneSize*(i/4)+2*(i%4)] = uint8(v)
|
||||
vertices[totalSize*n+oneSize*(i/4)+2*(i%4)+1] = uint8(v >> 8)
|
||||
for j := 0; j < 4; j++ {
|
||||
offset := totalSize*n + oneSize*j
|
||||
if endian.IsLittle() {
|
||||
for k, v := range vs[4*j : 4*j+4] {
|
||||
vertices[offset+2*k] = uint8(v)
|
||||
vertices[offset+2*k+1] = uint8(v >> 8)
|
||||
}
|
||||
} else {
|
||||
for k, v := range vs[4*j : 4*j+4] {
|
||||
vertices[offset+2*k] = uint8(v >> 8)
|
||||
vertices[offset+2*k+1] = uint8(v)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i, v := range vs {
|
||||
vertices[totalSize*n+oneSize*(i/4)+2*(i%4)] = uint8(v >> 8)
|
||||
vertices[totalSize*n+oneSize*(i/4)+2*(i%4)+1] = uint8(v)
|
||||
for k, g := range geoBytes {
|
||||
vertices[offset+8+k] = g
|
||||
}
|
||||
}
|
||||
n++
|
||||
|
@ -65,6 +65,7 @@ func (a *arrayBufferLayout) disable(c *opengl.Context, program opengl.Program) {
|
||||
|
||||
var (
|
||||
theArrayBufferLayout = arrayBufferLayout{
|
||||
// Note that GL_MAX_VERTEX_ATTRIBS is at least 16.
|
||||
parts: []arrayBufferLayoutPart{
|
||||
{
|
||||
name: "vertex",
|
||||
@ -78,6 +79,18 @@ var (
|
||||
num: 2,
|
||||
normalize: true,
|
||||
},
|
||||
{
|
||||
name: "geo_matrix",
|
||||
dataType: opengl.Float,
|
||||
num: 4,
|
||||
normalize: false,
|
||||
},
|
||||
{
|
||||
name: "geo_matrix_translation",
|
||||
dataType: opengl.Float,
|
||||
num: 2,
|
||||
normalize: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -39,14 +39,23 @@ func shader(c *opengl.Context, id shaderId) string {
|
||||
var shaders = map[shaderId]string{
|
||||
shaderVertexModelview: `
|
||||
uniform highp mat4 projection_matrix;
|
||||
uniform highp mat4 modelview_matrix;
|
||||
uniform highp mat4 modelview_matrix; // TODO: Remove this
|
||||
attribute highp vec2 vertex;
|
||||
attribute highp vec2 tex_coord;
|
||||
attribute highp vec4 geo_matrix;
|
||||
attribute highp vec2 geo_matrix_translation;
|
||||
varying highp vec2 vertex_out_tex_coord;
|
||||
|
||||
void main(void) {
|
||||
vertex_out_tex_coord = tex_coord;
|
||||
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 0, 1);
|
||||
mat4 x = modelview_matrix; // temporary hack not to omit modelview_matrix
|
||||
mat4 geom = mat4(
|
||||
vec4(geo_matrix[0], geo_matrix[2], 0, 0),
|
||||
vec4(geo_matrix[1], geo_matrix[3], 0, 0),
|
||||
vec4(0, 0, 1, 0),
|
||||
vec4(geo_matrix_translation, 0, 1)
|
||||
);
|
||||
gl_Position = projection_matrix * geom * vec4(vertex, 0, 1);
|
||||
}
|
||||
`,
|
||||
shaderFragmentTexture: `
|
||||
|
45
math.go
Normal file
45
math.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build !js
|
||||
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/endian"
|
||||
)
|
||||
|
||||
func floatBytes(xs ...float64) []uint8 {
|
||||
bits := make([]uint8, 0, len(xs)*4)
|
||||
for _, x := range xs {
|
||||
x32 := float32(x)
|
||||
n := *(*uint32)(unsafe.Pointer(&x32))
|
||||
if endian.IsLittle() {
|
||||
bits = append(bits,
|
||||
uint8(n),
|
||||
uint8(n>>8),
|
||||
uint8(n>>16),
|
||||
uint8(n>>24))
|
||||
} else {
|
||||
bits = append(bits,
|
||||
uint8(n>>24),
|
||||
uint8(n>>16),
|
||||
uint8(n>>8),
|
||||
uint8(n))
|
||||
}
|
||||
}
|
||||
return bits
|
||||
}
|
31
math_js.go
Normal file
31
math_js.go
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build js
|
||||
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"github.com/gopherjs/gopherjs/js"
|
||||
)
|
||||
|
||||
func floatBytes(xs ...float64) []uint8 {
|
||||
a := js.Global.Get("ArrayBuffer").New(4 * len(xs))
|
||||
af32 := js.Global.Get("Float32Array").New(a)
|
||||
a8 := js.Global.Get("Uint8Array").New(a)
|
||||
for i, x := range xs {
|
||||
af32.SetIndex(i, x)
|
||||
}
|
||||
return a8.Interface().([]uint8)
|
||||
}
|
Loading…
Reference in New Issue
Block a user