All pastes #389823 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-03-11 00:10 UTC
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)
{
	cout << w << h << endl;
	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 == "")
		{
			stringstream gamemode;
			stringstream j;
			j << glutGet(GLUT_SCREEN_WIDTH);
			stringstream k;
			k << glutGet(GLUT_SCREEN_HEIGHT);
			gamemode << j.str() << "x" << k.str() << ":8@60";
			cout << gamemode;
		}
		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)