Beispiel #1
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
			}
		}
	}
}
Beispiel #2
0
func (m *mainLoop) frame() {
	var timeout C.int = 0
	if !m.isRunning() {
		timeout = -1
	}
	ident := C.ALooper_pollAll(timeout, nil, nil, nil)
	switch ident {
	case LOOPER_ID_INPUT:
		if m.inputQ != nil {
			m.processInput(m.inputQ)
		}
	case C.ALOOPER_POLL_ERROR:
		log.Fatalf("ALooper_pollAll returned ALOOPER_POLL_ERROR\n")
	}
	if m.isRunning() {
		m.checkSize()
		createCtx := m.renderState.ctx == egl.Context(unsafe.Pointer(nil))
		if createCtx {
			log.Printf("Creating context\n")
			ctx_attribs := [...]int32{
				egl.CONTEXT_CLIENT_VERSION, 2,
				egl.NONE,
			}

			m.renderState.ctx = egl.CreateContext(m.renderState.disp, m.renderState.conf, egl.NO_CONTEXT, &ctx_attribs[0])
			if m.renderState.ctx == egl.Context(unsafe.Pointer(nil)) {
				panic("Error: eglCreateContext failed\n")
			}
		}

		if !egl.MakeCurrent(m.renderState.disp, m.renderState.surf, m.renderState.surf, m.renderState.ctx) {
			panic("Error: eglMakeCurrent() failed\n")
		}
		if createCtx {
			m.game.initGL()
		}
		m.game.drawFrame()
		egl.SwapBuffers(m.renderState.disp, m.renderState.surf)
	}
}
Beispiel #3
0
// SwapBuffers swaps the surface with the display actually showing the
// result of rendering.
func (win *window) SwapBuffers() {
	egl.SwapBuffers(win.eglState.Display, win.eglState.Surface)
}