func (j *jsonObject) object(meshes map[string]*jsonMesh, findTexture func(name string) *gfx.Texture, findTransform func(name string) *gfx.Transform, findShader func(name string) *gfx.Shader) *gfx.Object { o := gfx.NewObject() if j.OcclusionTest != nil { o.OcclusionTest = *j.OcclusionTest } //o.Props = j.Props o.Meshes = make([]*gfx.Mesh, len(j.Meshes)) for i, m := range j.Meshes { o.Meshes[i] = meshes[m].mesh() } o.Textures = make([]*gfx.Texture, len(j.Textures)) for i, t := range j.Textures { o.Textures[i] = findTexture(t) } if j.Shader != nil { o.Shader = findShader(*j.Shader) } if j.Transform != nil { o.Transform = findTransform(*j.Transform) } return o }
// gfxLoop is responsible for drawing things to the window. This loop must be // independent of the Chippy main loop. func gfxLoop(w *chippy.Window, r gfx.Renderer) { // Create a simple shader. shader := &gfx.Shader{ Name: "SimpleShader", GLSLVert: glslVert, GLSLFrag: glslFrag, } // Preload the shader (useful for seeing shader errors, if any). onLoad := make(chan *gfx.Shader, 1) r.LoadShader(shader, onLoad) go func() { <-onLoad shader.RLock() if shader.Loaded { fmt.Println("Shader loaded") } else { fmt.Println(string(shader.Error)) } shader.RUnlock() }() n := 25000 // Create a new batch. triangles := make([]*gfx.Object, 0, n) for i := 0; i < n; i++ { // Create a triangle object. triangle := gfx.NewObject() triangle.Shader = shader triangle.Meshes = []*gfx.Mesh{ &gfx.Mesh{ Vertices: []gfx.Vec3{ // Top {-.5, 0, 0}, {.5, 0, 0}, {0, 1, 0}, }, Colors: []gfx.Color{ // Top {1, 0, 0, 1}, {0, 1, 0, 1}, {0, 0, 1, 1}, }, }, } triangles = append(triangles, triangle) } for { // Clear the entire area (empty rectangle means "the whole area"). r.Clear(image.Rect(0, 0, 0, 0), gfx.Color{1, 1, 1, 1}) r.ClearDepth(image.Rect(0, 0, 0, 0), 1.0) // Clear a few rectangles on the window using different background // colors. r.Clear(image.Rect(0, 100, 640, 380), gfx.Color{0, 1, 0, 1}) r.Clear(image.Rect(100, 100, 540, 380), gfx.Color{1, 0, 0, 1}) r.Clear(image.Rect(100, 200, 540, 280), gfx.Color{0, 0.5, 0.5, 1}) r.Clear(image.Rect(200, 200, 440, 280), gfx.Color{1, 1, 0, 1}) // Draw triangles using the batcher. for _, triangle := range triangles { r.Draw(image.Rect(50, 50, 640-50, 480-50), triangle, nil) } // Render the whole frame. r.Render() } }
// gfxLoop is responsible for drawing things to the window. This loop must be // independent of the Chippy main loop. func gfxLoop(w *chippy.Window, r gfx.Renderer) { w.SetSize(640, 640) w.SetPositionCenter(chippy.DefaultScreen()) glr := r.(*gl2.Renderer) glr.UpdateBounds(image.Rect(0, 0, 640, 640)) // Create a camera. // Wait for the shader to load (not strictly required). onLoad := make(chan *gfx.Shader, 1) r.LoadShader(Wireframe, onLoad) go func() { <-onLoad Wireframe.RLock() if Wireframe.Loaded { fmt.Println("Shader loaded") } else { fmt.Println(string(Wireframe.Error)) } Wireframe.RUnlock() }() // Create a triangle object. triangle := gfx.NewObject() triangle.Shader = Wireframe triangle.Meshes = []*gfx.Mesh{ &gfx.Mesh{}, } triangle.Meshes[0].GenerateBary() triangle.FaceCulling = gfx.NoFaceCulling triangle.AlphaMode = gfx.AlphaToCoverage tree := ntree.New() level := 0 go func() { events := w.Events() for { e := <-events kev, ok := e.(keyboard.TypedEvent) if ok { if kev.Rune == ' ' || kev.Rune == 'b' { for i := 0; i < 1; i++ { s := random(0.1, 0.15) if kev.Rune == 'b' { s = random(0.1, 0.5) } tree.Add(s) } // Create new mesh and ask the renderer to load it. newMesh := NTreeMesh(tree, level) onLoad := make(chan *gfx.Mesh, 1) r.LoadMesh(newMesh, onLoad) <-onLoad // Swap the mesh. triangle.Lock() triangle.Meshes[0] = newMesh triangle.Unlock() } if kev.Rune == '1' || kev.Rune == '2' { if kev.Rune == '1' { level-- } else { level++ } fmt.Println("level", level) // Create new mesh and ask the renderer to load it. newMesh := NTreeMesh(tree, level) onLoad := make(chan *gfx.Mesh, 1) r.LoadMesh(newMesh, onLoad) <-onLoad // Swap the mesh. triangle.Lock() triangle.Meshes[0] = newMesh triangle.Unlock() } if kev.Rune == 's' || kev.Rune == 'S' { fmt.Println("Writing screenshot to file...") // Download the image from the graphics hardware and save // it to disk. complete := make(chan image.Image, 1) r.Download(image.Rect(0, 0, 0, 0), complete) img := <-complete // Wait for download to complete. // Save to png. f, err := os.Create("screenshot.png") if err != nil { log.Fatal(err) } err = png.Encode(f, img) if err != nil { log.Fatal(err) } fmt.Println("Wrote texture to screenshot.png") } } } }() for { // Clear the entire area (empty rectangle means "the whole area"). r.Clear(image.Rect(0, 0, 0, 0), gfx.Color{1, 1, 1, 1}) r.ClearDepth(image.Rect(0, 0, 0, 0), 1.0) // Update the rotation. dt := r.Clock().Dt() triangle.RLock() rot := triangle.Transform.Rot() if w.Keyboard.Down(keyboard.ArrowLeft) { rot.Z += 90 * dt } if w.Keyboard.Down(keyboard.ArrowRight) { rot.Z -= 90 * dt } if w.Keyboard.Down(keyboard.ArrowUp) { rot.X += 20 * dt } if w.Keyboard.Down(keyboard.ArrowDown) { rot.X -= 20 * dt } triangle.Transform.SetRot(rot) triangle.RUnlock() // Draw the triangle to the screen. r.Draw(image.Rect(0, 0, 0, 0), triangle, nil) // Render the whole frame. r.Render() } }