void idle() { // which eye are we on? (1/0 for left/right) static int current_eye = 0; // draw the frame for the current eye draw(current_eye); // this replaces our traditional glutSwapBuffers call (let the usb emitter // code call it and keep track of things) nvstusb_swap(nv_ctx, (nvstusb_eye) current_eye, glutSwapBuffers); current_eye = (current_eye + 1) % 2; // get the status of the button/wheel on the emitter (you MUST do this, // otherwise the whole system will stall out after just a couple of frames) struct nvstusb_keys k; nvstusb_get_keys(nv_ctx, &k); // the 3D button on the IR emitter controls toggling the rotation on and // off if (k.toggled3D) { rotation = !rotation; printf("Toggled rotation.\n"); } // the wheel on the back adjusts the focal length of the camera (and // interoccular distance, since we want to maintain IOD = 1/30th of the // focal length) if (k.deltaWheel != 0) { cam.focal += k.deltaWheel; cam.iod = cam.focal / 30.0f; printf("Set camera focal length to %f.\n", cam.focal); } // you can also use k.pressedDeltaWheel, which reports the amount the wheel // moves while the 3D button is pressed }
/* Main function */ int main(int argc, char **argv) { Display *dpy; Window win; uint i_swap_cnt = 0; char const * config_fw = NULL; /* Getopt section */ struct option long_options[] = { /* These options set a flag. */ {NULL, 0, 0, 0} }; while (1) { int c; /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case '?': default: usage(); exit(EXIT_FAILURE); } } if (optind < argc) { while (optind < argc) { config_fw = argv[optind++]; } } /* Openning X display */ dpy = XOpenDisplay(0); /* Preparing new X window */ Window s_window; static int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList); s_window = RootWindow(dpy, vi->screen); XSetWindowAttributes swa; swa.colormap = XCreateColormap(dpy, s_window, vi->visual, AllocNone); swa.override_redirect = 1; /* Create X window 1x1 top left of screen */ win = XCreateWindow(dpy, s_window , 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, CWColormap|CWOverrideRedirect, &swa); XMapWindow(dpy, win); /* Create glX context */ GLXContext glx_ctx = glXCreateContext(dpy, vi, 0, 1); glXMakeCurrent(dpy, win, glx_ctx); /* Initialize libnvstusb */ ctx = nvstusb_init(config_fw); if (0 == ctx) { fprintf(stderr, "could not initialize NVIDIA 3D Stereo Controller, aborting\n"); exit(EXIT_FAILURE); } /* Get Vsync rate from X11 */ XF86VidModeModeLine modeline; int pixelclock; XF86VidModeGetModeLine( dpy, DefaultScreen(dpy), &pixelclock, &modeline ); double frameRate=(double) pixelclock*1000/modeline.htotal/modeline.vtotal; printf("Vertical Refresh rate:%f Hz\n",frameRate); nvstusb_set_rate(ctx, frameRate); /* Loop until stop */ while (1) { /* Send swap to usb controler */ nvstusb_swap(ctx, nvstusb_quad, NULL /*f_swap*/); /* Read status from usb controler */ if(!(i_swap_cnt&0xF)) { struct nvstusb_keys k; nvstusb_get_keys(ctx, &k); if (k.toggled3D) { nvstusb_invert_eyes(ctx); } } i_swap_cnt++; } /* Destroy context */ glx_ctx = glXGetCurrentContext(); glXDestroyContext(dpy, glx_ctx); /* Denit libnvstusb */ nvstusb_deinit(ctx); return EXIT_SUCCESS; }
/* Stereo thread - For GL_STEREO */ static void * nvstusb_stereo_thread(void * in_pv_arg) { struct nvstusb_context *ctx = (struct nvstusb_context *) in_pv_arg; Display *dpy; Window win; /* Openning X display */ dpy = XOpenDisplay(0); /* Preparing new X window */ Window s_window; static int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeList); s_window = RootWindow(dpy, vi->screen); XSetWindowAttributes swa; swa.colormap = XCreateColormap(dpy, s_window, vi->visual, AllocNone); swa.override_redirect = true; /* Create X window 1x1 top left of screen */ win = XCreateWindow(dpy, s_window , 0, 0, 1, 1, 0, vi->depth, InputOutput, vi->visual, CWColormap|CWOverrideRedirect, &swa); XMapWindow(dpy, win); /* Create glX context */ GLXContext glx_ctx = glXCreateContext(dpy, vi, 0, true); glXMakeCurrent(dpy, win, glx_ctx); /* Loop until stop */ while (ctx->b_thread_running) { /* Send swap to usb controler */ nvstusb_swap(ctx, nvstusb_quad, NULL /*f_swap*/); /* Read status from usb controler */ struct nvstusb_keys k; nvstusb_get_keys(ctx, &k); if (k.toggled3D) { nvstusb_invert_eyes(ctx); } } /* Destroy context */ glx_ctx = glXGetCurrentContext(); glXDestroyContext(dpy, glx_ctx); return NULL; }