//!
    virtual void display() {

        static bool executed = false;
        static int counter = 0;
        static size_t normalsDuration = 0;
        static size_t displayDuration = 0;

        // clear
        glClearColor(0.4, 0.4, 0.8, 0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_DEPTH_TEST);
        glDisable(GL_CULL_FACE);


        timeval start, end;
        gettimeofday(&start, 0);

        computeNormals();

        gettimeofday(&end, 0);
        normalsDuration += timediff_usec(start, end);

        gettimeofday(&start, 0);

        displayOcean();
        //glFinish();

        gettimeofday(&end, 0);
        displayDuration += timediff_usec(start, end);

        if (++counter >= 100) {
            report("display() - computeNormals duration: " << normalsDuration/10.0f << " us"
                   << ", displayOcean() duration: " << displayDuration/10.0f << " us");
            counter = 0;
            normalsDuration = 0;
            displayDuration = 0;
        }
    }
    //!
    virtual void update() {
        const float baseDeltaT = 0.5f / 50.0f;
        time += baseDeltaT;

        if (joystick.good()) {
            joystick.sample();
            camera.position.y = joystick.getAxis().w * 10.0f + 5.0f;
            camera.position.x += joystick.getAxis().x * 0.1f;
            camera.position.z += joystick.getAxis().y * 0.1f;
        }

        timeval start, end;
        gettimeofday(&start, 0);
        oceanHeightMap->update(time);
        gettimeofday(&end, 0);

        report("OceanHeightMap::update() duration: " << (timediff_usec(start, end) / 1000) << " ms");
    }
Exemple #3
0
void
run()
{
    /* Using Xlib event handling to use the keyboard helpers */
    XEvent          event;
    fd_set          fds;
    struct timeval  timeout;
    struct timeval  now;
    uint32_t        usec_sleep = 1000000 / config.HZ;
    uint32_t        usec_sleep_passive = 1000000 / config.HZ_passive;

    int Xfd = XConnectionNumber(X.dpy);

    /* If there is no user activity, we can spend more time between screen
     * updates without the user feeling less responsiveness. Passive mode
     * means that there are no X events to respond to, and we could slow down
     * rendering a bit, offering more throughput
     */
    struct timeval last_event;
    last_event.tv_sec = 0;
    last_event.tv_usec = 0;
    bool passive = false;

    for (;;) {
        FD_ZERO(&fds);
        FD_SET(Xfd, &fds);
        FD_SET(shell_fd, &fds);


        timeout.tv_sec  = 0;
        timeout.tv_usec = usec_sleep; /* TODO: set to blinking time? */

        if (select(max(Xfd, shell_fd) + 1, &fds, NULL, NULL, &timeout) < 0) {
            if (errno == EINTR)
                continue;
            die("select failed");
        }

        if (FD_ISSET(shell_fd, &fds)) {
            sh_read(term_write); /* short circuit shell output and term input */
        }

        while (XPending(X.dpy)) {
            XNextEvent(X.dpy, &event);
            if (XFilterEvent(&event, X.window))
                continue;

            passive = false;
            if (event.type < (int)LENGTH(x_handler) && x_handler[event.type])
                (x_handler[event.type])(&event);
        }

        gettimeofday(&now, NULL);
        if (timediff_usec(now, X.last_draw) > (passive ? usec_sleep_passive : usec_sleep)) {
            x_draw();
        }

        if (FD_ISSET(Xfd, &fds)) {
            gettimeofday(&last_event, NULL);
            passive = false;
        }
        else {
            passive = timediff_usec(now, last_event) > usec_sleep_passive;
        }

        if (!FD_ISSET(shell_fd, &fds) && passive) {
            term_gc(); /* Clean up term if we have time to spare */
        }
    }
}