Il faut bien démarrer quelque part et c'est ici ! C'est sûr que c'est pas terrible, beaucoup de code pour un résultat bien consternant, mais je jette mes bases. Je dois reprendre ce qui était naturel il y a quelques années...
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
static int snglBuf[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 12, None};
static int dblBuf[] = {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 12, GLX_DOUBLEBUFFER, None};
Display* Dpy;
Window Win;
Bool DoubleBuffer = True;
GLfloat XAngle = 42.0, YAngle = 82.0, ZAngle = 112.0;
int FatalError(int errorCode, char* str)
{
printf("%s\n", str);
return errorCode;
}
void redraw()
{
static Bool DisplayListInited = False;
if (DisplayListInited) {
glCallList(1);
} else {
glNewList(1, GL_COMPILE_AND_EXECUTE);
//
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_QUADS);
glColor3f(0.0, 0.7, 0.1); //Green
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
glColor3f(0.9, 1.0, 0.0); //Yellow
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glColor3f(0.2, 0.2, 1.0); //Blue
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, -1.0);
glColor3f(0.7, 0.0, 0.1); //Red
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
//
glEndList();
DisplayListInited = True;
}
//On affiche réellement quelque chose...
if (DoubleBuffer) glXSwapBuffers(Dpy, Win);
else glFlush();
}
int main(int argc, char** argv)
{
XVisualInfo* vi;
Colormap CMap;
XSetWindowAttributes swa;
GLXContext cx;
XEvent Event;
Bool NeedRedraw = False, RecalcModelView = True;
int Dummy;
//
Dpy = XOpenDisplay(NULL);
if (!Dpy) return FatalError(1, "Couldn't open display...");
if (!glXQueryExtension(Dpy, &Dummy, &Dummy)) return FatalError(2, "X n'a pas d'extension OpenGL.");
//
vi = glXChooseVisual(Dpy, DefaultScreen(Dpy), dblBuf);
if (!vi) {
vi = glXChooseVisual(Dpy, DefaultScreen(Dpy), snglBuf);
if (!vi) return FatalError(3, "Pas de visuel RGB avec buffer de profondeur.");
DoubleBuffer = False;
}
printf("DoubleBuffer : %d\n", DoubleBuffer);
if (vi->class != TrueColor) return FatalError(4, "J'ai besoin d'un visuel en true color !");
//
cx = glXCreateContext(Dpy, vi, None, True);
if (!cx) return FatalError(5, "Impossible de créer le contexte de rendu.");
//
CMap = XCreateColormap(Dpy, RootWindow(Dpy, vi->screen), vi->visual, AllocNone);
swa.colormap = CMap;
swa.border_pixel = 0;
swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask;
Win = XCreateWindow(Dpy, RootWindow(Dpy, vi->screen), 0, 0, 300, 300, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
XSetStandardProperties(Dpy, Win, "glxsimple", "glxsimple", None, argv, argc, NULL);
//
glXMakeCurrent(Dpy, Win, cx);
XMapWindow(Dpy, Win);
//
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
//
while (True) {
do {
XNextEvent(Dpy, &Event);
switch (Event.type) {
case ButtonPress:
RecalcModelView = True;
switch(Event.xbutton.button) {
case 1: XAngle += 10.0; break;
case 2: YAngle += 10.0; break;
case 3: ZAngle += 10.0; break;
}
break;
case ConfigureNotify:
glViewport(0, 0, Event.xconfigure.width, Event.xconfigure.height);
case Expose:
NeedRedraw = True;
break;
}
} while(XPending(Dpy));
//
if (RecalcModelView) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
glRotatef(XAngle, 0.1, 0.0, 0.0);
glRotatef(YAngle, 0.0, 0.1, 0.0);
glRotatef(ZAngle, 0.0, 0.0, 1.0);
//
RecalcModelView = False;
NeedRedraw = True;
}
if (NeedRedraw) {
redraw();
NeedRedraw = False;
}
}
//
return 0;
}
Pour compiler ça, si on suppose que le code est sauvé dans un fichier simplegl.c, on lance :