TP-rendu/TP4/lumiere.c
2023-06-22 20:30:57 +02:00

384 lines
9.4 KiB
C

/*
* lumiere.c
*
* OpenGL light
*/
#include <stdlib.h>
#include <stdio.h>
// for mac osx
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
// only for windows
#ifdef _WIN32
#include <windows.h>
#endif
// for windows and linux
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/freeglut.h>
#endif
int angle_x = 45, angle_y = -45;
float distance = 8.f;
float shininess = 25.f;
int directional = 0;
int infinite_view = 0;
// the room: it's a cube with inverted normals, ie pointing inwards
void glRoom(GLfloat size)
{
GLfloat v = size / 2;
glBegin(GL_QUADS);
glNormal3f(0, 0, 1);
glVertex3f(-v, -v, -v);
glVertex3f(v, -v, -v);
glVertex3f(v, v, -v);
glVertex3f(-v, v, -v);
glNormal3f(0, 0, -1);
glVertex3f(v, -v, v);
glVertex3f(-v, -v, v);
glVertex3f(-v, v, v);
glVertex3f(v, v, v);
glNormal3f(-1, 0, 0);
glVertex3f(v, -v, -v);
glVertex3f(v, -v, v);
glVertex3f(v, v, v);
glVertex3f(v, v, -v);
glNormal3f(1, 0, 0);
glVertex3f(-v, -v, v);
glVertex3f(-v, -v, -v);
glVertex3f(-v, v, -v);
glVertex3f(-v, v, v);
glNormal3f(0, -1, 0);
glVertex3f(-v, v, -v);
glVertex3f(v, v, -v);
glVertex3f(v, v, v);
glVertex3f(-v, v, v);
glNormal3f(0, 1, 0);
glVertex3f(-v, -v, -v);
glVertex3f(-v, -v, v);
glVertex3f(v, -v, v);
glVertex3f(v, -v, -v);
glEnd();
}
// place the camera, make the scene turn around the scene origin
void place_camera()
{
glTranslatef(0.f, 0.f, -distance);
glRotatef(angle_x, 1.f, 0.f, 0.f);
glRotatef(angle_y, 0.f, 1.f, 0.f);
}
// place the light in x,y,z
void place_light(GLfloat x, GLfloat y, GLfloat z)
{
//**********************************
// set the light components: ambient (0.2 grey),
// diffuse and specular (both white)
//**********************************
GLfloat light_ambient[] = {0.2, 0.2, 0.2, 1.0}; // the ambient component
// GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0}; // the diffuse component
// GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0}; // the specular component
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
// glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
// glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
//**********************************
// set the light position (directional or positional)
//**********************************
GLfloat light_position[] = {x, y, z, directional}; // the light position
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
//**********************************
// draw a yellow point to visually represent the light
//**********************************
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glPushMatrix();
glColor3f(1, 1, 0);
glTranslatef(x, y, z);
glutSolidSphere(0.1, 100, 100); // a yellow sphere
glPopMatrix();
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
//**********************************
// turn the light and the lighting on
//**********************************
glEnable(GL_LIGHT0); // turn light on
glEnable(GL_LIGHTING); // turn lighting on
}
// define a material in terms of its components
void define_material(GLfloat ar, GLfloat ag, GLfloat ab, // ambient
GLfloat dr, GLfloat dg, GLfloat db, // diffuse
GLfloat sr, GLfloat sg, GLfloat sb, // specular
GLfloat sh // shininess
)
{
GLfloat mat_ambient[4];
GLfloat mat_diffuse[4];
GLfloat mat_specular[4];
//**********************************
// set the ambient property
//**********************************
mat_ambient[0] = ar;
mat_ambient[1] = ag;
mat_ambient[2] = ab;
mat_ambient[3] = 1.f;
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
//**********************************
// set the diffuse property
//**********************************
mat_diffuse[0] = dr;
mat_diffuse[1] = dg;
mat_diffuse[2] = db;
mat_diffuse[3] = 1.f;
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
//**********************************
// set the specular property
//**********************************
mat_specular[0] = sr;
mat_specular[1] = sg;
mat_specular[2] = sb;
mat_specular[3] = 1.f;
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
//**********************************
// set the shininess property
//**********************************
glMaterialf(GL_FRONT, GL_SHININESS, sh);
}
// draw the room
void place_background()
{
glPushMatrix();
glScalef(15.f, 15.f, 15.f);
glRoom(1.f);
glPopMatrix();
}
/*
* OpenGL Initialization
*/
void init()
{
glClearColor(0.f, 0.f, 0.f, 0.f);
//**********************************
// activate the Gouraud shading instead of the flat one
//**********************************
glShadeModel(GL_FLAT);
//**********************************
// enable face culling
//**********************************
glEnable(GL_CULL_FACE);
//**********************************
// enable the depth test
//**********************************
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH);
glEnable(GL_DEPTH_TEST);
//**********************************
// set the ambient light with glLightModelfv to a 50% grey
//**********************************
GLfloat light_ambient[] = {0.5, 0.5, 0.5, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_ambient);
glEnable(GL_NORMALIZE);
}
void display()
{
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, infinite_view);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// place the camera
place_camera();
//**********************************
// place the light in the scene using place_light
//**********************************
place_light(7.4, 4, -7.4);
//**********************************
// define the material for the room (instead of color)
//**********************************
// glColor3f(1.f, 1.f, 1.f);
define_material(1, 1, 1,
0.5, 0.5, 0.5,
0, 0, 0,
0);
place_background();
// the 2 objects
// red shining sphere
glPushMatrix();
glTranslatef(-2.f, 0.f, 0.f);
//**********************************
// define the material for the sphere (instead of color)
//**********************************
// glColor3f(1.f, 0.f, 0.f);
define_material(0.2, 0, 0,
0.8, 0, 0,
0.8, 0.8, 0.8,
shininess);
glutSolidSphere(1.0, 240, 120);
glPopMatrix();
// green cube
glPushMatrix();
glTranslatef(2.f, 0.f, 0.f);
//**********************************
// define the material for the cube (instead of color)
//**********************************
// glColor3f(0.f, 1.f, 0.f);
define_material(0, 0.8, 0,
0, 0.5, 0,
0, 0, 0,
0);
glutSolidCube(2.0);
glPopMatrix();
glutSwapBuffers();
}
/*
* @brief Callback for window size change
* @param[in] w new width of the window
* @param[in] h new height of the window
*/
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)w / (GLfloat)h, 0.1, 50);
}
/*
* Callback for special keys
*/
#define DELTA_ANGLE_X 5
#define DELTA_ANGLE_Y 5
#define DELTA_DISTANCE 0.3f
#define DISTANCE_MIN 0.0
void special(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_UP:
angle_x = (angle_x + DELTA_ANGLE_X) % 360;
break;
case GLUT_KEY_DOWN:
angle_x = (angle_x - DELTA_ANGLE_X) % 360;
break;
case GLUT_KEY_LEFT:
angle_y = (angle_y + DELTA_ANGLE_Y) % 360;
break;
case GLUT_KEY_RIGHT:
angle_y = (angle_y - DELTA_ANGLE_Y) % 360;
break;
case GLUT_KEY_PAGE_DOWN:
distance += DELTA_DISTANCE;
break;
case GLUT_KEY_PAGE_UP:
distance -= (distance > DISTANCE_MIN) ? DELTA_DISTANCE : 0.f;
break;
default:
break;
}
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
//**********************************
// directional light, use global variable directional
//**********************************
case 'd':
directional = (directional + 1) % 2;
break;
//**********************************
// infinite_view
//**********************************
case 'f':
infinite_view = (infinite_view + 1) % 2;
break;
//**********************************
// Shininess: 's' to decrement, 'S' to increment
//**********************************
case 'S':
shininess += 1;
break;
case 's':
shininess -= 1;
break;
case 'q':
case 27: // [ESC]
exit(0);
break;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
// enable the double buffer and the depth buffer
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
// main window
glutInitWindowSize(640, 480);
glutInitWindowPosition(50, 50);
glutCreateWindow("Testing OpenGL light");
// callbacks
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
init();
glutMainLoop();
exit(0);
}