|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
ATTRACTEURS DE FAMILLES DE CONTRACTIONS EN ÉCRAN DE VEILLE
Information sur la source
Description
Bonjour à tous, c'est mon tout premier programme en C posté ici, donc un peu d'indulgence ;-) Il s'agit d'un programme de démonstration OpenGl/GLUT qui affiche une famille d'IFS (Iterated Function System) d'une manière que l'auteur (moi!) espère harmonieuse. Ce sont des ensembles fractaux, colorés et animés dans le temps. Le programme essaie d'adapter la qualité (complexité) de l'image aux performances de la machine, ainsi que la densité de l'image pour qu'elle reste à peu près uniforme. Au démarrage l'image est peu détaillée, elle va progressivement le devenir au fur et à mesure que le programme détecte que les performances de la machine sont suffisantes pour suivre (en général au bout d'une quinzaine de secondes). Il ne faut pas demander plus de frames par secondes que la fréquence de l'écran en mode DoubleBuffered (sinon le programme va croire que la machine rame et diminuer la qualité). Le source a été pensé pour pouvoir aussi être compilé en tant qu'écran de veille (uniquement sous Windows): il suffit de définir #define SCREENSAVER pour que ça le compile en écran de veille (il faudra aussi changer l'extension du fichier compilé en .scr, et faire un clic droit dessus pour l'installer sous Windows). En mode normal (pas SCREENSAVER) ou en mode configuration de l'écran de veille il faut appuyer sur ESCAPE pour afficher/cacher le menu. Les paramètres peuvent être enregistrés dans un fichier ini du même nom que le programme, et automatiquement chargés au démarrage (si le fichier existe). Il y a encore deux options de compilation supplémentaire: USE_TEXTURE et USE_MULTIPLE_TEXTURES, la seconde nécessite la première. Avec USE_TEXTURE il est possibe de faire un motion blur plus "smooth" utilisant une texture. La seconde nécessite OpenGl 1.1 au moins, et utilise 2 textures pour le motion blur et le blending par couches, afin de permettre un filtrage des couleurs plus riche. À réserver aux cartes graphiques récentes... Noter que pour pouvoir compiler il faut que vous ayez installé GLUT. Par exemple comme expliqué ici sous dev-cpp: http://people.bath.ac.uk/ab8lam/computing/DevCpp.htm. Ou encore pour d'autres compilateurs: http://www.math.u-psud.fr/~feuvrier/enseignement/2007/M2/site005.html En théorie le source compile tant sous Windows que sous Linux (à condition de mettre les bonnes lib, comme indiqué dans les liens). J'ai mis le .exe (renommé en .ex_) et le .scr (l'écran de veille compilé) dans le zip au cas où... Si vous avez des commentaires, n'hésitez pas!
Source
- #define USE_COS_TABLE
- #define USE_TEXTURE
- #define USE_MULTIPLE_TEXTURES
- //#define SCREENSAVER
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <time.h>
- #include "glut_import.h"
- #include "menu.h"
-
- /*********************************************************************
- * CONSTANTS *
- *********************************************************************/
-
- #define FPS_COUNTER_TRIGGER 15
- #define FPS_COUNTER_SMOOTH 0.3
-
- #define PROXY_SIZE 32
- #define PROXY_QUALITY 5
-
- #define MIN_COLOR (10./256.)
- #define MIN_POINT_COUNT 300
-
- #define INI_FILENAME "AFC.ini"
-
- #ifdef USE_MULTIPLE_TEXTURES
- # ifndef USE_TEXTURE
- # error You cannot specify USE_MULTIPLE_TEXTURES without specifying USE_TEXTURE
- # endif
- # define INVALID_TEXTURE_INDEX 0xFFFFFFFF
- #endif
-
- /*********************************************************************
- * PLATFORM *
- *********************************************************************/
-
- #ifdef __WIN32__
- # ifdef SCREENSAVER
- # define SCREENSAVER_MODE_SHOW 0x1
- # define SCREENSAVER_MODE_CONFIGURE 0x2
- # define SCREENSAVER_MODE_PREVIEW 0x4
- # define MAX_SCREENSAVER_MOUSE_OFFSET 10
- # endif
- # include <windows.h>
- # define SLEEP(_DELAY) Sleep(_DELAY)
- # define TIME_GRANULARITY 12
- #else
- # ifdef SCREENSAVER
- # error Usage of SCREENSAVER reserved for Windows
- # endif
- # include <unistd.h>
- # define SLEEP(_DELAY) usleep(1000*_DELAY)
- # define TIME_GRANULARITY 6
- #endif
-
- /*********************************************************************
- * COSINE TABLE SUPPORT *
- *********************************************************************/
-
- #ifdef USE_COS_TABLE
- # define COS_TABLE_QUALITY 0x1000
- float CosTable[COS_TABLE_QUALITY];
- void initCos(void){
- int i;
- for (i=0;i<COS_TABLE_QUALITY;i++)
- CosTable[i]=cos(PI*i/COS_TABLE_QUALITY);
- }
- float cosTable(float x){
- int n;
- if (x<0)
- x=-x;
- n=((int) roundf(COS_TABLE_QUALITY*x/PI)) % (2*COS_TABLE_QUALITY);
- if (n<COS_TABLE_QUALITY)
- return CosTable[n];
- else
- return CosTable[2*COS_TABLE_QUALITY-1-n];
- }
- # define COS(_X) cosTable((_X))
- # define SIN(_X) cosTable((_X)-0.5*PI)
- #else
- # define COS(_X) cos((_X))
- # define SIN(_X) sin((_X))
- #endif
-
- /*********************************************************************
- * MACROS *
- *********************************************************************/
-
- #define ASSERT(_X,_S) if (!(_X)) {printf("%s\n",_S);exit(-1);}
- #define MEMCHECK(_X) if (!(_X)) {printf("Memory allocation failed\n");exit(-1);}
-
- /*********************************************************************
- * TYPES *
- *********************************************************************/
-
- typedef struct{
- int Count,Degree;
- float *Matrix;
- } transformation;
-
- #ifdef USE_TEXTURE
- typedef struct{
- # ifdef USE_MULTIPLE_TEXTURES
- unsigned int Index;
- # endif
- int ImageWidth,ImageHeight,Width,Height;
- } texture;
- #endif
-
- #pragma pack(push,1)
- #pragma pack(1)
- typedef struct{
- unsigned char R,G,B,A;
- float X,Y,Z;
- } point;
- #pragma pack(pop)
-
- /*********************************************************************
- * APPLICATION DATA *
- *********************************************************************/
-
- struct {
- struct {
- int Index,Width,Height,FullScreen,DesiredFullScreen,DoubleBuffered,DesiredDoubleBuffered,MultiSample,DesiredMultiSample,ChangeMode;
- #ifdef SCREENSAVER
- int ScreenSaverMode,MouseX,MouseY;
- #endif
- #ifdef USE_TEXTURE
- texture TextureMotion;
- # ifdef USE_MULTIPLE_TEXTURES
- texture TextureAccum;
- # endif
- #endif
- } Window;
- struct {
- int Tick,PeriodStart,PeriodLength,TickTime;
- float Elasticity,Map,FPS,DesiredFPS;
- } Time;
- struct {
- transformation T1,T2;
- int MinDegree,MaxDegree;
- } Transformations;
- struct {
- int Count,DesiredCount,Rounded;
- float Size;
- point *Data;
- } Points;
- struct {
- float Alpha,SpaceFrequency,TimeFrequency;
- } ColorMap;
- struct {
- int BlendMethod,LimitCPUUsage,MotionBlur,Accumulation;
- float Luminance,Sharpness,Attenuation;
- } Display;
- struct {
- float Density;
- char sFrame[64],sTime[64],sFPS[64],sPointCount[64],sDensity[64],sPointSize[64],sAlpha[64],sCycle[64],sAttractor1[64],sAttractor2[64];
- } Statistics;
- menu *MainMenu;
- } ApplicationData={
- {-1,1,1,0,0,1,1,0,0,0
- #ifdef SCREENSAVER
- ,0,-1,-1
- #endif
- #ifdef USE_TEXTURE
- # ifdef USE_MULTIPLE_TEXTURES
- ,{INVALID_TEXTURE_INDEX,0,0,0,0},{INVALID_TEXTURE_INDEX,0,0,0,0}
- # else
- ,{0,0,0,0}
- # endif
- #endif
- },
- {0,0,5000,0,5,0,50,40},
- {{0,0,NULL},{0,0,NULL},0,20},
- {0,2*MIN_POINT_COUNT,1,1,NULL},
- {0,1,1},
- {0,0,0,0,1,1,0.1},
- {0,"","","","","","","","","",""}
- };
-
- /*********************************************************************
- * FUNCTIONS *
- *********************************************************************/
-
- void evolveWindow(void);
- void evolveAlloc(void);
- void evolveTime(void);
- void evolvePoints(void);
- void evolveProxy(void);
- void evolveColorMap(void);
- void evolve(void);
-
- void displayFunc(void);
- void reshapeFunc(int,int);
- void idleFunc(void);
- void keyboardFunc(unsigned char,int,int);
- void specialFunc(int,int,int);
- void mouseFunc(int,int,int,int);
- #ifdef SCREENSAVER
- void passiveMotionFunc(int,int);
- #endif
-
- void readIniFile(void);
- void writeIniFile(void);
-
- void fullScreenChange(int);
- void fullScreenParamChange(int);
- void doubleBufferedChange(int);
- void multiSampleChange(int);
- #ifdef USE_TEXTURE
- void motionBlurChange(int);
- #endif
- void desiredFPSChange(int);
- void limitCPUUsageChange(int);
- void resetExecute(void);
- void saveExecute(void);
- void quitExecute(void);
-
- void roundedPointsChange(int);
- void blendMethodChange(int);
- void luminanceChange(float);
- void sharpnessChange(float);
- void attenuationChange(float);
- void spaceFrequencyChange(float);
- void timeFrequencyChange(float);
-
- void periodChange(float);
- void elasticityChange(float);
- void minDegreeChange(int);
- void maxDegreeChange(int);
-
- /*********************************************************************
- * MENU DESIGN *
- *********************************************************************/
-
- SEPARATOR(Separator);
-
- CHECKBOX(CheckBoxFullScreen,"Fullscreen (F)",0,fullScreenChange);
- static char *ListBoxResolution_Items[6]={"default","320x240","640x480","800x600","1024x768","1280x1024"};
- LISTBOX(ListBoxResolution,"Fullscreen resolution :",0,ListBoxResolution_Items,fullScreenParamChange);
- static char *ListBoxBPP_Items[4]={"default","16","24","32"};
- LISTBOX(ListBoxBPP,"Fullscreen color depth (BPP) :",0,ListBoxBPP_Items,fullScreenParamChange);
- static char *ListBoxFrequency_Items[11]={"default","50","60","65","70","72","75","80","85","90","100"};
- LISTBOX(ListBoxFrequency,"Fullscreen refresh rate (Hz) :",0,ListBoxFrequency_Items,fullScreenParamChange);
- CHECKBOX(CheckBoxDoubleBuffered,"Double buffered (D)",1,doubleBufferedChange);
- CHECKBOX(CheckBoxMultiSample,"Multi sample (M)",0,multiSampleChange);
- #ifdef USE_TEXTURE
- # ifdef USE_MULTIPLE_TEXTURES
- static char *ListBoxMotionBlur_Items[7]={"Single buffer","Double buffer","Triple buffer (2x filter)",
- "Triple buffer (3x filter)","Triple buffer (4x filter)","Triple buffer (5x filter)",
- "Triple buffer (6x filter)"};
- LISTBOX(ListBoxMotionBlur,"Motion blur",1,ListBoxMotionBlur_Items,motionBlurChange);
- # else
- CHECKBOX(CheckBoxMotionBlur,"High quality motion blur",1,motionBlurChange);
- # endif
- #endif
- ITRACKBAR(FTrackBarDesiredFPS,"Requested frame rate: %d",5,120,40,1,desiredFPSChange);
- CHECKBOX(CheckBoxLimitCPUUsage,"Limit CPU usage",0,limitCPUUsageChange);
- #ifdef SCREENSAVER
- STATICTEXT(StaticTextReset,"Reset settings (R)",1,resetExecute);
- STATICTEXT(StaticTextSave,"Save settings and exit (S)",1,saveExecute);
- STATICTEXT(StaticTextQuit,"Cancel (Q)",1,quitExecute);
- # ifdef USE_TEXTURE
- static menuitem *MenuPageAFC_Items[14]={
- # else
- static menuitem *MenuPageAFC_Items[13]={
- # endif
- #else
- STATICTEXT(StaticTextSave,"Save settings (S)",1,saveExecute);
- STATICTEXT(StaticTextReset,"Reset settings",1,resetExecute);
- STATICTEXT(StaticTextQuit,"Quit (Q)",1,quitExecute);
- # ifdef USE_TEXTURE
- static menuitem *MenuPageAFC_Items[15]={
- # else
- static menuitem *MenuPageAFC_Items[14]={
- # endif
- #endif
- &CheckBoxFullScreen,
- &ListBoxResolution,
- &ListBoxBPP,
- &ListBoxFrequency,
- &Separator,
- &CheckBoxDoubleBuffered,
- &CheckBoxMultiSample,
- #ifdef USE_TEXTURE
- # ifdef USE_MULTIPLE_TEXTURES
- &ListBoxMotionBlur,
- # else
- &CheckBoxMotionBlur,
- # endif
- #endif
- &FTrackBarDesiredFPS,
- &CheckBoxLimitCPUUsage,
- &Separator,
- #ifdef SCREENSAVER
- &StaticTextReset,
- &StaticTextSave,
- &StaticTextQuit
- #else
- &StaticTextSave,
- &StaticTextReset,
- &Separator,
- &StaticTextQuit
- #endif
- };
- MENUPAGE(MenuPageAFC,"AFC Version 1.0",MenuPageAFC_Items);
-
- CHECKBOX(CheckBoxRoundedPoints,"Rounded points",1,roundedPointsChange);
- static char *ListBoxBlendMethod_Items[3]={"Logarithmic","Linear","Maximum"};
- LISTBOX(ListBoxBlendMethod,"Blend color method :",0,ListBoxBlendMethod_Items,blendMethodChange);
- FTRACKBAR(FTrackBarLuminance,"Luminance : %.0f%%",0,200,100,1,luminanceChange);
- FTRACKBAR(FTrackBarSharpness,"Sharpness : %.0f%%",0,200,100,1,sharpnessChange);
- FTRACKBAR(FTrackBarAttenuation,"Attenuation : %.1f%%",0.1,100,10,0.1,attenuationChange);
- FTRACKBAR(FTrackBarSpaceFrequency,"Colormap space frequency : %.2f",0,50,1,0.02,spaceFrequencyChange);
- FTRACKBAR(FTrackBarTimeFrequency,"Colormap time frequency : %.2f",0,20,1,0.02,timeFrequencyChange);
- static menuitem *MenuPageDisplay_Items[9]={
- &CheckBoxRoundedPoints,
- &ListBoxBlendMethod,
- &Separator,
- &FTrackBarLuminance,
- &FTrackBarSharpness,
- &FTrackBarAttenuation,
- &Separator,
- &FTrackBarSpaceFrequency,
- &FTrackBarTimeFrequency
- };
- MENUPAGE(MenuPageDisplay,"DISPLAY",MenuPageDisplay_Items);
-
- FTRACKBAR(FTrackBarPeriod,"Cycle length : %.1f sec",0.5,20,5,0.1,periodChange);
- FTRACKBAR(FTrackBarElasticity,"Cycle elasticity : %.1f",0.1,30,5,0.1,elasticityChange);
- ITRACKBAR(ITrackBarMinDegree,"Min attractor degree : %d",3,15,6,1,minDegreeChange);
- ITRACKBAR(ITrackBarMaxDegree,"Max attractor degree : %d",3,15,6,1,maxDegreeChange);
- static menuitem *MenuPageAttractor_Items[4]={&FTrackBarPeriod,&FTrackBarElasticity,&ITrackBarMinDegree,&ITrackBarMaxDegree};
- MENUPAGE(MenuPageAttractor,"ATTRACTOR",MenuPageAttractor_Items);
-
- STATICTEXT(StaticTextFrame,ApplicationData.Statistics.sFrame,0,NULL);
- STATICTEXT(StaticTextTime,ApplicationData.Statistics.sTime,0,NULL);
- STATICTEXT(StaticTextFPS,ApplicationData.Statistics.sFPS,0,NULL);
- STATICTEXT(StaticTextPointCount,ApplicationData.Statistics.sPointCount,0,NULL);
- STATICTEXT(StaticTextDensity,ApplicationData.Statistics.sDensity,0,NULL);
- STATICTEXT(StaticTextPointSize,ApplicationData.Statistics.sPointSize,0,NULL);
- STATICTEXT(StaticTextAlpha,ApplicationData.Statistics.sAlpha,0,NULL);
- STATICTEXT(StaticTextCycle,ApplicationData.Statistics.sCycle,0,NULL);
- STATICTEXT(StaticTextAttractor1,ApplicationData.Statistics.sAttractor1,0,NULL);
- STATICTEXT(StaticTextAttractor2,ApplicationData.Statistics.sAttractor2,0,NULL);
- static menuitem *MenuPageStatistics_Items[12]={
- &StaticTextFrame,
- &StaticTextTime,
- &StaticTextFPS,
- &Separator,
- &StaticTextPointCount,
- &StaticTextDensity,
- &StaticTextPointSize,
- &StaticTextAlpha,
- &Separator,
- &StaticTextCycle,
- &StaticTextAttractor1,
- &StaticTextAttractor2
- };
- MENUPAGE(MenuPageStatistics," STATISTICS ",MenuPageStatistics_Items);
-
- static menupage *MainMenu_Pages[4]={&MenuPageAFC,&MenuPageDisplay,&MenuPageAttractor,&MenuPageStatistics};
- MENU(MainMenu,MainMenu_Pages);
-
- /*********************************************************************
- * UTILITIES *
- *********************************************************************/
-
- int pgcd(int x,int y){
- if (y)
- return pgcd(y,x%y);
- else
- return x;
- }
-
- int ppcm(int x,int y){
- return (x*y)/pgcd(x,y);
- }
-
- int nextPowerOfTwo(int x){
- int u=1;
- while (u<x)
- u*=2;//<<=1;
- return u;
- }
-
- float mapExp(float x,float t){
- if (x<0.5)
- return 0.5*pow(2*x,t);
- else
- return 1-0.5*pow(2-2*x,t);
- }
-
- /*********************************************************************
- * TEXTURE UTILITIES *
- *********************************************************************/
-
- #ifdef USE_TEXTURE
- void copyTexture(texture *T){
- # ifdef USE_MULTIPLE_TEXTURES
- if (T->Index==INVALID_TEXTURE_INDEX)
- glGenTextures(1,&T->Index);
- glBindTexture(GL_TEXTURE_2D,T->Index);
- # endif
- if (ApplicationData.Window.Width!=T->ImageWidth || ApplicationData.Window.Height!=T->ImageHeight){
- T->ImageWidth=ApplicationData.Window.Width;
- T->ImageHeight=ApplicationData.Window.Height;
- T->Width=nextPowerOfTwo(T->ImageWidth);
- T->Height=nextPowerOfTwo(T->ImageHeight);
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,T->Width,T->Height,0,GL_RGB,GL_UNSIGNED_BYTE,NULL);
- }
- glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,T->ImageWidth,T->ImageHeight);
- }
-
- int paintTexture(texture *T,int Mode){
- # ifdef USE_MULTIPLE_TEXTURES
- if (T->Index!=INVALID_TEXTURE_INDEX && T->Width && T->Height){
- # else
- if (T->Width && T->Height){
- # endif
- float u=(float) T->ImageWidth/T->Width,v=(float) T->ImageHeight/T->Height;
- glPushAttrib(GL_ALL_ATTRIB_BITS);
- glPushMatrix();
- # ifdef USE_MULTIPLE_TEXTURES
- glBindTexture(GL_TEXTURE_2D,T->Index);
- # endif
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
- glEnable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
- glTexCoord2f(0,0);
- glVertex2f(-1,-1);
- glTexCoord2f(0,v);
- glVertex2f(-1,1);
- glTexCoord2f(u,v);
- glVertex2f(1,1);
- glTexCoord2f(u,0);
- glVertex2f(1,-1);
- glEnd();
- glDisable(GL_TEXTURE_2D);
- glPopMatrix();
- glPopAttrib();
- return 1;
- }
- return 0;
- }
-
- void deleteTexture(texture *T){
- # ifdef USE_MULTIPLE_TEXTURES
- if (T->Index!=INVALID_TEXTURE_INDEX){
- glDeleteTextures(1,&T->Index);
- T->Index=INVALID_TEXTURE_INDEX;
- # endif
- T->Width=0;
- T->Height=0;
- T->ImageWidth=0;
- T->ImageHeight=0;
- # ifdef USE_MULTIPLE_TEXTURES
- }
- # endif
- }
- #endif
-
- /*********************************************************************
- * AFFINE TRANSFORMATIONS *
- *********************************************************************/
-
- void allocTransformation(transformation *t){
- int i,*T;
- if (ApplicationData.Transformations.MaxDegree==ApplicationData.Transformations.MinDegree)
- t->Degree=ApplicationData.Transformations.MinDegree;
- else
- t->Degree=ApplicationData.Transformations.MinDegree+(rand() % (1+ApplicationData.Transformations.MaxDegree-ApplicationData.Transformations.MinDegree));
- t->Count=t->Degree-(rand() % (t->Degree/2));
- if (t->Count==t->Degree)
- t->Count--;
- MEMCHECK(T=(int *) calloc(t->Degree,sizeof(int)));
- MEMCHECK(t->Matrix=(float *) malloc(6*t->Count*sizeof(float)));
- for (i=0;i<t->Count;i++){
- float o=2*PI*(rand() % t->Degree)/t->Degree,u=(rand() % 2)-0.5,v=-0.5;
- int k=-1,j=1+(rand() % (t->Degree-i));
- t->Matrix[6*i]=u*cos(o);
- t->Matrix[6*i+1]=-v*sin(o);
- t->Matrix[6*i+3]=u*sin(o);
- t->Matrix[6*i+4]=v*cos(o);
- while (j){
- k++;
- if (!T[k])
- j--;
- }
- T[k]=1;
- o=PI*(1.+2*k)/t->Degree;
- t->Matrix[6*i+2]=0.5*cos(o);
- t->Matrix[6*i+5]=0.5*sin(o);
- }
- free(T);
- }
-
- void freeTransformation(transformation *t){
- free(t->Matrix);
- t->Count=0;
- }
-
- void applyTransformation(transformation *t,int r,float *x,float *y){
- float u=t->Matrix[6*r]*(*x)+t->Matrix[6*r+1]*(*y)+t->Matrix[6*r+2];
- *y=t->Matrix[6*r+3]*(*x)+t->Matrix[6*r+4]*(*y)+t->Matrix[6*r+5];
- *x=u;
- }
-
- /*********************************************************************
- * WINDOW *
- *********************************************************************/
-
- void createWindow(void){
- if (ApplicationData.Window.Index==-1){
- int m=GLUT_RGBA;
- char s[64]="";
- if (ApplicationData.Window.DesiredDoubleBuffered)
- m|=GLUT_DOUBLE;
- ApplicationData.Window.DoubleBuffered=ApplicationData.Window.DesiredDoubleBuffered;
- if (ApplicationData.Window.DesiredMultiSample)
- m|=GLUT_MULTISAMPLE;
- ApplicationData.Window.MultiSample=ApplicationData.Window.DesiredMultiSample;
- glutInitDisplayMode(m);
- if (ApplicationData.Window.DesiredFullScreen){
- if (ListBoxResolution.Data.ListBox->ItemIndex)
- strcat(s,ListBoxResolution.Data.ListBox->Items[ListBoxResolution.Data.ListBox->ItemIndex]);
- if (ListBoxBPP.Data.ListBox->ItemIndex){
- strcat(s,":");
- strcat(s,ListBoxBPP.Data.ListBox->Items[ListBoxBPP.Data.ListBox->ItemIndex]);
- }
- if (ListBoxFrequency.Data.ListBox->ItemIndex){
- strcat(s,"@");
- strcat(s,ListBoxFrequency.Data.ListBox->Items[ListBoxFrequency.Data.ListBox->ItemIndex]);
- }
- if (*s){
- glutGameModeString(s);
- if (!glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)){
- printf("Unsupported display mode (%s). Fullscreen has been canceled.\n",s);
- ApplicationData.Window.DesiredFullScreen=0;
- }
- }
- }
- CheckBoxFullScreen.Data.CheckBox->Checked=ApplicationData.Window.DesiredFullScreen;
- if (ApplicationData.Window.DesiredFullScreen)
- ApplicationData.Window.Index=glutEnterGameMode();
- else {
- glutInitWindowSize(640,480);
- glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH)-640)/2,(glutGet(GLUT_SCREEN_HEIGHT)-480)/2);
- ApplicationData.Window.Index=glutCreateWindow("AFC");
- }
- ApplicationData.Window.FullScreen=ApplicationData.Window.DesiredFullScreen;
- ApplicationData.Window.ChangeMode=0;
- #ifdef USE_TEXTURE
- deleteTexture(&ApplicationData.Window.TextureMotion);
- # ifdef USE_MULTIPLE_TEXTURES
- deleteTexture(&ApplicationData.Window.TextureAccum);
- # endif
- #endif
- #ifdef SCREENSAVER
- if (ApplicationData.Window.ScreenSaverMode==SCREENSAVER_MODE_SHOW)
- glutSetCursor(GLUT_CURSOR_NONE);
- else
- #endif
- glutSetCursor(GLUT_CURSOR_CROSSHAIR);
- glutDisplayFunc(displayFunc);
- glutReshapeFunc(reshapeFunc);
- glutIdleFunc(idleFunc);
- glutKeyboardFunc(keyboardFunc);
- glutSpecialFunc(specialFunc);
- glutMouseFunc(mouseFunc);
- #ifdef SCREENSAVER
- glutPassiveMotionFunc(passiveMotionFunc);
- #endif
- }
- }
-
- void destroyWindow(void){
- if (ApplicationData.Window.Index!=-1){
- if (ApplicationData.Window.FullScreen)
- glutLeaveGameMode();
- else
- glutDestroyWindow(ApplicationData.Window.Index);
- }
- ApplicationData.Window.Index=-1;
- }
-
- /*********************************************************************
- * ANIMATION CORE *
- *********************************************************************/
-
- float u1,u2,u3,u4,u5,u6;
-
- void evolveWindow(void){
- if (ApplicationData.Window.MultiSample^ApplicationData.Window.DesiredMultiSample ||
- ApplicationData.Window.DoubleBuffered^ApplicationData.Window.DesiredDoubleBuffered ||
- ApplicationData.Window.FullScreen^ApplicationData.Window.DesiredFullScreen ||
- ApplicationData.Window.ChangeMode) {
- destroyWindow();
- createWindow();
- }
- }
-
- void evolveAlloc(void){
- if (ApplicationData.Points.Count!=ApplicationData.Points.DesiredCount){
- int i;
- MEMCHECK(ApplicationData.Points.Data=(point *) realloc(ApplicationData.Points.Data,ApplicationData.Points.DesiredCount*sizeof(point)));
- if (!ApplicationData.Points.Count){
- float o=2*PI*rand()/RAND_MAX,r=(float) rand()/RAND_MAX;
- ApplicationData.Points.Data[0].X=r*cos(o);
- ApplicationData.Points.Data[0].Y=r*sin(o);
- ApplicationData.Points.Data[0].Z=0;
- ApplicationData.Points.Data[0].A=255;
- }
- for (i=ApplicationData.Points.Count;i<ApplicationData.Points.DesiredCount;i++)
- ApplicationData.Points.Data[i]=ApplicationData.Points.Data[0];
- ApplicationData.Points.Count=ApplicationData.Points.DesiredCount;
- }
- }
-
- void evolveTime(void){
- int t=glutGet(GLUT_ELAPSED_TIME),u=(t-ApplicationData.Time.PeriodStart)/ApplicationData.Time.PeriodLength;
- while (u--){
- freeTransformation(&ApplicationData.Transformations.T1);
- ApplicationData.Transformations.T1=ApplicationData.Transformations.T2;
- allocTransformation(&ApplicationData.Transformations.T2);
- ApplicationData.Time.PeriodStart+=ApplicationData.Time.PeriodLength;
- }
- ApplicationData.Time.Map=mapExp((float) (t-ApplicationData.Time.PeriodStart)/ApplicationData.Time.PeriodLength,ApplicationData.Time.Elasticity);
- if ((++ApplicationData.Time.Tick & FPS_COUNTER_TRIGGER)==FPS_COUNTER_TRIGGER){
- char s[64];
- float r;
- ApplicationData.Time.FPS=(1-FPS_COUNTER_SMOOTH)*1000*(1+FPS_COUNTER_TRIGGER)/(t+1-ApplicationData.Time.TickTime)+FPS_COUNTER_SMOOTH*ApplicationData.Time.FPS;
- ApplicationData.Time.TickTime=t;
- r=ApplicationData.Time.FPS/ApplicationData.Time.DesiredFPS;
- if (r>1.05)
- ApplicationData.Points.DesiredCount+=ApplicationData.Points.DesiredCount*(1-1/r);
- if (r<0.95)
- ApplicationData.Points.DesiredCount-=ApplicationData.Points.DesiredCount*(1-r);
- if (ApplicationData.Points.DesiredCount<MIN_POINT_COUNT){
- ApplicationData.Points.DesiredCount=MIN_POINT_COUNT;
- printf("Your system is TOO SLOW to run this program at the requested frame rate. Please lower it to improve image quality (its value MUST be less than the screen refresh rate if you are using double buffered mode, since the display cannot go faster than the screen in this case).\n");
- }
- sprintf(s,"AFC (%.0f FPS , %d points)\0",ApplicationData.Time.FPS,ApplicationData.Points.Count);
- glutSetWindowTitle(s);
- }
- }
-
- void evolvePoints(void){
- int i;
- for (i=0;i<ApplicationData.Points.Count;i++){
- int r=rand(),r1=r % ApplicationData.Transformations.T1.Count,r2=r % ApplicationData.Transformations.T2.Count;
- point *p=ApplicationData.Points.Data+i;
- float u=p->X,v=p->Y,s=ApplicationData.Time.Map,t=1-ApplicationData.Time.Map;
- applyTransformation(&ApplicationData.Transformations.T1,r1,&p->X,&p->Y);
- applyTransformation(&ApplicationData.Transformations.T2,r2,&u,&v);
- p->X=t*p->X+s*u;
- p->Y=t*p->Y+s*v;
- p->Z=0.2*p->Z+0.8*(t*r1+s*r2);
- p->R=85.*ApplicationData.ColorMap.Alpha*(2+COS(ApplicationData.ColorMap.SpaceFrequency*u1*p->Z+u4));
- p->G=85.*ApplicationData.ColorMap.Alpha*(2+COS(ApplicationData.ColorMap.SpaceFrequency*u2*p->Z+u5));
- p->B=85.*ApplicationData.ColorMap.Alpha*(2+COS(ApplicationData.ColorMap.SpaceFrequency*u3*p->Z+u6));
- }
- }
-
- void evolveProxy(void){
- int i,j,k=0,T[PROXY_SIZE][PROXY_SIZE];
- float U[2]={1,1},u=0;
- float r=(float) (1+ApplicationData.Window.Width*ApplicationData.Window.Height)/(1+ApplicationData.Points.Count);
- for (i=0;i<PROXY_SIZE;i++)
- for (j=0;j<PROXY_SIZE;j++)
- T[i][j]=0;
- i=PROXY_SIZE*PROXY_SIZE*PROXY_QUALITY;
- if (i>=ApplicationData.Points.Count)
- i=ApplicationData.Points.Count-1;
- for (;i>=0;i--)
- T[(int) (PROXY_SIZE*(ApplicationData.Points.Data[i].X+1)*0.4999)][(int) (PROXY_SIZE*(ApplicationData.Points.Data[i].Y+1)*0.4999)]++;
- for (i=0;i<PROXY_SIZE;i++)
- for (j=0;j<PROXY_SIZE;j++)
- if (T[i][j])
- k++;
- ApplicationData.Statistics.Density=(float) k/(PROXY_SIZE*PROXY_SIZE);
- ApplicationData.Points.Size=(2.01-ApplicationData.Display.Sharpness)*sqrt(ApplicationData.Statistics.Density*r);
- if (ApplicationData.Points.Rounded){
- glGetFloatv(GL_POINT_SIZE_RANGE,U);
- if (U[1]>U[0]+0.01){
- ApplicationData.Points.Size*=0.5*PI;
- if (ApplicationData.Points.Size<U[0])
- ApplicationData.Points.Size=U[0];
- if (ApplicationData.Points.Size>U[1])
- ApplicationData.Points.Size=U[1];
- glGetFloatv(GL_POINT_SIZE_GRANULARITY,&u);
- if (u>0)
- ApplicationData.Points.Size=U[0]+roundf((ApplicationData.Points.Size-U[0])/u)*u;
- } else
- ApplicationData.Points.Size=U[0];
- } else
- ApplicationData.Points.Size=roundf(ApplicationData.Points.Size);
- if (ApplicationData.Points.Size<1)
- ApplicationData.Points.Size=1;
- if (ApplicationData.Display.BlendMethod<2){
- ApplicationData.ColorMap.Alpha=ApplicationData.Display.Attenuation*ApplicationData.Display.Luminance*r*ApplicationData.Statistics.Density/pow(ApplicationData.Points.Size,2);
- if (ApplicationData.ColorMap.Alpha>1)
- ApplicationData.ColorMap.Alpha=1;
- if (ApplicationData.Display.MotionBlur>=2)
- ApplicationData.ColorMap.Alpha=sqrt(ApplicationData.ColorMap.Alpha);
- if (ApplicationData.ColorMap.Alpha<MIN_COLOR)
- ApplicationData.ColorMap.Alpha=MIN_COLOR;
- } else
- ApplicationData.ColorMap.Alpha=ApplicationData.Display.Luminance;
- }
-
- void evolveColorMap(void){
- float t=0.001*ApplicationData.ColorMap.TimeFrequency*glutGet(GLUT_ELAPSED_TIME);
- u1=2+cos(+0.12*t);
- u2=2+cos(+0.13*t);
- u3=2+cos(-0.16*t);
- u4=+1.9*(t+cos(+1.0*t));
- u5=+1.4*(t-cos(-1.2*t));
- u6=-1.1*(t+cos(-1.4*t));
- }
-
- void evolveStatistics(void){
- if (ApplicationData.MainMenu->Active){
- int t=glutGet(GLUT_ELAPSED_TIME)/1000;
- sprintf(ApplicationData.Statistics.sFrame,"Frame : 0x%X",ApplicationData.Time.Tick);
- sprintf(ApplicationData.Statistics.sTime,"Time : %.2d:%.2d:%.2d",t/3600,(t/60) % 60,t % 60);
- sprintf(ApplicationData.Statistics.sFPS,"FPS : %.0f",ApplicationData.Time.FPS);
- sprintf(ApplicationData.Statistics.sPointCount,"Points count : %d",ApplicationData.Points.Count);
- sprintf(ApplicationData.Statistics.sDensity,"Surface : %.0f%%",ApplicationData.Statistics.Density*100);
- sprintf(ApplicationData.Statistics.sPointSize,"Point size : %.2f",ApplicationData.Points.Size);
- sprintf(ApplicationData.Statistics.sAlpha,"Alpha : %.1f%%",ApplicationData.ColorMap.Alpha*100);
- sprintf(ApplicationData.Statistics.sCycle,"Cycle : %.0f%%",ApplicationData.Time.Map*100);
- sprintf(ApplicationData.Statistics.sAttractor1,"Attractor #1 : %d/%d",ApplicationData.Transformations.T1.Count,ApplicationData.Transformations.T1.Degree);
- sprintf(ApplicationData.Statistics.sAttractor2,"Attractor #2 : %d/%d",ApplicationData.Transformations.T2.Count,ApplicationData.Transformations.T2.Degree);
- }
- }
-
- void evolve(void){
- evolveWindow();
- evolveAlloc();
- evolveTime();
- evolvePoints();
- evolveProxy();
- evolveColorMap();
- evolveStatistics();
- }
-
- /*********************************************************************
- * GLUT CALLBACKS *
- *********************************************************************/
-
- void displayFunc(void){
- float t=glutGet(GLUT_ELAPSED_TIME);
- glEnable(GL_BLEND);
- glPushAttrib(GL_ALL_ATTRIB_BITS);
- glPointSize(ApplicationData.Points.Size);
- if (ApplicationData.Points.Rounded)
- glEnable(GL_POINT_SMOOTH);
- else
- glDisable(GL_POINT_SMOOTH);
- #ifdef USE_TEXTURE
- switch (ApplicationData.Display.MotionBlur){
- case 0:
- #endif
- glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(0,0,0,ApplicationData.Display.Attenuation);
- glRectf(-1,-1,1,1);
- #ifdef USE_TEXTURE
- break;
- case 1:
- glBlendFunc(GL_ONE,GL_ZERO);
- glColor3f(1-ApplicationData.Display.Attenuation,1-ApplicationData.Display.Attenuation,1-ApplicationData.Display.Attenuation);
- if (!paintTexture(&ApplicationData.Window.TextureMotion,GL_MODULATE))
- glClear(GL_COLOR_BUFFER_BIT);
- break;
- }
- #endif
- switch(ApplicationData.Display.BlendMethod){
- case 0:
- glBlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE);
- break;
- case 1:
- glBlendFunc(GL_ONE,GL_ONE);
- break;
- case 2:
- glBlendFunc(GL_ONE,GL_ZERO);
- break;
- }
- glInterleavedArrays(GL_C4UB_V2F,sizeof(point),ApplicationData.Points.Data);
- #ifdef USE_TEXTURE
- switch (ApplicationData.Display.MotionBlur){
- int i;
- case 0:
- case 1:
- #endif
- glDrawArrays(GL_POINTS,0,ApplicationData.Points.Count);
- #ifdef USE_TEXTURE
- break;
- # ifdef USE_MULTIPLE_TEXTURES
- default:{
- float f=ApplicationData.Display.BlendMethod<2?ApplicationData.ColorMap.Alpha:ApplicationData.Display.Attenuation/ApplicationData.Display.MotionBlur;///ApplicationData.Display.MotionBlur;
- for (i=0;i<ApplicationData.Display.MotionBlur;i++){
- int a=i*ApplicationData.Points.Count/ApplicationData.Display.MotionBlur,b=(i+1)*ApplicationData.Points.Count/ApplicationData.Display.MotionBlur-a;
- glClear(GL_COLOR_BUFFER_BIT);
- glDrawArrays(GL_POINTS,a,b);
- glPushAttrib(GL_ALL_ATTRIB_BITS);
- copyTexture(&ApplicationData.Window.TextureAccum);
- glBlendFunc(GL_ONE,GL_ZERO);
- if (i){
- glColor3f(1,1,1);
- paintTexture(&ApplicationData.Window.TextureMotion,GL_MODULATE);
- } else {
- glColor3f(1-ApplicationData.Display.Attenuation,1-ApplicationData.Display.Attenuation,1-ApplicationData.Display.Attenuation);
- if (!paintTexture(&ApplicationData.Window.TextureMotion,GL_MODULATE))
- glClear(GL_COLOR_BUFFER_BIT);
- }
- glColor3f(f,f,f);
- glBlendFunc(GL_ONE,GL_ONE);
- paintTexture(&ApplicationData.Window.TextureAccum,GL_MODULATE);
- if (i<ApplicationData.Display.MotionBlur)
- copyTexture(&ApplicationData.Window.TextureMotion);
- glPopAttrib();
- }
- break;
- }
- # endif
- }
- #endif
- glPopAttrib();
- menuDisplay(ApplicationData.MainMenu,ApplicationData.Window.Width,ApplicationData.Window.Height);
- #ifdef USE_TEXTURE
- switch (ApplicationData.Display.MotionBlur){
- case 0:
- break;
- case 1:
- copyTexture(&ApplicationData.Window.TextureMotion);
- break;
- # ifdef USE_MULTIPLE_TEXTURES
- default:
- copyTexture(&ApplicationData.Window.TextureMotion);
- break;
- # endif
- }
- #endif
- glFlush();
- glutSwapBuffers();
- }
-
- void reshapeFunc(int width,int height){
- if (!(ApplicationData.Window.Width=width))
- ApplicationData.Window.Width=1;
- if (!(ApplicationData.Window.Height=height))
- ApplicationData.Window.Height=1;
- glViewport(0,0,width,height);
- }
-
- void idleFunc(void){
- evolve();
- glutPostRedisplay();
- if (ApplicationData.Display.LimitCPUUsage)
- SLEEP(TIME_GRANULARITY);
- }
-
- void keyboardFunc(unsigned char key,int x,int y){
- #ifdef SCREENSAVER
- if (ApplicationData.Window.ScreenSaverMode==SCREENSAVER_MODE_SHOW)
- exit(0);
- #endif
- switch (key){
- case 'd':
- ApplicationData.Window.DesiredDoubleBuffered=!ApplicationData.Window.DesiredDoubleBuffered;
- CheckBoxDoubleBuffered.Data.CheckBox->Checked=ApplicationData.Window.DesiredDoubleBuffered;
- break;
- case 'f':
- ApplicationData.Window.DesiredFullScreen=!ApplicationData.Window.DesiredFullScreen;
- CheckBoxFullScreen.Data.CheckBox->Checked=ApplicationData.Window.DesiredFullScreen;
- break;
- case 'm':
- ApplicationData.Window.DesiredMultiSample=!ApplicationData.Window.DesiredMultiSample;
- CheckBoxMultiSample.Data.CheckBox->Checked=ApplicationData.Window.DesiredMultiSample;
- break;
- case 'q':
- quitExecute();
- break;
- #ifdef SCREENSAVER
- case 'r':
- resetExecute();
- break;
- #endif
- case 's':
- saveExecute();
- break;
- default:
- menuKeyboard(ApplicationData.MainMenu,key);
- }
- }
-
- void specialFunc(int key,int x,int y){
- #ifdef SCREENSAVER
- if (ApplicationData.Window.ScreenSaverMode==SCREENSAVER_MODE_SHOW)
- exit(0);
- #endif
- menuSpecial(ApplicationData.MainMenu,key);
- }
-
- void mouseFunc(int button,int state,int x,int y){
- int i;
- float u=1-2.*x/ApplicationData.Window.Width,v=1-2.*y/ApplicationData.Window.Height;
- #ifdef SCREENSAVER
- if (ApplicationData.Window.ScreenSaverMode==SCREENSAVER_MODE_SHOW)
- exit(0);
- #endif
- for (i=0;i<ApplicationData.Points.Count;i++){
- ApplicationData.Points.Data[i].X=u;
- ApplicationData.Points.Data[i].Y=v;
- }
- };
-
- #ifdef SCREENSAVER
- void passiveMotionFunc(int x,int y){
- if (ApplicationData.Window.ScreenSaverMode==SCREENSAVER_MODE_SHOW){
- if (ApplicationData.Window.MouseX==-1){
- ApplicationData.Window.MouseX=x;
- ApplicationData.Window.MouseY=y;
- } else {
- if (abs(ApplicationData.Window.MouseX-x)+abs(ApplicationData.Window.MouseY-y)>MAX_SCREENSAVER_MOUSE_OFFSET)
- exit(0);
- }
- }
- };
- #endif
-
-
- /*********************************************************************
- * INI FILE *
- *********************************************************************/
-
- void readIniFile(void){
- FILE *f;
- if (f=fopen(INI_FILENAME,"r")){
- menuLoad(ApplicationData.MainMenu,f);
- fclose(f);
- } else
- printf("Cannot read file "INI_FILENAME"\n");
- menuInit(ApplicationData.MainMenu);
- }
-
- void writeIniFile(void){
- FILE *f;
- if (f=fopen(INI_FILENAME,"w")){
- menuSave(ApplicationData.MainMenu,f);
- fclose(f);
- } else
- printf("Cannot write file" INI_FILENAME "\n");
- }
-
- /*********************************************************************
- * MENU CALLBACKS *
- *********************************************************************/
-
- void fullScreenChange(int checked){
- #ifdef SCREENSAVER
- if (ApplicationData.Window.ScreenSaverMode==SCREENSAVER_MODE_SHOW)
- ApplicationData.Window.DesiredFullScreen=1;
- else
- #endif
- ApplicationData.Window.DesiredFullScreen=checked;
- }
-
- void fullScreenParamChange(int index){
- if (ApplicationData.Window.FullScreen)
- ApplicationData.Window.ChangeMode=1;
- }
-
- void doubleBufferedChange(int checked){
- ApplicationData.Window.DesiredDoubleBuffered=checked;
- }
-
- void multiSampleChange(int checked){
- ApplicationData.Window.DesiredMultiSample=checked;
- }
-
- #ifdef USE_TEXTURE
- # ifdef USE_MULTIPLE_TEXTURES
- void motionBlurChange(int index){
- ApplicationData.Display.MotionBlur=index;
- }
- # else
- void motionBlurChange(int checked){
- ApplicationData.Display.MotionBlur=checked;
- }
- # endif
- #endif
-
- void desiredFPSChange(int position){
- ApplicationData.Time.DesiredFPS=position;
- }
-
- void limitCPUUsageChange(int checked){
- ApplicationData.Display.LimitCPUUsage=checked;
- }
-
- void resetExecute(void){
- FILE *f;
- if (f=fopen(INI_FILENAME,"w")){
- fclose(f);
- printf("Settings reset, restart the application\n");
- }
- #ifdef SCREENSAVER
- exit(0);
- #endif
- }
-
- void saveExecute(void){
- writeIniFile();
- #ifdef SCREENSAVER
- exit(0);
- #endif
- }
-
- void quitExecute(void){
- exit(0);
- }
-
- void roundedPointsChange(int checked){
- ApplicationData.Points.Rounded=checked;
- }
-
- void blendMethodChange(int index){
- ApplicationData.Display.BlendMethod=index;
- }
-
- void luminanceChange(float position){
- ApplicationData.Display.Luminance=position*0.01;
- }
-
- void sharpnessChange(float position){
- ApplicationData.Display.Sharpness=position*0.01;
- }
-
- void attenuationChange(float position){
- ApplicationData.Display.Attenuation=position*0.01;
- }
-
- void spaceFrequencyChange(float position){
- ApplicationData.ColorMap.SpaceFrequency=position;
- }
-
- void timeFrequencyChange(float position){
- ApplicationData.ColorMap.TimeFrequency=position;
- }
-
- void periodChange(float position){
- ApplicationData.Time.PeriodLength=1000*position;
- }
-
- void elasticityChange(float position){
- ApplicationData.Time.Elasticity=position;
- }
-
- void minDegreeChange(int position){
- if (position>ApplicationData.Transformations.MaxDegree)
- ITrackBarMinDegree.Data.ITrackBar->Position=ApplicationData.Transformations.MaxDegree;
- else
- ApplicationData.Transformations.MinDegree=position;
- }
-
- void maxDegreeChange(int position){
- if (position<ApplicationData.Transformations.MinDegree)
- ITrackBarMaxDegree.Data.ITrackBar->Position=ApplicationData.Transformations.MaxDegree;
- else
- ApplicationData.Transformations.MaxDegree=position;
- }
-
- /*********************************************************************
- * MAIN PROGRAM *
- *********************************************************************/
-
- #ifdef SCREENSAVER
- int strcmpleft(char *s,char *t){
- while (*s && *s==*t){
- s++;
- t++;
- }
- return !*s;
- }
-
- int findstr(char *s,char *T[]){
- char *t;
- while (t=*(T++))
- if (strcmpleft(t,s))
- return 1;
- return 0;
- }
-
- int screenSaverMode(int argc,char *argv[]){
- char *sConfigureFlags[7]={"-C","/C","C","-c","/c","c",NULL},*sPreviewFlags[7]={"-P","/P","P","-p","/p","p",NULL};
- int i;
- for (i=1;i<argc;i++){
- if (findstr(argv[i],sConfigureFlags))
- return SCREENSAVER_MODE_CONFIGURE;
- if (findstr(argv[i],sPreviewFlags))
- return SCREENSAVER_MODE_PREVIEW;
- }
- return SCREENSAVER_MODE_SHOW;
- }
- #endif
-
- int main(int argc,char *argv[]){
- #ifdef SCREENSAVER
- switch(ApplicationData.Window.ScreenSaverMode=screenSaverMode(argc,argv)){
- case SCREENSAVER_MODE_CONFIGURE:
- MainMenu.Active=1;
- break;
- case SCREENSAVER_MODE_PREVIEW:
- return 0;
- }
- #endif
- srand(time(NULL));
- #ifdef USE_COS_TABLE
- initCos();
- #endif
- ApplicationData.MainMenu=&MainMenu;
- readIniFile();
- allocTransformation(&ApplicationData.Transformations.T1);
- allocTransformation(&ApplicationData.Transformations.T2);
- glutInit(&argc,argv);
- createWindow();
- printf("Entering main loop, press [Escape] for menu, use arrows to navigate.\n");
- glutMainLoop();
- return 0;
- }
#define USE_COS_TABLE
#define USE_TEXTURE
#define USE_MULTIPLE_TEXTURES
//#define SCREENSAVER
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "glut_import.h"
#include "menu.h"
/*********************************************************************
* CONSTANTS *
*********************************************************************/
#define FPS_COUNTER_TRIGGER 15
#define FPS_COUNTER_SMOOTH 0.3
#define PROXY_SIZE 32
#define PROXY_QUALITY 5
#define MIN_COLOR (10./256.)
#define MIN_POINT_COUNT 300
#define INI_FILENAME "AFC.ini"
#ifdef USE_MULTIPLE_TEXTURES
# ifndef USE_TEXTURE
# error You cannot specify USE_MULTIPLE_TEXTURES without specifying USE_TEXTURE
# endif
# define INVALID_TEXTURE_INDEX 0xFFFFFFFF
#endif
/*********************************************************************
* PLATFORM *
*********************************************************************/
#ifdef __WIN32__
# ifdef SCREENSAVER
# define SCREENSAVER_MODE_SHOW 0x1
# define SCREENSAVER_MODE_CONFIGURE 0x2
# define SCREENSAVER_MODE_PREVIEW 0x4
# define MAX_SCREENSAVER_MOUSE_OFFSET 10
# endif
# include <windows.h>
# define SLEEP(_DELAY) Sleep(_DELAY)
# define TIME_GRANULARITY 12
#else
# ifdef SCREENSAVER
# error Usage of SCREENSAVER reserved for Windows
# endif
# include <unistd.h>
# define SLEEP(_DELAY) usleep(1000*_DELAY)
# define TIME_GRANULARITY 6
#endif
/*********************************************************************
* COSINE TABLE SUPPORT *
*********************************************************************/
#ifdef USE_COS_TABLE
# define COS_TABLE_QUALITY 0x1000
float CosTable[COS_TABLE_QUALITY];
void initCos(void){
int i;
for (i=0;i<COS_TABLE_QUALITY;i++)
CosTable[i]=cos(PI*i/COS_TABLE_QUALITY);
}
float cosTable(float x){
int n;
if (x<0)
x=-x;
n=((int) roundf(COS_TABLE_QUALITY*x/PI)) % (2*COS_TABLE_QUALITY);
if (n<COS_TABLE_QUALITY)
return CosTable[n];
else
return CosTable[2*COS_TABLE_QUALITY-1-n];
}
# define COS(_X) cosTable((_X))
# define SIN(_X) cosTable((_X)-0.5*PI)
#else
# define COS(_X) cos((_X))
# define SIN(_X) sin((_X))
#endif
/*********************************************************************
* MACROS *
*********************************************************************/
#define ASSERT(_X,_S) if (!(_X)) {printf("%s\n",_S);exit(-1);}
#define MEMCHECK(_X) if (!(_X)) {printf("Memory allocation failed\n");exit(-1);}
/*********************************************************************
* TYPES *
*********************************************************************/
typedef struct{
int Count,Degree;
float *Matrix;
} transformation;
#ifdef USE_TEXTURE
typedef struct{
# ifdef USE_MULTIPLE_TEXTURES
unsigned int Index;
# endif
int ImageWidth,ImageHeight,Width,Height;
} texture;
#endif
#pragma pack(push,1)
#pragma pack(1)
typedef struct{
unsigned char R,G,B,A;
float X,Y,Z;
} point;
#pragma pack(pop)
/*********************************************************************
* APPLICATION DATA *
*********************************************************************/
struct {
struct {
int Index,Width,Height,FullScreen,DesiredFullScreen,DoubleBuffered,DesiredDoubleBuffered,MultiSample,DesiredMultiSample,ChangeMode;
#ifdef SCREENSAVER
int ScreenSaverMode,MouseX,MouseY;
#endif
#ifdef USE_TEXTURE
texture TextureMotion;
# ifdef USE_MULTIPLE_TEXTURES
texture TextureAccum;
# endif
#endif
} Window;
struct {
int Tick,PeriodStart,PeriodLength,TickTime;
float Elasticity,Map,FPS,DesiredFPS;
} Time;
struct {
transformation T1,T2;
int MinDegree,MaxDegree;
} Transformations;
struct {
int Count,DesiredCount,Rounded;
float Size;
point *Data;
} Points;
struct {
float Alpha,SpaceFrequency,TimeFrequency;
} ColorMap;
struct {
int BlendMethod,LimitCPUUsage,MotionBlur,Accumulation;
float Luminance,Sharpness,Attenuation;
} Display;
struct {
float Density;
char sFrame[64],sTime[64],sFPS[64],sPointCount[64],sDensity[64],sPointSize[64],sAlpha[64],sCycle[64],sAttractor1[64],sAttractor2[64];
} Statistics;
menu *MainMenu;
} ApplicationData={
{-1,1,1,0,0,1,1,0,0,0
#ifdef SCREENSAVER
,0,-1,-1
#endif
#ifdef USE_TEXTURE
# ifdef USE_MULTIPLE_TEXTURES
,{INVALID_TEXTURE_INDEX,0,0,0,0},{INVALID_TEXTURE_INDEX,0,0,0,0}
# else
,{0,0,0,0}
# endif
#endif
},
{0,0,5000,0,5,0,50,40},
{{0,0,NULL},{0,0,NULL},0,20},
{0,2*MIN_POINT_COUNT,1,1,NULL},
{0,1,1},
{0,0,0,0,1,1,0.1},
{0,"","","","","","","","","",""}
};
/*********************************************************************
* FUNCTIONS *
*********************************************************************/
void evolveWindow(void);
void evolveAlloc(void);
void evolveTime(void);
void evolvePoints(void);
void evolveProxy(void);
void evolveColorMap(void);
void evolve(void);
void displayFunc(void);
void reshapeFunc(int,int);
void idleFunc(void);
void keyboardFunc(unsigned char,int,int);
void specialFunc(int,int,int);
void mouseFunc(int,int,int,int);
#ifdef SCREENSAVER
void passiveMotionFunc(int,int);
#endif
void readIniFile(void);
void writeIniFile(void);
void fullScreenChange(int);
void fullScreenParamChange(int);
void doubleBufferedChange(int);
void multiSampleChange(int);
#ifdef USE_TEXTURE
void motionBlurChange(int);
#endif
void desiredFPSChange(int);
void limitCPUUsageChange(int);
void resetExecute(void);
void saveExecute(void);
void quitExecute(void);
void roundedPointsChange(int);
void blendMethodChange(int);
void luminanceChange(float);
void sharpnessChange(float);
void attenuationChange(float);
void spaceFrequencyChange(float);
void timeFrequencyChange(float);
void periodChange(float);
void elasticityChange(float);
void minDegreeChange(int);
void maxDegreeChange(int);
/*********************************************************************
* MENU DESIGN *
*********************************************************************/
SEPARATOR(Separator);
CHECKBOX(CheckBoxFullScreen,"Fullscreen (F)",0,fullScreenChange);
static char *ListBoxResolution_Items[6]={"default","320x240","640x480","800x600","1024x768","1280x1024"};
LISTBOX(ListBoxResolution,"Fullscreen resolution :",0,ListBoxResolution_Items,fullScreenParamChange);
static char *ListBoxBPP_Items[4]={"default","16","24","32"};
LISTBOX(ListBoxBPP,"Fullscreen color depth (BPP) :",0,ListBoxBPP_Items,fullScreenParamChange);
static char *ListBoxFrequency_Items[11]={"default","50","60","65","70","72","75","80","85","90","100"};
LISTBOX(ListBoxFrequency,"Fullscreen refresh rate (Hz) :",0,ListBoxFrequency_Items,fullScreenParamChange);
CHECKBOX(CheckBoxDoubleBuffered,"Double buffered (D)",1,doubleBufferedChange);
CHECKBOX(CheckBoxMultiSample,"Multi sample (M)",0,multiSampleChange);
#ifdef USE_TEXTURE
# ifdef USE_MULTIPLE_TEXTURES
static char *ListBoxMotionBlur_Items[7]={"Single buffer","Double buffer","Triple buffer (2x filter)",
"Triple buffer (3x filter)","Triple buffer (4x filter)","Triple buffer (5x filter)",
"Triple buffer (6x filter)"};
LISTBOX(ListBoxMotionBlur,"Motion blur",1,ListBoxMotionBlur_Items,motionBlurChange);
# else
CHECKBOX(CheckBoxMotionBlur,"High quality motion blur",1,motionBlurChange);
# endif
#endif
ITRACKBAR(FTrackBarDesiredFPS,"Requested frame rate: %d",5,120,40,1,desiredFPSChange);
CHECKBOX(CheckBoxLimitCPUUsage,"Limit CPU usage",0,limitCPUUsageChange);
#ifdef SCREENSAVER
STATICTEXT(StaticTextReset,"Reset settings (R)",1,resetExecute);
STATICTEXT(StaticTextSave,"Save settings and exit (S)",1,saveExecute);
STATICTEXT(StaticTextQuit,"Cancel (Q)",1,quitExecute);
# ifdef USE_TEXTURE
static menuitem *MenuPageAFC_Items[14]={
# else
static menuitem *MenuPageAFC_Items[13]={
# endif
#else
STATICTEXT(StaticTextSave,"Save settings (S)",1,saveExecute);
STATICTEXT(StaticTextReset,"Reset settings",1,resetExecute);
STATICTEXT(StaticTextQuit,"Quit (Q)",1,quitExecute);
# ifdef USE_TEXTURE
static menuitem *MenuPageAFC_Items[15]={
# else
static menuitem *MenuPageAFC_Items[14]={
# endif
#endif
&CheckBoxFullScreen,
&ListBoxResolution,
&ListBoxBPP,
&ListBoxFrequency,
&Separator,
&CheckBoxDoubleBuffered,
&CheckBoxMultiSample,
#ifdef USE_TEXTURE
# ifdef USE_MULTIPLE_TEXTURES
&ListBoxMotionBlur,
# else
&CheckBoxMotionBlur,
# endif
#endif
&FTrackBarDesiredFPS,
&CheckBoxLimitCPUUsage,
&Separator,
#ifdef SCREENSAVER
&StaticTextReset,
&StaticTextSave,
&StaticTextQuit
#else
&StaticTextSave,
&StaticTextReset,
&Separator,
&StaticTextQuit
#endif
};
MENUPAGE(MenuPageAFC,"AFC Version 1.0",MenuPageAFC_Items);
CHECKBOX(CheckBoxRoundedPoints,"Rounded points",1,roundedPointsChange);
static char *ListBoxBlendMethod_Items[3]={"Logarithmic","Linear","Maximum"};
LISTBOX(ListBoxBlendMethod,"Blend color method :",0,ListBoxBlendMethod_Items,blendMethodChange);
FTRACKBAR(FTrackBarLuminance,"Luminance : %.0f%%",0,200,100,1,luminanceChange);
FTRACKBAR(FTrackBarSharpness,"Sharpness : %.0f%%",0,200,100,1,sharpnessChange);
FTRACKBAR(FTrackBarAttenuation,"Attenuation : %.1f%%",0.1,100,10,0.1,attenuationChange);
FTRACKBAR(FTrackBarSpaceFrequency,"Colormap space frequency : %.2f",0,50,1,0.02,spaceFrequencyChange);
FTRACKBAR(FTrackBarTimeFrequency,"Colormap time frequency : %.2f",0,20,1,0.02,timeFrequencyChange);
static menuitem *MenuPageDisplay_Items[9]={
&CheckBoxRoundedPoints,
&ListBoxBlendMethod,
&Separator,
&FTrackBarLuminance,
&FTrackBarSharpness,
&FTrackBarAttenuation,
&Separator,
&FTrackBarSpaceFrequency,
&FTrackBarTimeFrequency
};
MENUPAGE(MenuPageDisplay,"DISPLAY",MenuPageDisplay_Items);
FTRACKBAR(FTrackBarPeriod,"Cycle length : %.1f sec",0.5,20,5,0.1,periodChange);
FTRACKBAR(FTrackBarElasticity,"Cycle elasticity : %.1f",0.1,30,5,0.1,elasticityChange);
ITRACKBAR(ITrackBarMinDegree,"Min attractor degree : %d",3,15,6,1,minDegreeChange);
ITRACKBAR(ITrackBarMaxDegree,"Max attractor degree : %d",3,15,6,1,maxDegreeChange);
static menuitem *MenuPageAttractor_Items[4]={&FTrackBarPeriod,&FTrackBarElasticity,&ITrackBarMinDegree,&ITrackBarMaxDegree};
MENUPAGE(MenuPageAttractor,"ATTRACTOR",MenuPageAttractor_Items);
STATICTEXT(StaticTextFrame,ApplicationData.Statistics.sFrame,0,NULL);
STATICTEXT(StaticTextTime,ApplicationData.Statistics.sTime,0,NULL);
STATICTEXT(StaticTextFPS,ApplicationData.Statistics.sFPS,0,NULL);
STATICTEXT(StaticTextPointCount,ApplicationData.Statistics.sPointCount,0,NULL);
STATICTEXT(StaticTextDensity,ApplicationData.Statistics.sDensity,0,NULL);
STATICTEXT(StaticTextPointSize,ApplicationData.Statistics.sPointSize,0,NULL);
STATICTEXT(StaticTextAlpha,ApplicationData.Statistics.sAlpha,0,NULL);
STATICTEXT(StaticTextCycle,ApplicationData.Statistics.sCycle,0,NULL);
STATICTEXT(StaticTextAttractor1,ApplicationData.Statistics.sAttractor1,0,NULL);
STATICTEXT(StaticTextAttractor2,ApplicationData.Statistics.sAttractor2,0,NULL);
static menuitem *MenuPageStatistics_Items[12]={
&StaticTextFrame,
&StaticTextTime,
&StaticTextFPS,
&Separator,
&StaticTextPointCount,
&StaticTextDensity,
&StaticTextPointSize,
&StaticTextAlpha,
&Separator,
&StaticTextCycle,
&StaticTextAttractor1,
&StaticTextAttractor2
};
MENUPAGE(MenuPageStatistics," STATISTICS ",MenuPageStatistics_ |