DRAFT: This module has unpublished changes.

/*
 * main.cpp
 *
 *  Created on: May 28, 2010
 *      Author: gamache
 */
#include "../include/StereoCamera.h"
#include <SURF.h>
#include <cv.h>
#include <highgui.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <math.h>

using namespace std;

#define WINDOW_X_RES 1024
#define WINDOW_Y_RES 768
#define IMAGE_WIDTH    320
#define IMAGE_HEIGHT 240

void ResizeGraphics (int w, int h);
void keyboard (unsigned char key, int x, int y);
void DrawGraphics();

float fX = 0;
float fY = 0;
float fZ = 0;
float lX = 0;
float lY = 0;
float lZ = 0;
//float theta = 90, phi = 0, radiusFromOrigin = 0;
int renderTriangles = 0;

float maxX, maxY, maxZ, maxDistance;

colorPoint3D *points;
StereoCamera *ptGreyCam;
static unsigned ImageWidth = IMAGE_WIDTH;
static unsigned ImageHeight = IMAGE_HEIGHT;

static GLuint LeftImageBuffer = 0;            // This is an identifier of a OpenGL Buffer Object which will hold the image to be displayed
static GLuint RightImageBuffer = 0;
static GLuint LeftImageBuffer2 = 0;
static GLuint RightImageBuffer2 = 0;

static GLuint LeftImageTexture = 0;        // We also need an OpenGL texture object to draw the image.  We will bind the data referenced by ImageBuffer to this texture
static GLuint RightImageTexture = 0;
static GLuint LeftImageTexture2 = 0;
static GLuint RightImageTexture2 = 0;

static GLuint GLWindowWidth = 800;
static GLuint GLWindowHeight = 600;

SURF *keyPnts;

void keyboard( unsigned char key, int x, int y);
void reshape(int x, int y);
void display(void);
void idle(void);

int main(int argc, char* argv[]){
    ptGreyCam = new StereoCamera();
    keyPnts = new SURF();
    points = (colorPoint3D*)malloc(sizeof(colorPoint3D)*320*240);

    // Now we are going to setup the OpenGL Utility Library Stuff to create our window and respond to user I/O
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowSize(GLWindowWidth, GLWindowHeight);
    glutCreateWindow("Stereo Disparity Map Computation Flow");
    glutDisplayFunc(display);        // set function pointer to call on display
    glutKeyboardFunc(keyboard);        // set function pointer to call on keyboard input
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);                // set function pointer to call on Idle
    glewInit(); // initi the extension wrangler to allow use of the buffer objects
    if (!glewIsSupported("GL_VERSION_2_0 GL_VERSION_1_5 GL_ARB_vertex_buffer_object GL_ARB_pixel_buffer_object")) {
        fprintf(stderr, "Required OpenGL extensions missing.");
        exit(-1);
    }


    // Now we need to create a couple memory buffers for drawing.  OpenGL
    // and CUDA will share these buffers. OpenGL Buffer Objects are simply
    // blocks of memory allocated on the Graphics card.  These buffers can contain
    // pixel data, vertex data, etc.  Using CUDA's OpenGL Interop capabilities
    // these buffers become accessable for read/write access.  When done, the buffers
    // can be returned to OpenGL control and used to draw whatever was placed into them

    // The following code is all OpenGL stuff to create and allocate the buffers, no CUDA yet.

    // Create a set of OpenGL Buffers to hold the image data we wish to draw
    unsigned int size = ImageWidth * ImageHeight *  sizeof(GLubyte)*3 ;  // Image will be in 8-bit greyscale format
    glGenBuffers( 1, &LeftImageBuffer);  // This creates the buffer
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, LeftImageBuffer);  // this make the buffer current
    glBufferData( GL_PIXEL_UNPACK_BUFFER, size, NULL, GL_DYNAMIC_DRAW);  // this allocates the proper size and sets the data null

    glGenBuffers( 1, &RightImageBuffer);
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, RightImageBuffer);
    glBufferData( GL_PIXEL_UNPACK_BUFFER, size, NULL, GL_DYNAMIC_DRAW);

    glGenBuffers( 1, &LeftImageBuffer2);
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, LeftImageBuffer2);
    glBufferData( GL_PIXEL_UNPACK_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0);  // this make the buffer current

    glGenBuffers( 1, &RightImageBuffer2);
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, RightImageBuffer2);
    glBufferData( GL_PIXEL_UNPACK_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0);  // this make the buffer current


    // Left Image Texture
    glGenTextures( 1, &LeftImageTexture);  // Create the texture reference
    glBindTexture( GL_TEXTURE_2D, LeftImageTexture);    // Make it current
    glTexImage2D( GL_TEXTURE_2D, 0, GL_BGR_EXT, ImageWidth, ImageHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, NULL); // Actually allocate the memory
    // Right Image Texture
    glGenTextures( 1, &RightImageTexture);  // Create the texture reference
    glBindTexture( GL_TEXTURE_2D, RightImageTexture);    // Make it current
    glTexImage2D( GL_TEXTURE_2D, 0, GL_BGR_EXT, ImageWidth, ImageHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, NULL); // Actually allocate the memory
    // Disparity Map Texture
    glGenTextures( 1, &LeftImageTexture2);  // Create the texture reference
    glBindTexture( GL_TEXTURE_2D, LeftImageTexture2);    // Make it current
    glTexImage2D( GL_TEXTURE_2D, 0, GL_BGR_EXT, ImageWidth, ImageHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, NULL); // Actually allocate the memory

    // Disparity2 Map Texture
    glGenTextures( 1, &RightImageTexture2);  // Create the texture reference
    glBindTexture( GL_TEXTURE_2D, RightImageTexture2);    // Make it current
    glTexImage2D( GL_TEXTURE_2D, 0, GL_BGR_EXT, ImageWidth, ImageHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, NULL); // Actually allocate the memory

    glBindTexture(GL_TEXTURE_2D, 0);

    glutMainLoop();  // that's all the setup!  now kick off the main loop
}



