2014-12-24 03:04:10 +01:00
|
|
|
// Copyright 2014 Hajime Hoshi
|
|
|
|
//
|
|
|
|
// 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.
|
2014-12-09 15:16:04 +01:00
|
|
|
|
2013-10-30 14:26:10 +01:00
|
|
|
package shader
|
|
|
|
|
|
|
|
import (
|
2014-12-06 07:47:48 +01:00
|
|
|
"github.com/go-gl/gl"
|
2013-10-30 14:26:10 +01:00
|
|
|
)
|
|
|
|
|
2014-12-13 06:41:38 +01:00
|
|
|
func glMatrix(m [4][4]float64) [16]float32 {
|
2014-12-07 10:25:28 +01:00
|
|
|
result := [16]float32{}
|
|
|
|
for j := 0; j < 4; j++ {
|
|
|
|
for i := 0; i < 4; i++ {
|
2014-12-13 06:41:38 +01:00
|
|
|
result[i+j*4] = float32(m[i][j])
|
2014-12-07 10:25:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2014-12-13 06:41:38 +01:00
|
|
|
type Matrix interface {
|
|
|
|
Element(i, j int) float64
|
|
|
|
}
|
|
|
|
|
2014-12-30 14:25:38 +01:00
|
|
|
type TextureQuads interface {
|
|
|
|
Len() int
|
|
|
|
Vertex(i int) (x0, y0, x1, y1 float32)
|
|
|
|
Texture(i int) (u0, v0, u1, v1 float32)
|
|
|
|
}
|
|
|
|
|
2014-12-25 17:19:08 +01:00
|
|
|
var initialized = false
|
2014-12-25 15:16:18 +01:00
|
|
|
|
|
|
|
const size = 10000
|
2014-12-26 12:44:15 +01:00
|
|
|
|
2014-12-26 12:13:57 +01:00
|
|
|
// TODO: Use unsafe.SizeOf?
|
2014-12-25 17:11:42 +01:00
|
|
|
const uint16Size = 2
|
2014-12-30 18:46:37 +01:00
|
|
|
const float32Size = 4
|
2014-12-25 17:11:42 +01:00
|
|
|
|
2014-12-30 14:25:38 +01:00
|
|
|
func DrawTexture(native gl.Texture, projectionMatrix [4][4]float64, quads TextureQuads, geo Matrix, color Matrix) error {
|
2014-12-25 15:16:18 +01:00
|
|
|
// TODO: Check len(quads) and gl.MAX_ELEMENTS_INDICES?
|
2014-12-25 17:11:42 +01:00
|
|
|
const stride = 4 * 4
|
2014-12-25 17:19:08 +01:00
|
|
|
if !initialized {
|
2014-12-28 16:21:40 +01:00
|
|
|
if err := initialize(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2014-12-25 17:11:42 +01:00
|
|
|
|
2014-12-26 12:13:57 +01:00
|
|
|
vertexBuffer := gl.GenBuffer()
|
|
|
|
vertexBuffer.Bind(gl.ARRAY_BUFFER)
|
2014-12-30 18:46:37 +01:00
|
|
|
s := float32Size * stride * size
|
2014-12-26 12:44:15 +01:00
|
|
|
gl.BufferData(gl.ARRAY_BUFFER, s, nil, gl.DYNAMIC_DRAW)
|
2014-12-26 12:13:57 +01:00
|
|
|
|
2014-12-25 17:19:08 +01:00
|
|
|
indexBuffer := gl.GenBuffer()
|
|
|
|
indexBuffer.Bind(gl.ELEMENT_ARRAY_BUFFER)
|
2014-12-25 15:16:18 +01:00
|
|
|
indices := make([]uint16, 6*size)
|
|
|
|
for i := uint16(0); i < size; i++ {
|
|
|
|
indices[6*i+0] = 4*i + 0
|
|
|
|
indices[6*i+1] = 4*i + 1
|
|
|
|
indices[6*i+2] = 4*i + 2
|
|
|
|
indices[6*i+3] = 4*i + 1
|
|
|
|
indices[6*i+4] = 4*i + 2
|
|
|
|
indices[6*i+5] = 4*i + 3
|
|
|
|
}
|
2014-12-25 17:11:42 +01:00
|
|
|
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, uint16Size*len(indices), indices, gl.STATIC_DRAW)
|
|
|
|
|
2014-12-25 17:19:08 +01:00
|
|
|
initialized = true
|
2014-12-25 15:16:18 +01:00
|
|
|
}
|
2013-10-30 14:26:10 +01:00
|
|
|
|
2014-12-30 14:25:38 +01:00
|
|
|
if quads.Len() == 0 {
|
2014-12-28 16:21:40 +01:00
|
|
|
return nil
|
2013-10-30 14:26:10 +01:00
|
|
|
}
|
2014-05-03 20:29:45 +02:00
|
|
|
// TODO: Check performance
|
2014-12-22 14:49:14 +01:00
|
|
|
program := useProgramColorMatrix(glMatrix(projectionMatrix), geo, color)
|
2013-11-25 17:08:12 +01:00
|
|
|
|
2014-12-19 21:22:10 +01:00
|
|
|
gl.ActiveTexture(gl.TEXTURE0)
|
2014-12-06 07:47:48 +01:00
|
|
|
native.Bind(gl.TEXTURE_2D)
|
2014-12-19 21:22:10 +01:00
|
|
|
|
2014-12-20 10:07:25 +01:00
|
|
|
vertexAttrLocation := getAttributeLocation(program, "vertex")
|
2014-12-22 13:51:58 +01:00
|
|
|
texCoordAttrLocation := getAttributeLocation(program, "tex_coord")
|
2013-10-30 14:26:10 +01:00
|
|
|
|
2014-12-06 07:47:48 +01:00
|
|
|
vertexAttrLocation.EnableArray()
|
2014-12-22 13:51:58 +01:00
|
|
|
texCoordAttrLocation.EnableArray()
|
2013-10-30 14:26:10 +01:00
|
|
|
defer func() {
|
2014-12-22 13:51:58 +01:00
|
|
|
texCoordAttrLocation.DisableArray()
|
2014-12-06 07:47:48 +01:00
|
|
|
vertexAttrLocation.DisableArray()
|
2013-10-30 14:26:10 +01:00
|
|
|
}()
|
|
|
|
|
2014-12-30 18:46:37 +01:00
|
|
|
vertexAttrLocation.AttribPointer(2, gl.FLOAT, false, stride, uintptr(float32Size*0))
|
|
|
|
texCoordAttrLocation.AttribPointer(2, gl.FLOAT, false, stride, uintptr(float32Size*2))
|
2014-12-25 17:11:42 +01:00
|
|
|
|
2013-10-30 14:26:10 +01:00
|
|
|
vertices := []float32{}
|
2014-12-30 14:25:38 +01:00
|
|
|
for i := 0; i < quads.Len(); i++ {
|
|
|
|
x0, y0, x1, y1 := quads.Vertex(i)
|
|
|
|
u0, v0, u1, v1 := quads.Texture(i)
|
2014-12-25 17:11:42 +01:00
|
|
|
vertices = append(vertices,
|
|
|
|
x0, y0, u0, v0,
|
|
|
|
x1, y0, u1, v0,
|
|
|
|
x0, y1, u0, v1,
|
|
|
|
x1, y1, u1, v1,
|
2013-10-30 14:26:10 +01:00
|
|
|
)
|
|
|
|
}
|
2014-12-30 18:46:37 +01:00
|
|
|
gl.BufferSubData(gl.ARRAY_BUFFER, 0, float32Size*len(vertices), vertices)
|
2014-12-30 14:25:38 +01:00
|
|
|
gl.DrawElements(gl.TRIANGLES, 6*quads.Len(), gl.UNSIGNED_SHORT, uintptr(0))
|
2014-12-20 07:36:31 +01:00
|
|
|
|
|
|
|
gl.Flush()
|
2014-12-28 16:21:40 +01:00
|
|
|
return nil
|
2013-10-30 14:26:10 +01:00
|
|
|
}
|