#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
/* colori possibili a scelta dal menu */
GLfloat colors [] = {
0.1f, 0.0f, 0.0f, /*red*/
0.0f, 0.1f, 0.0f, /*green*/
0.0f, 0.0f, 0.1f, /*blue*/
0.255f, 0.255f, 0.0f, /*yellow*/
0.160f, 0.160f, 0.160f, /*gray*/
0.255f, 0.192f, 0.192f/*pink*/
};
/* indice display list*/
GLuint listIndex;
GLsizei wh = 500, ww = 500;
int i;
/* coordinate (x, y) angolo in alto a sinistra del rettangolo */
int first_x, first_y;
/* coordinate (x', y') angolo in basso a destra del rettangolo */
int last_x, last_y;
/* variazioni di (x', y') rispetto a (x, y) */
int dx, dy;
/* id selezionato dal menu */
int idColor;
void init() {
idColor = 0;
dx = dy = first_x = first_y = last_x = last_y = 0;
glViewport(0, 0, ww, wh);
glClearColor(0.0, 0.0, 0.0, 1.0);
//glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) ww, 0.0, (GLdouble) wh);
glMatrixMode(GL_MODELVIEW);
}
/*
* disegna il rettangolo in fase di motion del mouse
*/
void drawSquare(int x0, int y0, int x1, int y1) {
y0 = wh - y0;
y1 = wh - y1;
//calcolo variazione infinitesima rispetto alle
//coortėdinate di partenza
dx = x1 - x0;
dy = y1 - y0;
glColor3fv(&colors[idColor]);
glBegin(GL_QUADS);
glVertex2f(x0, y0);
glVertex2f(x0 + dx, y0);
glVertex2f(x1, y1);
glVertex2f(x0, y0 + dy);
glEnd();
glFlush();
}
/*
* premendo il tasto 'q' dalla tastiera calcella le display list
* e termina il programma
*/
void keyboard(unsigned char key, int x, int y) {
if (key == 'q') {
glDeleteLists(1, listIndex);
exit(0);
}
}
/*
* repaint del rettangolo fino a quando non viene
* rilasciato il tasto sinistro del mouse
*/
void motion(int x, int y) {
glutPostRedisplay();
drawSquare(first_x, first_y, x, y);
}
/*
*
*/
void mouse(int button, int state, int x, int y) {
/*
* se viene premito il pulsante sinistro del mouse
* memorizzo le coordinate ovvero le coordinate del vertice
* il alto a sinistra del rettangolo
*/
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
//printf("FIRST (%d, %d)\n", x, y);
first_x = x;
first_y = y;
}
/*
* .. dopo aver trascinato il mouse avendo tenuto premuto il pulsante
* sinistro e avendo rilasciato tale pulsante ..
*/
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
//printf("LAST (%d, %d)\n", x, y);
last_x = x;
last_y = y;
/*
* ..salvo la serie di comandi per disegnare il rettangolo il una
* display list, evitando cosi evitando il trasferimento dei dati (immediate mode)
*/
glShadeModel(GL_SMOOTH);
listIndex = glGenLists(1);
glNewList(listIndex, GL_COMPILE_AND_EXECUTE);
first_y = wh - first_y;
last_y = wh - last_y;
dx = last_x - first_x;
dy = last_y - first_y;
glColor3fv(&colors[idColor]);
glBegin(GL_QUADS);
glVertex2f(first_x, first_y);
glVertex2f(first_x + dx, first_y);
glVertex2f(last_x, last_y);
glVertex2f(first_x, first_y + dy);
glEnd();
glEndList();
}
}
void reshape(GLsizei w, GLsizei h) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, w, h);
ww = w;
wh = h;
}
/*
* tiene traccia del colore scelto dal menu
*/
void menu(int id) {
idColor = id - 1;
}
void display() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
for (i = 1; i <= listIndex; i++) {
glCallList(i);
}
}
int main(int argc, const char * argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(ww, wh);
glutInitWindowPosition(0, 0);
glutCreateWindow("paint");
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutCreateMenu(menu);
glutAddMenuEntry("red", 1);
glutAddMenuEntry("green", 2);
glutAddMenuEntry("blue", 3);
glutAddMenuEntry("yellow", 4);
glutAddMenuEntry("gray", 5);
glutAddMenuEntry("pink", 6);
glutAttachMenu(GLUT_RIGHT_BUTTON);
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}