void reshape(int x, int y) {
    glViewport(0, 0, x, y);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 1, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glutPostRedisplay();
}



/* This is the main function where the stereo process is kicked off */
void display(void) {
    IpPairVec matches;
    ptGreyCam->stereoProcess(&matches);
    IplImage *img1 = cvLoadImage("rightRect.ppm");
    IplImage *img2 = cvLoadImage("leftRect.ppm");
    IplImage *img3 = cvLoadImage("rightRect.ppm");
    IplImage *img4 = cvLoadImage("leftRect.ppm");

    ptGreyCam->draw(&matches,img2,img1);

    //keyPnts->run(img1,img2,img3,img4);
    // Now we Draw!
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glClear(GL_COLOR_BUFFER_BIT);  // Clear the screen

    glBindTexture( GL_TEXTURE_2D, LeftImageTexture);  // Select the Image Texture
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, ImageWidth, ImageHeight,
                        GL_BGR_EXT, GL_UNSIGNED_BYTE, img2->imageData );
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);  // then unbind
    // Now just draw a square on the screen and texture it with the image texture
    glBegin( GL_QUADS);
        glVertex3f(0.0,0.0,0.5);
        glTexCoord2f(1.0, 0.0);

        glVertex3f(0.5,0.0,0.5);
        glTexCoord2f(1.0, 1.0);

        glVertex3f(0.5,0.5,0.5);
        glTexCoord2f( 0.0, 1.0);

        glVertex3f(0.0,0.5,0.5);
        glTexCoord2f( 0.0,0.0);

    glEnd();

    // right image
    glBindTexture( GL_TEXTURE_2D, RightImageTexture);  // Select the Image Texture
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, ImageWidth, ImageHeight,
                        GL_BGR_EXT, GL_UNSIGNED_BYTE, img1->imageData );
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);  // then unbind

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glBegin( GL_QUADS);
        glVertex3f(0.5,0.0,0.5);
        glTexCoord2f( 1.0, 0.0);

        glVertex3f(1.0,0.0,0.5);
        glTexCoord2f(1.0, 1.0);

        glVertex3f(1.0,0.5,0.5);
        glTexCoord2f( 0.0, 1.0);

        glVertex3f(0.5,0.5,0.5);
        glTexCoord2f( 0.0,0.0);

    glEnd();

    // disparity map
    glBindTexture( GL_TEXTURE_2D, RightImageTexture2);  // Select the Image Texture
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, ImageWidth, ImageHeight,
                        GL_BGR_EXT, GL_UNSIGNED_BYTE, img4->imageData );
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);  // then unbind

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glBegin( GL_QUADS);
        glVertex3f(0.5,0.5,0.5);
        glTexCoord2f( 1.0, 0.0);

        glVertex3f(1.0,0.5,0.5);
        glTexCoord2f(1.0, 1.0);

        glVertex3f(1.0,1.0,0.5);
        glTexCoord2f( 0.0, 1.0);

        glVertex3f(0.5,1.0,0.5);
        glTexCoord2f( 0.0,0.0);

    glEnd();

    // disparity map
    glBindTexture( GL_TEXTURE_2D, LeftImageTexture2);  // Select the Image Texture
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, ImageWidth, ImageHeight,
                        GL_BGR_EXT, GL_UNSIGNED_BYTE, img3->imageData );
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);  // then unbind

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glBegin( GL_QUADS);
        glVertex3f(0.0,0.5,0.0);
        glTexCoord2f( 1.0, 0.0);

        glVertex3f(0.5,0.5,0.5);
        glTexCoord2f(1.0, 1.0);

        glVertex3f(0.5,1.0,0.5);
        glTexCoord2f( 0.0, 1.0);

        glVertex3f(0.0,1.0,0.5);
        glTexCoord2f( 0.0,0.0);

    glEnd();

    glBindTexture( GL_TEXTURE_2D, 0);  // Select the Image Texture
    glutSwapBuffers();
    glutPostRedisplay();
}

void idle(void) {
    glutPostRedisplay();
}

void keyboard( unsigned char key, int x, int y) {
    switch( key) {
        case 27:
            ptGreyCam->~StereoCamera();
            exit(1);
            break;
        default: break;
    }
    glutPostRedisplay();
}

DRAFT: This module has unpublished changes.