diff src/video/win32/SDL_win32opengl.c @ 2150:abbe2c1dcf0a

Fixed bug #77 If the ARB pixel format selection fails, use a version of ChoosePixelFormat() that doesn't return a less capable format than was requested.
author Sam Lantinga <slouken@libsdl.org>
date Thu, 05 Jul 2007 06:14:26 +0000
parents 420716272158
children 114a541cfae2
line wrap: on
line diff
--- a/src/video/win32/SDL_win32opengl.c	Thu Jul 05 05:57:31 2007 +0000
+++ b/src/video/win32/SDL_win32opengl.c	Thu Jul 05 06:14:26 2007 +0000
@@ -155,6 +155,107 @@
     pfd->cStencilBits = _this->gl_config.stencil_size;
 }
 
+/* Choose the closest pixel format that meets or exceeds the target.
+   FIXME: Should we weight any particular attribute over any other?
+*/
+static int
+WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
+{
+    PIXELFORMATDESCRIPTOR pfd;
+    int count, index, best = 0;
+    unsigned int dist, best_dist = ~0U;
+
+    count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
+
+    for (index = 1; index <= count; index++) {
+
+        if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
+            continue;
+        }
+
+        if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
+            continue;
+        }
+
+        if (pfd.iLayerType != target->iLayerType) {
+            continue;
+        }
+        if (pfd.iPixelType != target->iPixelType) {
+            continue;
+        }
+
+        dist = 0;
+
+        if (pfd.cColorBits < target->cColorBits) {
+            continue;
+        } else {
+            dist += (pfd.cColorBits - target->cColorBits);
+        }
+        if (pfd.cRedBits < target->cRedBits) {
+            continue;
+        } else {
+            dist += (pfd.cRedBits - target->cRedBits);
+        }
+        if (pfd.cGreenBits < target->cGreenBits) {
+            continue;
+        } else {
+            dist += (pfd.cGreenBits - target->cGreenBits);
+        }
+        if (pfd.cBlueBits < target->cBlueBits) {
+            continue;
+        } else {
+            dist += (pfd.cBlueBits - target->cBlueBits);
+        }
+        if (pfd.cAlphaBits < target->cAlphaBits) {
+            continue;
+        } else {
+            dist += (pfd.cAlphaBits - target->cAlphaBits);
+        }
+        if (pfd.cAccumBits < target->cAccumBits) {
+            continue;
+        } else {
+            dist += (pfd.cAccumBits - target->cAccumBits);
+        }
+        if (pfd.cAccumRedBits < target->cAccumRedBits) {
+            continue;
+        } else {
+            dist += (pfd.cAccumRedBits - target->cAccumRedBits);
+        }
+        if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
+            continue;
+        } else {
+            dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
+        }
+        if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
+            continue;
+        } else {
+            dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
+        }
+        if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
+            continue;
+        } else {
+            dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
+        }
+        if (pfd.cDepthBits < target->cDepthBits) {
+            continue;
+        } else {
+            dist += (pfd.cDepthBits - target->cDepthBits);
+        }
+        if (pfd.cStencilBits < target->cStencilBits) {
+            continue;
+        } else {
+            dist += (pfd.cStencilBits - target->cStencilBits);
+        }
+
+        if (dist < best_dist) {
+            best = index;
+            best_dist = dist;
+        }
+    }
+
+    return best;
+}
+
 static SDL_bool
 HasExtension(const char *extension, const char *extensions)
 {
@@ -398,7 +499,7 @@
         || !_this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
                                                     1, &pixel_format,
                                                     &matching) || !matching) {
-        pixel_format = ChoosePixelFormat(hdc, &pfd);
+        pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
     }
     if (!pixel_format) {
         SDL_SetError("No matching GL pixel format available");