// x-connectcycle-test.cc : test X/GLX connection cycling static const char *Version[] = { "@(#) x-connectcycle-test.cc Copyright (c) 2000 Christopher Alexander North-Keys", "$Grueppe: Talisman $", "$Anfang: 2000-03-25 03:21:15 GMT (Mar Sat) 953954475 $", "$Compiliert: "__DATE__" " __TIME__ " $", "$Source: /home/erlkonig/z/zme/RCS/x-connectcycle-test.cc,v $", "$State: Exp $", "$Revision: 1.1 $", "$Date: 2000/03/25 03:21:15 $", "$Author: erlkonig $", (const char*)0 }; extern "C" { // X11 in general #include #include #include #include // GLX #include // OpenGL #include } // #include // autoconfiscation - now automatic #include void renderTestgrid(); void render(Display *display, Window window, GLXContext gxlcon); void runtest(); int main(int ac, char **av) { for(int i = 0 ; i <= 10 ; ++i) { runtest(); } return 0; } void runtest() { //===============================================class Port // All the following block should only be used by the spawned thread // X11 Display *display; int connection; char *display_name; Screen *screen; XVisualInfo *vis_info; Visual visual; Colormap colormap; int screen_num; Window window; Window window_root; XSetWindowAttributes attr; unsigned long int attr_mask; // - window details in X11 unsigned int border_width; unsigned int depth; unsigned int win_width, win_height; float win_hor_center, win_ver_center; float cursor_cx, cursor_cy; // mouse coörd in [-1,1] scientific orientation float aspect; // GLX GLXContext glxcon; // apparently can be shared, for display lists // OpenGL GLdouble clip_near, clip_far; float fog_distance_multiplier; // Voodoo2 ~170, default 1 (see onGinit) // Hardware char *renderer_name; // glRenderer: static string, no freeing //========================================================Port::Port border_width = depth = win_width = win_height = 0; win_hor_center = win_ver_center = 0; cursor_cx = cursor_cy = 0; aspect = 1; colormap = 0; glxcon = 0; clip_near = clip_far = 0; fog_distance_multiplier = 1; renderer_name = 0; //=========================================================Port::guiOpen cerr << "[Port::guiOpen]\n"; bool successp = false; if( ! (display = XOpenDisplay(0))) // uses $DISPLAY -----XOpenDisplay { cerr << "[Port::guiOpen:XOpenDisplay FAILED]\n"; exit(1); } XSynchronize(display, true); // =-=-=-=-=-=-=-=-=-=-=-=-= DEBUGGING display_name = XDisplayName(0); // uses $DISPLAY cerr << "[Port::guiOpen:XOpenDisplay -> " << display_name << "]\n"; connection = ConnectionNumber(display); int empty = 0; if( ! glXQueryExtension(display, &empty, &empty)) // ----glXQueryExtension { cerr << "[Port::guiOpen:glXQueryExtension FAILED]\n"; exit(1); } cerr << "[Port::guiOpen:glXQueryExtension -> success]\n"; int glopts[] = { GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, 0 }; // turns into: {4, 8, 4, 9, 4, 10, 4, 12, 16, 5, 0} vis_info = 0; screen = XScreenOfDisplay(display, XDefaultScreen(display)); screen_num = XScreenNumberOfScreen(screen); window_root = RootWindow(display, screen_num); // ----- glXChooseVisual if( ! (vis_info = glXChooseVisual(display, screen_num, &glopts[0]))) { cerr << "[Port::guiOpen:glXChooseVisual FAILED]\n"; exit(1); } depth = vis_info->depth; cerr << "[Port::guiOpen:glXChooseVisual -> depth " << depth << "]\n"; visual.visualid = vis_info->visualid; visual.c_class = vis_info->c_class; visual.red_mask = vis_info->red_mask; visual.green_mask = vis_info->green_mask; visual.blue_mask = vis_info->blue_mask; visual.bits_per_rgb = vis_info->bits_per_rgb; visual.map_entries = vis_info->colormap_size; colormap = XCreateColormap(display, window_root, // ---- XCreateColormap vis_info->visual, AllocNone ); cerr << "[Port::guiOpen:XCreateColormap -> " << colormap << "]\n"; // ---------- glXCreateContext cerr << "[Port::guiOpen:glXCreateContext...]\n"; if( ! (glxcon = glXCreateContext(display, vis_info, 0, GL_TRUE))) { // The (GLXContext*)0 above opts not to share glxContexts cerr << "[Port::guiOpen:glXCreateContext -> " << glxcon << "]\n"; exit(1); } memset((void*)&attr, 0, sizeof attr); attr.colormap = colormap; attr.background_pixmap = None; attr.bit_gravity = attr.win_gravity = CenterGravity; attr.backing_store = WhenMapped; attr.save_under = true; attr.event_mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | ExposureMask | StructureNotifyMask ); attr_mask = (0 | CWColormap | CWBackPixmap | CWBitGravity | CWWinGravity | CWBackingStore | CWSaveUnder | CWEventMask); cerr << "[Port::guiOpen:XCreateWindow...]\n"; if( ! (window = XCreateWindow(display, window_root, // --- XCreateWindow 0, 0, // x, y 800, 600, // width, height 0, // border width depth, InputOutput, // class of window &visual, attr_mask, &attr))) { cerr << "[Port::guiOpen:XCreateWindow -> success]\n"; exit(1); } win_hor_center = 400; win_ver_center = 300; XMapWindow(display, window); if(renderer_name = (char*)glGetString(GL_RENDERER)) { cerr << "Renderer: " << renderer_name << '\n'; if( ! strcmp(renderer_name, "Voodoo_Graphics")) fog_distance_multiplier = 128; // default: 1 } // glXMakeCurrent(display, window, glxcon); //--------------glXMakeCurrent // now call an event loop for(int i = 0 ; i <= 3 ; ++i) { render(display, window, glxcon); usleep(200000); } //===================================================Port::guiClose cerr << "[Port::guiClose]\n"; #if 1 glXMakeCurrent(display, None, 0); // ----------glXMakeCurrent (disable) if(glxcon) glXDestroyContext(display, glxcon), glxcon = 0; if(vis_info) XFree(vis_info), vis_info = 0; if(colormap) XFreeColormap(display, colormap), colormap = 0; if(window) XDestroyWindow(display, window), window = 0; #endif if(display) { XSetCloseDownMode(display, DestroyAll); // no effect XFlush(display); // no effect XCloseDisplay(display), display = 0; } screen = 0; renderer_name = 0; cerr << "[Port::guiClose - complete]\n"; } void renderTestgrid() { cerr << "[Port::renderTestgrid] "; glBegin(GL_LINES); { const int min = -10; const int max = -min; int step = 1; glColor3f(1,1,1); for(int i = min ; i <= max ; i += step) { // xy plane glVertex3d(i, min, 0); glVertex3d(i, max, 0); glVertex3d(min, i, 0); glVertex3d(max, i, 0); // xz plane glVertex3d(i, 0, min); glVertex3d(i, 0, max); glVertex3d(min, 0, i); glVertex3d(max, 0, i); // yz plane glVertex3d(0, i, min); glVertex3d(0, i, max); glVertex3d(0, min, i); glVertex3d(0, max, i); } } glEnd(); } void render(Display *display, Window window, GLXContext glxcon) { cerr << "[Port::render] "; glClearColor(0.2 , 0.2 , 0.5 , 0.0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // for 21" monitor. Should be determined from X, or entered, or something const float monitor_width = .38; // meters const float monitor_height = .285; // meters GLdouble clip_near = 1; // 1 meter GLdouble clip_far = 1000; // 1 kilometer glFrustum(0 - monitor_width, 0 + monitor_width, 0 - monitor_height, 0 + monitor_height, clip_near, clip_far); // place self using x, y from mouse // glTranslatef(30 * cursor_cx, 30 * cursor_cy, -50); // remember to disable fog before drawing sky. GLfloat position0[] = { 0.0, 0.0, 5.0, 1 }; GLfloat ambient[] = { 0.2, 0.2, 0.2, 1 }; GLfloat diffuse[] = { 0.9, 0.9, 0.9, 1 }; glLightfv(GL_LIGHT0, GL_POSITION, position0); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); // renderTestgrid(); // may need to be split out to allow for multiport synchronization glPopMatrix(); // still in GL_MODELVIEW glMatrixMode(GL_PROJECTION); glPopMatrix(); glXSwapBuffers(display, window); cerr << "\n"; }