1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
| #include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
// Sphere
#define X0 200
#define Y0 240
#define Z0 120
#define RAYON 100
// Source
#define XSOURCE 100
#define YSOURCE 240
#define ZSOURCE 420
struct vecteur{
int xi;
int xf;
int yi;
int yf;
int zi;
int zf;
};
// gcc -framework OpenGL -framework GLUT -framework Cocoa dures.c -o dures
void Display();
void Reshape(int h, int w);
int intersects(int xpix, int ypix, int zpix, int xsource, int ysource, int zsource);
int main(int argc, char **argv){
// Initialisation de OpenGL
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
// Creation de la fenetre
glutInitWindowPosition(0, 0);
glutInitWindowSize(640, 480);
glutCreateWindow("Ombres dures");
// Fonctions de base
glutReshapeFunc(Reshape);
glutDisplayFunc(Display);
// Boucle principale
glutMainLoop();
return EXIT_SUCCESS;
}
void Reshape(int h, int w){
// Zone d'affichage
glViewport(0, 0, h, w);
// Initialisation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 640, 0, 480);
glMatrixMode(GL_MODELVIEW);
}
void Display(){
int i, j;
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
// Simulation de construction des objets de la scene
for(i=0 ; i<640 ; i++){
for(j=0 ; j<480 ; j++){
if(sqrt((X0-i)*(X0-i)+(Y0-j)*(Y0-j))<RAYON){
// Le pixel montre une partie de la sphere
glBegin(GL_POINTS);
glColor3f(1, 1, 0);
glVertex2i(i, j);
glEnd();
}
else{
// Le pixel montre une partie du plan
if(intersects(i, j, 0, XSOURCE, YSOURCE, ZSOURCE) == 1){
// Le rayon lance du pixel vers la source intersecte la sphere
glBegin(GL_POINTS);
glColor3f(0, 0, 0);
glVertex2i(i, j);
glEnd();
}
else{
// Le rayon lance du pixel vers la source n'intersecte pas la sphere
glBegin(GL_POINTS);
glColor3f(1, 0, 1);
glVertex2i(i, j);
glEnd();
}
}
}
}
glFlush();
glutSwapBuffers();
}
int intersects(int xpix, int ypix, int zpix, int xsource, int ysource, int zsource){
float xpc, ypc, zpc;
float norm;
float distance;
// Vecteur rayon du pixel vers la source
struct vecteur rayon;
rayon.xi = xpix;
rayon.xf = xsource;
rayon.yi = ypix;
rayon.yf = ysource;
rayon.zi = zpix;
rayon.zf = zsource;
// Norme du vecteur rayon
norm = sqrt((rayon.xf-rayon.xi)*(rayon.xf-rayon.xi)+(rayon.yf-rayon.yi)*(rayon.yf-rayon.yi)+(rayon.zf-rayon.zi)*(rayon.zf-rayon.zi));
// Vecteur du pixel vers le centre de la sphere
struct vecteur vpc;
vpc.xi = xpix;
vpc.xf = X0;
vpc.yi = ypix;
vpc.yf = X0;
vpc.zi = zpix;
vpc.zf = Z0;
// Projection du centre de la sphere sur le rayon
xpc = (vpc.xf-vpc.xi)*(rayon.xf-rayon.xi) / norm;
ypc = (vpc.yf-vpc.yi)*(rayon.yf-rayon.yi) / norm;
zpc = (vpc.zf-vpc.zi)*(rayon.zf-rayon.zi) / norm;
// Distance du centre de la sphere au rayon
distance = sqrt((X0-xpc)*(X0-xpc)+(Y0-ypc)*(Y0-ypc)+(Z0-zpc)*(Z0-zpc));
if (distance>RAYON)
// Il n'y a pas d'intersection
return 0;
else
// Il y a une ou deux intersections
return 1;
} |
Partager