Created
September 8, 2014 07:12
-
-
Save emidoots/d0e018fdfb7f9785fada to your computer and use it in GitHub Desktop.
Cursor events in main loop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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