From 1f6cc300ccfac5aa072517a85bf7031e2d61b620 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Fri, 30 Jul 2004 07:16:33 +0000 Subject: Fixed a problem in GL init code which prevented zinc from working with Mesa. A (hopefully) more useful warning is emitted when openGL rendering is not good enough (most often 24 bits buffer or stencil not available). Tweaking and bending in the openGL init code to make it work better. --- generic/tkZinc.c | 85 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 29 deletions(-) (limited to 'generic/tkZinc.c') diff --git a/generic/tkZinc.c b/generic/tkZinc.c index dfa9614..0e4d878 100644 --- a/generic/tkZinc.c +++ b/generic/tkZinc.c @@ -139,10 +139,12 @@ static int ZnMajorGlx, ZnMinorGlx; static int ZnGLAttribs[] = { GLX_RGBA, GLX_DOUBLEBUFFER, - GLX_BUFFER_SIZE, 24, - /*GLX_BUFFER_SIZE, 32,*/ + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, GLX_STENCIL_SIZE, 8, /*GLX_ALPHA_SIZE, 8,*/ + GLX_DEPTH_SIZE, 0, None }; #endif @@ -916,6 +918,7 @@ ZnGLMakeCurrent(Display *dpy, ZnGLContextEntry *ce; ce = ZnGetGLContext(dpy); + if (!wi) { /* Get a zinc widget from the context struct * for this display. If no more are left, @@ -983,12 +986,10 @@ ZnGLSwapBuffers(ZnGLContextEntry *ce, #ifdef GL static void -InitRendering(ZnWInfo *wi) +InitRendering1(ZnWInfo *wi) { ZnGLContextEntry *ce; ZnGLContext gl_context; - GLfloat r[2]; /* Min, Max */ - GLint i[1]; if (wi->render) { # ifdef _WIN32 @@ -1023,12 +1024,13 @@ InitRendering(ZnWInfo *wi) ce->pfd.iLayerType = PFD_MAIN_PLANE; ce->ipixel = ChoosePixelFormat(ce->hdc, &ce->pfd); /*printf("ipixel=%d dwFlags=0x%x req=0x%x iPixelType=%d hdc=%d\n", - ce->ipixel, - ce->pfd.dwFlags, + ce->ipixel, ce->pfd.dwFlags, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, ce->pfd.iPixelType==PFD_TYPE_RGBA, ce->hdc);*/ - if (!ce->ipixel) { + if (!ce->ipixel || + (ce->pfd.cRedBits != 8) || (ce->pfd.cGreenBits != 8) || (ce->pfd.cBlueBits != 8) || + (ce->pfd.cStencilBits != 8)) { fprintf(stderr, "ChoosePixelFormat failed\n"); } @@ -1135,7 +1137,17 @@ InitRendering(ZnWInfo *wi) Tk_SetWindowVisual(wi->win, gl_visual->visual, 24, colormap); } # endif /* _WIN32 */ + } +} + +static void +InitRendering2(ZnWInfo *wi) +{ + ZnGLContextEntry *ce; + GLfloat r[2]; /* Min, Max */ + GLint i[1]; + if (wi->render) { ce = ZnGLMakeCurrent(wi->dpy, wi); glGetFloatv(ZN_GL_LINE_WIDTH_RANGE, r); ce->max_line_width = r[1]; @@ -1217,6 +1229,17 @@ ZincObjCmd(ClientData client_data, /* Main window associated with } } } + if (has_gl) { + XVisualInfo *visual = glXChooseVisual(dpy, + XScreenNumberOfScreen(screen), + ZnGLAttribs); + if (visual) { + XFree(visual); + } + else { + has_gl = False; + } + } # endif #endif @@ -1228,16 +1251,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with Tcl_AppendResult(interp, " GL", NULL); # else if (has_gl) { - XVisualInfo *visual = glXChooseVisual(dpy, - XScreenNumberOfScreen(screen), - ZnGLAttribs); - if (visual) { - Tcl_AppendResult(interp, " GL", NULL); - XFree(visual); - } - else { - has_gl = False; - } + Tcl_AppendResult(interp, " GL", NULL); } # endif #endif @@ -1268,7 +1282,6 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->real_top = None; ASSIGN(wi->flags, ZN_HAS_GL, has_gl); - #if defined(SHAPE) && !defined(_WIN32) ASSIGN(wi->flags, ZN_HAS_X_SHAPE, XQueryExtension(wi->dpy, "SHAPE", &major_op, &first_evt, &first_err)); @@ -1429,14 +1442,6 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->damaged_area.corner.x = wi->width = wi->opt_width; wi->damaged_area.corner.y = wi->height = wi->opt_height; - if (!has_gl) { - /* Do not allow GL rendering if not available. This should - * _not_ be changed later as images may have been created - * in the belief that GL will be available. - */ - wi->render = 0; - } - if (!wi->render) { /* * Allocate double buffer pixmap/image. @@ -1444,6 +1449,9 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->draw_buffer = Tk_GetPixmap(wi->dpy, RootWindowOfScreen(wi->screen), wi->width, wi->height, Tk_Depth(wi->win)); } + else { + InitRendering1(wi); + } #ifdef PTK Tcl_SetObjResult(interp, LangWidgetObj(interp, tkwin)); @@ -6487,6 +6495,14 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */ } wi->render = render; } + /* + * Reset the render mode if GL is not available. It'll be too late + * to do this after images or fonts have been allocated. + */ + if ((wi->render != 0) && ISCLEAR(wi->flags, ZN_HAS_GL)) { + fprintf(stderr, "GLX not available (need at least a 24 bits buffer with stencil)\n"); + wi->render = 0; + } #ifdef GL if (CONFIG_PROBE(FONT_SPEC) || !wi->font_tfi) { @@ -6729,6 +6745,14 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */ else if (wi->render < 0) { wi->render = 0; } + /* + * Reset the render mode if GL is not available. It'll be too late + * to do this after images or fonts have been allocated. + */ + else if ((wi->render != 0) && ISCLEAR(wi->flags, ZN_HAS_GL)) { + fprintf(stderr, "GLX not available (need at least a 24 bits buffer with stencil)\n"); + wi->render = 0; + } if ((mask & CONFIG_SCROLL_REGION) || init) { /* @@ -7065,7 +7089,7 @@ Event(ClientData client_data, /* Information about widget. */ if (!wi->gc) { SET(wi->flags, ZN_REALIZED); #ifdef GL - InitRendering(wi); + InitRendering2(wi); #endif /* @@ -8109,7 +8133,10 @@ Destroy(char *mem_ptr) /* Info about the widget. */ wglDeleteContext(ce->context); #else glXDestroyContext(ce->dpy, ce->context); - XFreeColormap(ce->dpy, ce->colormap); + /* + * This call seems to be a problem for X11/Mesa + */ + /*XFreeColormap(ce->dpy, ce->colormap);*/ XFree(ce->visual); #endif ZnListFree(ce->widgets); -- cgit v1.1