PDA

View Full Version : How to Stop a function in OpenGL and restart it again ? code in C



mimibibi
01-27-2016, 02:03 AM
Hello, I have a very fixer upper, dodgy, program that draws a 2D polygon with the mouse, everytime you click you add a new vertex to the polygon and so on...
bare with me cause i'm new at this.
what I would like to do is, if I press H on keyboard for example, to stop adding vertices to that polygon and start drawing a new one using the same function, how do I do that ?
Keep in mind that my program was originally for a hole other purpose and I just modified it to draw the darn polygon.
Would you help me please ? thanks !

/* Includes OpenGL */
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#endif


/* Includes standards */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>


/* Include de la bibliotheque d'algebre */
#include <ml.h>


/* Defines d'informations */
#define TP_TITLE "[TP01] Modelisation Geometrique - Courbes hermitiennes cubiques"
#define TP_GROUP ""
#define TP_PROMO "2010-2011"
void usage();


/* Taille de la fenetre */
int winX = 800;
int winY = 600;
int fill, Oo =0 ;


/* Nombre maximum de points de controle */
#define MAX_CTRL_POINTS 200


/* Structure d'une courbe hermitienne */
typedef struct _hermiteCurve {

/* Tableau de points de controle et nombre de points inseres */
mlVec3 controlPoints[MAX_CTRL_POINTS];
int nControlPoints;

/* Resolution d'echantillonnage de la courbe */
int resolution;
} hermiteCurve;


/* Courbe affichee a l'ecran */
hermiteCurve * hCurve;




/* Options d'affichage */
int optionDisplayPoints;
int optionDisplayPolygon;
int optionDisplayVectors;
int optionDisplayCoords;


/* Variables pour l'edition de la courbe */
int pointWindowSelection;
int idButtonPressed;
int idPointSelection;
int idPointDeletion;
int idPointHover;
int idPointInsertion;


/* Fonction pour afficher du texte en OpenGL */
void glPrintText(int _x, int _y, const char * _text)
{
int i;

glRasterPos2i(_x, _y);

for(i = 0; i < (int)strlen(_text); ++i)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, _text[i]);
}


/* Fonction pour rechercher un point aux coordonnees (x +/- p, y +/- p) */
int findPoints(mlVec3 * _points, int _nPoints, int _x, int _y, int _p)
{
int i;

for(i = 0; i < _nPoints; ++i)
{
if(fabs(_points[i][0] - _x) < _p && fabs(_points[i][1] - _y) < _p)
return i;
}

return -1;
}





void aff()
{
int i;

char buffer[32];
glPointSize(3.0);

if(optionDisplayPoints == 1)
{
if(idPointHover != -1)
{
glColor3ub(220, 220, 220);
glPointSize(pointWindowSelection * 2 + 6);

glBegin(GL_POINTS);
glVertex3dv(hCurve->controlPoints[idPointHover]);
glEnd();
}

if(idPointInsertion != -1)
{
glColor3ub(220, 220, 100);
glPointSize(pointWindowSelection * 2 + 6);

glBegin(GL_POINTS);
glVertex3dv(hCurve->controlPoints[idPointInsertion]);
glEnd();
}

glColor3ub(175, 125, 125);
glPointSize(pointWindowSelection * 2);

glBegin(GL_POINTS);
for(i = 0; i < hCurve->nControlPoints; ++i)
glVertex3dv(hCurve->controlPoints[i]);
glEnd();

if(idPointSelection != -1)
{
glColor3ub(225, 125, 125);
glBegin(GL_POINTS);
glVertex3dv(hCurve->controlPoints[idPointSelection]);
glEnd();
}

if (fill == 1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if (fill == 2) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
if (fill == 3) glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);

glBegin (GL_POLYGON);
for (i = 0; i < hCurve->nControlPoints-3; ++i)
{
glVertex3dv (hCurve->controlPoints[i]);
glVertex3dv (hCurve->controlPoints[i+1]);
glVertex3dv (hCurve->controlPoints[i+2]);
glVertex3dv (hCurve->controlPoints[i+3]);

}
glEnd ();
}

if(optionDisplayCoords == 1)
{
glColor3ub(100, 100, 100);
for(i = 0; i < hCurve->nControlPoints; ++i)
{
sprintf(buffer, "[%02d] (%3d, %3d)", i, (int)hCurve->controlPoints[i][0], (int)hCurve->controlPoints[i][1]);
glPrintText((int)hCurve->controlPoints[i][0], (int)hCurve->controlPoints[i][1] + pointWindowSelection + 6, buffer);
}
glEnd();
}



/* ************************************************** ************************ */






glutSwapBuffers();


}




