/* xlib_example1.c Basic example of using OpenGL wth Xlib. The program open the X11 window with appropriate visual, create OpenGL graphic context and render white square on grey background. The visual for OpenGL is selected using glXChooseVisual(3g). It is possible to supercede default visual selection by setting environment variable _OGL_VISUAL to desired visual's id. cc -o xlib_example1 xlib_example1.c -lX11 -lGL -lGLU -lGLX Joseph Hindin, 1996 hindin%robcad@uunet.uu.net */ #include #include #include #include #include #include #include #include #include #include int OGL_config[] = {GLX_DOUBLEBUFFER, GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE,1, GLX_GREEN_SIZE,1, GLX_BLUE_SIZE,1, GLX_RED_SIZE,1, None}; int highDefined; unsigned int low=0,high; int windowWidth,windowHeight; Display *dpy; Window win; Window createOGLWindow(Display *,XVisualInfo *); XVisualInfo *getVisual(Display *,int *); void processKey(XEvent *); void redraw(void); void resizeWindow(void); void drawFace(void); int main(int argc,char **argv) { XVisualInfo *vi; GLXContext OGLContext; XEvent event; if ((dpy= XOpenDisplay(0))==0) { fprintf(stderr,"Can't open X11 display\n"); exit(-1); } if ((vi = getVisual(dpy,OGL_config))==0) { fprintf(stderr,"Can't find OpenGL visual\n"); exit(-1); } if ((OGLContext = glXCreateContext(dpy,vi,0,True))==0) { fprintf(stderr,"Can't create OpenGL context\n"); exit(-1); } win = createOGLWindow(dpy,vi); glXMakeCurrent(dpy,win,OGLContext); XMapWindow(dpy,win); for (;;) { XNextEvent(dpy,&event); switch (event.type) { case Expose: if (event.xexpose.count == 0) redraw(); break; case KeyPress: processKey(&event); break; case ConfigureNotify: windowWidth = event.xconfigure.width; windowHeight = event.xconfigure.height; resizeWindow(); break; } } } XVisualInfo *getVisual(Display *dpy,int *config) { char *visualText; XVisualInfo template,*result; int nResults; char *endP; if (visualText=getenv("_OGL_VISUAL")) { template.visualid = strtol(visualText,&endP,0); if (*endP && *endP != ' ') { fprintf(stderr,"Illegal value for visual ID \"%s\"\n",visualText); exit(-1); } if ((result = XGetVisualInfo(dpy,VisualIDMask,&template,&nResults))==0) { fprintf(stderr,"No such visual 0x%lx\n",template.visualid); exit(-1); } if (nResults != 1) { fprintf(stderr,"Internal error in OpenGL widget: more than 1 visual\n"); exit(-1); } return result; } else { return glXChooseVisual(dpy,0,config); } } Window createOGLWindow(Display *dpy,XVisualInfo *vi) { XSetWindowAttributes attributes; attributes.colormap = XCreateColormap(dpy,DefaultRootWindow(dpy),vi->visual, (vi->class==TrueColor)?AllocNone:AllocAll); attributes.border_pixel = 0; attributes.background_pixel = 0; attributes.event_mask = KeyPressMask|ExposureMask|StructureNotifyMask; return XCreateWindow(dpy,DefaultRootWindow(dpy), 0,0,200,200, 0, vi->depth, InputOutput, vi->visual, CWColormap|CWEventMask|CWBorderPixel|CWBackPixel, &attributes); } void resizeWindow() { glViewport(0,0,windowWidth,windowHeight); } void redraw(void) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(20,1,4,12); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,8,0,0,0,0,1,0.0); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glDrawBuffer(GL_BACK); glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); drawFace(); glXSwapBuffers(dpy,win); } void processKey(XEvent *e) { KeySym ks; ks = XLookupKeysym((XKeyEvent *)e,0); if (ks==XK_Escape) exit(0); } void drawFace(void) { glBegin(GL_POLYGON); glVertex3f(-0.5,-0.5,-0.5); glVertex3f( 0.5,-0.5,-0.5); glVertex3f( 0.5, 0.5,-0.5); glVertex3f(-0.5, 0.5,-0.5); glEnd(); }