From 06640efa613fc4e707614eaca6facc7fb26c5f4a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 1 May 2008 14:44:49 +0200 Subject: [PATCH] opengl32: Dynamically load libGLU. Based on a patch by Roderick Colenbrander. --- configure | 3 +- configure.ac | 3 +- dlls/glu32/Makefile.in | 2 +- dlls/opengl32/wgl.c | 84 +++++++++++++++++++++++++++++++++++------- 4 files changed, 73 insertions(+), 19 deletions(-) diff --git a/configure b/configure index b732efd7efb..0ee0b8c60cb 100755 --- a/configure +++ b/configure @@ -11173,8 +11173,7 @@ cat >>confdefs.h <<_ACEOF #define SONAME_LIBGLU "$ac_cv_lib_soname_GLU" _ACEOF - OPENGL_LIBS="$OPENGL_LIBS -lGLU" - GLU32FILES='$(GLU32FILES)' + GLU32FILES='$(GLU32FILES)' fi fi diff --git a/configure.ac b/configure.ac index 946fa94524c..33562e3b6e9 100644 --- a/configure.ac +++ b/configure.ac @@ -746,8 +746,7 @@ This probably prevents linking to OpenGL. Try deleting the file and restarting c $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS) if test "$ac_cv_header_GL_glu_h" = "yes" then - WINE_CHECK_SONAME(GLU,gluLookAt,[OPENGL_LIBS="$OPENGL_LIBS -lGLU" - GLU32FILES='$(GLU32FILES)'],, + WINE_CHECK_SONAME(GLU,gluLookAt,[GLU32FILES='$(GLU32FILES)'],, [$OPENGL_LIBS $X_LIBS $X_PRE_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS]) fi WINE_NOTICE_WITH(glu,[test "x$ac_cv_lib_soname_GLU" = "x"], diff --git a/dlls/glu32/Makefile.in b/dlls/glu32/Makefile.in index 98d15e8e174..2fdbd994854 100644 --- a/dlls/glu32/Makefile.in +++ b/dlls/glu32/Makefile.in @@ -6,7 +6,7 @@ MODULE = glu32.dll IMPORTLIB = glu32 IMPORTS = kernel32 EXTRAINCL = @X_CFLAGS@ -EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ +EXTRALIBS = -lGLU @OPENGL_LIBS@ @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ C_SRCS = \ glu.c diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 2e3d1183792..6fbdeb4bdd1 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -56,6 +56,19 @@ typedef struct wine_wgl_s { /** global wgl object */ static wine_wgl_t wine_wgl; +#ifdef SONAME_LIBGLU +#define MAKE_FUNCPTR(f) static typeof(f) * p##f; +MAKE_FUNCPTR(gluNewTess) +MAKE_FUNCPTR(gluDeleteTess) +MAKE_FUNCPTR(gluTessBeginContour) +MAKE_FUNCPTR(gluTessBeginPolygon) +MAKE_FUNCPTR(gluTessCallback) +MAKE_FUNCPTR(gluTessEndContour) +MAKE_FUNCPTR(gluTessEndPolygon) +MAKE_FUNCPTR(gluTessVertex) +#undef MAKE_FUNCPTR +#endif /* SONAME_LIBGLU */ + /* x11drv GDI escapes */ #define X11DRV_ESCAPE 6789 enum x11drv_escape_codes @@ -76,6 +89,7 @@ void (*wine_tsx11_lock_ptr)(void) = NULL; void (*wine_tsx11_unlock_ptr)(void) = NULL; static HMODULE opengl32_handle; +static void* libglu_handle = NULL; static char* internal_gl_disabled_extensions = NULL; static char* internal_gl_extensions = NULL; @@ -315,6 +329,42 @@ BOOL WINAPI wglSwapLayerBuffers(HDC hdc, #ifdef SONAME_LIBGLU +static void *load_libglu(void) +{ + static int already_loaded; + void *handle; + + if (already_loaded) return libglu_handle; + already_loaded = 1; + + TRACE("Trying to load GLU library: %s\n", SONAME_LIBGLU); + handle = wine_dlopen(SONAME_LIBGLU, RTLD_NOW, NULL, 0); + if (!handle) + { + WARN("Failed to load %s\n", SONAME_LIBGLU); + return NULL; + } + +#define LOAD_FUNCPTR(f) if((p##f = (void*)wine_dlsym(handle, #f, NULL, 0)) == NULL) goto sym_not_found; +LOAD_FUNCPTR(gluNewTess) +LOAD_FUNCPTR(gluDeleteTess) +LOAD_FUNCPTR(gluTessBeginContour) +LOAD_FUNCPTR(gluTessBeginPolygon) +LOAD_FUNCPTR(gluTessCallback) +LOAD_FUNCPTR(gluTessEndContour) +LOAD_FUNCPTR(gluTessEndPolygon) +LOAD_FUNCPTR(gluTessVertex) +#undef LOAD_FUNCPTR + libglu_handle = handle; + return handle; + +sym_not_found: + WARN("Unable to load function ptrs from libGLU\n"); + /* Close the library as we won't use it */ + wine_dlclose(handle, NULL, 0); + return NULL; +} + static void fixed_to_double(POINTFX fixed, UINT em_size, GLdouble vertex[3]) { vertex[0] = (fixed.x.value + (GLdouble)fixed.x.fract / (1 << 16)) / em_size; @@ -365,14 +415,19 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc, TRACE("(%p, %d, %d, %d, %f, %f, %d, %p, %s)\n", hdc, first, count, listBase, deviation, extrusion, format, lpgmf, unicode ? "W" : "A"); + if (!load_libglu()) + { + ERR("libGLU is required for this function but isn't loaded\n"); + return FALSE; + } ENTER_GL(); - tess = gluNewTess(); + tess = pgluNewTess(); if(tess) { - gluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)tess_callback_vertex); - gluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)tess_callback_begin); - gluTessCallback(tess, GLU_TESS_END, tess_callback_end); + pgluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)tess_callback_vertex); + pgluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)tess_callback_begin); + pgluTessCallback(tess, GLU_TESS_END, tess_callback_end); } LEAVE_GL(); @@ -430,17 +485,17 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc, ENTER_GL(); glNewList(listBase++, GL_COMPILE); - gluTessBeginPolygon(tess, NULL); + pgluTessBeginPolygon(tess, NULL); pph = (TTPOLYGONHEADER*)buf; while((BYTE*)pph < buf + needed) { TRACE("\tstart %d, %d\n", pph->pfxStart.x.value, pph->pfxStart.y.value); - gluTessBeginContour(tess); + pgluTessBeginContour(tess); fixed_to_double(pph->pfxStart, em_size, vertices); - gluTessVertex(tess, vertices, vertices); + pgluTessVertex(tess, vertices, vertices); vertices += 3; ppc = (TTPOLYCURVE*)((char*)pph + sizeof(*pph)); @@ -454,7 +509,7 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc, { TRACE("\t\tline to %d, %d\n", ppc->apfx[i].x.value, ppc->apfx[i].y.value); fixed_to_double(ppc->apfx[i], em_size, vertices); - gluTessVertex(tess, vertices, vertices); + pgluTessVertex(tess, vertices, vertices); vertices += 3; } break; @@ -467,28 +522,28 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc, ppc->apfx[i * 2].x.value, ppc->apfx[i * 3].y.value, ppc->apfx[i * 2 + 1].x.value, ppc->apfx[i * 3 + 1].y.value); fixed_to_double(ppc->apfx[i * 2], em_size, vertices); - gluTessVertex(tess, vertices, vertices); + pgluTessVertex(tess, vertices, vertices); vertices += 3; fixed_to_double(ppc->apfx[i * 2 + 1], em_size, vertices); - gluTessVertex(tess, vertices, vertices); + pgluTessVertex(tess, vertices, vertices); vertices += 3; } break; default: ERR("\t\tcurve type = %d\n", ppc->wType); - gluTessEndContour(tess); + pgluTessEndContour(tess); goto error_in_list; } ppc = (TTPOLYCURVE*)((char*)ppc + sizeof(*ppc) + (ppc->cpfx - 1) * sizeof(POINTFX)); } - gluTessEndContour(tess); + pgluTessEndContour(tess); pph = (TTPOLYGONHEADER*)((char*)pph + pph->cb); } error_in_list: - gluTessEndPolygon(tess); + pgluTessEndPolygon(tess); glTranslated((GLdouble)gm.gmCellIncX / em_size, (GLdouble)gm.gmCellIncY / em_size, 0.0); glEndList(); LEAVE_GL(); @@ -498,7 +553,7 @@ error_in_list: error: DeleteObject(SelectObject(hdc, old_font)); - gluDeleteTess(tess); + pgluDeleteTess(tess); return TRUE; } @@ -676,6 +731,7 @@ static BOOL process_attach(void) static void process_detach(void) { + if (libglu_handle) wine_dlclose(libglu_handle, NULL, 0); HeapFree(GetProcessHeap(), 0, internal_gl_extensions); HeapFree(GetProcessHeap(), 0, internal_gl_disabled_extensions); }