|
|
|
@ -31,12 +31,170 @@ |
|
|
|
|
#include "internal.h" |
|
|
|
|
|
|
|
|
|
#include <string.h> |
|
|
|
|
#include <limits.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////// GLFW internal API //////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Return the available framebuffer config closest to the desired values
|
|
|
|
|
// This is based on the manual GLX Visual selection from 2.6
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, |
|
|
|
|
const _GLFWfbconfig* alternatives, |
|
|
|
|
unsigned int count) |
|
|
|
|
{ |
|
|
|
|
unsigned int i; |
|
|
|
|
unsigned int missing, leastMissing = UINT_MAX; |
|
|
|
|
unsigned int colorDiff, leastColorDiff = UINT_MAX; |
|
|
|
|
unsigned int extraDiff, leastExtraDiff = UINT_MAX; |
|
|
|
|
const _GLFWfbconfig* current; |
|
|
|
|
const _GLFWfbconfig* closest = NULL; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) |
|
|
|
|
{ |
|
|
|
|
current = alternatives + i; |
|
|
|
|
|
|
|
|
|
if (desired->stereo > 0 && current->stereo == 0) |
|
|
|
|
{ |
|
|
|
|
// Stereo is a hard constraint
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Count number of missing buffers
|
|
|
|
|
{ |
|
|
|
|
missing = 0; |
|
|
|
|
|
|
|
|
|
if (desired->alphaBits > 0 && current->alphaBits == 0) |
|
|
|
|
missing++; |
|
|
|
|
|
|
|
|
|
if (desired->depthBits > 0 && current->depthBits == 0) |
|
|
|
|
missing++; |
|
|
|
|
|
|
|
|
|
if (desired->stencilBits > 0 && current->stencilBits == 0) |
|
|
|
|
missing++; |
|
|
|
|
|
|
|
|
|
if (desired->auxBuffers > 0 && current->auxBuffers < desired->auxBuffers) |
|
|
|
|
missing += desired->auxBuffers - current->auxBuffers; |
|
|
|
|
|
|
|
|
|
if (desired->samples > 0 && current->samples == 0) |
|
|
|
|
{ |
|
|
|
|
// Technically, several multisampling buffers could be
|
|
|
|
|
// involved, but that's a lower level implementation detail and
|
|
|
|
|
// not important to us here, so we count them as one
|
|
|
|
|
missing++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// These polynomials make many small channel size differences matter
|
|
|
|
|
// less than one large channel size difference
|
|
|
|
|
|
|
|
|
|
// Calculate color channel size difference value
|
|
|
|
|
{ |
|
|
|
|
colorDiff = 0; |
|
|
|
|
|
|
|
|
|
if (desired->redBits > 0) |
|
|
|
|
{ |
|
|
|
|
colorDiff += (desired->redBits - current->redBits) * |
|
|
|
|
(desired->redBits - current->redBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->greenBits > 0) |
|
|
|
|
{ |
|
|
|
|
colorDiff += (desired->greenBits - current->greenBits) * |
|
|
|
|
(desired->greenBits - current->greenBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->blueBits > 0) |
|
|
|
|
{ |
|
|
|
|
colorDiff += (desired->blueBits - current->blueBits) * |
|
|
|
|
(desired->blueBits - current->blueBits); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Calculate non-color channel size difference value
|
|
|
|
|
{ |
|
|
|
|
extraDiff = 0; |
|
|
|
|
|
|
|
|
|
if (desired->alphaBits > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->alphaBits - current->alphaBits) * |
|
|
|
|
(desired->alphaBits - current->alphaBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->depthBits > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->depthBits - current->depthBits) * |
|
|
|
|
(desired->depthBits - current->depthBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->stencilBits > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->stencilBits - current->stencilBits) * |
|
|
|
|
(desired->stencilBits - current->stencilBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->accumRedBits > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->accumRedBits - current->accumRedBits) * |
|
|
|
|
(desired->accumRedBits - current->accumRedBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->accumGreenBits > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->accumGreenBits - current->accumGreenBits) * |
|
|
|
|
(desired->accumGreenBits - current->accumGreenBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->accumBlueBits > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->accumBlueBits - current->accumBlueBits) * |
|
|
|
|
(desired->accumBlueBits - current->accumBlueBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->accumAlphaBits > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) * |
|
|
|
|
(desired->accumAlphaBits - current->accumAlphaBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (desired->samples > 0) |
|
|
|
|
{ |
|
|
|
|
extraDiff += (desired->samples - current->samples) * |
|
|
|
|
(desired->samples - current->samples); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Figure out if the current one is better than the best one found so far
|
|
|
|
|
// Least number of missing buffers is the most important heuristic,
|
|
|
|
|
// then color buffer size match and lastly size match for other buffers
|
|
|
|
|
|
|
|
|
|
if (missing < leastMissing) |
|
|
|
|
closest = current; |
|
|
|
|
else if (missing == leastMissing) |
|
|
|
|
{ |
|
|
|
|
if ((colorDiff < leastColorDiff) || |
|
|
|
|
(colorDiff == leastColorDiff && extraDiff < leastExtraDiff)) |
|
|
|
|
{ |
|
|
|
|
closest = current; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (current == closest) |
|
|
|
|
{ |
|
|
|
|
leastMissing = missing; |
|
|
|
|
leastColorDiff = colorDiff; |
|
|
|
|
leastExtraDiff = extraDiff; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return closest; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Parses the OpenGL version string and extracts the version number
|
|
|
|
|
//========================================================================
|
|
|
|
|