IEM2_BOUWMANS_TP1/main.c

294 lines
5.8 KiB
C

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
void afficher(void);
int initWindow(int, char**, void(*)(void));
void destroyWindow(int);
long getFileSize(FILE*);
void parseFile(char*, long);
bool charger(char*);
void printCourbeTerminal(void);
void ligne(int, float, float, float, float);
float map(float, float, float, float, float);
void reshapeCallback(int, int);
void axes(float, float, float, float);
// Variables donneés
#define MAXC 20
#define MAXV 100
float courbe[MAXC][MAXV];
float valmin[MAXC];
float valmax[MAXC];
int nc = 0;
// Defines
#define HORIZONTAL 0
#define VERTICAL 1
#define SUPERPOSER 2
// Variables globales
int vx1 = 0, vx2 = 400, vy1 = 0, vy2 = 400;
int mode_affichage = HORIZONTAL;
float map(float smin, float smax, float val, float omin, float omax)
{
float percent = (val - smin) / (smax - smin);
//printf("v%f, p%f, min%f, max%f\n", val, percent, omin, omax);
return (omax-omin) * percent + omin;
}
void axes(float x1, float x2, float y1, float y2)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
glColor3f(1.0,0.5,0.5);
glBegin(GL_LINE_STRIP);
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glEnd();
}
void ligne(int index, float hgx, float hgy, float bdx, float bdy)
{
if(index >= nc)
{
printf("Courbe non-existante.");
return;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINE_STRIP);
unsigned int size = (unsigned int)courbe[index][0];
for(unsigned int i = 1; i < size+1; i++)
{
float pos_x = map(0, size-1, i-1, hgx, bdx);
float pos_y = map(valmin[index], valmax[index], courbe[index][i], bdy, hgy);
//printf("%d : {%f, %f}\n", i, pos_x, pos_y);
if(mode_affichage == VERTICAL)
{
float temp = pos_x;
pos_x = pos_y;
pos_y = temp;
}
glVertex2f(pos_x, pos_y);
}
fflush(stdout);
glEnd();
for(unsigned int i = 1; i < size+1; i++)
{
float pos_x = map(0, size-1, i-1, hgx, bdx);
float pos_y = map(valmin[index], valmax[index], courbe[index][i], bdy, hgy);
if(mode_affichage == VERTICAL)
{
axes(bdy, pos_y, hgx, pos_x);
}else{
axes(hgx, pos_x, bdy, pos_y);
}
}
}
void afficher(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
if(mode_affichage == HORIZONTAL)
{
for(unsigned int i = 1; i < nc+1; i++)
{
float haut = map(0, nc, i-1, 1.0, -1.0);
float bas = map(0, nc, i, 1.0, -1.0);
ligne(i-1, -1.0, haut, 1.0, bas);
}
}
if(mode_affichage == VERTICAL)
{
for(unsigned int i = 1; i < nc+1; i++)
{
float gauche = map(0, nc, i-1, -1.0, 1.0);
float droite = map(0, nc, i, -1.0, 1.0);
ligne(i-1, -1.0, gauche, 1.0, droite);
}
}
if(mode_affichage == SUPERPOSER)
{
for(unsigned int i = 1; i < nc+1; i++)
{
ligne(i-1, -1.0, 1.0, 1.0, -1.0);
}
}
glFlush();
}
void reshapeCallback(int largeur, int hauteur)
{
vx2 = largeur;
vy2 = hauteur;
glViewport(0, 0, largeur, hauteur);
//glutPostRedisplay();
printf("Reshape : [%d, %d]\n", vx2, vy2);
}
int initWindow(int argc, char* argv[], void(*display)(void))
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA);
glutInitWindowPosition(vx1, vy1);
glutInitWindowSize(vx2, vy2);
int window = glutCreateWindow("TP1");
glutDisplayFunc(display);
glutReshapeFunc(reshapeCallback);
return window;
}
void destroyWindow(int window)
{
glutDestroyWindow(window);
}
long getFileSize(FILE* file)
{
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
rewind(file);
return fileSize;
}
void parseFile(char* file, long size)
{
nc = atoi(file);
printf("nc=%d\n", nc);
//printf("====\n%s\n====\n", file);
// Pointeur mobile dans le fichier
char* pointeur = file;
unsigned int line = 0;
while(line < nc)
{
/* Cherche le premier \n à partir du pointeur
* /!\ on suppose un fichier encodé en UNIX (LF) /!\ */
pointeur = strchr(pointeur, '\n') + 1;
//printf(" ->\"%c\"", *pointeur);
int taille_tableau = atoi(pointeur);
courbe[line][0] = taille_tableau;
//printf(" ->\"%d\" \n", taille_tableau);
// On suppose que les nombres sont séparés par un espace
for(unsigned int i = 1; i < taille_tableau+1; i++)
{
pointeur = strchr(pointeur, ' ') + 1;
float num = strtof(pointeur, 0);
courbe[line][i] = num;
if(i == 1)
{
valmin[line] = num;
valmax[line] = num;
}else{
if(num < valmin[line])
valmin[line] = num;
if(num > valmax[line])
valmax[line] = num;
}
}
line++;
}
}
bool charger(char* nom)
{
FILE* file = fopen(nom, "r");
if(file == NULL)
{
printf("Erreur ouverture fichier.\n");
return false;
}
long fileSize = getFileSize(file);
char* buffer = (char*)malloc(sizeof(char) * fileSize + 1);
if(buffer == NULL)
{
printf("Erreur allocation mémoire.\n");
return false;
}
buffer[fileSize] = 0; // NULL à la fin du fichier
int res = fread(buffer, sizeof(char), fileSize, file);
if(res == 0)
{
printf("Erreur lecture fichier.\n");
return false;
}
fclose(file);
parseFile(buffer, fileSize);
free(buffer);
return true;
}
void printCourbeTerminal(void)
{
for(unsigned int i = 0; i < nc; i++)
{
for(unsigned int j = 0; j < courbe[i][0]+1; j++)
{
printf("%f", courbe[i][j]);
if(j < courbe[i][0])
printf(", ");
}
printf("\n");
}
}
int main(int argc, char* argv[])
{
if(!charger("valeurs.txt"))
return EXIT_FAILURE;
printCourbeTerminal();
mode_affichage = SUPERPOSER;
int window = initWindow(argc, argv, afficher);
glutMainLoop();
destroyWindow(window);
return EXIT_SUCCESS;
}