func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	mandala.Verbose = true
	mandala.Debug = true

	// Create rendering loop control channels
	renderLoopControl := newRenderLoopControl()
	// Start the rendering loop
	loop.GoRecoverable(
		renderLoopFunc(renderLoopControl),
		func(rs loop.Recoverings) (loop.Recoverings, error) {
			for _, r := range rs {
				mandala.Logf("%s", r.Reason)
				mandala.Logf("%s", mandala.Stacktrace())
			}
			return rs, fmt.Errorf("Unrecoverable loop\n")
		},
	)
	// Start the event loop
	loop.GoRecoverable(
		eventLoopFunc(renderLoopControl),
		func(rs loop.Recoverings) (loop.Recoverings, error) {
			for _, r := range rs {
				mandala.Logf("%s", r.Reason)
				mandala.Logf("%s", mandala.Stacktrace())
			}
			return rs, fmt.Errorf("Unrecoverable loop\n")
		},
	)

}
Beispiel #2
0
// eventLoopFunc listen to events originating from the
// framework.
func eventLoopFunc(renderLoopControl *renderLoopControl) loop.LoopFunc {
	return func(loop loop.Loop) error {

		for {
			select {

			case untypedEvent := <-mandala.Events():
				switch event := untypedEvent.(type) {

				// Receive a native window
				// from the framework and send
				// it to the render loop in
				// order to begin the
				// rendering process.
				case mandala.NativeWindowCreatedEvent:
					renderLoopControl.window <- event.Window

				// Finger down/up on the screen.
				case mandala.ActionUpDownEvent:
					if event.Down {
						renderLoopControl.tapEvent <- [2]float32{event.X, event.Y}
					}

					// Finger is moving on the screen.
				case mandala.ActionMoveEvent:
					mandala.Logf("Finger is moving at coord %f %f", event.X, event.Y)

				case mandala.DestroyEvent:
					mandala.Logf("Quitting from application now...\n")
					return nil

				case mandala.NativeWindowRedrawNeededEvent:

				case mandala.PauseEvent:
					mandala.Logf("Application was paused. Stopping rendering ticker.")
					renderLoopControl.pause <- event

				case mandala.ResumeEvent:
					mandala.Logf("Application was resumed. Reactivating rendering ticker.")
					renderLoopControl.resume <- true

				}
			}
		}
	}
}
Beispiel #3
0
func (t *TestSuite) timeoutLoopFunc() loop.LoopFunc {
	return func(loop loop.Loop) error {
		time := <-t.timeout
		err := fmt.Errorf("Tests timed out after %v", time)
		mandala.Logf("%s %s", err.Error(), mandala.Stacktrace())
		t.Error(err)
		return nil
	}
}
Beispiel #4
0
// Run runs renderLoop. The loop renders a frame and swaps the buffer
// at each tick received.
func renderLoopFunc(control *renderLoopControl) loop.LoopFunc {

	return func(loop loop.Loop) error {
		var window mandala.Window
		// 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()

		// Create an instance of ticker and immediately stop
		// it because we don't want to swap buffers before
		// initializing a rendering state.
		ticker := time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND)))
		ticker.Stop()

		for {
			select {
			case window = <-control.window:
				ticker.Stop()

				window.MakeContextCurrent()

				width, height := window.GetSize()
				gl.Viewport(0, 0, width, height)

				mandala.Logf("Restarting rendering loop...")
				ticker = time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND)))

				// Compute window radius
				windowRadius = math.Sqrt(math.Pow(float64(height), 2) + math.Pow(float64(width), 2))

				//gl.Init()
				gl.Disable(gl.DEPTH_TEST)
				// antialiasing
				gl.Enable(gl.BLEND)
				gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
				//gl.Enable(gl.LINE_SMOOTH)

			// At each tick render a frame and swap buffers.
			case <-ticker.C:
				draw()
				window.SwapBuffers()

			case event := <-control.pause:
				ticker.Stop()
				event.Paused <- true

			case <-control.resume:

			case <-loop.ShallStop():
				ticker.Stop()
				return nil
			}
		}
	}
}
Beispiel #5
0
// Run runs renderLoop. The loop renders a frame and swaps the buffer
// at each tick received.
func renderLoopFunc(control *renderLoopControl) loop.LoopFunc {
	return func(loop loop.Loop) error {
		var window mandala.Window
		// 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()

		// Create an instance of ticker and immediately stop
		// it because we don't want to swap buffers before
		// initializing a rendering state.
		ticker := time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND)))
		ticker.Stop()

		for {
			select {
			case window = <-control.window:
				ticker.Stop()

				window.MakeContextCurrent()

				width, height := window.GetSize()
				gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height))

				mandala.Logf("Restarting rendering loop...")
				ticker = time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND)))

			// At each tick render a frame and swap buffers.
			case <-ticker.C:
				draw()
				window.SwapBuffers()

			case event := <-control.pause:
				ticker.Stop()
				event.Paused <- true

			case <-control.resume:

			case <-loop.ShallStop():
				ticker.Stop()
				return nil
			}
		}
	}
}
Beispiel #6
0
func (t *TestSuite) BeforeAll() {
	// Create rendering loop control channels
	t.rlControl = newRenderLoopControl()
	// Start the rendering loop
	loop.GoRecoverable(
		t.renderLoopFunc(t.rlControl),
		func(rs loop.Recoverings) (loop.Recoverings, error) {
			for _, r := range rs {
				mandala.Logf("%s", r.Reason)
				mandala.Logf("%s", mandala.Stacktrace())
			}
			return rs, fmt.Errorf("Unrecoverable loop\n")
		},
	)
	// Start the event loop
	loop.GoRecoverable(
		t.eventLoopFunc(t.rlControl),
		func(rs loop.Recoverings) (loop.Recoverings, error) {
			for _, r := range rs {
				mandala.Logf("%s", r.Reason)
				mandala.Logf("%s", mandala.Stacktrace())
			}
			return rs, fmt.Errorf("Unrecoverable loop\n")
		},
	)

	if t.timeout != nil {
		// Start the timeout loop
		loop.GoRecoverable(
			t.timeoutLoopFunc(),
			func(rs loop.Recoverings) (loop.Recoverings, error) {
				for _, r := range rs {
					mandala.Logf("%s", r.Reason)
					mandala.Logf("%s", mandala.Stacktrace())
				}
				return rs, fmt.Errorf("Unrecoverable loop\n")
			},
		)
	}

}
Beispiel #7
0
// eventLoopFunc listen to events originating from the
// framework.
func eventLoopFunc(renderLoopControl *renderLoopControl) loop.LoopFunc {
	return func(loop loop.Loop) error {

		for {
			select {

			// Receive an EGL state from the
			// framework and notify the render
			// loop about that.
			// case eglState := <-mandala.Init:
			// 	mandala.Logf("EGL surface initialized W:%d H:%d", eglState.SurfaceWidth, eglState.SurfaceHeight)
			// 	renderLoopControl.eglState <- eglState

			// Receive events from the framework.
			//
			// When the application starts the
			// typical events chain is:
			//
			// * onCreate
			// * onResume
			// * onInputQueueCreated
			// * onNativeWindowCreated
			// * onNativeWindowResized
			// * onWindowFocusChanged
			// * onNativeRedrawNeeded
			//
			// Pausing (i.e. clicking on the back
			// button) the application produces
			// following events chain:
			//
			// * onPause
			// * onWindowDestroy
			// * onWindowFocusChanged
			// * onInputQueueDestroy
			// * onDestroy

			case untypedEvent := <-mandala.Events():
				switch event := untypedEvent.(type) {

				// Receive a native window
				// from the framework and send
				// it to the render loop in
				// order to begin the
				// rendering process.
				case mandala.NativeWindowCreatedEvent:
					renderLoopControl.window <- event.Window

				// Finger down/up on the screen.
				case mandala.ActionUpDownEvent:
					if event.Down {
						mandala.Logf("Finger is DOWN at %f %f", event.X, event.Y)
					} else {
						mandala.Logf("Finger is now UP")
					}

					// Finger is moving on the screen.
				case mandala.ActionMoveEvent:
					mandala.Logf("Finger is moving at coord %f %f", event.X, event.Y)

				case mandala.DestroyEvent:
					mandala.Logf("Stop rendering...\n")
					mandala.Logf("Quitting from application...\n")
					return nil

				case mandala.NativeWindowRedrawNeededEvent:

				case mandala.PauseEvent:
					mandala.Logf("Application was paused. Stopping rendering ticker.")
					renderLoopControl.pause <- true

				case mandala.ResumeEvent:
					mandala.Logf("Application was resumed. Reactivating rendering ticker.")
					renderLoopControl.resume <- true

				}
			}
		}
	}
}
Beispiel #8
0
func check() {
	error := gl.GetError()
	if error != 0 {
		mandala.Logf("An error occurred! Code: 0x%x", error)
	}
}
Beispiel #9
0
func main() {

	runtime.LockOSThread()

	verbose := flag.Bool("verbose", false, "produce verbose output")
	debug := flag.Bool("debug", false, "produce debug output")
	size := flag.String("size", "320x480", "set the size of the window")

	flag.Parse()

	if *verbose {
		mandala.Verbose = true
	}

	if *debug {
		mandala.Debug = true
	}

	dims := strings.Split(strings.ToLower(*size), "x")
	width, err := strconv.Atoi(dims[0])
	if err != nil {
		panic(err)
	}
	height, err := strconv.Atoi(dims[1])
	if err != nil {
		panic(err)
	}

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	// Enable OpenGL ES 2.0.
	glfw.WindowHint(glfw.ClientApi, glfw.OpenglEsApi)
	glfw.WindowHint(glfw.ContextVersionMajor, 2)
	window, err := glfw.CreateWindow(width, height, "{{.AppName}}", nil, nil)
	if err != nil {
		panic(err)
	}

	mandala.Init(window)

	// Create a rendering loop control struct containing a set of
	// channels that control rendering.
	renderLoopControl := newRenderLoopControl()

	// Start the rendering loop
	loop.GoRecoverable(
		renderLoopFunc(renderLoopControl),
		func(rs loop.Recoverings) (loop.Recoverings, error) {
			for _, r := range rs {
				mandala.Logf("%s", r.Reason)
				mandala.Logf("%s", mandala.Stacktrace())
			}
			return rs, fmt.Errorf("Unrecoverable loop\n")
		},
	)
	// Start the event loop
	loop.GoRecoverable(
		eventLoopFunc(renderLoopControl),
		func(rs loop.Recoverings) (loop.Recoverings, error) {
			for _, r := range rs {
				mandala.Logf("%s", r.Reason)
				mandala.Logf("%s", mandala.Stacktrace())
			}
			return rs, fmt.Errorf("Unrecoverable loop\n")
		},
	)

	for !window.ShouldClose() {
		glfw.WaitEvents()
	}

}
Beispiel #10
0
// Run runs renderLoop. The loop renders a frame and swaps the buffer
// at each tick received.
func renderLoopFunc(control *renderLoopControl) loop.LoopFunc {
	return func(loop loop.Loop) error {

		// renderState keeps the rendering state variables
		// such as the EGL status
		renderState := new(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()

		// Create an instance of ticker and immediately stop
		// it because we don't want to swap buffers before
		// initializing a rendering state.
		ticker := time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND)))
		ticker.Stop()

		for {
			select {
			case window := <-control.window:
				ticker.Stop()
				renderState.init(window)
				mandala.Logf("Restarting rendering loop...")
				ticker = time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND)))

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

			case viewport := <-control.resizeViewport:
				if renderState.world != nil {
					if viewport.width != renderState.world.Width || viewport.height != renderState.world.Height {
						mandala.Logf("Resize native window W:%v H:%v\n", viewport.width, viewport.height)
						ticker.Stop()
						renderState.world.Resize(viewport.width, viewport.height)
						ticker = time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND)))
					}
				}

			case event := <-control.pause:
				renderState.savedAngle = renderState.angle
				mandala.Logf("Save an angle value of %f", renderState.savedAngle)
				ticker.Stop()
				event.Paused <- true

			case <-control.resume:
				renderState.angle = renderState.savedAngle
				mandala.Logf("Restore an angle value of %f", renderState.angle)

			case <-loop.ShallStop():
				ticker.Stop()
				return nil
			}
		}
	}
}