Last active
August 29, 2015 14:06
-
-
Save dskinner/32e96f657cf43760dd6b to your computer and use it in GitHub Desktop.
This file contains hidden or 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.CursorMovedEvents | |
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) | |
} | |
case window.CursorMoved: | |
if w.Props().CursorGrabbed() { | |
CursorHandler(ev) | |
} | |
} | |
} | |
}() | |
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) | |
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