#include <windows.h> // Header File For Windows
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
// Linux/Unix specific
#include <time.h>
//#include <unistd.h>
// OPENGL stuff
#ifdef XMESA
#include <GL/xmesa.h>
#endif
#define _GDI32_
//#include <GL/glx.h>
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
//#include <gl\glaux.h> // Header File For The Glaux Library
#include <GL/glut.h>
static int fullscreen = 1;
static int voodoo_gfx = 0;
static int softrender = 0;
static int videoram = 32;
static int xres, yres;
// custom objects
#include "flotte.h"
//----------------------------------
// an instance of 'dmFlotte' object
//----------------------------------
dmFlotte *gFlotte = NULL;
static int win;
static int flag_func = 0;
static float mx=0.0f, my=0.0f;
static float mrota = 0.0f;
static float totalrot = 0.0f;
static int mbutton = -1;
static float pX = 0.0f;
static float pY = 0.0f;
static int waveFlag = 0;
static int vsizeX = 1024;
static int vsizeY = 768;
#include "TuioListener.h"
#include "TuioClient.h"
using namespace TUIO;
class TuioDemo : public TuioListener {
public:
TuioDemo(int port)
{
tuioClient = new TuioClient(port);
tuioClient->addTuioListener(this);
tuioClient->connect();
if (!tuioClient->isConnected())
{
}
}
~TuioDemo() {
tuioClient->disconnect();
delete tuioClient;
}
void addTuioObject(TuioObject *tobj) { }
void updateTuioObject(TuioObject *tobj) { }
void removeTuioObject(TuioObject *tobj){ }
void addTuioCursor(TuioCursor *tcur);
void updateTuioCursor(TuioCursor *tcur);
void removeTuioCursor(TuioCursor *tcur);
void refresh(TuioTime frameTime) { }
void showWave(dmFlotte *flotte)
{
std::list<TuioCursor*> lstCursor = tuioClient->getTuioCursors();
std::list<TuioCursor*>::iterator tcur;
for (tcur=lstCursor.begin(); tcur!= lstCursor.end(); tcur++) {
flotte->setWave((*tcur)->getX(),-(*tcur)->getY(), 128);
}
}
TuioClient *tuioClient;
};
TuioDemo *tuioListner = NULL;
//---------------------------
// callbacks ...
//---------------------------
void display(void)
{
// slow down fluid model if too quick to look like water
if (gFlotte->bench(10.0f))
{
tuioListner->showWave(gFlotte);
/*if (waveFlag)
{
// opposite face of the plane
if ( (abs(int(totalrot) % 360) > 90) && (abs(int(totalrot) % 360) < 270) )
{
gFlotte->setWave(pX, -pY, 512);
}
else // plane moreover in front of us
{
gFlotte->setWave(-pX,-pY, 128);
}
}
*/
// gFlotte->runWave(0.0f, 2.0f, 4.0f, 16);
// gFlotte->runWave(400.0f, 5.0f, 3.0f, 64);
// gFlotte->runWave(800.0f, 3.0f, 2.0f, 84);
// gFlotte->runWave(1000.0f, 4.0f, 3.0f, 100);
gFlotte->update();
gFlotte->nexttime();
}
gFlotte->build();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gFlotte->display();
glFlush();
glutSwapBuffers();
}
void rota(void)
{
if (mrota != 0.0f)
{
totalrot += mrota; // Y axis rotation
glRotatef(mrota,0.0f,1.0f,0.0f);
}
glutPostRedisplay();
}
void mouseclick(int button, int state, int x, int y)
{
// if (state == GLUT_DOWN)
// {
mbutton = button;
// }
}
void mousemoveclick(int x, int y)
{
static int prevX = 0;
switch (mbutton)
{
// plane rotation
case GLUT_RIGHT_BUTTON:
if (x < prevX)
mrota = -1.0f;
else if (x > prevX)
mrota = 1.0f;
prevX = x;
waveFlag = 0;
break;
// hole tracing
case GLUT_LEFT_BUTTON:
pX =-float(x)/vsizeX; //(float( x) - vsizeX/2.0f)/vsizeX ;
pY = float(y)/vsizeY; //(float( y) - vsizeY/2.0f)/vsizeY;
waveFlag = 1;
break;
default:
waveFlag = 0;
}
}
void mousemovenoclick(int x, int y)
{
mbutton = -1;
mrota = 0.0f;
waveFlag = 0;
}
void initView(void);
void key(unsigned char aKey, int x, int y)
{
switch(aKey)
{
case 's':
case 'S':
initView();
break;
case 27: /* Exit if we press ESC */
glutDestroyWindow(win);
delete gFlotte;
exit(0);
break;
}
}
void initView(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-0.15f, -0.25, -5.5f);
totalrot = 0.0f;
}
//...................................................
// try to detect if we have hardware geometry engine
// or at least similar cpu time
//...................................................
bool geometry_engine_detect(void)
{
char *gfx_model = NULL;
char *gfx_vendor = NULL;
bool tl = true; // T&L by default
gfx_vendor = strdup((char*)glGetString(GL_VENDOR));
gfx_model = strdup((char*)glGetString(GL_RENDERER));
if (strstr(gfx_model, "Generic")) // softwarer renderer
{
tl = false;
softrender = 1;
videoram = 4;
}
//.................
// PC/MAC hardware
//.................
#ifndef IRIX
else if (strstr(gfx_model, "Voodoo")) // Voodoo graphics
{
tl = false;
if (strstr(gfx_model, "Voodoo_Graphics"))
{
voodoo_gfx = 1;
videoram = 4;
}
else if (strstr(gfx_model, "Voodoo2"))
{
voodoo_gfx = 1;
videoram = 8;
}
}
else if (strstr(gfx_vendor, "Matrox")) // Matrox G400 and G200
{
if (strstr(gfx_model, "G200"))
{
tl = false;
videoram = 8;
}
else if (strstr(gfx_model, "G400"))
{
tl = false;
videoram = 16;
}
}
else if (strstr(gfx_vendor, "ATI")) // ATI cards RagePro / Rage128
{
if (strstr(gfx_model, "Rage"))
tl = false;
if (strstr(gfx_vendor, "RagePro"))
videoram = 8;
else if (strstr(gfx_vendor, "Rage128"))
videoram = 32;
}
else if (strstr(gfx_model, "Savage")) // S3 Savage, Savage4000
{
tl = false;
videoram = 8;
}
else if (strstr(gfx_model, "TNT")) // NVidia TNT, TNT2
{
tl = false;
if (strstr(gfx_model, "TNT2"))
videoram = 32;
else
videoram = 16;
}
else if (strstr(gfx_model, "Riva")) // NVidia Riva128
{
tl = false;
videoram = 8;
}
else if (strstr(gfx_model, "PowerVR")) // NEC PowerVR
{
tl = false;
videoram = 4;
}
else if (strstr(gfx_model, "Rendition")) // Rendition Verite
{
tl = false;
videoram = 4;
}
else if (strstr(gfx_model, "Quadro")) // NVidia/SGI professional, lot of RAM
{
videoram = 64;
}
else if (strstr(gfx_model, "Wildcat")) // 3DLabs professional, lot of RAM
{
videoram = 64;
}
else if (strstr(gfx_model, "Oxygen")) // 3DLabs professional, lot of RAM
{
videoram = 64;
}
else if (strstr(gfx_model, "Cobalt")) // SGI professional, lot of RAM
{
videoram = 64;
}
#endif
#ifdef IRIX
//................................................................
// SGI hardware - old hardwares that will not support 40000 polys
// other like IR (Infinite Reality), O2, Octane, Octane2 will be ok
//................................................................
else if (strstr(gfx_model, "VGXT")) // Iris-4D VGX
{
tl = false;
}
else if (strstr(gfx_model, "LIGHT")) // Indigo Starter
{
tl = false;
}
else if (strstr(gfx_model, "NEWPORT")) // Indy
{
tl = false;
}
else if (strstr(gfx_model, "EXTREME")) // carte Elan
{
tl = false;
}
else if (strstr(gfx_model, "GL4DRE")) // Reality Engine
{
tl = false;
}
#endif
if (gfx_vendor) free(gfx_vendor);
if (gfx_model) free(gfx_model);
return tl;
}
void myReshape(int w, int h)
{
if (voodoo_gfx > 0) // Voodoo 1, 2
{
w = 640;
h = 480;
}
vsizeX = w;
vsizeY = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, 1.0f*(GLfloat)w/(GLfloat)h, 1.0f, 30.0f);
initView();
}
void visible(int vis)
{
if (vis == GLUT_VISIBLE)
{
glutIdleFunc(rota);
}
else
{
glutIdleFunc(NULL);
}
}
void TuioDemo::addTuioCursor(TuioCursor *tcur) {
mouseclick(GLUT_LEFT_BUTTON, 0, tcur->getScreenX(xres), tcur->getScreenX(yres)) ;
}
void TuioDemo::updateTuioCursor(TuioCursor *tcur) {
// mousemoveclick(tcur->getScreenX(xres), tcur->getScreenX(yres));
pX =-tcur->getX();// float(x)/vsizeX; //(float( x) - vsizeX/2.0f)/vsizeX ;
pY = tcur->getY();// float(y)/vsizeY; //(float( y) - vsizeY/2.0f)/vsizeY;
waveFlag = 1;
}
void TuioDemo::removeTuioCursor(TuioCursor *tcur){
waveFlag = 0;
//mousemovenoclick(0,0);
}
//---------------------------
// main entry point
//---------------------------
int WINAPI WinMain( HINSTANCE hInstance, // Instance
HINSTANCE hPrevInstance, // Previous Instance
LPSTR lpCmdLine, // Command Line Parameters
int nCmdShow) // Window Show State
{
//int main(int argc, char *argv[])
//{
int high_def = FLOT_HIGHRES;
int poly_count = 4;
int poly_div = 1;
bool geom_engine = true;
char gfx_vendor[1024];
char gfx_model[1024];
bool gfx_multitex = true;
tuioListner = new TuioDemo(3333);
printf("\n\n-------------------------------------------------------------\n");
printf("DS Aqua 0.91 - linux release version - february 2001 \n");
printf("-------------------------------------------------------------\n\n");
printf("quick code by Laurent Lardinois (Type One) \n");
printf("IT Consultant - Project Manager - Research & Development\n");
printf("contact me at : llardin@dsimprove.be\n\n");
printf("DS Improve SPRL (http://www.dsimprove.com) \n\n");
printf("-Press ESC to exit.\n");
printf("-Keep RIGHT mouse button down and move the mouse to rotate the plane\n");
printf("-Keep LEFT bouton down and move the mouse to perturb the fluid\n");
printf("-Press S to set to initial rotation\n\n");
// create dummy context
glutInitWindowPosition(0,0);
// glutInit(&argc,argv);
int argc = 0;
char **argv=(char **)malloc(sizeof(char *));
argv[0] = (char *)malloc(sizeof(char)*10);
argv[0][0] = 0;
// glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);
if (!(win=glutCreateWindow("water")))
{
fprintf(stderr,"Error, couldn't open window\n");
exit(-1);
}
geom_engine = geometry_engine_detect();
strcpy(gfx_vendor, (char*)glGetString(GL_VENDOR));
strcpy(gfx_model, (char*)glGetString(GL_RENDERER));
if (glutExtensionSupported("GL_ARB_multitexture"))
{
gfx_multitex = true;
}
else
{
gfx_multitex = false;
}
// test Matrox G200/G400, OpenGL multitex buggy driver with DECAL...
if (strstr(gfx_vendor, "Matrox"))
{
if (strstr(gfx_model, "G200"))
gfx_multitex = false;
else if (strstr(gfx_model, "G400"))
gfx_multitex = false;
}
if (voodoo_gfx > 0) // if voodoo, we have o rebuild window
{
glutDestroyWindow(win);
}
// following code has effect on Voodoo Graphics only
if (voodoo_gfx > 0)
{
/* Tell Mesa GLX to use 3Dfx driver in fullscreen mode. */
putenv("MESA_GLX_FX=fullscreen");
/* Disable 3Dfx Glide splash screen */
putenv("FX_GLIDE_NO_SPLASH=");
}
printf("vendor: %s\n", gfx_vendor);
printf("model: %s\n", gfx_model);
// this line forces low res tesselation (3D on RedHat 7 and NVidia kernel
// seems buggy with high tesselation, however it works perfect with
// SGI SuSE 6.4 and Propack 1.3)
#ifdef FORCE_LOWRES
geom_engine = false;
#endif
if (geom_engine)
{
high_def = FLOT_HIGHRES;
poly_count = 4;
poly_div = 1;
printf("hardware T&L class machine\n");
}
else if (!softrender)
{
high_def = FLOT_MEDIUMRES;
poly_count = 1;
poly_div = 1;
printf("no hardware T&L class machine\n");
}
else if (softrender)
{
high_def = FLOT_LOWRES;
poly_count = 1;
poly_div = 4;
printf("software rendering class machine\n");
printf("really sloooow - are you sure you have a 3D accelerator ?\n");
printf("if you have a 3D accelerator then update your driver with an OpenGL ICD\n");
}
if (voodoo_gfx > 0)
{
printf("screen resolution (voodoo1/voodoo2): 640x480\n");
}
else
{
xres = glutGet(GLUT_SCREEN_WIDTH);
yres = glutGet(GLUT_SCREEN_HEIGHT);
printf("screen resolution : %dx%d\n", xres, yres);
switch(videoram)
{
case 4:
if (xres > 640)
{
printf("performance can be low (lack of memory for OpenGL acceleration)\n");
printf("if you get such problem try to switch to 640x480 x 16 bits or lower\n");
}
break;
case 8:
if (xres > 800)
{
printf("performance can be low (lack of memory for OpenGL acceleration)\n");
printf("if you get such problem try to switch to 800x600 x 16 bits or lower\n");
}
break;
case 16:
if (xres > 1024)
{
printf("performance can be low (lack of memory for OpenGL acceleration)\n");
printf("if you get such problem try to switch to 1024x768 x 16 bits or lower\n");
}
break;
case 32:
if (xres >= 1152)
{
printf("performance can be low (lack of memory for OpenGL acceleration)\n");
printf("if you get such problem try to switch to 1024x768 or lower\n");
}
break;
}
}
if (gfx_multitex)
{
printf("fluid : %d ARB bi-textured triangles\n\n\n", (FLOTSIZE*FLOTSIZE*2*poly_count)/poly_div);
}
else
{
printf("fluid : %d single-textured triangles\n\n\n", (FLOTSIZE*FLOTSIZE*2*poly_count*2)/poly_div);
}
// sleep(5);
if (voodoo_gfx > 0) // rebuild window for voodoo
{
glutInitWindowPosition(0,0);
glutInitWindowSize(640, 480);
glutInit(&argc,argv);
//glutInit(&argc,NULL);
//glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);
if (!(win=glutCreateWindow("water")))
{
fprintf(stderr,"Error, couldn't open window\n");
exit(-1);
}
}
/*
* Want the X window to fill the screen so that we don't have to
* worry about losing the mouse input focus.
* Note that we won't actually see the X window since we never draw
* to it, hence, the original X screen's contents aren't disturbed.
*/
// if (argc == 1) // fullscreen by default
{
glutFullScreen();
}
gFlotte = new dmFlotte(NULL, high_def);
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutMouseFunc(mouseclick);
glutMotionFunc(mousemoveclick);
glutPassiveMotionFunc(mousemovenoclick);
if (voodoo_gfx == 0)
glutVisibilityFunc(visible);
else if (voodoo_gfx > 0)
glutIdleFunc(rota); // can not be hidden with voodoo
//.....................
// resize screen
// to fit capabilities
//.....................
glutMainLoop();
delete gFlotte;
return 0;
}