//A small program displaying video from two IEEE1394 digital camera simultaneously
//ieee1394, raw1394, video1394, ohci1394, OpenGL library is needed
//Created by Yuan-Chu Tai, ycdai@csie.nctu.edu.tw
#include <GL/glut.h>
#include <stdlib.h>
#include <libraw1394/raw1394.h>
#include <libdc1394/dc1394_control.h>

static dc1394_cameracapture camera;
static dc1394_cameracapture camera2;
static int numNodes;
static int numCameras;
static raw1394handle_t handle;
static nodeid_t * camera_nodes;
static dc1394_feature_set features;
static dc1394_feature_set features2;

void display(void)
{
	glRasterPos2i(0,640);
  	dc1394_dma_single_capture(&camera);
	glPixelZoom(0.5,-0.5);
	glDrawPixels(640,480,GL_RGB,GL_UNSIGNED_BYTE,camera.capture_buffer);
	glPixelZoom(1.0,1.0);
	dc1394_dma_done_with_buffer(&camera);	
	
	glRasterPos2i(240,640);
  	dc1394_dma_single_capture(&camera2);	
	glPixelZoom(0.5,-0.5);
	glDrawPixels(640,480,GL_RGB,GL_UNSIGNED_BYTE,camera2.capture_buffer);
	glPixelZoom(1.0,1.0);
	dc1394_dma_done_with_buffer(&camera2);

	glutSwapBuffers();

}

void spinDisplay(void)
{
   glutPostRedisplay();
}

void init(void)
{
}

void ieee1394init()
{
	handle = dc1394_create_handle(0);
	numNodes = raw1394_get_nodecount(handle);
	camera_nodes = dc1394_get_camera_nodes(handle,&numCameras,1);
	dc1394_dma_setup_capture(handle,camera_nodes[0],
			0,
			FORMAT_VGA_NONCOMPRESSED,
			MODE_640x480_RGB,
			SPEED_400,
			FRAMERATE_15,
			4,
			&camera);
	printf("first camera\n");
	dc1394_get_camera_feature_set(handle, camera.node,&features);
	dc1394_print_feature_set(&features);

	dc1394_dma_setup_capture(handle,camera_nodes[1],
			1,
			FORMAT_VGA_NONCOMPRESSED,
			MODE_640x480_RGB,
			SPEED_400,
			FRAMERATE_15,
			4,
			&camera2);
	printf("second camera\n");
	dc1394_get_camera_feature_set(handle, camera2.node,&features2);
	dc1394_print_feature_set(&features2);
	
	dc1394_start_iso_transmission(handle,camera.node);
	dc1394_start_iso_transmission(handle,camera2.node);
}

void reshape(int w, int h)
{
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0.0, 480.0, 0.0, 640.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void mouse(int button, int state, int x, int y)
{
   switch (button) {
      case GLUT_LEFT_BUTTON:
         if (state == GLUT_DOWN) {
            glutIdleFunc(spinDisplay);
	 }
         break;
      case GLUT_RIGHT_BUTTON:
         if (state == GLUT_DOWN) {	    	 
            glutIdleFunc(NULL);
	 }
         break;
      default:
         break;
   }
}

static void
key(unsigned char k, int x, int y)
{
  switch (k) {
  case 27:  /* Escape */

   dc1394_stop_iso_transmission(handle,camera.node);
   dc1394_stop_iso_transmission(handle,camera2.node);
   dc1394_dma_release_camera(handle,&camera);
   dc1394_dma_unlisten(handle,&camera);
   dc1394_dma_release_camera(handle,&camera2);
   dc1394_dma_unlisten(handle,&camera2);
   raw1394_destroy_handle(handle);

    exit(0);
    break;
  default:
    return;
  }
  glutPostRedisplay();
}

int main(int argc, char** argv)
{
   ieee1394init();
	
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize (640, 240);
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);

	glDisable(GL_SCISSOR_TEST);
	glDisable(GL_ALPHA_TEST);
	glDisable(GL_STENCIL_TEST);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_COLOR_LOGIC_OP);
	glDisable(GL_BLEND);
	glDisable(GL_DITHER);

   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutMouseFunc(mouse);
   glutKeyboardFunc(key);
   glutMainLoop();

   return 0;  
}
