6
votes

We have a 3D viewer that uses OpenGL, but our clients sometimes complain about it "not working". We suspect that most of these issues stem from them trying to use, what is in effect a modern 3d realtime game, on a businiss laptop computer.

How can we, in the windows msi installer we use, check for support for openGL?

And as a side note, if you can answer "List of OpenGL supported graphic cards?", that would also be greate. Strange that google doesnt help here..

3

3 Answers

9
votes

Depends on what the customers mean by "not working". It could be one of:

  1. it does not install/launch at all, because of lack of some OpenGL support.
  2. it launches, but crashes further on.
  3. it launches, does not crash, but rendering is corrupt.
  4. it launches and renders everything correctly, but performance is abysmal.

All Windows versions (since 95) have OpenGL support built-in. So it's unlikely to cause situation 1) above, unless you application requires higher OpenGL version.

However, that default OpenGL implementation is OpenGL 1.1 with software rendering. If user did not manually install drivers that have OpenGL support (any driver downloaded from NVIDIA/AMD/Intel site will have OpenGL), they will default to this slow and old implementation. This is quite likely to cause situations 3) and 4) above.

Even if OpenGL is available, on Windows OpenGL drivers are not very robust, to say mildly. Various bugs in the drivers are very likely to cause situation 2), where doing something valid causes a crash in the driver.

Here's a C++/WinAPI code snippet that creates a dummy OpenGL context and retrieves info (GL version, graphics card name, extensions etc.):

// setup minimal required GL
HWND wnd = CreateWindow(
    "STATIC",
    "GL",
    WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
    0, 0, 16, 16,
    NULL, NULL,
    AfxGetInstanceHandle(), NULL );
HDC dc = GetDC( wnd );

PIXELFORMATDESCRIPTOR pfd = {
    sizeof(PIXELFORMATDESCRIPTOR), 1,
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
    PFD_TYPE_RGBA, 32,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0,
    16, 0,
    0, PFD_MAIN_PLANE, 0, 0, 0, 0
};

int fmt = ChoosePixelFormat( dc, &pfd );
SetPixelFormat( dc, fmt, &pfd );

HGLRC rc = wglCreateContext( dc );
wglMakeCurrent( dc, rc );

// get information
const char* vendor = (const char*)glGetString(GL_VENDOR);
const char* renderer = (const char*)glGetString(GL_RENDERER);
const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
const char* version = (const char*)glGetString(GL_VERSION);

// DO SOMETHING WITH THOSE STRINGS HERE!

// cleanup
wglDeleteContext( rc );
ReleaseDC( wnd, dc );
DestroyWindow( wnd );

You could somehow plug that code into your installer or application and at least check GL version for being 1.1; this will detect "driver is not installed" situation. To work around actual OpenGL driver bugs, well, you have to figure them out and work around them. Lots of work.

1
votes

OpenGL is part of Windows since Windows NT or Win95. It's unlikely that you'll ever find a windows system where OpenGL is not pre-installed (e.g. Windows 3.1)

However, your application may need a more recent version of OpenGL than the default OpenGL 1.1 that comes with very old versions of windows. You can check that from your program. I don't know of any way how to find that from msi.

Note that the OpenGL gets updated via the graphic drivers, not by installing a service pack or so.

Regarding OpenGL enabled graphic cards: All have OpenGL. Even if the customer uses a ISA ET4000 graphic card from the stone ages he at least has OpenGL 1.1 via software-rendering.

1
votes

Windows ships with support for OpenGL 1.1 (as others have noted here). So, the problems your users are facing is due to extensions which have been added to OpenGL after 1.1. If you are using the GLEW library, it is pretty easy to check support for all the extensions you are using programmatically. Here's how to check for support of Occlusion Query:

if (GLEW_OK != glewInit())
{
    // GLEW failed!
    exit(1);
}

// Check if required extensions are supported
if (!GLEW_ARB_occlusion_query)
    cout << "Occlusion query not supported" << endl;

For more on using GLEW, see here.