Example #1
0
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
}
Example #2
0
// 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()
	}
}
Example #3
0
// 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()
	}
}