Step 1: Use the "Starting Quake Dialog". Multisample requires restarting the OpenGL window (and doing a DestroyWindow too, to the best of my knowledge). This is annoying and causes the screen to flash. Since I do not want that, I have the "Starting Quake" window create a GL context and check for multisample there.
sys_win.c
Code: Select all
#if 1 //johnfitz -- 0 to supress the 'starting quake' dialog
if (!isDedicated)
{
wplat.hwnd_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL);
if (wplat.hwnd_dialog)
{
RECT rect;
GetWindowRect (wplat.hwnd_dialog, &rect);
WIN_AdjustRectToCenterScreen (&rect);
SetWindowPos
(
wplat.hwnd_dialog,
NULL,
rect.left,
rect.top,
0,
0,
SWP_NOZORDER | SWP_NOSIZE
);
ShowWindow (wplat.hwnd_dialog, SW_SHOWDEFAULT);
UpdateWindow (wplat.hwnd_dialog);
SetForegroundWindow (wplat.hwnd_dialog);
}
}
#endif
Grabbing desktop bpp =
Code: Select all
vmode_t VID_Local_GetDesktopProperties (void)
{
DEVMODE devmode;
vmode_t desktop = {0};
if (!EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &devmode))
{
Sys_Error ("VID_UpdateDesktopProperties: EnumDisplaySettings failed\n");
return desktop;
}
desktop.type = MODE_FULLSCREEN;
desktop.width = devmode.dmPelsWidth;
desktop.height = devmode.dmPelsHeight;
desktop.bpp = devmode.dmBitsPerPel;
return desktop;
}
Code: Select all
if (wplat.hwnd_dialog)
{
if (vid_multisample.value)
{
// Poke into it for the PFD
HDC hdc = GetDC(wplat.hwnd_dialog);
int unused = WIN_SetupPixelFormat (hdc);
HGLRC wglHRC = wglCreateContext( hdc );
HDC wglHDC = wglGetCurrentDC();
int unused2 = wglMakeCurrent( hdc, wglHRC);
int ask_samples = (int)vid_multisample.value;
if (ask_samples != 2 && ask_samples != 4 && ask_samples != 8)
{
Con_Warning ("Multisamples requested \"%i\" is invalid, trying 4\n", ask_samples);
ask_samples = 4;
}
// Do it. We already have desktop properties
wplat.multisamples = WIN_InitMultisample (wplat.hInstance, wplat.hwnd_dialog, wplat.pfd, ask_samples, &wplat.forcePixelFormat);
// Your mission is complete. You may leave now ...
wglMakeCurrent(NULL, NULL);
wglDeleteContext(wglHRC);
ReleaseDC(wplat.hwnd_dialog, wglHDC);
ReleaseDC(wplat.hwnd_dialog, hdc);
if (wplat.multisamples)
Con_Printf ("Multisample x %i Enabled (Requested %i, Received %i).\n", wplat.multisamples, ask_samples, wplat.multisamples);
else Con_Warning ("Multisample: Requested but not available.\n");
} else Con_Printf ("Note: Multisample not requested\n");
// Post teardown
DestroyWindow (wplat.hwnd_dialog);
wplat.hwnd_dialog = NULL;
}
Code: Select all
BOOL WIN_SetupPixelFormat (HDC hDC)
{
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
8, // 8-bit stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
PIXELFORMATDESCRIPTOR test; //johnfitz
#ifdef SUPPORTS_MULTISAMPLE // Baker change
if (!wplat.multisamples)
{
#endif // Baker change + #ifdef SUPPORTS_MULTISAMPLE // Baker change
if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 )
{
Sys_Error ("Video: ChoosePixelFormat failed");
return FALSE;
}
#ifdef SUPPORTS_MULTISAMPLE // Baker change
} else pixelformat = wplat.forcePixelFormat; // Multisample overrride
#endif // Baker change + #ifdef SUPPORTS_MULTISAMPLE // Baker change
DescribePixelFormat(hDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &test);
if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE)
{
Sys_Error ("SetPixelFormat failed");
return FALSE;
}
#ifdef SUPPORTS_MULTISAMPLE // Baker change
memcpy (&wplat.pfd, &pfd, sizeof(pfd) );
#endif // Baker change + #ifdef SUPPORTS_MULTISAMPLE // Baker change
return TRUE;
}
Code: Select all
#include "vid_wglext.h" //WGL extensions
int arbMultisampleSupported = false;
int arbMultisampleFormat = 0;
// WGLisExtensionSupported: This Is A Form Of The Extension For WGL
int WGLisExtensionSupported(const char *extension)
{
const size_t extlen = strlen(extension);
const char *supported = NULL;
const char* p;
// Try To Use wglGetExtensionStringARB On Current DC, If Possible
PROC wglGetExtString = wglGetProcAddress("wglGetExtensionsStringARB");
if (wglGetExtString)
supported = ((char*(__stdcall*)(HDC))wglGetExtString)(wglGetCurrentDC());
// If That Failed, Try Standard Opengl Extensions String
if (supported == NULL)
supported = (char*)glGetString(GL_EXTENSIONS);
// If That Failed Too, Must Be No Extensions Supported
if (supported == NULL)
return false;
// Begin Examination At Start Of String, Increment By 1 On False Match
for (p = supported; ; p++)
{
// Advance p Up To The Next Possible Match
p = strstr(p, extension);
if (p == NULL)
return false; // No Match
// Make Sure That Match Is At The Start Of The String Or That
// The Previous Char Is A Space, Or Else We Could Accidentally
// Match "wglFunkywglExtension" With "wglExtension"
// Also, Make Sure That The Following Character Is Space Or NULL
// Or Else "wglExtensionTwo" Might Match "wglExtension"
if ((p==supported || p[-1]==' ') && (p[extlen]=='\0' || p[extlen]==' '))
return true; // Match
}
}
// InitMultisample: Used To Query The Multisample Frequencies
int WIN_InitMultisample (HINSTANCE hInstance,HWND hWnd,PIXELFORMATDESCRIPTOR pfd, int ask_samples, int* pixelForceFormat)
{
// See If The String Exists In WGL!
if (!WGLisExtensionSupported("WGL_ARB_multisample"))
{
arbMultisampleSupported=false;
return false;
}
{
// Get Our Pixel Format
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
if (!wglChoosePixelFormatARB)
{
arbMultisampleSupported=false;
return false;
}
{
// Get Our Current Device Context
HDC hDC = GetDC(hWnd);
int pixelFormat;
int valid;
UINT numFormats;
float fAttributes[] = {0,0};
// These Attributes Are The Bits We Want To Test For In Our Sample
// Everything Is Pretty Standard, The Only One We Want To
// Really Focus On Is The SAMPLE BUFFERS ARB And WGL SAMPLES
// These Two Are Going To Do The Main Testing For Whether Or Not
// We Support Multisampling On This Hardware.
int iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB, 24 /*currentbpp? Nah */, // Baker: Mirror current bpp color depth?
WGL_ALPHA_BITS_ARB,8,
WGL_DEPTH_BITS_ARB,16,
WGL_STENCIL_BITS_ARB,8, // Baker: Stencil bits
WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
WGL_SAMPLES_ARB, ask_samples /*multisample bits*/,
0,0
};
while (ask_samples == 8 || ask_samples == 4 || ask_samples == 2)
{
iAttributes[19] = ask_samples;
// First We Check To See If We Can Get A Pixel Format For 4 Samples
valid = wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
// If We Returned True, And Our Format Count Is Greater Than 1
if (valid && numFormats >= 1)
{
*pixelForceFormat = arbMultisampleFormat = pixelFormat;
return (arbMultisampleSupported = ask_samples);
}
ask_samples >>= 1; // Divide by 2
}
// Return Fail
return (arbMultisampleSupported = 0);
}
}
}