示例#1
0
func (s *renderState) Destroy() {
	if s == nil {
		return
	}
	if s.disp != egl.Display(unsafe.Pointer(nil)) {
		if s.ctx != egl.Context(unsafe.Pointer(nil)) {
			egl.DestroyContext(s.disp, s.ctx)
		}
		egl.Terminate(s.disp)
	}
}
示例#2
0
// Run runs renderLoop. The loop renders a frame and swaps the buffer
// at each tick received.
func renderLoopFunc(controlCh *controlCh) loop.LoopFunc {
	return func(loop loop.Loop) error {

		var state renderState

		// Lock/unlock the loop to the current OS thread. This is
		// necessary because OpenGL functions should be called from
		// the same thread.
		runtime.LockOSThread()
		defer runtime.UnlockOSThread()

		// We don't have yet a proper rendering state so the
		// ticker should be stopped as soon as it is created.
		ticker := time.NewTicker(time.Duration(int(time.Second) / int(FRAMES_PER_SECOND)))
		ticker.Stop()

		for {
			select {
			// At each tick render a frame and swap buffers.
			case <-ticker.C:
				state.angle += 0.05
				state.cube.Rotate(state.angle, [3]float32{0, 1, 0})
				state.world.Draw()
				egl.SwapBuffers(state.eglState.Display, state.eglState.Surface)

				// Receive an EGL state from the
				// native graphics subsystem and
				// initialize a rendering state.
			case eglState := <-controlCh.eglState:
				if err := state.init(eglState); err != nil {
					panic(err)
				}
				// Now that we have a proper rendering
				// state we can start the ticker.
				ticker = time.NewTicker(time.Duration(int(time.Second) / int(FRAMES_PER_SECOND)))

			case <-controlCh.exit:
				go loop.Stop()

			case <-loop.ShallStop():
				ticker.Stop()
				egl.DestroySurface(state.eglState.Display, state.eglState.Surface)
				egl.DestroyContext(state.eglState.Display, state.eglState.Context)
				egl.Terminate(state.eglState.Display)
				return nil
			}
		}
	}
}