aminal/vendor/github.com/4ydx/gltext/v4.1/bounding_box.go

183 lines
4.4 KiB
Go

// Copyright 2012 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package v41
import (
"fmt"
"github.com/4ydx/gltext"
"github.com/go-gl/gl/v4.1-core/gl"
"github.com/go-gl/mathgl/mgl32"
)
var boxVertexShaderSource string = `
#version 330
uniform mat4 orthographic_matrix;
uniform vec2 final_position;
in vec4 centered_position;
void main() {
vec4 center = orthographic_matrix * centered_position;
gl_Position = vec4(center.x + final_position.x, center.y + final_position.y, center.z, center.w);
}
` + "\x00"
var boxFragmentShaderSource string = `
#version 330
out vec4 fragment_color;
void main() {
fragment_color = vec4(0.3,0.3,0.3,1);
}
` + "\x00"
type BoundingBox struct {
program uint32 // program compiled from shaders
// font holds our orthographic matrix
font *Font
// attributes
centeredPosition uint32 // vertex position
// the final screen position post-scaling
finalPositionUniform int32
finalPosition mgl32.Vec2
// transform to orthographic projection
orthographicMatrixUniform int32
vao uint32
vbo uint32
ebo uint32
windowWidth float32
windowHeight float32
vboData []float32
vboIndexCount int
eboData []int32
eboIndexCount int
// X1, X2: the lower left and upper right points of a box that bounds the text
X1 gltext.Point
X2 gltext.Point
}
func loadBoundingBox(f *Font, X1 gltext.Point, X2 gltext.Point) (b *BoundingBox, err error) {
b = new(BoundingBox)
b.font = f
// create shader program and define attributes and uniforms
b.program, err = NewProgram(boxVertexShaderSource, boxFragmentShaderSource)
if err != nil {
return b, err
}
// ebo, vbo data
b.vboIndexCount = 4 * 2 // 4 indexes per bounding box (containing 2 position)
b.eboIndexCount = 6 // each rune requires 6 triangle indices for a quad
b.vboData = make([]float32, b.vboIndexCount, b.vboIndexCount)
b.eboData = make([]int32, b.eboIndexCount, b.eboIndexCount)
b.makeBufferData(X1, X2)
if gltext.IsDebug {
prefix := gltext.DebugPrefix()
fmt.Printf("%s bounding %v %v\n", prefix, X1, X2)
fmt.Printf("%s bounding vbo data\n%v\n", prefix, b.vboData)
fmt.Printf("%s bounding ebo data\n%v\n", prefix, b.eboData)
}
// attributes
b.centeredPosition = uint32(gl.GetAttribLocation(b.program, gl.Str("centered_position\x00")))
// uniforms
b.finalPositionUniform = gl.GetUniformLocation(b.program, gl.Str("final_position\x00"))
b.orthographicMatrixUniform = gl.GetUniformLocation(b.program, gl.Str("orthographic_matrix\x00"))
// size of glfloat
glfloatSize := int32(4)
gl.GenVertexArrays(1, &b.vao)
gl.GenBuffers(1, &b.vbo)
gl.GenBuffers(1, &b.ebo)
// vao
gl.BindVertexArray(b.vao)
// vbo
// specify the buffer for which the VertexAttribPointer calls apply
gl.BindBuffer(gl.ARRAY_BUFFER, b.vbo)
gl.EnableVertexAttribArray(b.centeredPosition)
gl.VertexAttribPointer(
b.centeredPosition,
2,
gl.FLOAT,
false,
0,
gl.PtrOffset(0),
)
gl.BufferData(gl.ARRAY_BUFFER, int(glfloatSize)*b.vboIndexCount, gl.Ptr(b.vboData), gl.DYNAMIC_DRAW)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.ebo)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int(glfloatSize)*b.eboIndexCount, gl.Ptr(b.eboData), gl.DYNAMIC_DRAW)
gl.BindVertexArray(0)
// not necesssary, but i just want to better understand using vertex arrays
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
return b, nil
}
func (b *BoundingBox) Release() {
gl.DeleteBuffers(1, &b.vbo)
gl.DeleteBuffers(1, &b.ebo)
gl.DeleteBuffers(1, &b.vao)
}
func (b *BoundingBox) Draw() {
gl.UseProgram(b.program)
// uniforms
gl.Uniform2fv(b.finalPositionUniform, 1, &b.finalPosition[0])
gl.UniformMatrix4fv(b.orthographicMatrixUniform, 1, false, &b.font.OrthographicMatrix[0])
// draw
gl.BindVertexArray(b.vao)
gl.DrawElements(gl.TRIANGLES, int32(b.eboIndexCount), gl.UNSIGNED_INT, nil)
gl.BindVertexArray(0)
}
func (b *BoundingBox) makeBufferData(X1, X2 gltext.Point) {
// counter-clockwise quad
// index (0,0)
b.vboData[0] = X1.X // position
b.vboData[1] = X1.Y
// index (1,0)
b.vboData[2] = X2.X
b.vboData[3] = X1.Y
// index (1,1)
b.vboData[4] = X2.X
b.vboData[5] = X2.Y
// index (0,1)
b.vboData[6] = X1.X
b.vboData[7] = X2.Y
// ebo data
b.eboData[0] = 0
b.eboData[1] = 1
b.eboData[2] = 2
b.eboData[3] = 0
b.eboData[4] = 2
b.eboData[5] = 3
return
}