Skip to content

Instantly share code, notes, and snippets.

@slimsag
Created September 8, 2014 07:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slimsag/d0e018fdfb7f9785fada to your computer and use it in GitHub Desktop.
Save slimsag/d0e018fdfb7f9785fada to your computer and use it in GitHub Desktop.
Cursor events in main loop
package main
import (
"image"
"azul3d.org/gfx.v1"
"azul3d.org/gfx/window.v2"
"azul3d.org/keyboard.v1"
"azul3d.org/lmath.v1"
"azul3d.org/mouse.v1"
"dasa.cc/htm"
)
var (
Speed float64 = 0.05
Near float64 = 0.0001
Far float64 = 1000.0
Camera = gfx.NewCamera()
KeyHandler = WASDZC
CursorHandler = Roam
)
type KeyEventHandler func(*keyboard.Watcher)
type CursorEventHandler func(window.CursorMoved)
func WASDZC(kb *keyboard.Watcher) {
Camera.Lock()
defer Camera.Unlock()
transform := func(v lmath.Vec3) {
quat := Camera.Transform.Quat()
Camera.SetPos(Camera.Pos().Add(quat.TransformVec3(v)))
}
if kb.Down(keyboard.A) {
transform(lmath.Vec3{-Speed, 0, 0})
}
if kb.Down(keyboard.D) {
transform(lmath.Vec3{Speed, 0, 0})
}
if kb.Down(keyboard.S) {
transform(lmath.Vec3{0, -Speed, 0})
}
if kb.Down(keyboard.W) {
transform(lmath.Vec3{0, Speed, 0})
}
if kb.Down(keyboard.C) {
transform(lmath.Vec3{0, 0, -Speed})
}
if kb.Down(keyboard.Z) {
transform(lmath.Vec3{0, 0, Speed})
}
}
func Roam(ev window.CursorMoved) {
Camera.Lock()
defer Camera.Unlock()
a := Camera.Transform.ConvertRot(Camera.Rot(), gfx.WorldToLocal)
b := lmath.Vec3{float64(ev.Y) / 10, 0, float64(ev.X) / 10}
c := Camera.Transform.ConvertRot(a.Sub(b), gfx.LocalToWorld)
Camera.SetRot(c)
}
func NewCongruentTrees(h *htm.HTM) []*gfx.Object {
var objs []*gfx.Object
objs = append(objs, NewTreeChildObjects(h.S0)...)
objs = append(objs, NewTreeChildObjects(h.S1)...)
objs = append(objs, NewTreeChildObjects(h.S2)...)
objs = append(objs, NewTreeChildObjects(h.S3)...)
objs = append(objs, NewTreeChildObjects(h.N0)...)
objs = append(objs, NewTreeChildObjects(h.N1)...)
objs = append(objs, NewTreeChildObjects(h.N2)...)
objs = append(objs, NewTreeChildObjects(h.N3)...)
return objs
}
func NewTreeChildObjects(t *htm.Tree) []*gfx.Object {
var objs []*gfx.Object
objs = append(objs, NewTreeObject(t.T0), NewTreeObject(t.T1), NewTreeObject(t.T2), NewTreeObject(t.T3))
return objs
}
func NewTreeObject(t *htm.Tree) *gfx.Object {
o := gfx.NewObject()
m := gfx.NewMesh()
o.Meshes = []*gfx.Mesh{m}
tv := t.Vertices()
tcp := htm.TexCoordsPlanar(tv)
var verts []gfx.Vec3
for _, v0 := range tv {
verts = append(verts, gfx.ConvertVec3(v0))
}
m.Vertices = verts
var tc []gfx.TexCoord
for i := 0; i < len(tcp); i += 2 {
tc = append(tc, gfx.TexCoord{tcp[i], tcp[i+1]})
}
m.TexCoords = []gfx.TexCoordSet{gfx.TexCoordSet{Slice: tc}}
o.Shader = gfx.NewShader(t.Name)
o.Shader.GLSLVert = []byte(`#version 130
attribute vec3 Bary;
attribute vec4 Vertex;
varying vec3 bary;
uniform mat4 MVP;
void main() {
bary = Bary;
gl_Position = MVP * Vertex;
}
`)
o.Shader.GLSLFrag = []byte(`#version 130
varying vec3 bary;
float edgeFactor(vec3 v) {
vec3 a = smoothstep(vec3(0.0), fwidth(v)*1.5, v);
return (a.x + a.y + a.z)/3;
}
void main(void) {
vec3 clr = mix(vec3(0.0), vec3(0.8), edgeFactor(bary));
gl_FragColor = vec4(clr, 1);
}
`)
m.GenerateBary()
return o
}
func gfxLoop(w window.Window, r gfx.Renderer) {
Camera.SetPersp(r.Bounds(), 75, Near, Far)
Camera.SetPos(lmath.Vec3{0, -2.2, 0})
h := htm.New()
h.SubDivide(9)
objs := NewCongruentTrees(h)
// uncomment this, get a dup sphere, still only one sphere with issue
// for _, obj := range objs {
// obj.SetPos(lmath.Vec3{5, 0, 0})
// }
// objs = append(objs, NewCongruentTrees(h)...)
go func() {
evMask := window.FramebufferResizedEvents
evMask |= window.MouseEvents
events := make(chan window.Event, 256)
w.Notify(events, evMask)
for e := range events {
switch ev := e.(type) {
case window.FramebufferResized:
Camera.Lock()
Camera.SetPersp(r.Bounds(), 75, Near, Far)
Camera.Unlock()
case keyboard.TypedEvent:
_ = ev
case mouse.Event:
if ev.Button == mouse.Left && ev.State == mouse.Down {
props := w.Props()
props.SetCursorGrabbed(!w.Props().CursorGrabbed())
w.Request(props)
}
}
}
}()
cursorEvents := make(chan window.Event, 256)
w.Notify(cursorEvents, window.CursorMovedEvents)
for {
r.Clear(image.Rect(0, 0, 0, 0), gfx.Color{1, 1, 1, 1})
r.ClearDepth(image.Rect(0, 0, 0, 0), 1.0)
// Handle each pending cursor event.
pending := len(cursorEvents)
for i := 0; i < pending; i++ {
ev := <-cursorEvents
if w.Props().CursorGrabbed() {
CursorHandler(ev.(window.CursorMoved))
}
}
KeyHandler(w.Keyboard())
for _, obj := range objs {
r.Draw(r.Bounds(), obj, Camera)
}
r.Render()
}
}
func main() {
window.Run(gfxLoop, nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment