From 4444f1451bec0c37bb2b8883f5d8625b23858213 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Sun, 6 Nov 2011 23:15:40 +0100 Subject: x11argb_opengl added --- x11argb_opengl/Makefile | 3 + x11argb_opengl/x11argb_opengl.c | 369 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 372 insertions(+) create mode 100644 x11argb_opengl/Makefile create mode 100644 x11argb_opengl/x11argb_opengl.c diff --git a/x11argb_opengl/Makefile b/x11argb_opengl/Makefile new file mode 100644 index 0000000..658fc06 --- /dev/null +++ b/x11argb_opengl/Makefile @@ -0,0 +1,3 @@ +x11argb_opengl: x11argb_opengl.c Makefile + $(CC) -std=c99 -g3 -o x11argb_opengl x11argb_opengl.c -lX11 -lXrender -lGL -lm + diff --git a/x11argb_opengl/x11argb_opengl.c b/x11argb_opengl/x11argb_opengl.c new file mode 100644 index 0000000..fb8b814 --- /dev/null +++ b/x11argb_opengl/x11argb_opengl.c @@ -0,0 +1,369 @@ +/*------------------------------------------------------------------------ + * A demonstration of OpenGL in a ARGB window + * => support for composited window transparency + * + * (c) 2011 by Wolfgang 'datenwolf' Draxinger + * See me at comp.graphics.api.opengl and StackOverflow.com + + * License agreement: This source code is provided "as is". You + * can use this source code however you want for your own personal + * use. If you give this source code to anybody else then you must + * leave this message in it. + * + * This program is based on the simplest possible + * Linux OpenGL program by FTB (see info below) + + The simplest possible Linux OpenGL program? Maybe... + + (c) 2002 by FTB. See me in comp.graphics.api.opengl + + -- + <\___/> + / O O \ + \_____/ FTB. + +------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define USE_CHOOSE_FBCONFIG + +static void fatalError(const char *why) +{ + fprintf(stderr, "%s", why); + exit(0x666); +} + +static int Xscreen; +static Atom del_atom; +static Colormap cmap; +static Display *Xdisplay; +static XVisualInfo *visual; +static XRenderPictFormat *pict_format; +static GLXFBConfig *fbconfigs, fbconfig; +static int numfbconfigs; +static GLXContext render_context; +static Window Xroot, window_handle; +static GLXWindow glX_window_handle; +static int width, height; + +static int VisData[] = { +GLX_RENDER_TYPE, GLX_RGBA_BIT, +GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, +GLX_DOUBLEBUFFER, True, +GLX_RED_SIZE, 8, +GLX_GREEN_SIZE, 8, +GLX_BLUE_SIZE, 8, +GLX_ALPHA_SIZE, 8, +GLX_DEPTH_SIZE, 16, +None +}; + +static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg) +{ + return d && e && arg && (e->type == MapNotify) && (e->xmap.window == *(Window*)arg); +} + +static void describe_fbconfig(GLXFBConfig fbconfig) +{ + int doublebuffer; + int red_bits, green_bits, blue_bits, alpha_bits, depth_bits; + + glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DOUBLEBUFFER, &doublebuffer); + glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_RED_SIZE, &red_bits); + glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_GREEN_SIZE, &green_bits); + glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_BLUE_SIZE, &blue_bits); + glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_ALPHA_SIZE, &alpha_bits); + glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DEPTH_SIZE, &depth_bits); + + fprintf(stderr, "FBConfig selected:\n" + "Doublebuffer: %s\n" + "Red Bits: %d, Green Bits: %d, Blue Bits: %d, Alpha Bits: %d, Depth Bits: %d\n", + doublebuffer == True ? "Yes" : "No", + red_bits, green_bits, blue_bits, alpha_bits, depth_bits); +} + +static void createTheWindow() +{ + XEvent event; + int x,y, attr_mask; + XSizeHints hints; + XWMHints *startup_state; + XTextProperty textprop; + XSetWindowAttributes attr = {0,}; + static char *title = "FTB's little OpenGL example - ARGB extension by WXD"; + + Xdisplay = XOpenDisplay(NULL); + if (!Xdisplay) { + fatalError("Couldn't connect to X server\n"); + } + Xscreen = DefaultScreen(Xdisplay); + Xroot = RootWindow(Xdisplay, Xscreen); + + fbconfigs = glXChooseFBConfig(Xdisplay, Xscreen, VisData, &numfbconfigs); + fbconfig = 0; + for(int i = 0; ivisual); + if(!pict_format) + continue; + + fbconfig = fbconfigs[i]; + if(pict_format->direct.alphaMask > 0) { + break; + } + } + + if(!fbconfig) { + fatalError("No matching FB config found"); + } + + describe_fbconfig(fbconfig); + + /* Create a colormap - only needed on some X clients, eg. IRIX */ + cmap = XCreateColormap(Xdisplay, Xroot, visual->visual, AllocNone); + + attr.colormap = cmap; + attr.background_pixmap = None; + attr.border_pixmap = None; + attr.border_pixel = 0; + attr.event_mask = + StructureNotifyMask | + EnterWindowMask | + LeaveWindowMask | + ExposureMask | + ButtonPressMask | + ButtonReleaseMask | + OwnerGrabButtonMask | + KeyPressMask | + KeyReleaseMask; + + attr_mask = + CWBackPixmap| + CWColormap| + CWBorderPixel| + CWEventMask; + + width = DisplayWidth(Xdisplay, DefaultScreen(Xdisplay))/2; + height = DisplayHeight(Xdisplay, DefaultScreen(Xdisplay))/2; + x=width/2, y=height/2; + + window_handle = XCreateWindow( Xdisplay, + Xroot, + x, y, width, height, + 0, + visual->depth, + InputOutput, + visual->visual, + attr_mask, &attr); + + if( !window_handle ) { + fatalError("Couldn't create the window\n"); + } + +#if USE_GLX_CREATE_WINDOW + int glXattr[] = { None }; + glX_window_handle = glXCreateWindow(Xdisplay, fbconfig, window_handle, glXattr); + if( !glX_window_handle ) { + fatalError("Couldn't create the GLX window\n"); + } +#else + glX_window_handle = window_handle; +#endif + + textprop.value = (unsigned char*)title; + textprop.encoding = XA_STRING; + textprop.format = 8; + textprop.nitems = strlen(title); + + hints.x = x; + hints.y = y; + hints.width = width; + hints.height = height; + hints.flags = USPosition|USSize; + + startup_state = XAllocWMHints(); + startup_state->initial_state = NormalState; + startup_state->flags = StateHint; + + XSetWMProperties(Xdisplay, window_handle,&textprop, &textprop, + NULL, 0, + &hints, + startup_state, + NULL); + + XFree(startup_state); + + XMapWindow(Xdisplay, window_handle); + XIfEvent(Xdisplay, &event, WaitForMapNotify, (char*)&window_handle); + + if ((del_atom = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", 0)) != None) { + XSetWMProtocols(Xdisplay, window_handle, &del_atom, 1); + } +} + +static void createTheRenderContext() +{ + int dummy; + if (!glXQueryExtension(Xdisplay, &dummy, &dummy)) { + fatalError("OpenGL not supported by X server\n"); + } + + render_context = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0, False); + if (!render_context) { + fatalError("Failed to create a GL context\n"); + } + + if (!glXMakeContextCurrent(Xdisplay, glX_window_handle, glX_window_handle, render_context)) { + fatalError("glXMakeCurrent failed for window\n"); + } +} + +static int updateTheMessageQueue() +{ + XEvent event; + XConfigureEvent *xc; + + while (XPending(Xdisplay)) + { + XNextEvent(Xdisplay, &event); + switch (event.type) + { + case ClientMessage: + if (event.xclient.data.l[0] == del_atom) + { + return 0; + } + break; + + case ConfigureNotify: + xc = &(event.xconfigure); + width = xc->width; + height = xc->height; + break; + } + } + return 1; +} + +GLfloat cube_vertices[][8] = { + /* X Y Z Nx Ny Nz S T */ + {-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0 + { 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0}, // 1 + { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2 + {-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3 + + { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0}, + {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0}, + {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0}, + { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0}, + + {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0}, + {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0}, + {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0}, + {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, + + { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0}, + { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0}, + { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0}, + { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, + + { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0}, + {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0}, + {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0}, + { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0}, + + {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0}, + { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0}, + { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0}, + {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0}, +}; + +static void draw_cube(void) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][0]); + glNormalPointer(GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][3]); + glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][6]); + + glDrawArrays(GL_QUADS, 0, 24); +} + +float const light_dir[]={1,1,1,0}; +float const light_color[]={1,0.95,0.9,1}; + +static void redrawTheWindow() +{ + float const aspect = (float)width / (float)height; + + static float a=0; + static float b=0; + static float c=0; + + glDrawBuffer(GL_BACK); + + glViewport(0, 0, width, height); + + // Clear with alpha = 0.0, i.e. full transparency + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-aspect, aspect, -1, 1, 2.5, 10); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glLightfv(GL_LIGHT0, GL_POSITION, light_dir); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color); + + glTranslatef(0., 0., -5.); + + glRotatef(a, 1, 0, 0); + glRotatef(b, 0, 1, 0); + glRotatef(c, 0, 0, 1); + + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + + draw_cube(); + + a = fmod(a+0.1, 360.); + b = fmod(b+0.5, 360.); + c = fmod(c+0.25, 360.); + + glXSwapBuffers(Xdisplay, glX_window_handle); +} + +int main(int argc, char *argv[]) +{ + createTheWindow(); + createTheRenderContext(); + + while (updateTheMessageQueue()) { + redrawTheWindow(); + } + + return 0; +} + -- cgit v1.2.3