diff --git a/Debug/bouncing_balls.dll b/Debug/bouncing_balls.dll new file mode 100755 index 0000000..fded5ed Binary files /dev/null and b/Debug/bouncing_balls.dll differ diff --git a/DrawBeat.h b/DrawBeat.h new file mode 100755 index 0000000..5207184 --- /dev/null +++ b/DrawBeat.h @@ -0,0 +1,28 @@ +int DrawBeat(struct winampVisModule *this_mod, float beat_help,GLuint base,int choice, + GLuint texture[6],char * title,float title_transformation) +{ + + glLoadIdentity(); + glPushMatrix(); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + int decimal, sign; + char *beat_text; + double source = double(beat_help); + beat_text = _fcvt( source, 0, &decimal, &sign ); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glPushMatrix(); + glTranslatef(-40.0f,20.0f,0.0f); + glColor4ub(255,255,255,200); + glTranslatef(20.0f,0.0f,-60.0f); + glPrint(beat_text,base); + glPopMatrix(); + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + return TRUE; +} + diff --git a/GLScene.cpp b/GLScene.cpp new file mode 100755 index 0000000..8ad03ce --- /dev/null +++ b/GLScene.cpp @@ -0,0 +1,440 @@ +#include "declarations.h" + +void myinit(void) +{ + /*Initialize and compute the vectors for the spiral*/ + spir[0][0]=0.0; + spir[0][1]=-1.0; + spir[1][0]=-sin(30.0*M_PI/180); + spir[1][1]=-cos(30.0*M_PI/180); + spir[2][0]=-cos(30.0*M_PI/180); + spir[2][1]=-sin(30.0*M_PI/180); + spir[3][0]=-1.0; + spir[3][1]=0.0; + spir[4][0]=-cos(30.0*M_PI/180); + spir[4][1]=sin(30.0*M_PI/180); + spir[5][0]=-sin(30.0*M_PI/180); + spir[5][1]=cos(30.0*M_PI/180); + spir[6][0]=0.0; + spir[6][1]=1.0; + spir[7][0]=sin(30.0*M_PI/180); + spir[7][1]=cos(30.0*M_PI/180); + spir[8][0]=cos(30.0*M_PI/180); + spir[8][1]=sin(30.0*M_PI/180); + spir[9][0]=1.0; + spir[9][1]=0; + spir[10][0]=cos(30.0*M_PI/180); + spir[10][1]=-sin(30.0*M_PI/180); + spir[11][0]=sin(30.0*M_PI/180); + spir[11][1]=-cos(30.0*M_PI/180); + +/*create all needed spheres and initialize them with default values*/ + initializeSpheres(); + +/*Initialize the random number creator*/ + time_t t; + time(&t); + srand((unsigned int)t); //initialize with date and time + +/* attributes */ + + glClearColor(0.0, 0.0, 0.0, 1.0); /* black background */ + +/* Lighting */ + glLoadIdentity(); + + GLfloat light_ambient[] = {0.0,0.0,0.0,1.0}; + GLfloat light_diffuse[] = {1.0,1.0,1.0,1.0}; + //GLfloat light_specular[] = {1.0,1.0,1.0,1.0}; + GLfloat lmodel_ambient[] = {0.5,0.5,0.5,1.0}; + GLfloat mat_amb_diff[] = { 0.5, 0.5, 0.5, 1.0 }; + //GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + //GLfloat mat_shininess[] = { 40.0 }; + + GLfloat light_position0[] = {1.0, 1.0, 0.0, 0.0 }; + + glShadeModel (GL_SMOOTH); + + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + //glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff); + //glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + //glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); + + //Enable Lighting + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); +} + +void displayScene (struct winampVisModule *this_mod) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*clear the window*/ + + /*Draw circle surface*/ + if(SURFACE) { + + glColor3d(0.86,0.86,0.86); + + glBegin(GL_POLYGON); + double rad=groundRad; + double steps=1; + for(double x=rad; x>=-rad; x-=steps) { + double z=sqrt(((double)rad*(double)rad)-((double)x*(double)x)); + glVertex3d(x,0.0,z); + } + for(x=-rad; x<=rad; x+=steps) { + double z=sqrt(((double)rad*(double)rad)-((double)x*(double)x)); + glVertex3d(x,0.0,-z); + } + glEnd(); + + } + + /*Draw spheres and belonging cones to bump them*/ + for(int o=0; o>>>> + //Sound input goes here for sphere with size sphere[i].r + //Input ranges from 0-MAXSTRENGTH, so now from 0-100 + + //change everything in the function to return an input the value + //the function delivers you the index of the sphere which is i out of NUMSPHERE Spheres, so try to + //keep it dynamic by base your return value on i and on NUMSPHERE, so if NUMSPHERE changes during + //execution of the program your function is possible to always return values for each sphere + double input=computeSoundInput(i); + + //this function bumps the ball up and is called each time, it actually just bumps the ball up, + //when it is on the ground and so just disregard the input if not. + bump(&sphere[i], input); +//-------->>>>> + + //Draw the sphere + glColor3fv(sphere[i].color); + glTranslatef(sphere[i].x,sphere[i].r+sphere[i].height,sphere[i].z); + glutSolidSphere(sphere[i].r, + 20.0+(int)((1-NUMSPHERES/MAXSPHERES)*(sphere[i].r/10)), + 50.0+(int)((1-NUMSPHERES/MAXSPHERES)*(sphere[i].r))); + + glPopMatrix(); //restore the origin + } + +/*Text output*/ + setOrthographicProjection(); //switch to orthographic projection to easier print out text + glPushMatrix(); + glLoadIdentity(); + + //Data ouput of current settings + if(OUTPUT) { + char temp[50]; + glColor3f(1.0,1.0,1.0); + + //Number of Balls + sprintf(temp," Balls: %.d", NUMSPHERES); + printOut(10,10,temp); + //Airtime + sprintf(temp," max. Airtime: %.1f", NUMSEC); + printOut(10,25,temp); + //Speedfactor + sprintf(temp," Speedfactor: %.1f", SPEEDFACTOR); + printOut(10,40,temp); + //Cones on/off? + sprintf(temp," Cones: %s", (CONES)?"on":"off"); + printOut(10,55,temp); + //Surface on/off? + sprintf(temp," Surface: %s", (SURFACE)?"on":"off"); + printOut(10,70,temp); + //Bouncing balls? + sprintf(temp,"Bouncing Balls: %s", (BOUNCE)?"on":"off"); + printOut(10,85,temp); + //Color change? + sprintf(temp," Change color: %s", (COLORCHANGE)?"on":"off"); + printOut(10,100,temp); + //Index color of balls + printOut(10,115," Start color: "); + char * color; + if(COLOR==0) color="white"; + if(COLOR==1) {color="red"; glColor3f(1.0,0.0,0.0);} + if(COLOR==2) {color="green"; glColor3f(0.0,1.0,0.0);} + if(COLOR==3) {color="blue"; glColor3f(0.0,0.0,1.0);} + if(COLOR==4) {color="yellow"; glColor3f(1.0,1.0,0.0);} + if(COLOR==5) {color="magenta"; glColor3f(1.0,0.0,1.0);} + if(COLOR==6) {color="cyan"; glColor3f(0.0,1.0,1.0);} + sprintf(temp,"%s", color); + printOut(138,115,temp); + + //help message + if(!HELP) { + glColor3f(1.0,1.0,0.0); + printOut(width-20*8,10,"Press \'h\' for help!"); + } + } + + //help instructions + if(HELP) { + glColor3f(1.0,1.0,0.0); + int x=200; + int y=0; + + printOut(x,y+10," h = switch help on/off"); + printOut(x,y+25," o = switch output of the current settings on/off"); + + printOut(x,y+55,"-/+ = decrease/increase number of balls"); + printOut(x,y+70,"u/i = decrease/increase the maximum airtime of the balls"); + printOut(x,y+85,"j/k = decrease/increase the speed factor of the balls"); + printOut(x,y+100,"n/m = decrease/increase the start color of the balls"); + printOut(x,y+130," c = display cones?"); + printOut(x,y+145," s = display white circle surface?"); + printOut(x,y+160," b = allow balls to bounce on the ground?"); + printOut(x,y+175," l = allow balls to change color?"); + + printOut(x,y+205," r = reset all settings to default value"); + + printOut(x,y+235,"written by Ryan Messner and Simon Beisel"); + } + + glPopMatrix(); + resetPerspectiveProjection(); //reset to old view + + glFlush(); /* clear buffers */ + //glutSwapBuffers(); /*swap the buffers*/ +} + +void initializeSpheres() { + groundRad=0; + int i; + for(i=0; i0.0)||!(sphere[i].color[1]>0.0)||!(sphere[i].color[2]>0.0)) { + changeColor(&sphere[i], COLOR); + } + sphere[i].up=true; + sphere[i].firstUp=false; + sphere[i].inAir=false; + sphere[i].SEC=0; + sphere[i].height=0; + if (i==NUMSPHERES-1) { + groundRad=sqrt((double)((sphere[i].x)*(sphere[i].x))+(double)((sphere[i].z)*(sphere[i].z)))+(double)(i*1.2); + } + doSort(i,sphere[i].z); + } + + //to always have the same view on the scene independend of how big the circle surface is + //and how many spheres are on it I compute the coordinates for y and z dynamically + double distance=(double)(groundRad*1.02)/(double)(sin((alpha/2)*(M_PI/180))); + double yz=sqrt((distance*distance)/2); + + //The view is along and on the z axis to the origin + glLoadIdentity(); + gluLookAt(0.0, yz, yz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); +} + +//-------->>>>> +//That is your function, implement everything here and return a double value for the +//strength of the tune in the specific frequency range for sphere i +double computeSoundInput(int i) { + //at the moment it is just a random number + return (double)((rand() % 101)+0); +} +//-------->>>>> + +//is used to print out several text at the position x,y +void printOut(int x, int y, char * text) { + glRasterPos2i(x,y); + int length=strlen(text); + for (int i = 0; i < length; i++) + { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, text[i]); + } +} + +//Most important function of the whole program, it gets a strength variable as an input and based +//on it bumps a ball in the air if it is laying still on the ground and is not bouncing or in the air +void bump(struct SPHERE *sp, double strength) { + + //if ball not in Air compute it current new airtime SEC based on the strength value + if(!sp->inAir&&strength>0) { + startTimer(sp); //start the timer + //this is the main calculation, SEC is always higher for smaller balls than for + //bigger balls with the same strength input, that is what the second term of the + //function is for, the last term is the max air time and is calculated in + sp->SEC=strength/MAXSTRENGTH*(1-(sp->r/(NUMSPHERES*2)))*NUMSEC; + + //change color of the ball slightly + if(COLORCHANGE) { + int choice=(int) (rand() % 3); + int plusminus=(int) (rand() % 2); + float change=((float)(rand() % 10)+5)/100.0; + if (plusminus==1) change=-change; + sp->color[choice]+=(sp->color[choice]+change<1.0&&sp->color[choice]+change>0.0)?change:-change; + } + + sp->firstUp=true; + sp->inAir=true; + } + + //stop the timer and compute seconds till the start of the timer + stopTimer(sp); + double seconds=timerSeconds(sp); + + //compute the speed based on the speedfactor and the number of spheres + double speed=NUMSPHERES*SPEEDFACTOR; + + //let the ball fly up and down + if(sp->SEC>0.05) + { + if(!BOUNCE) sp->inAir=true; + + //up-direction + if(sp->up==true) { + double max=4.905*sp->SEC*sp->SEC; + sp->height=(max-4.905*(sp->SEC-seconds)*(sp->SEC-seconds))*speed; + } + //down-direction + else { + double max=4.905*sp->SEC*sp->SEC; + sp->height=(max-4.905*seconds*seconds)*speed; + } + + //if ball reaches the floor or is at the top of its flight turn the direction and + //probably decrease the height for let the ball bounce + if(seconds>sp->SEC) { + sp->up=(sp->up==true)?false:true; + startTimer(sp); + if(sp->SEC>0&&sp->up==true) { + sp->firstUp=false; + sp->SEC-=(sp->SEC*4/9); + + if(!BOUNCE) sp->inAir=false; + } + + } + } + //finished with bouncing or at the ground again and accepting input again + else { + sp->inAir=false; + } +} + +/*function to change color of one sphere*/ +void changeColor(struct SPHERE *sp, int c) { + double red=0.0; + double green=0.0; + double blue=0.0; + + //0 = white + //1 = red + //2 = green + //3 = blue + //4 = yellow + //5 = magenta + //6 = cyan + if(c==1||c==4||c==5||c==0) red=1.0; //red + if(c==2||c==4||c==6||c==0) green=1.0; //green + if(c==3||c==5||c==6||c==0) blue=1.0; //blue + + sp->color[0]=red; //SET COLOR + sp->color[1]=green; + sp->color[2]=blue; +} + +/*Sort the z value from one sphere with index no, into an array*/ +void doSort(int no, double z) { + int place=0; + for(int i=0; iplace; i--) { + order[i][0]=order[i-1][0]; + order[i][1]=order[i-1][1]; + } + order[place][0]=no; + order[place][1]=z; +} + +/*switch to an orthographic projection which makes it easier to output text*/ +void setOrthographicProjection() { + + // switch to projection mode + glMatrixMode(GL_PROJECTION); + // save previous matrix which contains the + //settings for the perspective projection + glPushMatrix(); + // reset matrix + glLoadIdentity(); + // set a 2D orthographic projection + gluOrtho2D(0, width, 0, height); + // invert the y axis, down is positive + glScalef(1, -1, 1); + // mover the origin from the bottom left corner + // to the upper left corner + glTranslatef(0, -height, 0); + glMatrixMode(GL_MODELVIEW); +} + +/*switch back to the perspective projection and reset the matrix*/ +void resetPerspectiveProjection() { + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + +/*start the timer for a sphere*/ +void startTimer(struct SPHERE *sp) { + ::QueryPerformanceCounter(&sp->startTime_); +} + +/*stop the timer for a sphere*/ +void stopTimer(struct SPHERE *sp) { + ::QueryPerformanceCounter(&sp->stopTime_); +} + +/*get the seconds between start and stop of the timer for a sphere*/ +double timerSeconds(struct SPHERE *sp) { + if (!::QueryPerformanceFrequency(&sp->frequency_)) + throw "Error with QueryPerformanceFrequency"; + return (double)(sp->stopTime_.QuadPart - sp->startTime_.QuadPart) / (double) sp->frequency_.QuadPart; +} diff --git a/Headers.h b/Headers.h new file mode 100755 index 0000000..163a202 --- /dev/null +++ b/Headers.h @@ -0,0 +1,24 @@ +#include // Header File For Windows +#include // Header File For The OLE Controls Library (BuildTexture) +//#include // Header File For The OpenGL32 Library +//#include // Header File For The GLu32 Library +#ifndef HEADERS_H +#define HEADERS_H + +//#include // Header File For The GLaux Library +#include +#include // Header File For Math +//#include // Header File For Variable Argument Routines +//#include +//#include "Glext.h" +//#include +#include +#include +#include +#pragma comment(lib, "opengl32.lib") +#pragma comment(lib, "glu32.lib") +#pragma comment(lib, "glaux.lib") +#pragma comment(lib, "glut32.lib") +//#pragma comment(lib, "jpeg.lib") + +#endif \ No newline at end of file diff --git a/HelperFuncs.cpp b/HelperFuncs.cpp new file mode 100755 index 0000000..20a3583 --- /dev/null +++ b/HelperFuncs.cpp @@ -0,0 +1,17 @@ +#include "HelperFuncs.h" + +bool bReadyToExit; + +void initHelperFuncs() +{ + srand(time(NULL)); + + bReadyToExit = false; +} + +void setExit() +{ + bReadyToExit = true; +} + + diff --git a/HelperFuncs.h b/HelperFuncs.h new file mode 100755 index 0000000..c3e81d4 --- /dev/null +++ b/HelperFuncs.h @@ -0,0 +1,13 @@ +#ifndef HELPERFUNCS_H +#define HELPERFUNCS_H + +#include "HEADERS.H" + +#define PI 3.14159 + +void initHelperFuncs(); + +void setExit(); + +#endif + diff --git a/Liquid1.cpp b/Liquid1.cpp new file mode 100755 index 0000000..f824c7e --- /dev/null +++ b/Liquid1.cpp @@ -0,0 +1,212 @@ +#include "headers.h" +#include "Misc.h" +#include "liquid1.h" + +scene1::scene1(double time,float wid,float hei):Manager(time) +{ + xrot = 0.0f; + t = 0.0f; + liquid_cube = new cube(); + direction = -1; + beat_responder = 0.0f; + bg = new background(); + timeeffect = 0; + multi_texture =0; + speedTexure = FALSE; + + glClientActiveTextureARB = NULL; + glActiveTextureARB = NULL; + + glActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) wglGetProcAddress ( "glActiveTextureARB" ); + glClientActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) wglGetProcAddress ( "glClientActiveTextureARB" ); + t2 = 0.0f; + sceneTime = 0.0f; + lastTime = 0.0f; + width = wid; + height = hei; + fade_def = 0; + +} + +scene1::~scene1() +{ + if (liquid_cube) + delete liquid_cube; +} + + +void scene1::Draw(GLuint blend_colour,struct winampVisModule *this_mod) +{ + glDisable(GL_FOG); + glDisable(GL_LIGHT0); + glDisable(GL_LIGHT1); + glDisable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); + glDisable(GL_LIGHT0); + glDisable(GL_LIGHTING); + glDisable ( GL_DEPTH_TEST ); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + + glEnable(GL_BLEND); + + for (int i=0;i<7;i++) + { + glPushMatrix(); + glTranslatef(0.0f,0.0f,-20.0f+(10-i)*(float)pow(beat_responder/50,2)); + glPushMatrix(); + liquid_cube->Update(20*i+blend_colour,beat_responder/10,timeeffect); + liquid_cube->Draw(1.0f-beat_responder/120.0f,0.1f,m_Texture,beat_responder*i/100.0f+0.1f,xrot); + glPopMatrix(); + glPopMatrix(); + } + +} + +void scene1::Update(float beat_help,struct winampVisModule *this_mod,float beat_scaler,bool Tex_on) +{ + glLoadIdentity (); + + speedTexure = Tex_on; + if (fade_def==0) + fadeffect+=0.1f; + if (fade_def==1) + fadeffect-=0.1f; + + timeeffect=(GetTickCount()-SceneStart)/1000; + beat_responder=beat_help*beat_scaler; + xrot+=direction*((beat_responder/30.0f)*(beat_responder/30.0f))+1.0f; + t+=(beat_responder/20.0f)*0.01f*(float)cos(timeeffect/300.0f*(beat_responder))*direction; + if (t>1.5*beat_responder/16) + direction=-1; + if (t<-1.5*beat_responder/16) + direction=1; + float currTime = GetTime(); + float deltaTime = currTime - lastTime; + lastTime = currTime; + float speed = 1; + sceneTime += deltaTime * speed; +} + +bool scene1::Init(loadall *textures) +{ + textures_in=textures; + liquid_cube->Init(); + glClientActiveTextureARB ( GL_TEXTURE0_ARB ); + glEnableClientState ( GL_TEXTURE_COORD_ARRAY ); + + glClientActiveTextureARB ( GL_TEXTURE1_ARB ); + glEnableClientState ( GL_TEXTURE_COORD_ARRAY ); + SceneStart = GetTickCount(); + fadeffect = 0; + + multi_texture=rand()%19; + + switch (multi_texture) + { + case 0: + m_Texture[0]=textures->Bind(22); + m_Texture[1]=textures->Bind(1); + break; + case 1: + m_Texture[0]=textures->Bind(1); + m_Texture[1]=textures->Bind(0); + break; + case 2: + m_Texture[0]=textures->Bind(0); + m_Texture[1]=textures->Bind(2); + break; + case 3: + m_Texture[0]=textures->Bind(1); + m_Texture[1]=textures->Bind(4); + break; + case 4: + m_Texture[0]=textures->Bind(3); + m_Texture[1]=textures->Bind(21); + break; + case 5: + m_Texture[0]=textures->Bind(21); + m_Texture[1]=textures->Bind(3); + break; + case 6: + m_Texture[0]=textures->Bind(10); + m_Texture[1]=textures->Bind(7); + break; + case 7: + m_Texture[0]=textures->Bind(11); + m_Texture[1]=textures->Bind(3); + break; + case 8: + m_Texture[0]=textures->Bind(13); + m_Texture[1]=textures->Bind(21); + break; + case 9: + m_Texture[0]=textures->Bind(12); + m_Texture[1]=textures->Bind(4); + break; + case 10: + m_Texture[0]=textures->Bind(14); + m_Texture[1]=textures->Bind(7); + break; + case 11: + m_Texture[0]=textures->Bind(15); + m_Texture[1]=textures->Bind(3); + break; + case 12: + m_Texture[0]=textures->Bind(16); + m_Texture[1]=textures->Bind(21); + break; + case 13: + m_Texture[0]=textures->Bind(17); + m_Texture[1]=textures->Bind(4); + break; + case 14: + m_Texture[0]=textures->Bind(18); + m_Texture[1]=textures->Bind(2); + break; + case 15: + m_Texture[0]=textures->Bind(19); + m_Texture[1]=textures->Bind(4); + break; + case 16: + m_Texture[0]=textures->Bind(20); + m_Texture[1]=textures->Bind(17); + break; + case 17: + m_Texture[0]=textures->Bind(21); + m_Texture[1]=textures->Bind(15); + break; + case 18: + m_Texture[0]=textures->Bind(1); + m_Texture[1]=textures->Bind(22); + break; + } + /*multi_texture=rand()%18; + if (multi_texture==19) + multi_texture=0;*/ + return true; +} + +float scene1::GetTime(void) +{ + static bool init = false; + static bool hires = false; + static __int64 freq = 1; + if(!init) + { + hires = !QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + if(!hires) + freq = 1000; + init = true; + } + + __int64 now; + + if(hires) + QueryPerformanceCounter((LARGE_INTEGER *)&now); + else + now = GetTickCount(); + + return (float)((double)now / (double)freq); + +} + diff --git a/Liquid1.h b/Liquid1.h new file mode 100755 index 0000000..7a6074f --- /dev/null +++ b/Liquid1.h @@ -0,0 +1,45 @@ +#ifndef __LIQUID1_H_ +#define __LIQUID1_H_ + +#include "TextureLoader.h" +#include "Scenemanager.h" +#include "LoadAlltextures.h" +#include "cube.h" +#include "Background.h" +#include "vis.h" + +class scene1:public Manager +{ + + public: + scene1(double time,float wid,float hei); + ~scene1(); + virtual void Draw (GLuint blend_colour,struct winampVisModule *this_mod); + virtual void Update (float beat_help,struct winampVisModule *this_mod,float beat_scaler,bool Tex_on); + virtual bool Init (loadall *textures); + + private: + float GetTime(void); + + GLuint m_Texture[5]; + cube *liquid_cube; + int i,direction; + int scene_switcher; + float scalefactor; + float xrot,t,t2; + float beat_responder; + int multi_texture; + DWORD timeeffect,SceneStart; + background *bg; + float fadeffect; + PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; + PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; + loadall *textures_in; + bool speedTexure; + float lastTime,sceneTime; + Manager *liquid_next; + float width,height; + int fade_def; +}; + +#endif __LIQUID1_H_ diff --git a/Liquidmanager.cpp b/Liquidmanager.cpp new file mode 100755 index 0000000..336b8c0 --- /dev/null +++ b/Liquidmanager.cpp @@ -0,0 +1,203 @@ +#include "HelperFuncs.h" +#include "TextGeneration.h" +#include "MeshGeneration.h" +#include "Liquidmanager.h" +#include "LiquidTime.h" +#include "3ds.h" + +#define FILE_NAME "Liquid\\face.3ds" + + +liqTime *g_pFrameTime; +TextGeneration *Generated_textures; +MeshGeneration *Generated_Meshes; +CLoad3DS g_Load3ds; +t3DModel liquidmodel; + +Liquidmanager::Liquidmanager(int wid,int hei,struct winampVisModule *this_mod) +{ + Generated_textures = new TextGeneration(); + Generated_Meshes = new MeshGeneration(); + + char *ini_file=new char[70]; + char *help=new char[70]; + char *p; + GetModuleFileName(this_mod->hDllInstance,ini_file,MAX_PATH); + p=ini_file+strlen(ini_file); + while (p >= ini_file && *p != '\\') p--; + if (++p >= ini_file) + *p = 0; + strcpy(help,ini_file); + strcat(help,FILE_NAME); + + g_Load3ds.Import3DS(&liquidmodel, help); + + width = wid; + height = hei; + + textures = new loadall(this_mod); + + liquid1 = new scene1(40.0f,(float)width,(float)height); + /*liquid2 = new scene2(40.0f,4,(float)width,(float)height,0); + liquid3 = new scene3(40.0f,Generated_textures,(float)width,(float)height); + liquid6 = new scene6(40.0f,(float)width,(float)height); + liquid7 = new scene7(40.0f,(float)width,(float)height); + liquid8 = new scene8(40.0f,(float)width,(float)height); + liquid9 = new scene9(40.0f,(float)width,(float)height); + liquid10 = new scene10(40.0f,(float)width,(float)height); + liquid11 = new scene11(40.0f,(float)width,(float)height); + liquid12 = new scene12(40.0f,(float)width,(float)height); + liquid13 = new scene13(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid14 = new scene14(40.0f,(float)width,(float)height); + liquid15 = new scene15(40.0f,(float)width,(float)height); + liquid16 = new scene16(40.0f,0,(float)width,(float)height); + liquid17 = new scene17(40.0f,(float)width,(float)height); + liquid18 = new scene18(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid19 = new scene19(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid20 = new scene20(40.0f,(float)width,(float)height); + liquid21 = new scene21(40.0f,(float)width,(float)height); + liquid22 = new scene22(40.0f,(float)width,(float)height); + liquid23 = new scene23(40.0f,(float)width,(float)height); + liquid24 = new scene24(40.0f,(float)width,(float)height); + liquid25 = new scene25(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid26 = new scene26(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid27 = new scene27(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid28 = new scene28(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid29 = new scene29(40.0f,Generated_textures,Generated_Meshes,(float)width,(float)height); + liquid30 = new scene30(40.0f,(float)width,(float)height); + liquid31 = new scene31(40.0f,Generated_textures,Generated_Meshes,&liquidmodel,(float)width,(float)height); + //liquid34 = new scene34(40.0f,(float)width,(float)height);*/ + g_pFrameTime = new liqTime(); + liquid1->Init(textures); + + lockscene = FALSE; +} + +void Liquidmanager::Init() +{ + initScenes(); +} + +void Liquidmanager::initScenes() +{ + liquid1->add_Next_Prev(liquid1,liquid1); + /*liquid2->add_Next_Prev(liquid3,liquid1); + liquid3->add_Next_Prev(liquid6,liquid2); + liquid6->add_Next_Prev(liquid7,liquid3); + liquid7->add_Next_Prev(liquid8,liquid6); + liquid8->add_Next_Prev(liquid9,liquid7); + liquid9->add_Next_Prev(liquid10,liquid8); + liquid10->add_Next_Prev(liquid11,liquid9); + liquid11->add_Next_Prev(liquid12,liquid10); + liquid12->add_Next_Prev(liquid13,liquid11); + liquid13->add_Next_Prev(liquid14,liquid12); + liquid14->add_Next_Prev(liquid15,liquid13); + liquid15->add_Next_Prev(liquid16,liquid14); + liquid16->add_Next_Prev(liquid17,liquid15); + liquid17->add_Next_Prev(liquid18,liquid16); + liquid18->add_Next_Prev(liquid19,liquid17); + liquid19->add_Next_Prev(liquid20,liquid18); + liquid20->add_Next_Prev(liquid21,liquid19); + liquid21->add_Next_Prev(liquid22,liquid20); + liquid22->add_Next_Prev(liquid23,liquid21); + liquid23->add_Next_Prev(liquid24,liquid22); + liquid24->add_Next_Prev(liquid25,liquid23); + liquid25->add_Next_Prev(liquid26,liquid24); + liquid26->add_Next_Prev(liquid27,liquid25); + liquid27->add_Next_Prev(liquid28,liquid26); + liquid28->add_Next_Prev(liquid29,liquid27); + liquid29->add_Next_Prev(liquid30,liquid28); + liquid30->add_Next_Prev(liquid31,liquid29); + liquid31->add_Next_Prev(liquid1,liquid30); + //liquid34->add_Next_Prev(liquid1,liquid31);*/ + + m_pCurrentScene = liquid1; + m_pCurrentScene->start(); +} + +void Liquidmanager::Update(float beat_help,struct winampVisModule *this_mod,float beat_scaler,bool Tex_on) +{ + g_pFrameTime->update(); + if(m_pCurrentScene != NULL) + { + if(m_pCurrentScene->isComplete()) + { + nextScene(); + } + + if(m_pCurrentScene != NULL) + m_pCurrentScene->Update(beat_help,this_mod,beat_scaler,Tex_on); + } +} + +void Liquidmanager::nextScene() +{ + if (lockscene==FALSE) + { + m_pCurrentScene = m_pCurrentScene->getNext(); + } + else + { + m_pCurrentScene = m_pCurrentScene; + } + + if(m_pCurrentScene == NULL) + setExit(); + else + { + m_pCurrentScene->Init(textures); + m_pCurrentScene->start(); + } +} + +void Liquidmanager::prevScene() +{ + if (lockscene==FALSE) + { + m_pCurrentScene = m_pCurrentScene->getPrev(); + } + else + { + m_pCurrentScene = m_pCurrentScene; + } + + if(m_pCurrentScene == NULL) + setExit(); + else + { + m_pCurrentScene->Init(textures); + m_pCurrentScene->start(); + } +} + +void Liquidmanager::holdScene() +{ + lockscene = !lockscene; +} + +void Liquidmanager::holdBeat(float beat_help) +{ +} + + +void Liquidmanager::Draw(GLuint blend_colour,struct winampVisModule *this_mod) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if(m_pCurrentScene != NULL) + m_pCurrentScene->Draw(blend_colour,this_mod); +} + +Liquidmanager::~Liquidmanager() +{ + if(liquid1) + delete liquid1; + //if(liquid2) + // delete liquid2; + //if(liquid3) + // delete liquid3; +} diff --git a/Liquidmanager.h b/Liquidmanager.h new file mode 100755 index 0000000..8afe5d7 --- /dev/null +++ b/Liquidmanager.h @@ -0,0 +1,97 @@ +#ifndef __LIQMANAGER_H +#define __LIQMANAGER_H + +#include "headers.h" +#include "Misc.h" +#include "Scenemanager.h" +#include "LoadAlltextures.h" +#include "Texture.h" +#include "Liquid1.h" +/*#include "Liquid2.h" +#include "Liquid3.h" +#include "Liquid6.h" +#include "Liquid7.h" +#include "Liquid8.h" +#include "Liquid9.h" +#include "Liquid10.h" +#include "Liquid11.h" +#include "Liquid12.h" +#include "Liquid13.h" +#include "Liquid14.h" +#include "Liquid15.h" +#include "Liquid16.h" +#include "Liquid17.h" +#include "Liquid18.h" +#include "Liquid19.h" +#include "Liquid20.h" +#include "Liquid21.h" +#include "Liquid22.h" +#include "Liquid23.h" +#include "Liquid24.h" +#include "Liquid25.h" +#include "Liquid26.h" +#include "Liquid27.h" +#include "Liquid28.h" +#include "Liquid29.h" +#include "Liquid30.h" +#include "Liquid31.h" +#include "Liquid34.h"*/ +#include "vis.h" + +class Liquidmanager +{ + public: + Liquidmanager(int wid,int hei,struct winampVisModule *this_mod); + ~Liquidmanager(); + + void Init(); + void Update(float beat_help,struct winampVisModule *this_mod,float beat_scaler,bool Tex_on); + void Draw(GLuint blend_colour,struct winampVisModule *this_mod); + void holdBeat(float beat_help); + loadall *textures; + void nextScene(); + void prevScene(); + void holdScene(); + void adveScene(bool status); + + protected: + bool lockscene; + void initScenes(); + Manager *m_pCurrentScene; + + int width,height; + + scene1 *liquid1; + /*scene2 *liquid2; + scene3 *liquid3; + scene6 *liquid6; + scene7 *liquid7; + scene8 *liquid8; + scene9 *liquid9; + scene10 *liquid10; + scene11 *liquid11; + scene12 *liquid12; + scene13 *liquid13; + scene14 *liquid14; + scene15 *liquid15; + scene16 *liquid16; + scene17 *liquid17; + scene18 *liquid18; + scene19 *liquid19; + scene20 *liquid20; + scene21 *liquid21; + scene22 *liquid22; + scene23 *liquid23; + scene24 *liquid24; + scene25 *liquid25; + scene26 *liquid26; + scene27 *liquid27; + scene28 *liquid28; + scene29 *liquid29; + scene30 *liquid30; + scene31 *liquid31; + scene34 *liquid34;*/ + Manager *liquid_next; +}; + +#endif __LIQMANAGER_H diff --git a/Release/bouncing_balls.exp b/Release/bouncing_balls.exp new file mode 100755 index 0000000..7cec5ef Binary files /dev/null and b/Release/bouncing_balls.exp differ diff --git a/Release/bouncing_balls.lib b/Release/bouncing_balls.lib new file mode 100755 index 0000000..3b1d374 Binary files /dev/null and b/Release/bouncing_balls.lib differ diff --git a/SVIS.CPP b/SVIS.CPP new file mode 100755 index 0000000..2f020b2 --- /dev/null +++ b/SVIS.CPP @@ -0,0 +1,1248 @@ +#include "declarations.h" + +GLuint m_texture[]; + +int xmin=1,xmax=20; + +#ifdef __cplusplus +extern "C" { +#endif +__declspec( dllexport ) winampVisHeader *winampVisGetHeader() +{ + return &hdr; +} +#ifdef __cplusplus +} +#endif + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + +winampVisModule *getModule(int which) +{ + switch (which) + { + case 0: return &mod; + default:return NULL; + } +} + +char* winampGetTitle(HWND handle) +{ + GetWindowText(handle,tmp,70); + pos = strcspn( tmp, "Winamp"); + strncpy(title,tmp,strlen(tmp)-9); + return title; +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------winamp config function------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +void config(struct winampVisModule *this_mod) +{ + MessageBox( this_mod->hwndParent, + "Bouncing Balls Visualizer /n(c) 2004 Ryan Messner and Simon Biesel", + "Configuration",MB_OK); +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------frame rate function---------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +void CalculateFrameRate() +{ + static float framesPerSecond = 0.0f; + static float lastTime = 0.0f; + static char strFrameRate[50] = {0}; + float currentTime = GetTickCount() * 0.001f; + ++framesPerSecond; + if( currentTime - lastTime > 1.0f ) + { + lastTime = currentTime; + sprintf(strFrameRate, "FPS: %d -Bouncing Balls- Ryan Messner & Simon Beisel", int(framesPerSecond)); + SetWindowText(hMainWnd, strFrameRate); + framesPerSecond = 0; + } +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------KillGL function-------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +GLvoid KillGLWindow(struct winampVisModule *this_mod) +{ + if (fullscreen) // Kontrolle auf Vollbildmodus + { + ChangeDisplaySettings(NULL,0); // Zurück zum Desktop + ShowCursor(TRUE); // Der abgeschaltete Mauszeiger wird wieder angezeigt + } + if (hRC) // Rendering Context (RC) vorhanden? + { + if (!wglMakeCurrent(NULL,NULL)) // Kann der DC und RC überhaupt gelöscht werden? + { + MessageBox( NULL,"Entfernen des DC und RC fehlgeschlagen.","Fehler", + MB_OK | MB_ICONINFORMATION); + } + + if (!wglDeleteContext(hRC)) // Kann der RC gelöscht werden? + { + MessageBox( NULL,"Entfernen des RC fehlgeschlagen.","Fehler...", + MB_OK | MB_ICONINFORMATION); + } + hRC=NULL; // Der RC wird NULL gesetzt, also entfernt + } +} +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------Resize function-------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +GLvoid ReSizeGLScene(GLsizei w, GLsizei h) +{ + width=w; + height=h; + + glViewport (0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(alpha,(GLfloat)w/(GLfloat)h, 0.0, 100.0); //perspective view + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + //to always have the same view on the scene independend of how big the circle surface is + //and how many spheres are on it I compute the coordinates for y and z dynamically + double distance=(double)(groundRad*1.02)/(double)(sin((alpha/2)*(M_PI/180))); + double yz=sqrt((distance*distance)/2); + + //The view is along and on the z axis to the origin + gluLookAt(0.0, yz, yz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------change resolution-----------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +bool change_resolution(struct winampVisModule *this_mod) +{ + if (fullscreen) // Soll im Vollbildmodus gestartet werden + { + DWORD dwExStyle2; + DWORD dwStyle2; + DEVMODE dmScreenSettings; + memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Diese wird geleert + dmScreenSettings.dmSize=sizeof(dmScreenSettings); // dmsize soll genauso groß wie die dmScreenSettings sein + dmScreenSettings.dmPelsWidth = width; + dmScreenSettings.dmPelsHeight = height; + dmScreenSettings.dmBitsPerPel = 32; + dmScreenSettings.dmFields=DM_BITSPERPEL| + DM_PELSWIDTH|DM_PELSHEIGHT; + RECT WindowRect2; // Speicher für aktuelle Auflösung + WindowRect2.left=(long)0; // Die linke Seite des Rechtecks wirtd auf 0 gesetzt + WindowRect2.right=(long)width; // Hier wird die gewünschte Breite des Fensters gespeichert + WindowRect2.top=(long)0; // Die obere Seite wird auch auf 0 gesetzt + WindowRect2.bottom=(long)height; // Und hier wird die Höhe abgelegt + dwExStyle2=WS_EX_APPWINDOW; // Fenstereigenschaften + dwStyle2=WS_POPUP; + ShowCursor(FALSE); + ChangeDisplaySettings(&dmScreenSettings,0); // Zurück zum Desktop + ReSizeGLScene(width, height); + AdjustWindowRectEx(&WindowRect2,dwStyle2,FALSE,dwExStyle2); + SetForegroundWindow(hMainWnd); + SetFocus(hMainWnd); + } + // Der Mauszeiger wird nicht angezeigt + + else + { + DWORD dwExStyle2; + DWORD dwStyle2; + DEVMODE dmScreenSettings; // + memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // + dmScreenSettings.dmSize=sizeof(dmScreenSettings); // + dmScreenSettings.dmPelsWidth = width; + dmScreenSettings.dmPelsHeight = height; + dmScreenSettings.dmBitsPerPel = 32; + dmScreenSettings.dmFields=DM_BITSPERPEL| + DM_PELSWIDTH|DM_PELSHEIGHT; + dwExStyle2=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Das Fenster soll zusätzlich einen 3D Rahmen bekommen + dwStyle2=WS_OVERLAPPEDWINDOW; // Ein typisches Windowsfenster mit Minimieren, Maximieren, etc + ReSizeGLScene(width, height); + RECT WindowRect2; // Speicher für aktuelle Auflösung + WindowRect2.left=(long)0; // Die linke Seite des Rechtecks wirtd auf 0 gesetzt + WindowRect2.right=(long)width; // Hier wird die gewünschte Breite des Fensters gespeichert + WindowRect2.top=(long)0; // Die obere Seite wird auch auf 0 gesetzt + WindowRect2.bottom=(long)height; // Und hier wird die Höhe abgelegt + dwExStyle2=WS_EX_APPWINDOW; // Fenstereigenschaften + dwStyle2=WS_POPUP; + SetWindowPos(hMainWnd,HWND_TOP, 0, 0,width,height,SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + SetForegroundWindow(hMainWnd); + SetFocus(hMainWnd); + + } + return 0; +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* -----------------------------------------------OPENGL init function-------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +bool InitGL(struct winampVisModule *this_mod) +{ + if (width==640) + current_window_size=0; + if (width==800) + current_window_size=1; + if (width==1024) + current_window_size=2; + if (width==1280) + current_window_size=3; + if (width==1600) + current_window_size=4; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(1.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0f); // Enables Clearing Of The Depth Buffer + glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glLoadIdentity(); // Reset The Projection Matrix + gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glEnable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + //glEnable(GL_TEXTURE_2D); + + return TRUE; // Initialization Went OK +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------init function for our window------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +int init(struct winampVisModule *this_mod) +{ + //config_read(this_mod); + + /* ----------------------------------------------------Register our window class-----------------------------------*/ + /* ----------------------------------------------------------------------------------------------------------------*/ + + GLuint PixelFormat; // Speichert das Pixelformat + WNDCLASS wc; // wc wird eine Instanz der Fensterklasse + DWORD dwExStyle; // weitere Informationen + DWORD dwStyle; // Fensterinformationen + RECT WindowRect; // Speicher für aktuelle Auflösung + WindowRect.left=(long)0; // Die linke Seite des Rechtecks wirtd auf 0 gesetzt + WindowRect.right=(long)width; // Hier wird die gewünschte Breite des Fensters gespeichert + WindowRect.top=(long)0; // Die obere Seite wird auch auf 0 gesetzt + WindowRect.bottom=(long)height; // Und hier wird die Höhe abgelegt + hInstance = this_mod->hDllInstance; + memset(&wc,0,sizeof(wc)); + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.hInstance = this_mod->hDllInstance; // hInstance of DLL + wc.lpszClassName = szAppName; // our window class name + wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Lädt einen Cursor + wc.lpszMenuName = NULL; // Auch ein Menü wird nicht benötigt. + //if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", + // "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO) + //{ + fullscreen=FALSE; // Windowed Mode + //} + + if (!RegisterClass(&wc)) + { + MessageBox( NULL,"Can't register window class.","ERROR", + MB_OK|MB_ICONEXCLAMATION); + return 1; + } + if (fullscreen) // Soll im Vollbildmodus gestartet werden + { + DEVMODE dmScreenSettings; // Instanz von DEVMODE wird erzeugt + memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Diese wird geleert + dmScreenSettings.dmSize=sizeof(dmScreenSettings); // dmsize soll genauso groß wie die dmScreenSettings sein + dmScreenSettings.dmPelsWidth = width; + dmScreenSettings.dmPelsHeight = height; + dmScreenSettings.dmBitsPerPel = 32; + dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; + if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) + !=DISP_CHANGE_SUCCESSFUL) + { + if (MessageBox(NULL,"Fullscreen device not available , Do you want to start in a windowed mode?", + "Problem",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) + { + fullscreen=FALSE; + } + + else + { + return FALSE; + } + } + } + if (fullscreen) + { + dwExStyle=WS_EX_APPWINDOW; // Fenstereigenschaften + dwStyle=WS_POPUP; + ShowCursor(FALSE); // Der Mauszeiger wird nicht angezeigt + } + else + { + dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Das Fenster soll zusätzlich einen 3D Rahmen bekommen + dwStyle=WS_OVERLAPPEDWINDOW; // Ein typisches Windowsfenster mit Minimieren, Maximieren, etc + } + AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Fenster wird angepasst + hMainWnd = CreateWindowEx(dwExStyle, // these exstyles put a nice small frame, but also a button in the taskbar + szAppName, // our window class name + this_mod->description, // use description for a window title + WS_CLIPSIBLINGS | // Wird von OpenGL benötigt + WS_CLIPCHILDREN | // Wird auch von OpenGL benötigt + dwStyle, + 0,0, // screen position (read from config) + WindowRect.right-WindowRect.left, // Hier werden die ermittelten Werte für die Breite eingesetzt + WindowRect.bottom-WindowRect.top, // und hier für die Länge + this_mod->hwndParent, // parent window (winamp main window) + NULL, // no menu + this_mod->hDllInstance, // hInstance of DLL + 0); // no window creation data + if (!hMainWnd) + { + MessageBox(this_mod->hwndParent,"Error creating window","ERROR",MB_OK); + return 1; + } + static PIXELFORMATDESCRIPTOR pfd= // pdf ist jetzt ein PIXELFORMATDESCRIPTOR + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, // Versionsnummer + PFD_DRAW_TO_WINDOW | // Das Format muss in Fenster sichtbar sein können + PFD_SUPPORT_OPENGL | // OpenGL muss unterstützt werden + PFD_DOUBLEBUFFER, // Double Buffering muss unterstützt werden + PFD_TYPE_RGBA, // Das RGBA (Rot,Grün,Blau,Alpha(Transparenz)) muss unterstützt werden + 32, // Die Farbtiefe, die schon übergeben wurde, wird hier benötigt + 0, 0, 0, 0, 0, 0, // wird nicht benötigt + 0, // kein Alpha Buffer + 0, // Shift Bit ignoriert + 0, // kein Accumulation Buffer + 0, 0, 0, 0, // nicht benötigt + 32, // 16Bit Z-Buffer (Depth Buffer) + 0, // kein Stencil Buffer + 0, // kein Auxiliary Buffer + PFD_MAIN_PLANE, // Die Hauptebene auf die später gezeichnet wird + 0, // unwichtig + 0, 0, 0 // keine Ebenenmasken benötigt + }; + if (!(hDC=GetDC(hMainWnd))) // Versuch, den DC zu bekommen + { + KillGLWindow(this_mod); // Alles rückgängig machen + + MessageBox( NULL,"NO dc available.","ERROR", + MB_OK|MB_ICONEXCLAMATION); + return FALSE; // FALSE zurückgeben, beenden + } + if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Kann Windows ein passendes finden? + { + KillGLWindow(this_mod); // Alles zurücksetzen + MessageBox( NULL,"Can't find pixelformat.","ERROR", + MB_OK|MB_ICONEXCLAMATION); + return FALSE; // FALSE zurück und Ende. + } + if(!SetPixelFormat(hDC,PixelFormat,&pfd)) + { + KillGLWindow(this_mod); // Leider nicht, Fehlerpopup und raus + MessageBox( NULL,"Can't use pixelformat.", + "ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // FALSE zurück und raus + } + if (!(hRC=wglCreateContext(hDC))) // Versuch den RC zu bekommen + { + KillGLWindow(this_mod); // Alles rückgängig machen + MessageBox( NULL,"Can't get rendering context.","ERROR", + MB_OK|MB_ICONEXCLAMATION); + return FALSE; + } + if(!wglMakeCurrent(hDC,hRC)) // Versuch den RC zu aktivieren + { + KillGLWindow(this_mod); // hat nicht geklappt, also alles zurück + MessageBox( NULL,"Can't activate rendering context.","ERROR", + MB_OK|MB_ICONEXCLAMATION); + return FALSE; + } + ShowWindow(hMainWnd,SW_SHOW); // Fenster anzeigen + SetForegroundWindow(hMainWnd); // Priorität des Programms wird erhöht + SetFocus(hMainWnd); // Tastatureingaben werden jetzt an das Programm geleitet + ReSizeGLScene(width, height); // Die Perspektive wird aktiviert + + SetTimer(hMainWnd , FPS_TIMER, FPS_INTERVAL, NULL); + + myinit(); + initializeSpheres(); + + return 0; +} + +void myinit(void) +{ + /*Initialize and compute the vectors for the spiral*/ + spir[0][0]=0.0; + spir[0][1]=-1.0; + spir[1][0]=-sin(30.0*M_PI/180); + spir[1][1]=-cos(30.0*M_PI/180); + spir[2][0]=-cos(30.0*M_PI/180); + spir[2][1]=-sin(30.0*M_PI/180); + spir[3][0]=-1.0; + spir[3][1]=0.0; + spir[4][0]=-cos(30.0*M_PI/180); + spir[4][1]=sin(30.0*M_PI/180); + spir[5][0]=-sin(30.0*M_PI/180); + spir[5][1]=cos(30.0*M_PI/180); + spir[6][0]=0.0; + spir[6][1]=1.0; + spir[7][0]=sin(30.0*M_PI/180); + spir[7][1]=cos(30.0*M_PI/180); + spir[8][0]=cos(30.0*M_PI/180); + spir[8][1]=sin(30.0*M_PI/180); + spir[9][0]=1.0; + spir[9][1]=0; + spir[10][0]=cos(30.0*M_PI/180); + spir[10][1]=-sin(30.0*M_PI/180); + spir[11][0]=sin(30.0*M_PI/180); + spir[11][1]=-cos(30.0*M_PI/180); + + for (int i = 0; i <= 103; i++) + { + cosTable[i] = cos((double)(M_PI*2*i/100.0)); + sinTable[i] = sin((double)(M_PI*2*i/100.0)); + } +/*create all needed spheres and initialize them with default values*/ + initializeSpheres(); + +/*Initialize the random number creator*/ + time_t t; + time(&t); + srand((unsigned int)t); //initialize with date and time + +/* attributes */ + + glClearColor(0.0, 0.0, 0.0, 1.0); /* black background */ + +/* Lighting */ + glLoadIdentity(); + + GLfloat light_ambient[] = {0.0,0.0,0.0,1.0}; + GLfloat light_diffuse[] = {1.0,1.0,1.0,1.0}; + GLfloat light_specular[] = {1.0,1.0,1.0,1.0}; + GLfloat lmodel_ambient[] = {0.5,0.5,0.5,1.0}; + GLfloat mat_amb_diff[] = { 0.5, 0.5, 0.5, 1.0 }; + GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat mat_shininess[] = { 40.0 }; + + GLfloat light_position0[] = {1.0, 1.0, 0.0, 0.0 }; + + glShadeModel (GL_SMOOTH); + + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); + + //Enable Lighting + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); +} +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ---------------------------------------------mainrenderfunction-----------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +int render(struct winampVisModule *this_mod) +{ + displayScene(this_mod); + SwapBuffers(hDC); // Die Puffer werden getauscht + CalculateFrameRate(); + if (done==TRUE) + return 1; + else + return 0; +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ---------------------------------------------------quitfunction-----------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +void quit(struct winampVisModule *this_mod) +{ + SelectObject(memDC,oldBM); // delete our doublebuffer + DeleteObject(memDC); + DeleteObject(memBM); + DestroyWindow(hMainWnd); // delete our window + UnregisterClass(szAppName,this_mod->hDllInstance); // unregister window class + KillGLWindow(this_mod); +} + +void quit3(struct winampVisModule *this_mod) +{ + if (current_window_size==0) + { + width=640; + height=480; + } + if (current_window_size==1) + { + width=800; + height=600; + } + if (current_window_size==2) + { + width=1024; + height=768; + } + if (current_window_size==3) + { + width=1280; + height=1024; + } + if (current_window_size==4) + { + width=1600; + height=1200; + } + + //config_write(this_mod); // write configuration + change_resolution(this_mod); +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ---------------------------------------------------------keysfunction-----------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: return 0; + case WM_ERASEBKGND: return 0; + case WM_PAINT: + { + PAINTSTRUCT ps; + RECT r; + HDC hdc = BeginPaint(hwnd,&ps); + GetClientRect(hwnd,&r); + BitBlt(hdc,0,0,r.right,r.bottom,memDC,0,0,SRCCOPY); + EndPaint(hwnd,&ps); + } + return 0; + case WM_CLOSE: // Did We Receive A Close Message? + { + PostQuitMessage(0); // Send A Quit Message + return 0; // Jump Back + } + case WM_DESTROY: PostQuitMessage(0); return 0; + { // get this_mod from our window's user data + winampVisModule *this_mod = (winampVisModule *) GetWindowLong(hwnd,GWL_USERDATA); + PostMessage(this_mod->hwndParent,message,wParam,lParam); + } + return 0; + case WM_MOVE: + { + RECT r; + GetWindowRect(hMainWnd,&r); + config_x = 1024; + config_y = 768; + } + return 0; + case WM_SIZE: // Resize The OpenGL Window + { + width=LOWORD(lParam); + height=HIWORD(lParam); + ReSizeGLScene(width,height); // LoWord=Width, HiWord=Height + return 0; // Jump Back + } + case WM_SYSCOMMAND: // Intercept System Commands + { + switch (wParam) // Check System Calls + { + case SC_SCREENSAVE: // Screensaver Trying To Start? + case SC_MONITORPOWER: // Monitor Trying To Enter Powersave? + return 0; // Prevent From Happening + } + break; // Exit + } + case WM_KEYDOWN: // Is A Key Being Held Down? + { + keys[wParam] = TRUE; // If So, Mark It As TRUE + keyboard(); + return 0; // Jump Back + } + case WM_KEYUP: // Has A Key Been Released? + { + keys[wParam] = FALSE; // If So, Mark It As FALSE + return 0; // Jump Back + } + case WM_MOUSEMOVE: + { + return 0; + } + case WM_LBUTTONUP : + { + return 0; + } + case WM_RBUTTONDOWN : + { + return 0; + } + } + return DefWindowProc(hwnd,message,wParam,lParam); +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------winamp plugin module--------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +void config_getinifn(struct winampVisModule *this_mod, char *ini_file) +{ + char *p; + GetModuleFileName(this_mod->hDllInstance,ini_file,MAX_PATH); + p=ini_file+strlen(ini_file); + while (p >= ini_file && *p != '\\') p--; + if (++p >= ini_file) *p = 0; + strcat(ini_file,"plugin.ini"); + delete p; +} + +void config_read(struct winampVisModule *this_mod) +{ + char ini_file[MAX_PATH]; + config_getinifn(this_mod,ini_file); + width = GetPrivateProfileInt(this_mod->description,"width",width,ini_file); + height = GetPrivateProfileInt(this_mod->description,"height",height,ini_file); + if ((width!=640) && (width!=800) && (width!=1024) && (width!=1280) && (width!=1600)) + { + width=640; + height=480; + } +} + +void config_write(struct winampVisModule *this_mod) +{ + char string[32]; + char ini_file[MAX_PATH]; + + config_getinifn(this_mod,ini_file); + + wsprintf(string,"%d",width); + WritePrivateProfileString(this_mod->description,"width",string,ini_file); + wsprintf(string,"%d",height); + WritePrivateProfileString(this_mod->description,"height",string,ini_file); +} +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------winmain function------------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +int WINAPI WinMain( HINSTANCE hInstance, // Instance + HINSTANCE hPrevInstance, // Previous Instance + LPSTR lpCmdLine, // Command Line Parameters + int nCmdShow) // Window Show State +{ + MSG msg; // Windows Message Structure + config(&mod); + init(&mod); + while(!done) // Loop That Runs While done=FALSE + { + if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? + { + if (msg.message==WM_QUIT) // Have We Received A Quit Message? + { + done=TRUE; // If So done=TRUE + if (done==TRUE) quit(&mod); + } + else // If Not, Deal With Window Messages + { + TranslateMessage(&msg); // Translate The Message + DispatchMessage(&msg); // Dispatch The Message + } + } + else // If There Are No Messages + { + int ret=render(&mod); + if (ret==1) + quit(&mod); + } + } + return 1; // Exit The Program +} + + + +void setLighting (GLfloat r, + GLfloat g, + GLfloat b) +{ + GLfloat light_ambient[] = {0.0,0.0,0.0,1.0}; + GLfloat light_diffuse[] = {r,g,b,1.0}; + GLfloat light_specular[] = {1.0,1.0,1.0,1.0}; + GLfloat lmodel_ambient[] = {0.5,0.5,0.5,1.0}; + GLfloat mat_amb_diff[] = { 0.5, 0.5, 0.5, 1.0 }; + GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat mat_shininess[] = { 40.0 }; + + GLfloat light_position0[] = {1.0, 1.0, 0.0, 0.0 }; + + glShadeModel (GL_SMOOTH); + + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); +} + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* --------------------------------------------- Rendering Functions ------------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +/*Draw the circles which reflects the beat*/ +void drawWaveformCircles(struct winampVisModule *this_mod, int numSamples) +{ + double istep = groundRad/numSamples; + double jstep = 0.05; + double beatFactor = (((double)winampDetectBass(this_mod, 0,100)/100.0)*0.2)+0.8; + double color = (double)winampDetectBass(this_mod, 0, 100)/100.0 + .01; + for (double i = groundRad; i > 0; i -= istep) + { + + + glColor3d(color,1,color); + glLineWidth(2.0); + glBegin(GL_LINE_LOOP); + double steps=1; + for(double x = 1; x > 0; x -= .02) + { + + glVertex3d(beatFactor*i*my_cos(x), + 0.0, + beatFactor*i*my_sin(x) ); + } + glEnd(); + } +} + +void displayScene (struct winampVisModule *this_mod) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + GLfloat lcolor = (GLfloat)winampDetectBass(this_mod,0,100)/100.0; + + rotateFactor += rotateRate; + if (rotateFactor >= 1.0) rotateFactor = 0.0; + + /*Draw circle surface*/ + if(SURFACE) { + glColor3d(0.86,0.86,0.86); + + glBegin(GL_POLYGON); + glVertex3d(0.0,0.0,0.0); + for(double x = 1.02; x >=0; x -= .02) + { + glVertex3d(groundRad*my_cos(x), + 0.0, + groundRad*my_sin(x) ); + } + glEnd(); + } + if (WAVEFORMCIRCLES) + { + drawWaveformCircles(this_mod, NUM_CIRCLES); + } + + /*Draw spheres and belonging cones to bump them*/ + for(int o=0; o>>>> + //Sound input for the balls goes here for sphere with size sphere[i].r + //Input ranges from 0-MAXSTRENGTH, so now from 0-100 + + //the input is only computed if the ball is not in the air + if (!sphere[i].inAir) + input=computeSoundInput(i, NUMSPHERES, this_mod, BT_BEAT); + + //this function bumps the ball up and is called each time, it actually just bumps the ball up, + //when it is on the ground and so just disregard the input if not. + bump(&sphere[i], input); + +//-------->>>>> + + //Draw the sphere + if (SPHERES) + { + glColor3fv(sphere[i].color); + glTranslatef(sphere[i].x,sphere[i].r+sphere[i].height,sphere[i].z); + if(SQUASH) { + double squash = (sphere[i].height/100.0)*0.6 + 0.5; + glScaled(1.0, squash,1.0); + } + glutSolidSphere(sphere[i].r, + 20.0+(int)((1-NUMSPHERES/MAXSPHERES)*(sphere[i].r/10)), + 50.0+(int)((1-NUMSPHERES/MAXSPHERES)*(sphere[i].r))); + } + + glPopMatrix(); //restore the origin + + + } + +/*Text output*/ + setOrthographicProjection(); //switch to orthographic projection to easier print out text + glPushMatrix(); + glLoadIdentity(); + + //Data ouput of current settings + if(OUTPUT) { + char temp[50]; + glColor4f(1.0,1.0,1.0, 1.0); + + //Number of Balls + sprintf(temp," # Balls: %.d", NUMSPHERES); + printOut(10,10,temp); + //Balls on/off? + sprintf(temp," Balls: %s", (SPHERES)?"on":"off"); + printOut(10,25,temp); + //Airtime + sprintf(temp," max. Airtime: %.1f", NUMSEC); + printOut(10,40,temp); + //Speedfactor + sprintf(temp," Speedfactor: %.1f", SPEEDFACTOR); + printOut(10,55,temp); + //Cones on/off? + sprintf(temp," Cones: %s", (CONES)?"on":"off"); + printOut(10,70,temp); + //Surface on/off? + sprintf(temp," Surface: %s", (SURFACE)?"on":"off"); + printOut(10,85,temp); + //Bouncing balls? + sprintf(temp,"Bouncing Balls: %s", (BOUNCE)?"on":"off"); + printOut(10,100,temp); + //Squash balls? + sprintf(temp," Squash Balls: %s", (SQUASH)?"on":"off"); + printOut(10,115,temp); + //Beat Circles? + sprintf(temp," Beat Circles: %s", (WAVEFORMCIRCLES)?"on":"off"); + printOut(10, 130, temp); + //Color change? + sprintf(temp," Change color: %s", (COLORCHANGE)?"on":"off"); + printOut(10,145,temp); + //Index color of balls + printOut(10,160," Start color: "); + char * color; + if(COLOR==0) color="white"; + if(COLOR==1) {color="red"; glColor3f(1.0,0.0,0.0);} + if(COLOR==2) {color="green"; glColor3f(0.0,1.0,0.0);} + if(COLOR==3) {color="blue"; glColor3f(0.0,0.0,1.0);} + if(COLOR==4) {color="yellow"; glColor3f(1.0,1.0,0.0);} + if(COLOR==5) {color="magenta"; glColor3f(1.0,0.0,1.0);} + if(COLOR==6) {color="cyan"; glColor3f(0.0,1.0,1.0);} + sprintf(temp,"%s", color); + printOut(138,160,temp); + glColor3f(1.0, 1.0, 1.0); + //help message + if(!HELP) { + glColor3f(1.0,1.0,0.0); + printOut(width-20*8,10,"Press \'h\' for help!"); + } + } + + //help instructions + if(HELP) { + glColor3f(1.0,1.0,0.0); + int x=200; + int y=0; + + printOut(x,y+10," h = switch help on/off"); + printOut(x,y+25," o = switch output of the current settings on/off"); + + printOut(x,y+55,"z/x = decrease/increase number of balls"); + printOut(x,y+70,"u/i = decrease/increase the maximum airtime of the balls"); + printOut(x,y+85,"j/k = decrease/increase the speed factor of the balls"); + printOut(x,y+100,"n/m = decrease/increase the start color of the balls"); + printOut(x,y+130," c = display cones?"); + printOut(x,y+145," s = display white circle surface?"); + printOut(x,y+160," w = display beat circles?"); + printOut(x,y+175," a = display balls?"); + printOut(x,y+190," b = allow balls to bounce on the ground?"); + printOut(x,y+205," t = allow balls to be squashed?"); + printOut(x,y+220," l = allow balls to change color?"); + + printOut(x,y+250," r = reset all settings to default value"); + + printOut(x,y+280,"by Ryan Messner and Simon Beisel"); + } + + glPopMatrix(); + resetPerspectiveProjection(); //reset to old view + + glFlush(); /* clear buffers */ + + //glutSwapBuffers(); /*swap the buffers*/ +} + +void initializeSpheres() { + groundRad=0; + int i; + for(i=0; i0.0)||!(sphere[i].color[1]>0.0)||!(sphere[i].color[2]>0.0)) { + changeColor(&sphere[i], COLOR); + } + sphere[i].up=true; + sphere[i].firstUp=false; + sphere[i].inAir=false; + sphere[i].SEC=0; + sphere[i].height=0; + if (i==NUMSPHERES-1) { + groundRad=sqrt((double)((sphere[i].x)*(sphere[i].x))+(double)((sphere[i].z)*(sphere[i].z)))+(double)(i*1.2); + } + doSort(i,sphere[i].z); + } + + //to always have the same view on the scene independend of how big the circle surface is + //and how many spheres are on it I compute the coordinates for y and z dynamically + double distance=(double)(groundRad*1.02)/(double)(sin((alpha/2)*(M_PI/180))); + double yz=sqrt((distance*distance)/2); + + //The view is along and on the z axis to the origin + glLoadIdentity(); + gluLookAt(0.0, yz, yz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); +} + +//-------->>>>> +//compute the sound input for each single sphere depending on their size +double computeSoundInput(int i, int total, struct winampVisModule *this_mod, int BounceType) +{ + int range = (int) (576/NUMSPHERES); + int place=(int)(((NUMSPHERES-(i+1))/NUMSPHERES)*576); + place=(place<0)?0:place; + double tempstrength=0; + double level=0; + double strength; + + switch (BounceType) + { + case BT_WAVEFORM: + for(int a=0; aspectrumData[0][place+a] + this_mod->spectrumData[1][place+a]) /2); + tempstrength+=level; + } + + strength=((tempstrength/range)/255)*MAXSTRENGTH; + strength=(strength+(i/(NUMSPHERES*2)))*1.8; + + strength=(strength>MAXSTRENGTH)?MAXSTRENGTH:strength; + return strength; + case BT_BEAT: + return ((double)winampBeat(this_mod)/100)*MAXSTRENGTH; + case BT_BASS: + default: + return (rand()%100)+1; + } +} +//-------->>>>> + +//is used to print out several text at the position x,y +void printOut(int x, int y, char * text) { + glRasterPos2i(x,y); + int length=strlen(text); + for (int i = 0; i < length; i++) + { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, text[i]); + } +} + +//Most important function of the whole program, it gets a strength variable as an input and based +//on it bumps a ball in the air if it is laying still on the ground and is not bouncing or in the air +void bump(struct SPHERE *sp, double strength) { + + //if ball not in Air compute it current new airtime SEC based on the strength value + if(!sp->inAir&&strength>MAXSTRENGTH/10) { + startTimer(sp); //start the timer + //this is the main calculation, SEC is always higher for smaller balls than for + //bigger balls with the same strength input, that is what the second term of the + //function is for, the last term is the max air time and is calculated in + sp->SEC=strength/MAXSTRENGTH*(1-(sp->r/(NUMSPHERES*2)))*NUMSEC; + + //change color of the ball slightly + if(COLORCHANGE) { + int choice=(int) (rand() % 3); + int plusminus=(int) (rand() % 2); + float change=(strength/MAXSTRENGTH)/10+0.02; + if (plusminus==1) change=-change; + sp->color[choice]+=(sp->color[choice]+change<1.0&&sp->color[choice]+change>0.0)?change:-change; + } + + sp->firstUp=true; + sp->inAir=true; + } + + //stop the timer and compute seconds till the start of the timer + stopTimer(sp); + double seconds=timerSeconds(sp); + + //compute the speed based on the speedfactor and the number of spheres + double speed=NUMSPHERES*SPEEDFACTOR; + + //let the ball fly up and down + if(sp->SEC>0.05) + { + if(!BOUNCE) sp->inAir=true; + + //up-direction + if(sp->up==true) { + double max=4.905*sp->SEC*sp->SEC; + sp->height=(max-4.905*(sp->SEC-seconds)*(sp->SEC-seconds))*speed; + } + //down-direction + else { + double max=4.905*sp->SEC*sp->SEC; + sp->height=(max-4.905*seconds*seconds)*speed; + } + + //if ball reaches the floor or is at the top of its flight turn the direction and + //probably decrease the height for let the ball bounce + if(seconds>sp->SEC) { + sp->up=(sp->up==true)?false:true; + startTimer(sp); + if(sp->SEC>0&&sp->up==true) { + sp->firstUp=false; + sp->SEC-=(sp->SEC*4/9); + + if(!BOUNCE) sp->inAir=false; + } + + } + } + //finished with bouncing or at the ground again and accepting input again + else { + sp->inAir=false; + } +} + +/*function to change color of one sphere*/ +void changeColor(struct SPHERE *sp, int c) { + double red=0.0; + double green=0.0; + double blue=0.0; + + //0 = white + //1 = red + //2 = green + //3 = blue + //4 = yellow + //5 = magenta + //6 = cyan + if(c==1||c==4||c==5||c==0) red=1.0; //red + if(c==2||c==4||c==6||c==0) green=1.0; //green + if(c==3||c==5||c==6||c==0) blue=1.0; //blue + + sp->color[0]=red; //SET COLOR + sp->color[1]=green; + sp->color[2]=blue; +} + +/*Sort the z value from one sphere with index no, into an array*/ +void doSort(int no, double z) { + int place=0; + for(int i=0; iplace; i--) { + order[i][0]=order[i-1][0]; + order[i][1]=order[i-1][1]; + } + order[place][0]=no; + order[place][1]=z; +} + +/*switch to an orthographic projection which makes it easier to output text*/ +void setOrthographicProjection() { + + // switch to projection mode + glMatrixMode(GL_PROJECTION); + // save previous matrix which contains the + //settings for the perspective projection + glPushMatrix(); + // reset matrix + glLoadIdentity(); + // set a 2D orthographic projection + gluOrtho2D(0, width, 0, height); + // invert the y axis, down is positive + glScalef(1, -1, 1); + // mover the origin from the bottom left corner + // to the upper left corner + glTranslatef(0, -height, 0); + glMatrixMode(GL_MODELVIEW); +} + +/*switch back to the perspective projection and reset the matrix*/ +void resetPerspectiveProjection() { + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + +/*start the timer for a sphere*/ +void startTimer(struct SPHERE *sp) { + ::QueryPerformanceCounter(&sp->startTime_); +} + +/*stop the timer for a sphere*/ +void stopTimer(struct SPHERE *sp) { + ::QueryPerformanceCounter(&sp->stopTime_); +} + +/*get the seconds between start and stop of the timer for a sphere*/ +double timerSeconds(struct SPHERE *sp) { + if (!::QueryPerformanceFrequency(&sp->frequency_)) + throw "Error with QueryPerformanceFrequency"; + return (double)(sp->stopTime_.QuadPart - sp->startTime_.QuadPart) / (double) sp->frequency_.QuadPart; +} + +void keyboard () +{ + if(keys['R']) { //reset to default settings + CONES = DEFAULTCONES; + SURFACE = DEFAULTSURFACE; + NUMSPHERES = DEFAULTSPHERES; + SPEEDFACTOR = DEFAULTSPEEDFACTOR; + NUMSEC = DEFAULTSEC; + COLORCHANGE = DEFAULTCOLORCHANGE; + COLOR = DEFAULTCOLOR; + WAVEFORMCIRCLES = DEFAULTWAVEFORMCIRCLES; + SPHERES = SPHERESONOFF; + SQUASH = DEFAULTSQUASH; + + for(int i=0; iMINSPHERES) { //decrease number of spheres + NUMSPHERES--; + changeColor(&sphere[NUMSPHERES], COLOR); //RESET COLOR + initializeSpheres(); + } + if(keys['I']&&NUMSECMINSEC) { //decrease Airtime + NUMSEC-=0.1; + } + if(keys['K']&&SPEEDFACTORMINSPEEDFACTOR) { //decrease Speedfactor + SPEEDFACTOR-=0.1; + } + if(keys['S']) { //switch surface on/off + SURFACE=(SURFACE==true)?false:true; + } + if(keys['C']) { //switch cones on/off + CONES=(CONES==true)?false:true; + } + if(keys['B']) { //switch bouncing balls on/off + BOUNCE=(BOUNCE==true)?false:true; + } + if(keys['O']) { //switch output of data on/off + OUTPUT=(OUTPUT==true)?false:true; + } + + if(keys['H']) { //switch help on/off + if(HELP==false) { + surfacetemp=SURFACE; + SURFACE=false; + circlestemp=WAVEFORMCIRCLES; + WAVEFORMCIRCLES=false; + } + if(HELP==true) { + SURFACE=(SURFACE==true)?true:surfacetemp; + WAVEFORMCIRCLES=(WAVEFORMCIRCLES==true)?true:circlestemp; + } + HELP=(HELP==true)?false:true; + } + if(keys['L']) { //switch colorchange on/off + COLORCHANGE=(COLORCHANGE==true)?false:true; + for(int i=0; iMINCOLOR) { //switch through colors + COLOR--; + for(int i=0; i\plugin.ini +// Look at the example plugin for a framework. + +// ints are 32 bits, and structure members are aligned on the default 8 byte boundaries +// tested with VC++ 4.2 and 5.0 + + +typedef struct winampVisModule { + char *description; // description of module + HWND hwndParent; // parent window (filled in by calling app) + HINSTANCE hDllInstance; // instance handle to this DLL (filled in by calling app) + int sRate; // sample rate (filled in by calling app) + int nCh; // number of channels (filled in...) + int latencyMs; // latency from call of RenderFrame to actual drawing + // (calling app looks at this value when getting data) + int delayMs; // delay between calls in ms + + // the data is filled in according to the respective Nch entry + int spectrumNch; + int waveformNch; + unsigned char spectrumData[2][576]; + unsigned char waveformData[2][576]; + + void (*Config)(struct winampVisModule *this_mod); // configuration dialog + int (*Init)(struct winampVisModule *this_mod); // 0 on success, creates window, etc + int (*Render)(struct winampVisModule *this_mod); // returns 0 if successful, 1 if vis should end + void (*Quit)(struct winampVisModule *this_mod); // call when done + + void *userData; // user data, optional +} winampVisModule; + +typedef struct { + int version; // VID_HDRVER + char *description; // description of library + winampVisModule* (*getModule)(int); +} winampVisHeader; + +// exported symbols +typedef winampVisHeader* (*winampVisGetHeaderType)(); + +// version of current module (0x101 == 1.01) +#define VIS_HDRVER 0x101 + +#endif //VIS_H \ No newline at end of file diff --git a/bouncing_balls.dsp b/bouncing_balls.dsp new file mode 100755 index 0000000..9523a94 --- /dev/null +++ b/bouncing_balls.dsp @@ -0,0 +1,121 @@ +# Microsoft Developer Studio Project File - Name="bouncing_balls" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=bouncing_balls - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bouncing_balls.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bouncing_balls.mak" CFG="bouncing_balls - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bouncing_balls - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "bouncing_balls - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bouncing_balls - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOUNCING_BALLS_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOUNCING_BALLS_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "bouncing_balls - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOUNCING_BALLS_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOUNCING_BALLS_EXPORTS" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bouncing_balls - Win32 Release" +# Name "bouncing_balls - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\SVIS.CPP +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\declarations.h +# End Source File +# Begin Source File + +SOURCE=.\Headers.h +# End Source File +# Begin Source File + +SOURCE=.\VIS.H +# End Source File +# Begin Source File + +SOURCE=.\winampdetectbeat.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/bouncing_balls.dsw b/bouncing_balls.dsw new file mode 100755 index 0000000..d4eb323 --- /dev/null +++ b/bouncing_balls.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "bouncing_balls"=".\bouncing_balls.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/bouncing_balls.ncb b/bouncing_balls.ncb new file mode 100755 index 0000000..cdbfca7 Binary files /dev/null and b/bouncing_balls.ncb differ diff --git a/bouncing_balls.opt b/bouncing_balls.opt new file mode 100755 index 0000000..5cccc70 Binary files /dev/null and b/bouncing_balls.opt differ diff --git a/bouncing_balls.plg b/bouncing_balls.plg new file mode 100755 index 0000000..417a689 --- /dev/null +++ b/bouncing_balls.plg @@ -0,0 +1,34 @@ + + +
+

