codice:
#include <GL/glut.h> //include automaticamente gl.h e glu.h
static int width,height;
static int startX, startY; //Queste due le uso per salvare la
//posizione del mouse quando è
//premuto. Questo mi permette di calcolare
//gli incrementi di spostamento ogni volta
//che mi muovo (ovvero ad ogni nuova
//chiamata della callback di movimento
//ATTIVO)
static bool left, right, middle; //Questi tre booleani li uso per
//memorizzare lo stato dei bottoni
//del mouse. Quando uno di questi è a
//true, significa che il tasto è
//premuto. Se è a false il tasto NON
//è premuto.
// Queste variabili rappresentano gli angoli di rotazione e la
// distanza dell'oggetto in profondità rispetto allo zero del sistema
// "world". Vengono aggiornati durante le callback del mouse e poi
// utilizzati ad ogni chiamata di callback di rendering.
static GLfloat distance, xrot, yrot, zrot;
void reshape (int w, int h)
{
width=w;
height=h;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
// estendo la viewport a tutta la finestra
glViewport(0, 0, width, height);
// proiezione prospettica
GLdouble ratio = static_cast<GLdouble>(width) / static_cast<GLdouble>(height);
gluPerspective(45, //angolo di visuale
ratio, //aspect ratio (rapporto tra larghezza e altezza)
1, //Z near cutting plane
1000); //Z far cutting plane
}
void idle(void)
{
glutPostRedisplay(); //forzo il redrawing nei momenti di idle
}
void initGL (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
distance=10;
xrot=yrot=zrot=0;
}
void renderScene(void) {
glEnable(GL_DEPTH_TEST);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
GLfloat mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat mat_shininess[] = { 0.0 };
//LUCI
glEnable(GL_LIGHTING);
GLfloat light1_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light1_position[] = { 0.5,3, 0, 1 };
GLfloat spot_direction[] = { 0,-1,0};
//GLfloat light0_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
//GLfloat light0_position[] = { 10.0, 10.0, 10.0, 0.0 };
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.5);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.2);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 30.0);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 20.0);
glEnable(GL_LIGHT1);
//luce ambientale, per ora disattivata
//glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
//glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
//glEnable(GL_LIGHT0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -distance);
glRotatef(-zrot, 0.0, 0.0, 1.0);
glRotatef(-xrot, 1.0, 0.0, 0.0);
glRotatef(yrot, 0.0, 1.0, 0.0);
glViewport (0, 0, static_cast<GLsizei> (width) , static_cast<GLsizei> (height));
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glColor3f(1,1,0);
glBegin(GL_POLYGON); //palo
glNormal3f(0,0,-0.6);
glVertex3f (-0.5, 0, 0.1);
glVertex3f (-0.3, 0, 0.1);
glVertex3f (-0.3, 3, 0.1);
glVertex3f (-0.5, 3, 0.1);
glEnd();
glBegin(GL_POLYGON);
glNormal3f(-0.6,0,0);
glVertex3f (-0.3, 0, 0.1);
glVertex3f (-0.3, 0, -0.1);
glVertex3f (-0.3, 3, -0.1);
glVertex3f (-0.3, 3, 0.1);
glEnd();
glBegin(GL_POLYGON);
glNormal3f(0,0,0.6);
glVertex3f (-0.5, 0, -0.1);
glVertex3f (-0.3, 0, -0.1);
glVertex3f (-0.3, 3, -0.1);
glVertex3f (-0.5, 3, -0.1);
glEnd();
glBegin(GL_POLYGON);
glNormal3f(0.6,0,0);
glVertex3f (-0.5, 0, -0.1);
glVertex3f (-0.5, 0, 0.1);
glVertex3f (-0.5, 3, 0.1);
glVertex3f (-0.5, 3, -0.1);
glEnd();
glBegin(GL_POLYGON); //braccio
glNormal3f(0,0,0.225);
glVertex3f (-0.5, 3, 0.1);
glVertex3f (0.5, 3, 0.1);
glVertex3f (0.5, 3.225, 0.1);
glVertex3f (-0.5, 3.225, 0.1);
glEnd();
glBegin(GL_POLYGON);
glNormal3f(0.045,0,0);
glVertex3f (0.5, 3, 0.1);
glVertex3f (0.5, 3, -0.1);
glVertex3f (0.5, 3.225, -0.1);
glVertex3f (0.5, 3.225, 0.1);
glEnd();
glBegin(GL_POLYGON);
glNormal3f(0,0,0.225);
glVertex3f (-0.5, 3, -0.1);
glVertex3f (0.5, 3, -0.1);
glVertex3f (0.5, 3.225, -0.1);
glVertex3f (-0.5, 3.225, -0.1);
glEnd();
glBegin(GL_POLYGON);
glNormal3f(-0.045,0,0);
glVertex3f (-0.5, 3, 0.1);
glVertex3f (-0.5, 3.225, 0.1);
glVertex3f (-0.5, 3.225, -0.1);
glVertex3f (-0.5, 3, -0.1);
glEnd();
glBegin(GL_POLYGON); //sotto
glNormal3f(0,0.2,0);
glVertex3f (-0.5, 3, 0.1);
glVertex3f (0.5, 3, 0.1);
glVertex3f (0.5, 3, -0.1);
glVertex3f (-0.5, 3, -0.1);
glEnd();
glBegin(GL_POLYGON); //sopra
glNormal3f(0,0.2,0);
glVertex3f (-0.5, 3.225, 0.1);
glVertex3f (0.5, 3.225, 0.1);
glVertex3f (0.5, 3.225, -0.1);
glVertex3f (-0.5, 3.225, -0.1);
glEnd();
glColor3f(1,0,0);
glBegin(GL_POLYGON); //piano
glNormal3f(0,1,0);
glVertex3f (-2, 0, 2);
glVertex3f (2, 0, 2);
glVertex3f (2, 0, -2);
glVertex3f (-2, 0, -2);
glEnd();
glFlush();
glutSwapBuffers();
}
void processMouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
startX=x;
startY=y;
if (button == GLUT_LEFT_BUTTON) left=true;
else if (button == GLUT_RIGHT_BUTTON) right=true;
else if (button == GLUT_MIDDLE_BUTTON) middle=true;
}
if (state == GLUT_UP)
{
if (button == GLUT_LEFT_BUTTON) left=false;
else if (button == GLUT_RIGHT_BUTTON) right=false;
else if (button == GLUT_MIDDLE_BUTTON) middle=false;
}
}
void processMouseActiveMotion(int x, int y)
{
if (left)
{
xrot += y-startY;
yrot += x-startX;
}
if (right)
{
distance += y-startY;
if (distance < 1)
distance = 1;
}
if (middle)
{
zrot += x-startX;
}
startX=x;
startY=y;
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("Lampione");
glutMouseFunc(processMouse); //handler per i click
glutMotionFunc(processMouseActiveMotion); //handler per i movimenti "attivi" del mouse
initGL();
glutDisplayFunc(renderScene);
glutReshapeFunc(reshape);
glutIdleFunc(idle); //idle (per forzare il redraw della scena)
glutMainLoop();
return 0;
}
Buona parte del codice l'ho presa da slides e materiale on line, perchè non sono ferratissimo su openGL ^^