Exemplo n.º 1
0
func Run(gfxLoop func(w *chippy.Window, r gfx.Renderer)) {
	// Enable debug messages.
	chippy.SetDebugOutput(os.Stdout)

	// Initialize Chippy
	err := chippy.Init()
	if err != nil {
		log.Fatal(err)
	}
	defer chippy.Exit()

	// Start the program.
	go program(gfxLoop)

	// Enter the main loop.
	chippy.MainLoop()
}
Exemplo n.º 2
0
func program(gfxLoop func(w *chippy.Window, r gfx.Renderer)) {
	defer chippy.Exit()

	window := chippy.NewWindow()
	window.SetTitle("Azul3D")
	screen := chippy.DefaultScreen()
	window.SetPositionCenter(screen)

	events := window.Events()

	// Actually open the windows
	err := window.Open(screen)
	if err != nil {
		log.Fatal(err)
	}

	// All OpenGL related calls must occur in the same OS thread.
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	// Choose and set a frame buffer configuration.
	configs := window.GLConfigs()
	bestConfig := chippy.GLChooseConfig(configs, chippy.GLWorstConfig, chippy.GLBestConfig)
	log.Println("Chosen configuration:", bestConfig)
	window.GLSetConfig(bestConfig)

	// Create the OpenGL rendering context.
	ctx, err := window.GLCreateContext(2, 1, chippy.GLCoreProfile, nil)
	if err != nil {
		log.Fatal(err)
	}

	// Create the OpenGL loader context.
	loaderCtx, err := window.GLCreateContext(2, 1, chippy.GLCoreProfile, ctx)
	if err != nil {
		log.Fatal(err)
	}

	// OpenGL rendering context must be active to create the renderer.
	window.GLMakeCurrent(ctx)
	defer window.GLMakeCurrent(nil)

	// Disable vertical sync.
	//window.GLSetVerticalSync(chippy.NoVerticalSync)

	// Create the renderer.
	r, err := gl2.New()
	if err != nil {
		log.Fatal(err)
	}

	// Start the graphics rendering loop.
	go gfxLoop(window, r)

	// Channel to signal shutdown to renderer and loader.
	shutdown := make(chan bool, 2)

	// Start event loop.
	go func() {
		cl := r.Clock()
		printFPS := time.Tick(1 * time.Second)

		for {
			select {
			case <-printFPS:
				window.SetTitle(fmt.Sprintf("Azul3D %vFPS (%f Avg.)", cl.FrameRate(), cl.AverageFrameRate()))

			case e := <-events:
				switch ev := e.(type) {
				case chippy.ResizedEvent:
					r.UpdateBounds(image.Rect(0, 0, ev.Width, ev.Height))

				case chippy.CloseEvent, chippy.DestroyedEvent:
					shutdown <- true
					shutdown <- true
					return
				}
			}
		}
	}()

	// Start loading goroutine.
	go func() {
		// All OpenGL related calls must occur in the same OS thread.
		runtime.LockOSThread()
		defer runtime.UnlockOSThread()

		// OpenGL loading context must be active.
		window.GLMakeCurrent(loaderCtx)
		defer window.GLMakeCurrent(nil)

		for {
			select {
			case <-shutdown:
				return
			case fn := <-r.LoaderExec:
				fn()
			}
		}
	}()

	// Enter rendering loop.
	for {
		select {
		case <-shutdown:
			return

		case fn := <-r.RenderExec:
			if renderedFrame := fn(); renderedFrame {
				// Swap OpenGL buffers.
				window.GLSwapBuffers()
			}
		}
	}
}