Pour la suite du cours, lorsqu'on dessinera nous-même nos lignes et polygones, il faudra aussi modifier la fonctionaallocateBuffers du fichier graphics.c Voir la fin de ce document pour voir ma version. Mais le mieux est d'attendre le cours sur le tracé de lignes et polygones.
if((display=XOpenDisplay(display_name))==NULL) {
fprintf(stderr,"fenetre de base: ne peut pas
se connecter ");
fprintf(stderr,"au serveur %s\n",XDisplayName(display_name));
exit(-1);
}
/* Initialiser la taille de la fenetre */
width = Wsizex;
height = Wsizey;
/* Recuperer les informations concernant l'ecran (root window)
sur
lequel on va afficher notre application.
Le numero de l'ecran
par defaut s'obtient a l'aide de la macro
DefaultScreen() */
screen = DefaultScreen(display);
root = RootWindow(display, screen);
depth = XDefaultDepth(display,
screen);
visual = DefaultVisual(display, screen);
black = BlackPixel(display, screen);
white = WhitePixel(display, screen);
/* Allocation du double buffer */
db = XCreatePixmap(display, root, width, height, depth);
/* COLOR MODE */
/* creation d'une colormap privee en niveaux de gris */
if (depth<=8) {
cmap = XCreateColormap(display,
root, visual, AllocAll);
Lut_16M(display, cmap);
}
printf("Color mode on!\n");
WAttribs.save_under = True;
WAttribs.border_pixel = 0;
WAttribs.colormap = cmap;
WAttribs.override_redirect = False;
WAttribs.backing_store = Always;
WMask= CWBorderPixel | CWBackingStore | CWSaveUnder |
CWOverrideRedirect | CWColormap ;
win=XCreateWindow(display,
root,
0, 0,
(unsigned int) width, (unsigned
int) height,
0,
CopyFromParent,
CopyFromParent,
CopyFromParent,
WMask,
&WAttribs);
get_GC_color(win, &gc);
/* selection des evenements que l'on desirera traiter pour
cette fenetre */
XSelectInput(display, win, ExposureMask | KeyPressMask |
ButtonPressMask | ButtonReleaseMask
| StructureNotifyMask |
PointerMotionMask);
/* Pour le double buffer */
gcbg = XCreateGC(display, root, 0, NULL);
XSetForeground(display, gcbg, white);
/* affichage (mapping) de la fenetre, on mappe les differentes
fenetres juste avant la gestion des evenements
*/
XMapWindow(display,win);
/* Allocation du pixmap pour la visu fil de fer et flat shading,
et d'une
XImage pour la visu gouraud, phong et
textures */
allocateBuffers(&cam);
/* appel de la boucle principale */
mainloop();
freeBuffers(&cam);
}
NOTE : Je ne souviens pas a quoi ressemble la fonction suivante chez vous... Si on ne parle pas de memset, ne modifiez rien.
/*------------------------------*/
static void clear_double_buffer()
/*------------------------------*/
/* Efface le contenu du double buffer */
{
if(cam.use_pixmap)
XFillRectangle(display, db, gcbg, 0, 0, cam.resX,
cam.resY);
else {
/* la couleur. 0 = ecran noir */
if (depth<=8)
cam.image=(char
*)memset(cam.image, 0, sizeof(char)*cam.resX*cam.resY);
else
cam.image=(char
*)memset(cam.image, 0, sizeof(char)*cam.resX*cam.resY*4);
}
}
Remarques concernant la fonction suivante
: la macro RGBTO24 se trouve dans color.h. La structure Color aussi.
Par rappot à la version que vous avez,
on indique la couleur des faces à cette fonction en passant un pointeur
sur un objet de cette structure
La macro RGBTOONE permet de trouver dans une
colormap spécialement formée de 256 couleurs, la couleur
la plus
proche de la couleur R,G,B passée
en paramètre. Utile pour le support des écrans 8 bits et
le tramage des couleurs
qui fera l'objet d'un prochain cours.
dans color.h rajouter : #define RGBTO24(r,g,b) ((((unsigned long)(r))<<16)|(((unsigned long)(g))<<8)|(b))
/*-----------------------------------------------------------------------*/
static void FillFace(PIXEL *A, PIXEL *B, PIXEL *C, PIXEL *D, Color
*color)
/*-----------------------------------------------------------------------*/
/* Dessine la face definie par les sommets A,B,C,D, en mode plein.
Si C == D alors il s'agit d'un triangle */
{
XPoint point[4];
if (depth<=8)
XSetForeground(display,
gc, RGBTOONE( color->r, color->g, color->b ) );
else
XSetForeground(display,
gc, RGBTO24( color->r, color->g, color->b ) );
point[0].x = A->x;
point[0].y = A->y;
point[1].x = B->x;
point[1].y = B->y;
if(C != D) {
point[2].x = C->x;
point[2].y = C->y;
point[3].x = D->x;
point[3].y = D->y;
XFillPolygon(display, db, gc, point, 4, Convex,
CoordModeOrigin);
}
else {
point[2].x = C->x;
point[2].y = C->y;
XFillPolygon(display, db, gc, point, 3, Convex,
CoordModeOrigin);
}
}
/*---------------------------------------*/
static void allocateBuffers(Camera *cam)
/*---------------------------------------*/
/* Allocation des buffers de visualisation.
Normalement, pour une scene
complete, il faudrait faire
ca pour chaque camera.*/
{
/* Pour la shared memory X11 */
int CompletionType;
long Shm_OK;
/* Allocation du double buffer pour
les modes de rendus simples */
db = XCreatePixmap(display, root,
cam->resX, cam->resY, depth);
/* Allocation du buffer cam->image,
en Shared Memory X11 si possible */
Shm_OK = XShmQueryExtension(display);
Shm_OK=0; // Si on utilise la memoire partagee, ca plante!
switch(Shm_OK) {
case 0:
/* On a pas pas pu allouer
de Shared memory. On alloue donc le Z-Buffer
manuellement
a l'aide d'un malloc */
/* Allocation d'un buffer
8 bits */
if
(depth<=8)
cam->image
= (char *) malloc(cam->resX * cam->resY * sizeof(char));
else
cam->image
= (char *) malloc(cam->resX * cam->resY * sizeof(char) * 4);
/* Allocation d'une XImage
8 ou 24 bits dont les données sont stockées dans le buffer
cam->image qu'on vient
juste
d'allouer */
if
(depth<=8)
Image = XCreateImage(display,
visual, 8, ZPixmap , 0,
cam->image,
cam->resX, cam->resY,
8, 0);
else {
Image = XCreateImage(display,
visual, 24, ZPixmap , 0,
cam->image,
cam->resX, cam->resY,
8, 0);
}
if (!cam->image)
{
perror("L'allocation
de cam->image a echouee!\n");
exit(0);
}
/* Flag qui indique qu'on a
pas alloue la Shared Memory */
Shm_Hard_Buffer_Flag =
False;
printf("Je n'ai pas reussi
a allouer la Shared memory X11!\n");
break;
case 1:
/* On a pu allouer la
Shared memory. Le Z-Buffer va donc se trouver dans
cette
zone */
if
(depth<=8)
Image = XShmCreateImage(display,
visual ,8, ZPixmap ,
NULL,
&Shminfo, cam->resX, cam->resY);
else
Image = XShmCreateImage(display,
visual , 24, ZPixmap ,
NULL,
&Shminfo, cam->resX, cam->resY);
Shminfo.shmid = shmget(IPC_PRIVATE,
cam->resX
* cam->resY * sizeof(char),
IPC_CREAT
| 0777);
Shminfo.shmaddr = Image->data
= cam->image =
shmat(Shminfo.shmid,
NULL, 0);
if (!cam->image) {
printf("Je
n'ai pas reussi a allouer la Shared memory X11!\n");
exit(0);
}
else
printf("Shared
memory X11 allouee!\n");
Shminfo.readOnly = False;
XShmAttach(display, &Shminfo);
Shm_Hard_Buffer_Flag =
True;
CompletionType = XShmGetEventBase(display)
+ ShmCompletion;
break;
}
}