Build Log

+

+--------------------Configuration: bouncing_balls - Win32 Debug-------------------- +

+

Command Lines

+Creating temporary file "C:\DOCUME~1\Owner\LOCALS~1\Temp\RSP12D.tmp" with contents +[ +/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOUNCING_BALLS_EXPORTS" /FR"Debug/" /Fp"Debug/bouncing_balls.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c +"C:\Documents and Settings\Owner\Desktop\bouncing_balls\SVIS.CPP" +] +Creating command line "cl.exe @C:\DOCUME~1\Owner\LOCALS~1\Temp\RSP12D.tmp" +Creating temporary file "C:\DOCUME~1\Owner\LOCALS~1\Temp\RSP12E.tmp" with contents +[ +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /pdb:"Debug/bouncing_balls.pdb" /debug /machine:I386 /out:"Debug/bouncing_balls.dll" /implib:"Debug/bouncing_balls.lib" /pdbtype:sept +".\Debug\SVIS.OBJ" +] +Creating command line "link.exe @C:\DOCUME~1\Owner\LOCALS~1\Temp\RSP12E.tmp" +

Output Window

+Compiling... +SVIS.CPP +Linking... +LINK : LNK6004: Debug/bouncing_balls.dll not found or not built by the last incremental link; performing full link + Creating library Debug/bouncing_balls.lib and object Debug/bouncing_balls.exp + + + +