/* Callback OpenGL d'affichage */
void displayGL()
{


/*char buffer[32];*/

glClear(GL_COLOR_BUFFER_BIT);

aff() ;


glutSwapBuffers();






}


/* Callback OpenGL de redimensionnement */
void reshapeGL(int _w, int _h)
{
winX = _w;
winY = _h;

glViewport(0, 0, winX, winY);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluOrtho2D(0.0, winX, 0.0, winY);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glutPostRedisplay();
}


/* Callback OpenGL de gestion de souris */
void mouseGL(int _button, int _state, int _x, int _y)
{
int i;

idButtonPressed = _state == GLUT_DOWN ? _button : -1;
idPointSelection = -1;
idPointHover = -1;

_y = winY - _y;

if(optionDisplayPoints == 1)
{
if(_button == GLUT_LEFT_BUTTON)
{
idPointSelection = idPointHover = findPoints(hCurve->controlPoints, hCurve->nControlPoints, _x, _y, pointWindowSelection);

if(_state == GLUT_DOWN)
{
if(idPointSelection == -1 && hCurve->nControlPoints < MAX_CTRL_POINTS - 2)
{
if(idPointInsertion != -1)
{
for(i = hCurve->nControlPoints; i >= idPointInsertion; --i)
mlVec3_Copy(hCurve->controlPoints[i], hCurve->controlPoints[i - 1]);

mlVec3_Set(hCurve->controlPoints[idPointInsertion++], _x, _y, 0.0);
idPointSelection = idPointHover = idPointInsertion - 1;
hCurve->nControlPoints++;
}
else
{
mlVec3_Set(hCurve->controlPoints[hCurve->nControlPoints++], _x, _y, 0.0);
idPointSelection = idPointHover = hCurve->nControlPoints - 1;
}


}
}
else
{
idPointSelection = -1;
}
}

if(_button == GLUT_RIGHT_BUTTON)
{
idPointDeletion = findPoints(hCurve->controlPoints, hCurve->nControlPoints, _x, _y, pointWindowSelection);

if(idPointDeletion != -1 && _state == GLUT_UP)
{
for(i = idPointDeletion; i < hCurve->nControlPoints - 1; ++i)
mlVec3_Copy(hCurve->controlPoints[i], hCurve->controlPoints[i + 1]);

--hCurve->nControlPoints;

if(idPointDeletion == idPointInsertion)
idPointInsertion = -1;

idPointDeletion = -1;

}
}

if(_button == GLUT_MIDDLE_BUTTON)
{
if(_state == GLUT_UP)
idPointInsertion = findPoints(hCurve->controlPoints, hCurve->nControlPoints, _x, _y, pointWindowSelection);
}
}




glutPostRedisplay();
}


/* Callback OpenGL de gestion de clavier */
void keyboardGL(unsigned char _k, int _x, int _y)
{
if(_k == 27 || _k == 'q' || _k == 'Q')
exit(0);

if(_k == 'h' || _k == 'H')
usage();

if(_k == 'e' || _k == 'e')
{
hCurve->nControlPoints = 0;
idButtonPressed = -1;
idPointSelection = -1;
idPointDeletion = -1;
idPointHover = -1;
idPointInsertion = -1;


}
if(_k == '1')
{
/* changement du mode de rendu : plein */

fill=1 ;
}

if(_k == '2')
{
/* changement du mode de rendu : fil de fer */

fill=2 ;
}

if(_k == '3')
{
/* changement du mode de rendu : points */

fill=3 ;
}



if(_k == 'c' || _k == 'C')
optionDisplayCoords = !optionDisplayCoords;

if(_k == '+')
{
Oo=1;
}

if(_k == '-')
{

}

glutPostRedisplay();
}


