Getting Started

The instructions below will assume you use CMake to generate your build environment. If you use some other setup you will have to adapt the setup instructions. If you are not familiar with CMake you can click here for an external tutorial.

After finishing this walkthrough you will have a console application printing eye tracking data.

Step 1: Create a C/C++ project

This example assumes you are creating a console application. Make sure your project compiles and executes before proceeding to add Stream Engine to it.

Step 2: Download Tobii XR Native SDK

Click here to download Tobii XR Native SDK

After the download has finished, unzip the SDK into your project where you keep external dependencies. We will refer to that path as sdk-root below.

Step 3: Add Stream Engine headers

Open your CMakeLists.txt file and find the line where you declare your application and add the following:

add_executable(${APPLICATION_NAME} ...)
target_include_directories(${APPLICATION_NAME} PRIVATE "sdk-root/stream_engine/include")

You can now reference Stream Engine headers in your project:

#include <tobii/tobii.h>
#include <tobii/tobii_wearable.h>

Your project now compiles but it won’t link.

For the linker to find the symbols declared in the Stream Engine headers you need to link to the Stream Engine binary:

target_link_libraries(${APPLICATION_NAME} sdk-root/stream_engine/lib/tobii/tobii_stream_engine)

You have now integrated Stream Engine library into your project and you are now ready to write some code to access your eye tracker.

Step 5: Print eye tracking data to the console

Here is a simple example that shows how to find, connect and stream data from your eye tracker. Error handling has been omitted to keep the example small.

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <tobii/tobii.h>
#include <tobii/tobii_wearable.h>

// This function will be called synchronously when calling tobii_process_callbacks and there is new data available
static void wearable_callback(tobii_wearable_consumer_data_t const* wearable, void* user_data) {
    if (wearable->gaze_direction_combined_validity) {
        printf("Combined gaze direction: (%f, %f, %f)\n", wearable->gaze_direction_combined_normalized_xyz[0],
    } else {
        printf("Combined gaze direction: INVALID\n");

// This callback will be invoked once for each connected eye tracker
static void url_receiver(char const* url, void* user_data) {
    char* buffer = (char*)user_data;
    if (*buffer != '\0') return;  // only keep first value
    if (strlen(url) < 256) strcpy(buffer, url);

int main() {
    tobii_api_t* api;
    tobii_error_t error = tobii_api_create(&api, NULL, NULL);
    assert(error == TOBII_ERROR_NO_ERROR);

    // Find an eye tracker
    char url[256] = {0};
    error = tobii_enumerate_local_device_urls(api, url_receiver, url);
    assert(error == TOBII_ERROR_NO_ERROR && *url != '\0');

    // Connect to eye tracker
    tobii_device_t* device;
    error = tobii_device_create(api, url, TOBII_FIELD_OF_USE_INTERACTIVE, &device);
    assert(error == TOBII_ERROR_NO_ERROR);

    // Start streaming eye tracking data
    error = tobii_wearable_consumer_data_subscribe(device, wearable_callback, 0);
    assert(error == TOBII_ERROR_NO_ERROR);

    int is_running = 1000;  // in this sample, exit after some iterations
    while( --is_running > 0 ) {
        // Wait for new data
        error = tobii_wait_for_callbacks(1, &device);
        assert(error == TOBII_ERROR_NO_ERROR || error == TOBII_ERROR_TIMED_OUT);

        // Process received data
        error = tobii_device_process_callbacks(device);
        assert(error == TOBII_ERROR_NO_ERROR);

    // Stop streaming eye tracking data
    error = tobii_wearable_consumer_data_unsubscribe(device);
    assert(error == TOBII_ERROR_NO_ERROR);

    // Disconnect eye tracker
    error = tobii_device_destroy(device);
    assert(error == TOBII_ERROR_NO_ERROR);

    // Clean up
    error = tobii_api_destroy(api);
    assert(error == TOBII_ERROR_NO_ERROR);

    return 0;

Next step

Congratulations! You’re now up and running with the Stream Engine SDK.

To continue exploring the Stream Engine API you can read the API reference here.