Commit 57233cc4 authored by Luis Peñaranda's avatar Luis Peñaranda
Browse files

initial commit

parents
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifdef _WIN32
#include <windows.h>
#else
#include <ctime>
#include <sys/time.h>
#endif
#include "chronos.h"
Chronos::
Chronos() {
reset();
}
void
Chronos::
reset(void) {
m_reset = time();
}
double
Chronos::
elapsed(void) {
return time() - m_reset;
}
double
Chronos::time(void) {
#ifdef _WIN32
LARGE_INTEGER counter, freq;
QueryPerformanceCounter(&counter);
QueryPerformanceFrequency(&freq);
return (1.0*counter.QuadPart)/(1.0*freq.QuadPart);
#else
struct timeval v;
gettimeofday(&v, (struct timezone *) NULL);
return v.tv_sec + v.tv_usec/1.0e6;
#endif
}
#ifndef CHRONOS_H
#define CHRONOS_H
class Chronos {
public:
Chronos();
void reset(void);
double elapsed(void);
double time(void);
private:
double m_reset;
};
#endif // CHRONOS_H
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#include <QtGui/QApplication>
#include "panowindow1.h"
#include "openglcanvas.h"
#include <QMainWindow>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PanoWindow1 w;
OpenGLCanvas canvas;
// QObject::connect(&canvas, SIGNAL(fps(QString)), w.statusBar(), SLOT(showMessage(QString)));
w.show();
return a.exec();
}
#include <QtGui>
#ifdef NEEDGLEE
#include "GLee.h"
#endif
#include "openglcanvas.h"
#include <cmath>
#define PROGNAME "pano_interface"
#define ROOT_DIR /Users/lvelho/Desktop/Work/omni/pano_interface_1
#define INPUT_IMAGE_FILE "/Users/lvelho/Desktop/pano_interface_1/input_images/image_4_input.pnm"
#define VERT_SHADER_FILE "/Users/lvelho/Desktop/pano_interface_1/shaders/test_vertex_shader.vert"
#define FRAG_SHADER_FILE "/Users/lvelho/Desktop/pano_interface_1/shaders/fragment_shader.frag"
OpenGLCanvas::OpenGLCanvas(QWidget *parent) :
QGLWidget(parent)
{
setFormat(QGL::DoubleBuffer | QGL::DepthBuffer);
fov = 60.f;
scale = 1.0f;
center_lambda = 0.f;
center_phi = 0.f;
fov_scale_relation = "Square Root";
visualization = "Perspective";
time_frames = 0;
time_timer.setInterval(0);
connect(&time_timer, SIGNAL(timeout()), this, SLOT(slotTimer()));
time_start = time_time.time();
}
void OpenGLCanvas::slotTimer(void) {
updateGL();
}
void OpenGLCanvas::change_fov(double f){
if (fov!=f && f>=1.f && f<=360.f) fov = f;
if (fov<60.f) scale = 1.f;
else if (fov>295.f) scale = 0.02f;
else {
if (fov_scale_relation == "Square Root") scale = sqrt((300.f-fov)/240.f);
else if (fov_scale_relation == "Linear") scale = (300.f-fov)/240.f;
else if (fov_scale_relation == "Square Power") scale = powf((300.f-fov)/240.f,2);
else if (fov_scale_relation == "Cubic Power") scale = powf((300.f-fov)/240.f,3);
else if (fov_scale_relation == "Logarithm") scale = log(exp(1.f) + (1.f-exp(1.f))*(fov-60.f)/240.f);
}
// scale = 0.3f;
updateGL();
}
//void OpenGLCanvas::change_scale(double s){
// if (scale!=s && s>=0.0 && s<=1.0) scale = s;
// updateGL();
//}
void OpenGLCanvas::change_center_lambda(double lambda){
if (center_lambda!=lambda && lambda>=-3.14f && lambda<=3.14f) {
center_lambda = lambda;
updateGL();
}
}
void OpenGLCanvas::change_center_phi(double phi){
if (center_phi!=phi && phi>=-1.57f && phi<=1.57f) {
center_phi = phi;
updateGL();
}
}
void OpenGLCanvas::change_fov_scale_relation(QString name){
fov_scale_relation = name;
if (fov<60.f) scale = 1.f;
else if (fov>295.f) scale = 0.01f;
else{
if (fov_scale_relation == "Square Root") scale = sqrt((300.f-fov)/240.f);
else if (fov_scale_relation == "Linear") scale = (300.f-fov)/240.f;
else if (fov_scale_relation == "Square Power") scale = powf((300.f-fov)/240.f,2);
else if (fov_scale_relation == "Cubic Power") scale = powf((300.f-fov)/240.f,3);
else if (fov_scale_relation == "Logarithm") scale = log(exp(1.f) + (1.f-exp(1.f))*(fov-60.f)/240.f);
}
updateGL();
}
void OpenGLCanvas::change_visualization(QString name){
visualization = name;
updateGL();
}
void OpenGLCanvas::initializeGL(){
glShadeModel(GL_SMOOTH);
glClearColor(1.0f,1.0f,1.0f,0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
//in Mac
const char * const progname = "PROJ_ROOT_DIR";
const char * input_image = INPUT_IMAGE_FILE;
// // in Linux
// const char * const progname = "/home/leo-ks/Research_PHD/Panoramic_Videos-2012-June-to-August/src/Qt-Creator/pano_interface_1-build-desktop-Qt_in_PATH_Release/pano_interface_1";
// const char * input_image = "/home/leo-ks/Research_PHD/Panoramic_Videos-2012-June-to-August/src/Qt-Creator/pano_interface_1/input_images/image_8_input.pnm";
int textureSize = getTextureSize(progname,input_image);
unsigned char * textureBytes = (unsigned char*)malloc(textureSize);
int width, height;
readTextureBytes(progname, input_image, textureBytes, &width, &height);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
GLuint tex;
glGenTextures(1,&tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, width,height,0,GL_RGB,GL_UNSIGNED_BYTE,textureBytes);
// mesh resolution
int m,n;
m = n = 100;
//defining texture coordinates
int meshNumTexCoord = m*n;
float *texCoord = (float *)malloc(2*meshNumTexCoord*sizeof(float));
if (texCoord == NULL){
printf("problem allocating memory for texture coordinates \n");
}
define_texture_coordinates(texCoord, m, n, -1.57f, 1.57f, -3.14f, 3.14f);
//defining positions of the sphere vertices
int meshNumVertices = m*n;
float* positions = (float *)malloc(3*meshNumVertices*sizeof(float));
if (positions == NULL){
printf("problem allocating memory for positions \n");
}
// vertex_transformation(positions, m, n, center_lambda, center_phi, fov_rads, scale); //passar pelo vertex shader
load_sphere_mesh(positions, m, n); //colocar essa e funcoes para textura e triangulos no initializeGL
//defining triagle indices
unsigned int meshNumFaces = 2*(m-1)*(n-1);
unsigned int meshNumIndices = 3*meshNumFaces;
unsigned int * indices = (unsigned int *)malloc(meshNumIndices*sizeof(unsigned int));
define_triangle_indices(indices, m, n);
// draw setup
verticesPositions = positions;
textureCoordinates = texCoord;
numberOfIndices = meshNumIndices;
triangleIndices = indices;
setShaders();
}
void OpenGLCanvas::define_texture_coordinates(float *texCoord, int m, int n, float min_phi, float max_phi, float min_lambda, float max_lambda){
float delta_lambda = (max_lambda-min_lambda)/(1.0*(n-1));
float delta_phi = (max_phi-min_phi)/(1.0*(m-1));
for (int i = 0; i<m; i++){
for (int j = 0; j<n; j++){
texCoord[2*(j+i*n)] = (min_lambda+delta_lambda*j)/(6.2832) + 0.5;
texCoord[2*(j+i*n)+1] = (min_phi+delta_phi*i)/(3.1416) + 0.5;
}
}
}
void OpenGLCanvas::vertex_transformation(float *positions, int m, int n, float center_lambda, float center_phi, float fov_rads, float scale){
float min_lambda = -3.1415f;
float max_lambda = 3.1415f;
float min_phi = -1.5708f;
float max_phi = 1.5708f;
float delta_lambda = (max_lambda-min_lambda)/(1.0*(n-1));
float delta_phi = (max_phi-min_phi)/(1.0*(m-1));
float lambda, phi, x, y, z, u, v, r, theta;
//calculating the extent of the projection for the given FOV
lambda = fov_rads;
phi = 0.f;
// OpenGL: x is the vertical axes pointg downwards, and y is horizontal axes
y = sin(phi);
x = -sin(lambda)*cos(phi);
z = -cos(lambda)*cos(phi);
u = 2.f*x/(-z+1.f);
v = 2.f*y/(-z+1.f);
r = sqrt(u*u+v*v);
theta = atan2(u,v);
r *= scale;
u = -r*sin(theta);
v = r*cos(theta);
x = (4.f*u)/(u*u+v*v+4.f);
y = (4.f*v)/(u*u+v*v+4.f);
z = (u*u+v*v-4.f)/(u*u+v*v+4.f);
u = x/(-z);
v = y/(-z);
float extent = u;
for (int i = 0; i<m; i++){
for (int j = 0; j<n; j++){
lambda = (min_lambda+delta_lambda*j);
phi = (min_phi+delta_phi*i);
// OpenGL: x is the vertical axes pointg downwards, and y is horizontal axes
y = sin(phi);
x = -sin(lambda)*cos(phi);
z = -cos(lambda)*cos(phi);
//Rotation 1: (-center_lambda)-rotation on the xz-plane
float x_copy = x;
x = cos(-center_lambda)*x - sin(-center_lambda)*z;
y = 1.f*y;
z = sin(-center_lambda)*x_copy + cos(-center_lambda)*z;
//Rotation 2: (-center_phi)-rotation on the yz-plane
float y_copy = y;
x = 1.f*x;
y = cos(-center_phi)*y - sin(-center_phi)*z;
z = sin(-center_phi)*y_copy + cos(-center_phi)*z;
u = 2.f*x/(-z+1.f);
v = 2.f*y/(-z+1.f);
r = sqrt(u*u+v*v);
theta = atan2(u,v);
// scaling the complex plane according to scale specified in the interface (relate it to FOV)
r *= scale;
u = -r*sin(theta);
v = r*cos(theta);
x = (4.f*u)/(u*u+v*v+4.f);
y = (4.f*v)/(u*u+v*v+4.f);
z = (u*u+v*v-4.f)/(u*u+v*v+4.f);
lambda = atan2(x,-z)/3.1415;
phi = asin(y)/1.5708;
u = x/(-z);
v = y/(-z);
if (visualization=="Perspective"){
positions[3*(j+i*n)] = u/extent;
positions[3*(j+i*n)+1] = v/extent;
positions[3*(j+i*n)+2] = z;
}
if (visualization=="3D Sphere"){
positions[3*(j+i*n)] = 0.9f*x;
positions[3*(j+i*n)+1] = 0.9f*y;
positions[3*(j+i*n)+2] = z;
}
if (visualization=="Equi-Rectangular"){
positions[3*(j+i*n)] = lambda;
positions[3*(j+i*n)+1] = phi;
positions[3*(j+i*n)+2] = z;
}
}
}
}
void OpenGLCanvas::load_sphere_mesh(float *positions, int m, int n){
float min_lambda = -3.1415f;
float max_lambda = 3.1415f;
float min_phi = -1.5708f;
float max_phi = 1.5708f;
float delta_lambda = (max_lambda-min_lambda)/(1.0*(n-1));
float delta_phi = (max_phi-min_phi)/(1.0*(m-1));
float lambda, phi, x, y, z;
for (int i = 0; i<m; i++){
for (int j = 0; j<n; j++){
lambda = (min_lambda+delta_lambda*j);
phi = (min_phi+delta_phi*i);
// OpenGL: x is the vertical axes pointg downwards, and y is horizontal axes
y = sin(phi);
x = -sin(lambda)*cos(phi);
z = -cos(lambda)*cos(phi);
positions[3*(j+i*n)] = x;
positions[3*(j+i*n)+1] = y;
positions[3*(j+i*n)+2] = z;
}
}
}
float OpenGLCanvas::calculate_extent(float fov_rads){
float lambda, phi, x, y, z, u, v, r, theta;
//calculating the extent of the projection for the given FOV
lambda = fov_rads;
phi = 0.f;
// OpenGL: x is the vertical axes pointg downwards, and y is horizontal axes
y = sin(phi);
x = -sin(lambda)*cos(phi);
z = -cos(lambda)*cos(phi);
u = 2.f*x/(-z+1.f);
v = 2.f*y/(-z+1.f);
r = sqrt(u*u+v*v);
theta = atan2(u,v);
r *= scale;
u = -r*sin(theta);
v = r*cos(theta);
x = (4.f*u)/(u*u+v*v+4.f);
y = (4.f*v)/(u*u+v*v+4.f);
z = (u*u+v*v-4.f)/(u*u+v*v+4.f);
u = x/(-z);
v = y/(-z);
return u;
}
void OpenGLCanvas::define_triangle_indices(unsigned int * indices, int m, int n){
for (int i = 0; i<m-1; i++){
for (int j = 0; j<n-1; j++){
unsigned int index = (j+i*n);
indices[3*(2*(j+i*(n-1)))] = index;
indices[3*(2*(j+i*(n-1)))+1] = index+1;
indices[3*(2*(j+i*(n-1)))+2] = index+n;
indices[3*(2*(j+i*(n-1))+1)] = index+1;
indices[3*(2*(j+i*(n-1))+1)+1] = index+n+1;
indices[3*(2*(j+i*(n-1))+1)+2] = index+n;
}
}
}
int OpenGLCanvas::getTextureSize(const char * const progname, const char * texturePath)
{
struct pam inpam;
pm_init(progname, 0);
FILE * in_file = fopen(texturePath,"r");
if (in_file==NULL){
printf("\n ERROR in getTextureSize: unable to open specified file \n");
return -1;
}
pnm_readpaminit(in_file, &inpam,PAM_STRUCT_SIZE(tuple_type)); // IN MAC
// pnm_readpaminit(in_file, &inpam,sizeof(inpam)); //in linux
int size = inpam.width*inpam.height*inpam.depth*inpam.bytes_per_sample;
pm_close(in_file);
return size;
}
void OpenGLCanvas::readTextureBytes(const char * const progname,
const char * texturePath,
unsigned char * textureBytes,
int * outImageWidth,
int * outImageHeight)
{
struct pam inpam;
tuple * tuplerow;
int row;
pm_init(progname, 0);
FILE * in_file = fopen(texturePath, "r");
pnm_readpaminit(in_file, &inpam,PAM_STRUCT_SIZE(tuple_type)); // IN MAC
// pnm_readpaminit(in_file, &inpam,sizeof(inpam)); //in linux
tuplerow = pnm_allocpamrow(&inpam);
for (row = 0; row < inpam.height; row++) {
int column;
pnm_readpamrow(&inpam, tuplerow);
for (column = 0; column < inpam.width; ++column) {
unsigned int plane;
for (plane = 0; plane < inpam.depth; ++plane) {
textureBytes[(inpam.height-row-1)*3*inpam.width+3*column+plane] = tuplerow[column][plane];
}
}
}
pnm_freepamrow(tuplerow);
*outImageWidth = inpam.width;
*outImageHeight = inpam.height;
pm_close(in_file);
}
void OpenGLCanvas::resizeGL(int w, int h){
glViewport(0,0,w,h);
}
char * OpenGLCanvas::textFileRead(char *fn) {
FILE *fp;
char *content = NULL;
int f, count;
f = open(fn, O_RDONLY);
count = lseek(f, 0, SEEK_END);
// close(f);
if (fn != NULL) {
fp = fopen(fn,"rt");
if (fp != NULL) {
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
return content;
}
void OpenGLCanvas::setShaders() {
char *vs,*fs;
GLuint v = glCreateShader(GL_VERTEX_SHADER);
GLuint f = glCreateShader(GL_FRAGMENT_SHADER);
// in Mac
vs = textFileRead(VERT_SHADER_FILE);
fs = textFileRead(FRAG_SHADER_FILE);
// // in Linux
// vs = textFileRead("/home/leo-ks/Research_PHD/Panoramic_Videos-2012-June-to-August/src/Qt-Creator/pano_interface_1/shaders/test_vertex_shader.vert");
// fs = textFileRead("/home/leo-ks/Research_PHD/Panoramic_Videos-2012-June-to-August/src/Qt-Creator/pano_interface_1/shaders/fragment_shader.frag");
const char * vv = vs;
const char * ff = fs;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
free(vs);free(fs);
glCompileShader(v);
glCompileShader(f);
GLuint p = glCreateProgram();
glAttachShader(p,v);
glAttachShader(p,f);
glLinkProgram(p);
glUseProgram(p);
}
void OpenGLCanvas::paintGL(){
float fov_rads = (fov/180.f)*1.5708f;
// // changing scale to generate the figures for the paper (remove it after)
// scale = 0.8;
// defining transformation parameters (that will be passed to the vertex shader)
float extent = calculate_extent(fov_rads);
float vis_mode;
if (visualization=="Perspective") vis_mode=1.0;
else if (visualization=="3D Sphere") vis_mode=2.0;
else if (visualization=="Equi-Rectangular") vis_mode=3.0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 2.0/extent, 0.0, 2.0/scale, 0.0, -2.0/vis_mode);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0.0, 2.0/center_lambda, 0.0, 2.0/center_phi, -1.0, 1.0);
// drawing the mesh
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor3f(1, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, verticesPositions);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates);
glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_INT, triangleIndices);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
time_frames++;
// if (time_frames > 0) {
double dt = time_time.elapsed();
// if (dt > 0.5) {
time_fps = time_frames/dt;
time_frames = 0;
time_time.reset();</