/* Callback OpenGL de gestion des touches speciales de claviers */
void keyboardSpecialGL(int _k, int _x, int _y)
{
glutPostRedisplay();
}


/* Callback OpenGL de gestion de drag */
void motionGL(int _x, int _y)
{
_y = winY - _y;

if(idButtonPressed == GLUT_LEFT_BUTTON && idPointSelection != -1)
{
mlVec3_Set(hCurve->controlPoints[idPointSelection], _x, _y, 0.0);

}

glutPostRedisplay();
}


/* Callback OpenGL de gestion de survol */
void passiveMotionGL(int _x, int _y)
{
_y = winY - _y;

idPointHover = findPoints(hCurve->controlPoints, hCurve->nControlPoints, _x, _y, pointWindowSelection);

glutPostRedisplay();
}


/* Fonction d'initialisation des variables */
void init()
{
hCurve = (hermiteCurve *)malloc(sizeof(hermiteCurve));
hCurve->nControlPoints = 0;
hCurve->resolution = 200;

optionDisplayPoints = 1;
optionDisplayVectors = 0;
optionDisplayCoords = 0;

pointWindowSelection = 4;
idButtonPressed = -1;
idPointSelection = -1;
idPointDeletion = -1;
idPointHover = -1;
idPointInsertion = -1;


}


/* Fonction d'initialisation OpenGL */
void initGL()
{
glClearColor(0.8, 0.8, 0.7, 1.0);
}


/* Fonction d'affichage du manuel */
void usage()
{
printf("---------------------------------------------------------------------------\n");
printf("%c[%dm", 27, 1);
printf("%s\n", TP_TITLE);
printf("%c[%dm", 27, 0);
printf("%s (%s)\n", TP_GROUP, TP_PROMO);
printf("\n\n");

printf("%c[%dm", 27, 1);
printf("[Utilisation]\n");
printf("%c[%dm", 27, 0);
printf(" ./tp01\n");
printf("\n\n");

printf("%c[%dm", 27, 1);
printf("[Manuel]\n");
printf("%c[%dm", 27, 0);
printf(" Clic gauche :\t ajouter/deplacer un point de controle\n");
printf(" Clic droit :\t supprimer un point de controle\n");
printf(" Clic milieu :\t definir l'indice d'insertion des points de controle\n\n");
printf(" 'e' :\t supprimer tous les points de controle\n");
printf(" '+'/'-' :\t augmenter/diminuer le nombre de points d'echantillonnage\n");
printf(" 'c' :\t afficher/masquer les coordonnees des points de controle\n");
printf(" 'q'/Esc :\t quitter\n");
printf("---------------------------------------------------------------------------\n");
}


/* Fonction principale */
int main(int _argc, char ** _argv)
{
int posX, posY;

glutInit(&_argc, _argv);
usage();

posX = (glutGet(GLUT_SCREEN_WIDTH ) - winX) / 2;
posY = (glutGet(GLUT_SCREEN_HEIGHT) - winY) / 2;

glutInitWindowSize(winX, winY);
glutInitWindowPosition(posX, posY);

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow(TP_TITLE);

glutDisplayFunc(displayGL);
glutReshapeFunc(reshapeGL);

glutMouseFunc(mouseGL);
glutKeyboardFunc(keyboardGL);
glutSpecialFunc(keyboardSpecialGL);

glutMotionFunc(motionGL);
glutPassiveMotionFunc(passiveMotionGL);

init();
initGL();
glutMainLoop();

return 0;
}

GClements
01-27-2016, 04:59 AM
what I would like to do is, if I press H on keyboard for example, to stop adding vertices to that polygon and start drawing a new one using the same function, how do I do that ?

Rather than allocating a single hermiteCurve structure, you'd allocate an array of them and keep track of how many were used (much like you currently keep track of how many vertices are used). Each new vertex is added to the current polygon. Pressing H would advance to the next polygon (setting the number of vertices to zero). For rendering, you'd render all of the polygons in a loop.