Hi, I'm working on a program to display 2D map data derived from the World Data Bank, and have run across a couple of problems that look to me like Mesa bugs. I'm running Mesa 3.1 from Ryan Weaver's RPMs on a Red Hat 5.1 Linux system and XFree86 3.3.2. I've displayed locally in 24 bit truecolor, and remotely to an OpenVMS display that I believe is 24 bit direct color. The program reads a map data file and builds a display list consisting of line strips, which can be quite lengthy. I sometimes see extra lines appear on the display. This seems to happen at about the time the last point of some line strip gets clipped out of the display. I have a GLUT-based program and dataset that can reproduce the problem. Controls in the program use the middle mouse button and drag action to pan/zoom the map. Control-drag to zoom, drag to pan, escape to quit. The second problem is that when I use double buffering, after panning/zooming for a little while (under 30 seconds of use) I get a segmentation fault. This hasn't happened when I don't double-buffer. The program's a little over 200 lines, so I've included that. The smallest dataset I have which reproduces the problem is about 80K, so I thought I should ask before emailing it. The 80K dataset is apparently insufficient to cause the seg fault, but I have one that's 916K that will do it. Please let me know if you'd like me to send either or both datasets. Joe Bronkema Senior Member Engineering Staff Lockheed Martin NE&SS - Moorestown [EMAIL PROTECTED]
extern "C" { #include <GL/glut.h> } #include <math.h> #include <fstream> #include <iostream.h> const float RAD_PER_DEG = 0.017453293; const float EARTH_RADIUS_KM = 6378.137; // earth radius in km float world_x_min; float world_x_max; float world_y_min; float world_y_max; void cxsr_ll_xy (float longitude, float latitude, float &x, float &y) { y = EARTH_RADIUS_KM * log(tan(0.785398163 + (latitude * RAD_PER_DEG / 2.0))); x = EARTH_RADIUS_KM * longitude * RAD_PER_DEG; } GLuint mapList; int loadmap(char *fname) { ifstream mapfile(fname); if (mapfile.fail()) return(0); int rectype; // record type from map file float point_lat, point_long; // latitude and longitude float point_x, point_y; // get map limits from first two lines of the file mapfile >> rectype >> point_long >> point_lat; cxsr_ll_xy(point_long, point_lat, world_x_min, world_y_min); mapfile >> rectype >> point_long >> point_lat; cxsr_ll_xy(point_long, point_lat, world_x_max, world_y_max); float delta_x = world_x_max - world_x_min; float delta_y = world_y_max - world_y_min; if (delta_x > delta_y) delta_y = delta_x; else delta_x = delta_y; world_x_max = world_x_min + delta_x; world_y_max = world_y_min + delta_y; // Build display list mapList, but do not draw it at this time glNewList(mapList, GL_COMPILE); int skip; int junk = 0; while (!mapfile.eof()) { mapfile >> rectype >> point_long >> point_lat; if (rectype == 4) { // beginning land section glBegin(GL_LINE_STRIP); // color = coast/island/lake color glColor3f(0.0, 0.7, 0.0); skip = 0; } else if (rectype == 2) { // beginning border section glEnd(); glBegin(GL_LINE_STRIP); // color = border color glColor3f(0.85,0.85, 0.25); skip = 0; } else if (rectype == 1) { // new segment within section glEnd(); glBegin(GL_LINE_STRIP); skip = 0; } // If point is within our limits, add it to the point list cxsr_ll_xy(point_long, point_lat, point_x, point_y); if ((point_x >= world_x_min) && (point_x <= world_x_max) && (point_y >= world_y_min) && (point_y <= world_y_max)) { if (skip == 0) { glVertex2f(point_x, point_y); } skip++; if (skip >= 2) skip = 0; } } // end reading map file glEnd(); glEndList(); return(1); } // Variables used in setting up the projection int zoom; int zoom_max; float pan_x; float pan_y; // aspect ratio float aspect; // Variables used in mouse control bool panning; bool zooming; int last_x; int last_y; int window_pixels_wide; int window_pixels_high; float window_world_wide; // width of viewing area in world coordinates float window_world_high; // height of viewing area in world coordinates void resize(int caller) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Specifying near and far with same magnitude and opposite sign // gives parallel projection like gluOrtho2D // left right bottom top near far if (aspect >= 1) { // y longer than x float right = world_x_min + (world_x_max - world_x_min) / aspect; glOrtho(world_x_min + zoom + pan_x, right - zoom + pan_x, world_y_min + zoom + pan_y, world_y_max - zoom + pan_y, -10000.0, 10000.0); window_world_wide = right - world_x_min - 2.0 * zoom; window_world_high = world_y_max - world_y_min - 2.0 * zoom; } else { float top = world_y_min + aspect * (world_y_max - world_y_min); glOrtho(world_x_min + zoom + pan_x, world_x_max - zoom + pan_x, world_y_min + zoom + pan_y, top - zoom + pan_y, -10000.0, 10000.0); window_world_wide = world_x_max - world_x_min - 2.0 * zoom; window_world_high = top - world_y_min - 2.0 * zoom; } glutPostRedisplay(); } void reshape(int x, int y) { window_pixels_wide = x; window_pixels_high = y; cout << "reshape " << x << " " << y << endl; aspect = (float) y / (float) x; glViewport(0,0,x,y); resize(0); } void click(int button, int state, int x, int y) { if (button == GLUT_MIDDLE_BUTTON) { if (state == GLUT_DOWN) { last_x = x; last_y = y; if (glutGetModifiers() & GLUT_ACTIVE_CTRL) zooming = true; else panning = true; } else { // user let go of the button panning = false; zooming = false; } } } void drag (int x, int y) { int delta_x = x - last_x; int delta_y = y - last_y; if (panning) { pan_x -= window_world_wide * delta_x / window_pixels_wide; pan_y += window_world_high * delta_y / window_pixels_high; resize(-1); } if (zooming) { zoom += 20 * delta_x; if (zoom > zoom_max) zoom = zoom_max; if (zoom < 0) zoom = 0; resize(-1); } last_x = x; last_y = y; } void display() { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glCallList(mapList); //glFlush(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } int main(int argc, char *argv[]) { if (argc != 2) { cout << "Usage: drawmap <mapfile name>" << endl; exit(0); } glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowPosition(50,50); glutInitWindowSize(600,600); int mainWindow = glutCreateWindow("Map"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(click); glutMotionFunc(drag); glutKeyboardFunc(keyboard); glShadeModel(GL_FLAT); mapList = glGenLists(1); if (!loadmap(argv[1])) { cout << "Error loading map file" << endl; } zoom_max = int((world_x_max - world_x_min) * 0.485); glutMainLoop(); }