From 281013002de3751f2ecb6c28cf90ac4695a9b3de Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 8 Apr 2014 18:57:43 +0200 Subject: [PATCH] Added GLFW_DONT_CARE. This changes the behavior of framebuffer hints set to zero. Before, zero meant that any value was acceptable. This changes zero to be an explicit preference and adds GLFW_DONT_CARE to mean that any value is equally acceptable. Fixes #70. --- README.md | 1 + docs/window.dox | 37 +++++++++++++++------------- include/GLFW/glfw3.h | 2 ++ src/context.c | 34 +++++++++++++------------- src/internal.h | 20 +++++++-------- src/monitor.c | 12 ++++++--- src/nsgl_context.m | 58 ++++++++++++++++++++++++++++++-------------- src/window.c | 44 ++++++++++++++------------------- tests/glfwinfo.c | 14 +++++++++++ 9 files changed, 131 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index a7ecbfc1..e6822bfc 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ GLFW bundles a number of dependencies in the `deps/` directory. the client area of a window - Added `GLFW_AUTO_ICONIFY` for controlling whether full screen windows automatically iconify (and restore the previous video mode) on focus loss + - Added `GLFW_DONT_CARE` for indicating that any value is acceptable - Added `GLFW_INCLUDE_ES31` for including the OpenGL ES 3.1 header - Added *partial and experimental* support for Wayland - Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even diff --git a/docs/window.dox b/docs/window.dox index d6dfdf37..eece9c8e 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -126,19 +126,22 @@ This hint is ignored for windowed mode windows. The `GLFW_RED_BITS`, `GLFW_GREEN_BITS`, `GLFW_BLUE_BITS`, `GLFW_ALPHA_BITS`, `GLFW_DEPTH_BITS` and `GLFW_STENCIL_BITS` hints specify the desired bit -depths of the various components of the default framebuffer. +depths of the various components of the default framebuffer. `GLFW_DONT_CARE` +means the application has no preference. The `GLFW_ACCUM_RED_BITS`, `GLFW_ACCUM_GREEN_BITS`, `GLFW_ACCUM_BLUE_BITS` and `GLFW_ACCUM_ALPHA_BITS` hints specify the desired bit depths of the -various components of the accumulation buffer. +various components of the accumulation buffer. `GLFW_DONT_CARE` means the +application has no preference. The `GLFW_AUX_BUFFERS` hint specifies the desired number of auxiliary -buffers. +buffers. `GLFW_DONT_CARE` means the application has no preference. The `GLFW_STEREO` hint specifies whether to use stereoscopic rendering. The `GLFW_SAMPLES` hint specifies the desired number of samples to use for -multisampling. Zero disables multisampling. +multisampling. Zero disables multisampling. `GLFW_DONT_CARE` means the +application has no preference. The `GLFW_SRGB_CAPABLE` hint specifies whether the framebuffer should be sRGB capable. @@ -201,19 +204,19 @@ a robustness strategy. | `GLFW_VISIBLE` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_DECORATED` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_AUTO_ICONIFY` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | -| `GLFW_RED_BITS` | 8 | 0 to `INT_MAX` | -| `GLFW_GREEN_BITS` | 8 | 0 to `INT_MAX` | -| `GLFW_BLUE_BITS` | 8 | 0 to `INT_MAX` | -| `GLFW_ALPHA_BITS` | 8 | 0 to `INT_MAX` | -| `GLFW_DEPTH_BITS` | 24 | 0 to `INT_MAX` | -| `GLFW_STENCIL_BITS` | 8 | 0 to `INT_MAX` | -| `GLFW_ACCUM_RED_BITS` | 0 | 0 to `INT_MAX` | -| `GLFW_ACCUM_GREEN_BITS` | 0 | 0 to `INT_MAX` | -| `GLFW_ACCUM_BLUE_BITS` | 0 | 0 to `INT_MAX` | -| `GLFW_ACCUM_ALPHA_BITS` | 0 | 0 to `INT_MAX` | -| `GLFW_AUX_BUFFERS` | 0 | 0 to `INT_MAX` | -| `GLFW_SAMPLES` | 0 | 0 to `INT_MAX` | -| `GLFW_REFRESH_RATE` | 0 | 0 to `INT_MAX` | +| `GLFW_RED_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_GREEN_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_BLUE_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_ALPHA_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_DEPTH_BITS` | 24 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_STENCIL_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_ACCUM_RED_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_ACCUM_GREEN_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_ACCUM_BLUE_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_ACCUM_ALPHA_BITS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_AUX_BUFFERS` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_SAMPLES` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | +| `GLFW_REFRESH_RATE` | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | | `GLFW_STEREO` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_SRGB_CAPABLE` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_CLIENT_API` | `GLFW_OPENGL_API` | `GLFW_OPENGL_API` or `GLFW_OPENGL_ES_API` | diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 8ac11c15..553aecbb 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -546,6 +546,8 @@ extern "C" { #define GLFW_CONNECTED 0x00040001 #define GLFW_DISCONNECTED 0x00040002 +#define GLFW_DONT_CARE -1 + /************************************************************************* * GLFW API types diff --git a/src/context.c b/src/context.c index d331d46e..6b53f792 100644 --- a/src/context.c +++ b/src/context.c @@ -235,8 +235,11 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, if (desired->stencilBits > 0 && current->stencilBits == 0) missing++; - if (desired->auxBuffers > 0 && current->auxBuffers < desired->auxBuffers) + if (desired->auxBuffers > 0 && + current->auxBuffers < desired->auxBuffers) + { missing += desired->auxBuffers - current->auxBuffers; + } if (desired->samples > 0 && current->samples == 0) { @@ -254,19 +257,19 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, { colorDiff = 0; - if (desired->redBits > 0) + if (desired->redBits != GLFW_DONT_CARE) { colorDiff += (desired->redBits - current->redBits) * (desired->redBits - current->redBits); } - if (desired->greenBits > 0) + if (desired->greenBits != GLFW_DONT_CARE) { colorDiff += (desired->greenBits - current->greenBits) * (desired->greenBits - current->greenBits); } - if (desired->blueBits > 0) + if (desired->blueBits != GLFW_DONT_CARE) { colorDiff += (desired->blueBits - current->blueBits) * (desired->blueBits - current->blueBits); @@ -277,59 +280,56 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, { extraDiff = 0; - if (desired->alphaBits > 0) + if (desired->alphaBits != GLFW_DONT_CARE) { extraDiff += (desired->alphaBits - current->alphaBits) * (desired->alphaBits - current->alphaBits); } - if (desired->depthBits > 0) + if (desired->depthBits != GLFW_DONT_CARE) { extraDiff += (desired->depthBits - current->depthBits) * (desired->depthBits - current->depthBits); } - if (desired->stencilBits > 0) + if (desired->stencilBits != GLFW_DONT_CARE) { extraDiff += (desired->stencilBits - current->stencilBits) * (desired->stencilBits - current->stencilBits); } - if (desired->accumRedBits > 0) + if (desired->accumRedBits != GLFW_DONT_CARE) { extraDiff += (desired->accumRedBits - current->accumRedBits) * (desired->accumRedBits - current->accumRedBits); } - if (desired->accumGreenBits > 0) + if (desired->accumGreenBits != GLFW_DONT_CARE) { extraDiff += (desired->accumGreenBits - current->accumGreenBits) * (desired->accumGreenBits - current->accumGreenBits); } - if (desired->accumBlueBits > 0) + if (desired->accumBlueBits != GLFW_DONT_CARE) { extraDiff += (desired->accumBlueBits - current->accumBlueBits) * (desired->accumBlueBits - current->accumBlueBits); } - if (desired->accumAlphaBits > 0) + if (desired->accumAlphaBits != GLFW_DONT_CARE) { extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) * (desired->accumAlphaBits - current->accumAlphaBits); } - if (desired->samples > 0) + if (desired->samples != GLFW_DONT_CARE) { extraDiff += (desired->samples - current->samples) * (desired->samples - current->samples); } - if (desired->sRGB) - { - if (!current->sRGB) - extraDiff++; - } + if (desired->sRGB && !current->sRGB) + extraDiff++; } // Figure out if the current one is better than the best one found so far diff --git a/src/internal.h b/src/internal.h index fef8dc48..7b31725a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -197,9 +197,9 @@ struct _GLFWfbconfig int accumBlueBits; int accumAlphaBits; int auxBuffers; - GLboolean stereo; + int stereo; int samples; - GLboolean sRGB; + int sRGB; // This is defined in the context API's context.h _GLFW_PLATFORM_FBCONFIG; @@ -317,19 +317,19 @@ struct _GLFWlibrary int accumBlueBits; int accumAlphaBits; int auxBuffers; - GLboolean stereo; - GLboolean resizable; - GLboolean visible; - GLboolean decorated; - GLboolean autoIconify; + int stereo; + int resizable; + int visible; + int decorated; + int autoIconify; int samples; - GLboolean sRGB; + int sRGB; int refreshRate; int api; int major; int minor; - GLboolean forward; - GLboolean debug; + int forward; + int debug; int profile; int robustness; } hints; diff --git a/src/monitor.c b/src/monitor.c index 662c4266..26a6f1d5 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -220,15 +220,21 @@ const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, { current = monitor->modes + i; - colorDiff = abs((current->redBits + current->greenBits + current->blueBits) - - (desired->redBits + desired->greenBits + desired->blueBits)); + colorDiff = 0; + + if (desired->redBits != GLFW_DONT_CARE) + colorDiff += abs(current->redBits - desired->redBits); + if (desired->greenBits != GLFW_DONT_CARE) + colorDiff += abs(current->greenBits - desired->greenBits); + if (desired->blueBits != GLFW_DONT_CARE) + colorDiff += abs(current->blueBits - desired->blueBits); sizeDiff = abs((current->width - desired->width) * (current->width - desired->width) + (current->height - desired->height) * (current->height - desired->height)); - if (desired->refreshRate) + if (desired->refreshRate != GLFW_DONT_CARE) rateDiff = abs(current->refreshRate - desired->refreshRate); else rateDiff = UINT_MAX - current->refreshRate; diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 32ef85c8..5bd3e83f 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -65,13 +65,6 @@ int _glfwCreateContext(_GLFWwindow* window, { unsigned int attributeCount = 0; - // OS X needs non-zero color size, so set resonable values - int colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits; - if (colorBits == 0) - colorBits = 24; - else if (colorBits < 15) - colorBits = 15; - if (ctxconfig->api == GLFW_OPENGL_ES_API) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, @@ -142,33 +135,62 @@ int _glfwCreateContext(_GLFWwindow* window, ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); + if (fbconfig->redBits != GLFW_DONT_CARE && + fbconfig->greenBits != GLFW_DONT_CARE && + fbconfig->blueBits != GLFW_DONT_CARE) + { + int colorBits = fbconfig->redBits + + fbconfig->greenBits + + fbconfig->blueBits; - if (fbconfig->alphaBits > 0) + // OS X needs non-zero color size, so set resonable values + if (colorBits == 0) + colorBits = 24; + else if (colorBits < 15) + colorBits = 15; + + ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); + } + + if (fbconfig->alphaBits != GLFW_DONT_CARE) ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); - if (fbconfig->depthBits > 0) + if (fbconfig->depthBits != GLFW_DONT_CARE) ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); - if (fbconfig->stencilBits > 0) + if (fbconfig->stencilBits != GLFW_DONT_CARE) ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); - int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits + - fbconfig->accumBlueBits + fbconfig->accumAlphaBits; + if (fbconfig->accumRedBits != GLFW_DONT_CARE && + fbconfig->accumGreenBits != GLFW_DONT_CARE && + fbconfig->accumBlueBits != GLFW_DONT_CARE && + fbconfig->accumAlphaBits != GLFW_DONT_CARE) + { + const int accumBits = fbconfig->accumRedBits + + fbconfig->accumGreenBits + + fbconfig->accumBlueBits + + fbconfig->accumAlphaBits; - if (accumBits > 0) ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits); + } - if (fbconfig->auxBuffers > 0) + if (fbconfig->auxBuffers != GLFW_DONT_CARE) ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); if (fbconfig->stereo) ADD_ATTR(NSOpenGLPFAStereo); - if (fbconfig->samples > 0) + if (fbconfig->samples != GLFW_DONT_CARE) { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); - ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + if (fbconfig->samples == 0) + { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 0); + } + else + { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + } } // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB diff --git a/src/window.c b/src/window.c index bf26e806..39b1c691 100644 --- a/src/window.c +++ b/src/window.c @@ -32,14 +32,6 @@ #include -// Return the maxiumum of the specified values -// -static int Max(int a, int b) -{ - return (a > b) ? a : b; -} - - ////////////////////////////////////////////////////////////////////////// ////// GLFW event API ////// ////////////////////////////////////////////////////////////////////////// @@ -151,20 +143,20 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, } // Set up desired framebuffer config - fbconfig.redBits = Max(_glfw.hints.redBits, 0); - fbconfig.greenBits = Max(_glfw.hints.greenBits, 0); - fbconfig.blueBits = Max(_glfw.hints.blueBits, 0); - fbconfig.alphaBits = Max(_glfw.hints.alphaBits, 0); - fbconfig.depthBits = Max(_glfw.hints.depthBits, 0); - fbconfig.stencilBits = Max(_glfw.hints.stencilBits, 0); - fbconfig.accumRedBits = Max(_glfw.hints.accumRedBits, 0); - fbconfig.accumGreenBits = Max(_glfw.hints.accumGreenBits, 0); - fbconfig.accumBlueBits = Max(_glfw.hints.accumBlueBits, 0); - fbconfig.accumAlphaBits = Max(_glfw.hints.accumAlphaBits, 0); - fbconfig.auxBuffers = Max(_glfw.hints.auxBuffers, 0); - fbconfig.stereo = _glfw.hints.stereo ? GL_TRUE : GL_FALSE; - fbconfig.samples = Max(_glfw.hints.samples, 0); - fbconfig.sRGB = _glfw.hints.sRGB ? GL_TRUE : GL_FALSE; + fbconfig.redBits = _glfw.hints.redBits; + fbconfig.greenBits = _glfw.hints.greenBits; + fbconfig.blueBits = _glfw.hints.blueBits; + fbconfig.alphaBits = _glfw.hints.alphaBits; + fbconfig.depthBits = _glfw.hints.depthBits; + fbconfig.stencilBits = _glfw.hints.stencilBits; + fbconfig.accumRedBits = _glfw.hints.accumRedBits; + fbconfig.accumGreenBits = _glfw.hints.accumGreenBits; + fbconfig.accumBlueBits = _glfw.hints.accumBlueBits; + fbconfig.accumAlphaBits = _glfw.hints.accumAlphaBits; + fbconfig.auxBuffers = _glfw.hints.auxBuffers; + fbconfig.stereo = _glfw.hints.stereo; + fbconfig.samples = _glfw.hints.samples; + fbconfig.sRGB = _glfw.hints.sRGB; // Set up desired window config wndconfig.width = width; @@ -202,10 +194,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, // Set up desired video mode window->videoMode.width = width; window->videoMode.height = height; - window->videoMode.redBits = Max(_glfw.hints.redBits, 0); - window->videoMode.greenBits = Max(_glfw.hints.greenBits, 0); - window->videoMode.blueBits = Max(_glfw.hints.blueBits, 0); - window->videoMode.refreshRate = Max(_glfw.hints.refreshRate, 0); + window->videoMode.redBits = _glfw.hints.redBits; + window->videoMode.greenBits = _glfw.hints.greenBits; + window->videoMode.blueBits = _glfw.hints.blueBits; + window->videoMode.refreshRate = _glfw.hints.refreshRate; } window->monitor = wndconfig.monitor; diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index fc312dee..07c1142e 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -284,6 +284,20 @@ int main(int argc, char** argv) if (strategy) glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, strategy); + glfwWindowHint(GLFW_RED_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_GREEN_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_BLUE_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ALPHA_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_DEPTH_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_STENCIL_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_RED_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_GREEN_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_BLUE_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_AUX_BUFFERS, GLFW_DONT_CARE); + glfwWindowHint(GLFW_SAMPLES, GLFW_DONT_CARE); + glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_DONT_CARE); + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); window = glfwCreateWindow(200, 200, "Version", NULL, NULL);