Results

+bouncing_balls.dll - 0 error(s), 0 warning(s) +
+ + diff --git a/bouncing_balls.sln b/bouncing_balls.sln new file mode 100755 index 0000000..1ffd915 --- /dev/null +++ b/bouncing_balls.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bouncing_balls", "bouncing_balls.vcproj", "{1F8B3371-FE47-4DAB-A32D-EAA23B3089AE}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {1F8B3371-FE47-4DAB-A32D-EAA23B3089AE}.Debug.ActiveCfg = Debug|Win32 + {1F8B3371-FE47-4DAB-A32D-EAA23B3089AE}.Debug.Build.0 = Debug|Win32 + {1F8B3371-FE47-4DAB-A32D-EAA23B3089AE}.Release.ActiveCfg = Release|Win32 + {1F8B3371-FE47-4DAB-A32D-EAA23B3089AE}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/bouncing_balls.suo b/bouncing_balls.suo new file mode 100755 index 0000000..fd44395 Binary files /dev/null and b/bouncing_balls.suo differ diff --git a/bouncing_balls.vcproj b/bouncing_balls.vcproj new file mode 100755 index 0000000..6e99d93 --- /dev/null +++ b/bouncing_balls.vcproj @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/declarations.h b/declarations.h new file mode 100755 index 0000000..816d72d --- /dev/null +++ b/declarations.h @@ -0,0 +1,233 @@ +#ifndef DECLARATIONS_H +#define DECLARATIONS_H + +#include "headers.h" +#include "vis.h" +#include "winampdetectbeat.h" +//#include "structures.h" +//#include "beat_return.h" + +const FPS_TIMER = 1; +const FPS_INTERVAL = 2000; +double input; + +HGLRC hRC=NULL; // Der OpenGL Rendering Context +HDC hDC=NULL; // Geschützter GDI Device Context +HWND hWnd=NULL; // Verweist später auf den Windows Handle +HINSTANCE hInstance; +HWND hMainWnd; // main window handle +HDC memDC; // memory device context +HBITMAP memBM, // memory bitmap (for memDC) + oldBM; // old bitmap (from memDC) // Die Instanz der Anwendung + +char szAppName[] = "Bouncing Balls"; // Our window class, etc +char *tmp=new char[70]; +char *title=new char[70]; +char *old_title=new char[70]; +char ** title_winamp; + +int width=640 ,config_x = 1600 ,height=480 ,config_y =1200 ; +int key=1; +int current_window_size=4; +int now_playing,pos; +float old_beat,beat_help =0.0f; +bool keys[256]; // Vektor (Array) der den Status einzelner Tasten enthält (gedrückt/nicht gedrückt) +bool done=FALSE; +bool new_title=TRUE; +bool fullscreen=TRUE; // Läuft das Programm im Vollbildmodus oder nicht? +bool change_scene=TRUE; +bool active=TRUE; + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* -----------------------------------------------------winamp functions-----------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + // configuration declarations +void config_read(struct winampVisModule *this_mod); // reads the configuration +void config_write(struct winampVisModule *this_mod); // writes the configuration +void config_getinifn(struct winampVisModule *this_mod, char *ini_file); // makes the .ini file filename + winampVisModule *getModule(int which); // returns a winampVisModule when requested. Used in hdr, below +void config(struct winampVisModule *this_mod); // configuration dialog +int init(struct winampVisModule *this_mod); // initialization for module +int render(struct winampVisModule *this_mod); // rendering for winamp module +void quit(struct winampVisModule *this_mod); // deinitialization for module +void quit3(struct winampVisModule *this_mod); // deinitialization for module and restart + + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* -------------Module header, includes version, description, and address of the module retriever function-------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +winampVisHeader hdr = { VIS_HDRVER, "Bouncing Balls Visualisation plugin for winamp", getModule }; + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------module OpenGL---------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +winampVisModule mod = +{ + "Bouncing Balls Visualizer", + NULL, // hwndParent + NULL, // hDllInstance + 0, // sRate + 0, // nCh + 1, // latencyMS + 1, // delayMS + 2, // spectrumNch + 2, // waveformNch + { 0, }, // spectrumData + { 0, }, // waveformData + config, + init, + render, + quit +}; + +/* --------------------------------------------------------------------------------------------------------------------*/ +/* ----------------------------------------------------Scene Variables---------------------------------------------------*/ +/* --------------------------------------------------------------------------------------------------------------------*/ + +#define M_PI 3.14159265358979323846 + +//Maximum input number for each sphere ranges from 0 to MAXSTRENGTH +#define MAXSTRENGTH 100 + +//Define the values for the number of spheres +#define MAXSPHERES 100 +#define MINSPHERES 7 +#define DEFAULTSPHERES 19 + +//Define the values for the max air-time in one direction +//so 1 sec means actually max 2 sec a ball can be in the air +#define MAXSEC 3.0 +#define MINSEC 0.5 +#define DEFAULTSEC 1.0 + +//Define the speedfactor which is multiplied whith the actual height of each ball, +//when he is in the air, so a higher speedfactor with would let a ball jump higher in +//the same amount of time than with a lower speedfactor +#define MAXSPEEDFACTOR 5.0 +#define MINSPEEDFACTOR 0.5 +#define DEFAULTSPEEDFACTOR 3.5 + +//define the number of different colors with which the balls can be initialized +#define MINCOLOR 0 +#define MAXCOLOR 6 +#define DEFAULTCOLOR 1 + +//show cones or not? +#define DEFAULTCONES false +//show the circle surface or not? +#define DEFAULTSURFACE true +//let the ball change the color when they are bumped up? +#define DEFAULTCOLORCHANGE true +//let ball first bounce a little up and down after they accept the next input? +#define DEFAULTBOUNCE false +//Output the current settings for all necessary user-variables on the screen? +#define DEFAULTOUTPUT true +//print out a short help on the screen? +#define DEFAULTHELP false +//output the waveform circles? +#define DEFAULTWAVEFORMCIRCLES false +//output the spheres? +#define SPHERESONOFF true +//squash the balls? +#define DEFAULTSQUASH false + +#define DEFAULTSAMPLES 20 +#define BT_WAVEFORM 0 +#define BT_BEAT 1 +#define BT_BASS 2 +#define MAXPILLARHEIGHT 50 +//set the decision variables to their default values + +#define my_cos(n) cosTable[(int)(n*100)] +#define my_sin(n) sinTable[(int)(n*100)] + + +int NUMSPHERES = DEFAULTSPHERES; +int COLOR = DEFAULTCOLOR; +int NUM_CIRCLES = DEFAULTSAMPLES; +bool CONES = DEFAULTCONES; +bool SURFACE = DEFAULTSURFACE; +bool WAVEFORMCIRCLES = DEFAULTWAVEFORMCIRCLES; +bool COLORCHANGE = DEFAULTCOLORCHANGE; +bool BOUNCE = DEFAULTBOUNCE; +bool OUTPUT = DEFAULTOUTPUT; +bool HELP = DEFAULTHELP; +bool SPHERES = SPHERESONOFF; +bool SQUASH = DEFAULTSQUASH; +double sinTable[104]; +double cosTable[104]; +double SPEEDFACTOR = DEFAULTSPEEDFACTOR; +double NUMSEC = DEFAULTSEC; +double rotateFactor = 0; +double rotateRate = .05; + +bool surfacetemp; +bool circlestemp; + +//function definition for later use +void bump(struct SPHERE *sp, double strength); +void startTimer(struct SPHERE *sp); +void stopTimer(struct SPHERE *sp); +void doSort(int no, double z); +void initializeSpheres(); +void changeColor(struct SPHERE *sp, int c); +void printOut(int x, int y, char * text); +void setOrthographicProjection(); +void resetPerspectiveProjection(); +double computeSoundInput(int index, int total, struct winampVisModule *this_mod, int BounceType); +double timerSeconds(struct SPHERE *sp); +void displayScene(struct winampVisModule *this_mod); +void myinit(void); +void keyboard(void); +void drawPillars (int i, int spherenum, bool orient, struct winampVisModule* this_mod); +void drawSquare (double a[3], double b[3], double c[3], double d[3]); +//Datastructure to safe the state of each single sphere +struct SPHERE { + //radius + double r; + //x,z - coordinates + double x; + double z; + GLfloat color[3]; + //is the sphere flying upwards at the moment? + bool up; + //is it his first way up after being bumped up? + bool firstUp; + //is he in air now or waiting for an input? + bool inAir; + //store the current air-time for each sphere + double SEC; + //contains the current height of the ball + double height; + //needed to store start and stop times of each ball, to + //compute its height + LARGE_INTEGER frequency_; + LARGE_INTEGER startTime_; + LARGE_INTEGER stopTime_; +}; + + + +/*Define global variables*/ +//First define an array of Spheres +SPHERE *sphere = new SPHERE[MAXSPHERES]; + +//will later store the radius of the ground circle +double groundRad=0; +//this will determine the number of circles drawn in waveformcircle mode +int wfci_samples = 10; +//this will determine whether the color and alpha shift with the beat +bool wfcb_color = true; +//used to store the vectors for creating the spiral shape +double spir[12][2]; +//view angle for the perspective view +double alpha=45.0; +//is used to order the Spheres by their z-values to print them out in the right +//order so that no unwanted overlap can happen +int order[MAXSPHERES][2]; + +#endif //DECLARATIONS_H diff --git a/particle.cpp b/particle.cpp new file mode 100755 index 0000000..9ba7241 --- /dev/null +++ b/particle.cpp @@ -0,0 +1,174 @@ +#include "headers.h" +#include "Misc.h" +#include "particle.h" + +particle::particle(float xg,float yg,float zg) +{ + GLfloat colors[12][3]= + { + {1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f}, + {0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f}, + {0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f} + }; + + const int MAX_PARTICLES=100; + for (int loop=0;loopwaveformData[1][int(loop)]/127; + //float waveform2=(32767.0f-pcm[int(loop)])*SPECHEIGHT/105536.0f; + + particle_in[loop].xi+=particle_in[loop].xg+waveform2/5; + particle_in[loop].yi+=particle_in[loop].yg+waveform2/100; + particle_in[loop].zi+=particle_in[loop].zg*waveform2/10; + particle_in[loop].life-=particle_in[loop].fade; + particle_in[loop].xg+=(float)cos(rand()%180)*waveform2/(10*60); + particle_in[loop].yg-=((float)cos(rand()%180)/10)*xrot/60; + particle_in[loop].zg-=(float)cos(rand()%180)*waveform2/127; + + if (particle_in[loop].life<0.0f) + { + particle_in[loop].life=1.0f; + particle_in[loop].fade=float(rand()%100)/1000.0f+0.003f; + particle_in[loop].x=0.0f; + particle_in[loop].y=0.0f; + particle_in[loop].z=0.0f; + particle_in[loop].xi=xspeed+float((rand()%60)-32.0f); + particle_in[loop].yi=yspeed+float((rand()%60)-30.0f); + particle_in[loop].zi=float((rand()%60)-30.0f); + particle_in[loop].r=colors[col][0]; + particle_in[loop].g=colors[col][1]; + particle_in[loop].b=colors[col][2]; + } + glVertexPointer ( 3, GL_FLOAT, 0, &vertices ); + glColorPointer ( 4, GL_FLOAT, 0, &colours ); + glDrawElements ( GL_QUADS, 4 , GL_UNSIGNED_INT, &indices ); + } + } +} + + + diff --git a/particle.h b/particle.h new file mode 100755 index 0000000..b84bc68 --- /dev/null +++ b/particle.h @@ -0,0 +1,43 @@ +#ifndef __PARTICLE_H_ +#define __PARTICLE_H_ +#include "vis.h" + +class particle +{ + + public: + + typedef struct // Create A Structure For Particle + { + bool active; // Active (Yes/No) + float life; // Particle Life + float fade; // Fade Speed + float r; // Red Value + float g; // Green Value + float b; // Blue Value + float x; // X Position + float y; // Y Position + float z; // Z Position + float xi; // X Direction + float yi; // Y Direction + float zi; // Z Direction + float xg; // X Gravity + float yg; // Y Gravity + float zg; // Z Gravity + }particles; + + particle(float xg,float yg,float zg); + ~particle(); + + void Draw(GLuint blend_colour,float beat_responder,struct winampVisModule *this_mod,float xrot,float xspeed,float yspeed,int col); + void Restore(float xg,float yg,float zg); + + particles particle_in[500]; + + float slowdown; + PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; + PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; + +}; + +#endif __PARTICLE_H_ diff --git a/winampdetectbeat.h b/winampdetectbeat.h new file mode 100755 index 0000000..f26a4c6 --- /dev/null +++ b/winampdetectbeat.h @@ -0,0 +1,97 @@ +int winampDetectBeat(struct winampVisModule *this_mod) +{ + int y=0; // y=0 | 1 right | left channel; + int last=this_mod->waveformData[y][0]; + int total=0; + for (int x = 1; x < 576; x ++) + { + total += abs(last - this_mod->waveformData[y][x]); + last = this_mod->waveformData[y][x]; + } + total /= 576; + if (total > 127) total = 127; + return total; +} + +int winampDetectBass(struct winampVisModule *this_mod,int xmin,int xmax) +{ + int last=this_mod->waveformData[0][0]; + int total=0; + for (int y=0;y<2;y++) + { + for (int x = xmin; x < xmax; x ++) + { + total += abs(this_mod->spectrumData[y][x]); + last = this_mod->waveformData[y][x]; + } + total /= (xmax-xmin); + } + if (total > 100) total = 100; + return total; +} + +int winampDetectMiddle(struct winampVisModule *this_mod) +{ + int y=0; // y=0 | 1 right | left channel; + int last=this_mod->waveformData[y][0]; + int total=0; + for (int x = 550; x < 555; x ++) + { + total += abs(this_mod->waveformData[y][x]); + last = this_mod->waveformData[y][x]; + } + total /= 5; + if (total > 127) total = 127; + return total; +} + +int winampMiddleUp(struct winampVisModule *this_mod,int i,int j) +{ + int y=0; // y=0 | 1 right | left channel; + int last=this_mod->waveformData[y][i]; + int total=0; + for (int x = 0; x < j; x ++) + { + total += abs(this_mod->spectrumData[y][x+i]); + last = this_mod->waveformData[y][x+i]; + } + total /= j; + if (total > 127) total = 127; + return total; +} + +int winampDetectTreble(struct winampVisModule *this_mod) +{ + int y=0; // y=0 | 1 right | left channel; + int last=this_mod->waveformData[y][0]; + int total=0; + for (int x = 250; x < 560; x ++) + { + total += abs(this_mod->spectrumData[y][x]); + last = this_mod->waveformData[y][x]; + } + total /= 310; + if (total > 127) total = 127; + return total; +} + +int winampBeat(struct winampVisModule *this_mod) +{ + int total; + for (int y = 0; y < 2; y ++) + { + int last=this_mod->waveformData[y][0]; + total=0; + + //get average waveformData level + for (int x = 1; x < 576; x ++) + { + total+=abs(last-this_mod->waveformData[y][x]); + last = this_mod->waveformData[y][x]; + } + total /= 576; + + if (total > 100) total = 100; + } + return total; +} \ No newline at end of file