rendered paste body//gcc -Wall -I/usr/include -o phimage phimage.cpp `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0` -L/usr/X11R6/lib -lX11 -lglut -lGL -lGLU -lm
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
//#include <gtk/gtk.h>
//#include <gdk-pixbuf/gdk-pixbuf.h>
#include <unistd.h> // needed to sleep
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <dirent.h>
#include <sstream>
#include <vector>
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#include <gtkmm.h>
#include <math.h>
#include <sys/timeb.h>
//#include <math.h>
#define ESCAPE 27
using namespace std;
void keyPressed(unsigned char key, int x, int y);
void ReSizeGLScene(int Width, int Height);
void DrawGLScene();
void IdleFunc();
double getTime();
class TextureLoader
{
private:
int buffersize, tilesize;
float nix, niy;
GdkInterpType tilequality;
string filename;
bool closed;
bool resize;
GdkPixbufLoader *pixbuf;
GdkPixbuf *pixbuf_new, *pixbuf_old;
ifstream file;
public:
TextureLoader(string, int, int, GdkInterpType);
bool next_chunk();
guchar* transfer(void);
int get_width();
int get_height();
};
TextureLoader::TextureLoader(string in_filename, int in_buffersize, int in_tilesize, GdkInterpType in_tilequality)
{
filename = in_filename;
buffersize = in_buffersize;
tilesize = in_tilesize;
tilequality = in_tilequality;
closed = false;
resize = false;
pixbuf = gdk_pixbuf_loader_new();
pixbuf_new = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, tilesize, tilesize);
gdk_pixbuf_fill(pixbuf_new, 0x00000000);
file.open(filename.data(), ios::in | ios::binary);
file.seekg(0, ios::beg);
}
bool TextureLoader::next_chunk(void)
{
float ix, iy;
char *buffer;
buffer = new char [buffersize];
if (!closed)
{
if (file.eof())
{
gdk_pixbuf_loader_close(pixbuf, NULL);
file.close();
closed = true;
pixbuf_old = gdk_pixbuf_loader_get_pixbuf(pixbuf);
pixbuf_old = gdk_pixbuf_add_alpha(pixbuf_old, false, 'a', 'a', 'a');
ix = gdk_pixbuf_get_width(pixbuf_old);
iy = gdk_pixbuf_get_height(pixbuf_old);
if (ix > iy)
{
nix = tilesize - 4;
niy = (nix / ix) * iy;
}
else
{
niy = tilesize - 4;
nix = (niy / iy) * ix;
}
return true;
}
else
{
file.read(buffer, buffersize);
gdk_pixbuf_loader_write(pixbuf, reinterpret_cast<const guchar*>(buffer), buffersize, NULL);
return true;
}
}
else if (!resize)
{
pixbuf_old = gdk_pixbuf_scale_simple(pixbuf_old, (int)nix, (int)niy, tilequality);
gdk_pixbuf_copy_area(pixbuf_old, 0, 0, (int)nix, (int)niy, pixbuf_new, (int)(2+(tilesize - 4 - nix)/2), (int)(2+(tilesize - 4 - niy)/2));
resize = true;
}
return false;
}
guchar* TextureLoader::transfer()
{
return gdk_pixbuf_get_pixels(pixbuf_new);
}
int TextureLoader::get_width()
{
return (int)tilesize;
}
int TextureLoader::get_height()
{
return (int)tilesize;
}
class phimage
{
public:
gint true_window;
gint tilesize, tilequality, buffersize, blendtime, hangtime;
uint counter;
char *dir, *resolution, *constraint, *speed, *o_distance, *o_perspective, *o_angle;
float distance, perspective, xm, ym, xr, yr, movth, rotth;
float theta, thetar, angle;
gint window;
GdkInterpType realtilequality;
vector <Glib::ustring> files;
GLuint textureName[2];
int state;
double diffTime, stateTime, stateCounter, d2;
float alpha[2];
TextureLoader *tex[2];
phimage(int, char**);
void init_options(int argc, char **argv);
void check_options();
void get_files();
// Glib::OptionEntry entry(char short_name, const char* long_name, const char* description);
Glib::ustring next_file();
vector <Glib::ustring> split(char *, char *);
void storeIDLTexture(guchar *, int, int, int);
void InitGL(int Width, int Height);
void main();
};
phimage::phimage(int argc, char **argv)
{
alpha[0]=1;
alpha[1]=0;
stateCounter=0;
diffTime=0;
stateTime=0;
state = 0;
o_perspective = NULL;
o_distance = NULL;
o_angle = NULL;
true_window = 0;
theta = 0.0;
thetar = 0.0;
this->check_options();
this->init_options(argc, argv);
this->get_files();
// vector <Glib::ustring> c_options = this->split(constraint);
gtk_init(&argc, &argv);
// this->main();
////Example for texture loader function
//GdkPixbuf *man;
//TextureLoader test("/home/pete/NeHe.bmp", 0, 16384, 512, realtilequality);
//while (test.next_chunk());
//man = test.transfer();
//gdk_pixbuf_save(man, "/home/pete/opengl/test.png", "png", NULL, NULL);
////Example of float to string conversion
//float jim;
//Glib::ustring s = "33.2";
//std::istringstream i(s);
//i >> jim;
//cout << jim;
}
void phimage::get_files()
{
DIR *pdir;
struct dirent *pent;
vector <Glib::ustring> tmpfiles;
pdir=opendir(reinterpret_cast<char*>(dir)); //"." refers to the current dir
if (!pdir)
{
printf ("opendir() failure; terminating");
exit(1);
}
errno=0;
while ((pent=readdir(pdir)))
{
tmpfiles.push_back(pent->d_name);
}
if (errno)
{
printf ("readdir() failure; terminating");
exit(1);
}
closedir(pdir);
int size = tmpfiles.size();
int i;
Glib::ustring tempString;
for (i=0 ; i< size; i++)
{
tempString = tmpfiles[i].lowercase();
if (tempString.find(".jpg")!=string::npos || tempString.find(".png")!=string::npos || tempString.find(".bmp")!=string::npos)
{
files.push_back(tmpfiles[i]);
}
}
}
void phimage::check_options()
{
d2 = 0;
tilesize=512;
tilequality=1;
dir=".";
angle=10.0;
buffersize=16384;
blendtime=300;
hangtime=100;
constraint="0.5,0.5,30,30";
speed="0.05,0.05";
resolution="";
window=0;
distance=2.5;
perspective=45.0;
}
void phimage::storeIDLTexture(guchar *data, int idl, int w, int h)
{
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glBindTexture(GL_TEXTURE_2D, textureName[idl]);
glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}
void phimage::InitGL(int Width, int Height)
{
glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glShadeModel(GL_FLAT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(perspective, float(Width)/float(Height), 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
{
TextureLoader test(this->dir+string("/")+this->next_file(), buffersize, tilesize, realtilequality);
while (test.next_chunk());
guchar* data = test.transfer();
this->storeIDLTexture(data, 0, test.get_width(), test.get_height());
}
{
TextureLoader test(this->dir+string("/")+this->next_file(), buffersize, tilesize, realtilequality);
while (test.next_chunk());
guchar* data = test.transfer();
this->storeIDLTexture(data, 1, test.get_width(), test.get_height());
}
}
void phimage::main()
{
int wi, he;
string wid, hei;
int argc;
char* argv;
vector <Glib::ustring> sizes;
vector <Glib::ustring> splres;
argc = 0;
argv = "";
glutInit(&argc, &argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
if (window == 1 || !glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
{
if (resolution == "")
glutInitWindowSize(800, 600);
else
{
sizes = this->split(resolution,":");
Glib::ustring wandh = sizes[0];
splres = this->split(const_cast<char*>(wandh.data()),"x");
std::istringstream j(splres[0]);
j >> wi;
std::istringstream k(splres[1]);
k >> he;
glutInitWindowSize(wi, he);
}
glutInitWindowPosition(0, 0);
true_window = glutCreateWindow("Phimage");
}
else
{
if (resolution == "")
{
string gamemode;
stringstream j;
j << glutGet(GLUT_SCREEN_WIDTH);
stringstream k;
k << glutGet(GLUT_SCREEN_HEIGHT);
gamemode.assign(j.str() + (string)"x" + k.str() + (string)":8@60");
glutGameModeString(gamemode.data());
}
else
glutGameModeString(resolution);
glutEnterGameMode();
}
glutDisplayFunc(&DrawGLScene);
glutIdleFunc(&IdleFunc);
glutReshapeFunc(&ReSizeGLScene);
glutKeyboardFunc(&keyPressed);
glGenTextures(2, &textureName[0]);
InitGL(1024, 768);
glutMainLoop();
}
/*
Glib::OptionEntry phimage::entry(char short_name, const char* long_name, const char* description)
{
Glib::OptionEntry ent1;
ent1.set_short_name(short_name);
ent1.set_long_name(long_name);
ent1.set_description(description);
return ent1;
}
*/
void phimage::init_options(int argc, char **argv)
{
/*
Glib::OptionContext test;
Glib::OptionGroup idiot("example", "example", "example");
idiot.add_entry(this->entry('b',"buffersize","no"), buffersize);
test.set_main_group(idiot);
test.parse(argc, argv);
cout << "test";
*/
static GOptionEntry entries[] =
{
{ "tilesize", 't', 0, G_OPTION_ARG_INT, &tilesize, "Tile Size", "N" },
{ "tilequality", 'q', 0, G_OPTION_ARG_INT, &tilequality, "Tile Quality", "M" },
{ "dir", 'd', 0, G_OPTION_ARG_STRING, &dir, "Directory", NULL },
{ "angle", 'a', 0, G_OPTION_ARG_STRING, &o_angle, "Angle", NULL },
{ "buffersize", 'b', 0, G_OPTION_ARG_INT, &buffersize, "Buffer Size", "N" },
{ "blendtime", 'B', 0, G_OPTION_ARG_INT, &blendtime, "Blend Time", "M" },
{ "hangtime", 'H', 0, G_OPTION_ARG_INT, &hangtime, "Hang Time", NULL },
{ "constraint", 'c', 0, G_OPTION_ARG_STRING, &constraint, "Constraint", NULL },
{ "speed", 's', 0, G_OPTION_ARG_STRING, &speed, "Speed", "N" },
{ "resolution", 'r', 0, G_OPTION_ARG_STRING, &resolution, "Resolution", "M" },
{ "window", 'w', 0, G_OPTION_ARG_INT, &window, "Window", NULL },
{ "distance", 'D', 0, G_OPTION_ARG_STRING, &o_distance, "Distance", NULL },
{ "perspective", 'p', 0, G_OPTION_ARG_STRING, &o_perspective, "Perspective", NULL },
{ NULL }
};
GOptionContext *context;
context = g_option_context_new ("- test tree model performance");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
g_option_context_parse (context, &argc, &argv, NULL);
if (tilequality == 0) realtilequality = GDK_INTERP_NEAREST;
else if (tilequality == 1) realtilequality = GDK_INTERP_BILINEAR;
if (o_perspective)
{
std::istringstream i(o_perspective);
i >> perspective;
}
if (o_angle)
{
std::istringstream i(o_angle);
i >> angle;
}
if (o_distance)
{
std::istringstream w(o_distance);
w >> distance;
}
vector <Glib::ustring> a_constraints = this->split(constraint,",");
std::istringstream xmw(a_constraints[0]);
xmw >> xm;
std::istringstream ymw(a_constraints[1]);
ymw >> ym;
std::istringstream xrw(a_constraints[2]);
xrw >> xr;
std::istringstream yrw(a_constraints[3]);
yrw >> yr;
vector <Glib::ustring> a_speed = this->split(speed,",");
std::istringstream movw(a_speed[0]);
movw >> movth;
std::istringstream rotw(a_speed[1]);
rotw >> rotth;
}
Glib::ustring phimage::next_file()
{
counter++;
if (counter >= files.size())
counter = 0;
return files[counter];
}
vector <Glib::ustring> phimage::split(char *string, char *split)
{
vector <Glib::ustring> tmp;
Glib::ustring test = string;
int flag = 0;
while (test.find_first_of(split, flag)!=string::npos)
{
tmp.push_back(test.substr(flag, test.find_first_of(split, flag) - flag));
flag = test.find_first_of(split, flag) + 1;
}
tmp.push_back(test.substr(flag, string::npos));
return tmp;
}
phimage *globalObject = NULL;
void keyPressed(unsigned char key, int x, int y)
{
/* avoid thrashing this procedure */
usleep(100);
/* If escape is pressed, kill everything. */
if (key == ESCAPE)
{
/* shut down our window */
glutDestroyWindow(globalObject->true_window);
/* exit the program...normal termination. */
exit(0);
}
}
void ReSizeGLScene(int Width, int Height)
{
if (Height == 0)
Height = 1;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(globalObject->perspective, float(Width)/float(Height), 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void DrawGLScene()
{
float xmov, ymov, xmovr, ymovr;
//self.stateChecker()
//Trying to imporve performance here
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0,0.0,-globalObject->distance);
xmov = sin(globalObject->theta);
ymov = cos(globalObject->theta);
xmovr = sin(globalObject->thetar);
ymovr = cos(globalObject->thetar);
glTranslatef(xmov*globalObject->xm,ymov*globalObject->ym,0);
glRotatef (-ymovr*globalObject->yr, 0.0, 1.0, 0.0);
glRotatef (xmovr*globalObject->xr, 1.0, 0.0, 0.0);
glRotatef(globalObject->angle,0.0,1.0,0.0);
// glColor4f(1.0, 1.0, 1.0, 1.0);
glColor4f(1.0, 1.0, 1.0, globalObject->alpha[0]);
glBindTexture(GL_TEXTURE_2D, globalObject->textureName[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex2f( 1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex2f( 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, 1.0);
glEnd();
glTranslatef(-2*xmov*globalObject->xm,-2*ymov*globalObject->ym,0);
glRotatef(-2*(globalObject->angle),0.0,1.0,0.0);
// glColor4f(1.0, 1.0, 1.0, 1.0);
glColor4f(1.0, 1.0, 1.0, globalObject->alpha[1]);
glBindTexture(GL_TEXTURE_2D,globalObject->textureName[1]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex2f( 1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex2f( 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, 1.0);
glEnd();
// globalObject->theta = globalObject->theta + globalObject->movth;
// globalObject->thetar = globalObject->thetar + globalObject->rotth;
if ((getTime() - globalObject->d2) >= .01)
{
globalObject->d2 = getTime();
globalObject->theta = globalObject->theta + globalObject->movth;
globalObject->thetar = globalObject->thetar + globalObject->rotth;
}
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}
void IdleFunc()
{
double diffTime;
diffTime = getTime() - globalObject->stateTime;
globalObject->diffTime = diffTime;
if (globalObject->state == 0)
{
globalObject->alpha[0] = (1.0 / globalObject->blendtime) * globalObject->stateCounter;
globalObject->alpha[1] = (globalObject->blendtime - globalObject->stateCounter) * (1.0 / globalObject->blendtime);
globalObject->stateCounter = globalObject->stateCounter + (diffTime * 100);
if (globalObject->stateCounter > globalObject->blendtime)
{
globalObject->alpha[0] = 1;
globalObject->alpha[1] = 0;
globalObject->state = 1;
globalObject->stateCounter = 0;
}
}
else if (globalObject->state == 1)
{
globalObject->tex[1] = new TextureLoader(globalObject->dir+string("/")+globalObject->next_file(), globalObject->buffersize, globalObject->tilesize, globalObject->realtilequality);
globalObject->state = 2;
}
else if (globalObject->state == 2)
{
if (globalObject->tex[1]->next_chunk() == false)
{
guchar* data = globalObject->tex[1]->transfer();
globalObject->storeIDLTexture(data, 1, globalObject->tex[1]->get_width(), globalObject->tex[1]->get_height());
}
globalObject->stateCounter = globalObject->stateCounter + (diffTime * 100);
if (globalObject->stateCounter > globalObject->hangtime)
{
globalObject->state = 3;
globalObject->stateCounter = 0;
}
}
else if (globalObject->state == 3)
{
globalObject->alpha[1] = (1.0 / globalObject->blendtime) * globalObject->stateCounter;
globalObject->alpha[0] = (globalObject->blendtime - globalObject->stateCounter) * (1.0 / globalObject->blendtime);
globalObject->stateCounter = globalObject->stateCounter + (diffTime * 100);
if (globalObject->stateCounter > globalObject->blendtime)
{
globalObject->alpha[1] = 1;
globalObject->alpha[0] = 0;
globalObject->state = 4;
globalObject->stateCounter = 0;
}
}
else if (globalObject->state == 4)
{
globalObject->tex[0] = new TextureLoader(globalObject->dir+string("/")+globalObject->next_file(), globalObject->buffersize, globalObject->tilesize, globalObject->realtilequality);
globalObject->state = 5;
}
else if (globalObject->state == 5)
{
if (globalObject->tex[0]->next_chunk() == false)
{
guchar* data = globalObject->tex[0]->transfer();
globalObject->storeIDLTexture(data, 0, globalObject->tex[0]->get_width(), globalObject->tex[0]->get_height());
}
globalObject->stateCounter = globalObject->stateCounter + (diffTime * 100);
if (globalObject->stateCounter > globalObject->hangtime)
{
globalObject->state = 0;
globalObject->stateCounter = 0;
}
}
globalObject->stateTime = globalObject->stateTime + diffTime;
// self.frameCnt = self.frameCnt + 1
// print self.frameCnt / (self.stateTime - self.startTime)
}
double getTime()
{
timeval tim;
gettimeofday(&tim, NULL);
double t1=(double)tim.tv_sec+((double)tim.tv_usec/1000000.0);
return t1;
}
int main(int argc, char *argv[]) {
phimage main(argc, argv);
globalObject = &main;
main.main();
//dir * = opendir("./");
}
//change the next line too (buffer=) new char, and then pass to pixbufloader reinterpret_cast<const guchar*>(buffer)