//Fill in the samplesSupported array void WINDOW::FindSamplesSupported() { int attributes[12]; int results[12]; //Find out how many PFDs there are attributes[0]=WGL_NUMBER_PIXEL_FORMATS_ARB; wglGetPixelFormatAttribivARB(hDC, 1, 0, 1, attributes, results); int numPfds=results[0]; //A list of attributes to check for each pixel format attributes[0] = WGL_RED_BITS_ARB; //bits attributes[1] = WGL_GREEN_BITS_ARB; attributes[2] = WGL_BLUE_BITS_ARB; attributes[3] = WGL_ALPHA_BITS_ARB; attributes[4] = WGL_DEPTH_BITS_ARB; attributes[5] = WGL_STENCIL_BITS_ARB; attributes[6] = WGL_DRAW_TO_WINDOW_ARB; //required to be true attributes[7] = WGL_SUPPORT_OPENGL_ARB; attributes[8] = WGL_DOUBLE_BUFFER_ARB; attributes[9] = WGL_ACCELERATION_ARB; //required to be FULL_ACCELERATION_ARB attributes[10] = WGL_SAMPLE_BUFFERS_ARB; //Multisample attributes[11] = WGL_SAMPLES_ARB; //Loop through all the pixel formats for(int i=0; i<numPfds; ++i) { //Get the attributes wglGetPixelFormatAttribivARB(hDC, i+1, 0, 12, attributes, results); //See if this format supports the bits required if( results[0]!=redBits || results[1]!=greenBits || results[2]!=blueBits || results[3]!=alphaBits || results[4]!=depthBits || results[5]!=stencilBits) continue; //Ensure required attributes are true if( results[6]==false || results[7]==false || results[8]==false || results[9]!=WGL_FULL_ACCELERATION_ARB) continue; //Save the number of samples in this pixel format if( results[10]==false) samplesSupported[0]=true; else if(results[11]<=16) //don't support >16x AA samplesSupported[results[11]]=true; } }
std::vector<int> CStdGLCtx::EnumerateMultiSamples() const { std::vector<int> result; std::vector<int> vec = EnumeratePixelFormats(hDC); for(unsigned int i = 0; i < vec.size(); ++i) { int attributes[] = { WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB }; const unsigned int n_attributes = 2; int results[2]; if(!wglGetPixelFormatAttribivARB(hDC, vec[i], 0, n_attributes, attributes, results)) continue; if(results[0] == 1) result.push_back(results[1]); } return result; }
static int GetPixelFormatForMS(HDC hDC, int samples) { std::vector<int> vec = EnumeratePixelFormats(hDC); for(unsigned int i = 0; i < vec.size(); ++i) { int attributes[] = { WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB }; const unsigned int n_attributes = 2; int results[2]; if(!wglGetPixelFormatAttribivARB(hDC, vec[i], 0, n_attributes, attributes, results)) continue; if( (samples == 0 && results[0] == 0) || (samples > 0 && results[0] == 1 && results[1] == samples)) { return vec[i]; } } return 0; }
void VisualInfoARB (GLContext* ctx) { int attrib[32], value[32], n_attrib, n_pbuffer=0, n_float=0; int i, pf, maxpf; unsigned int c; /* to get pbuffer capable pixel formats */ attrib[0] = WGL_DRAW_TO_PBUFFER_ARB; attrib[1] = GL_TRUE; attrib[2] = 0; wglChoosePixelFormatARB(ctx->dc, attrib, 0, 1, &pf, &c); /* query number of pixel formats */ attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB; wglGetPixelFormatAttribivARB(ctx->dc, 0, 0, 1, attrib, value); maxpf = value[0]; for (i=0; i<32; i++) value[i] = 0; attrib[0] = WGL_SUPPORT_OPENGL_ARB; attrib[1] = WGL_DRAW_TO_WINDOW_ARB; attrib[2] = WGL_DRAW_TO_BITMAP_ARB; attrib[3] = WGL_ACCELERATION_ARB; /* WGL_NO_ACCELERATION_ARB, WGL_GENERIC_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB */ attrib[4] = WGL_SWAP_METHOD_ARB; /* WGL_SWAP_EXCHANGE_ARB, WGL_SWAP_COPY_ARB, WGL_SWAP_UNDEFINED_ARB */ attrib[5] = WGL_DOUBLE_BUFFER_ARB; attrib[6] = WGL_STEREO_ARB; attrib[7] = WGL_PIXEL_TYPE_ARB; /* WGL_TYPE_RGBA_ARB, WGL_TYPE_COLORINDEX_ARB, WGL_TYPE_RGBA_FLOAT_ATI (WGL_ATI_pixel_format_float) */ /* Color buffer information */ attrib[8] = WGL_COLOR_BITS_ARB; attrib[9] = WGL_RED_BITS_ARB; attrib[10] = WGL_GREEN_BITS_ARB; attrib[11] = WGL_BLUE_BITS_ARB; attrib[12] = WGL_ALPHA_BITS_ARB; /* Accumulation buffer information */ attrib[13] = WGL_ACCUM_BITS_ARB; attrib[14] = WGL_ACCUM_RED_BITS_ARB; attrib[15] = WGL_ACCUM_GREEN_BITS_ARB; attrib[16] = WGL_ACCUM_BLUE_BITS_ARB; attrib[17] = WGL_ACCUM_ALPHA_BITS_ARB; /* Depth, stencil, and aux buffer information */ attrib[18] = WGL_DEPTH_BITS_ARB; attrib[19] = WGL_STENCIL_BITS_ARB; attrib[20] = WGL_AUX_BUFFERS_ARB; /* Layer information */ attrib[21] = WGL_NUMBER_OVERLAYS_ARB; attrib[22] = WGL_NUMBER_UNDERLAYS_ARB; attrib[23] = WGL_SWAP_LAYER_BUFFERS_ARB; attrib[24] = WGL_SAMPLES_ARB; attrib[25] = WGL_SUPPORT_GDI_ARB; n_attrib = 26; if (WGLEW_ARB_pbuffer) { attrib[n_attrib] = WGL_DRAW_TO_PBUFFER_ARB; n_pbuffer = n_attrib; n_attrib++; } if (WGLEW_NV_float_buffer) { attrib[n_attrib] = WGL_FLOAT_COMPONENTS_NV; n_float = n_attrib; n_attrib++; } if (!verbose) { /* print table header */ fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { wglGetPixelFormatAttribivARB(ctx->dc, i, 0, n_attrib, attrib, value); /* only describe this format if it supports OpenGL */ if (!value[0]) continue; /* by default show only fully accelerated window or pbuffer capable visuals */ if (!showall && ((value[2] && !value[1]) || (!WGLEW_ARB_pbuffer || !value[n_pbuffer]) || (value[3] != WGL_FULL_ACCELERATION_ARB))) continue; /* print out the information for this visual */ /* visual id */ fprintf(file, " |% 4d | ", i); /* visual type */ if (value[1]) { if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "wp "); else fprintf(file, "wn "); } else { if (value[2]) fprintf(file, "bm "); else if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "pb "); } /* acceleration */ fprintf(file, "%s ", value[3] == WGL_FULL_ACCELERATION_ARB ? "fu" : value[3] == WGL_GENERIC_ACCELERATION_ARB ? "ge" : value[3] == WGL_NO_ACCELERATION_ARB ? "no" : ". "); /* gdi support */ fprintf(file, " %c ", value[25] ? 'y' : '.'); /* format */ if (WGLEW_NV_float_buffer && value[n_float]) fprintf(file, " f "); else if (WGLEW_ATI_pixel_format_float && value[7] == WGL_TYPE_RGBA_FLOAT_ATI) fprintf(file, " f "); else if (value[7] == WGL_TYPE_RGBA_ARB) fprintf(file, " i "); else if (value[7] == WGL_TYPE_COLORINDEX_ARB) fprintf(file, " c "); /* double buffer */ fprintf(file, " %c ", value[5] ? 'y' : '.'); /* swap method */ if (value[4] == WGL_SWAP_EXCHANGE_ARB) fprintf(file, " x "); else if (value[4] == WGL_SWAP_COPY_ARB) fprintf(file, " c "); else if (value[4] == WGL_SWAP_UNDEFINED_ARB) fprintf(file, " . "); else fprintf(file, " . "); /* stereo */ fprintf(file, " %c ", value[6] ? 'y' : '.'); /* multisample */ if (value[24] > 0) fprintf(file, "%2d | ", value[24]); else fprintf(file, " . | "); /* color size */ if (value[8]) fprintf(file, "%3d ", value[8]); else fprintf(file, " . "); /* red */ if (value[9]) fprintf(file, "%2d ", value[9]); else fprintf(file, " . "); /* green */ if (value[10]) fprintf(file, "%2d ", value[10]); else fprintf(file, " . "); /* blue */ if (value[11]) fprintf(file, "%2d ", value[11]); else fprintf(file, " . "); /* alpha */ if (value[12]) fprintf(file, "%2d | ", value[12]); else fprintf(file, " . | "); /* aux buffers */ if (value[20]) fprintf(file, "%2d ", value[20]); else fprintf(file, " . "); /* depth */ if (value[18]) fprintf(file, "%2d ", value[18]); else fprintf(file, " . "); /* stencil */ if (value[19]) fprintf(file, "%2d | ", value[19]); else fprintf(file, " . | "); /* accum size */ if (value[13]) fprintf(file, "%3d ", value[13]); else fprintf(file, " . "); /* accum red */ if (value[14]) fprintf(file, "%2d ", value[14]); else fprintf(file, " . "); /* accum green */ if (value[15]) fprintf(file, "%2d ", value[15]); else fprintf(file, " . "); /* accum blue */ if (value[16]) fprintf(file, "%2d ", value[16]); else fprintf(file, " . "); /* accum alpha */ if (value[17]) fprintf(file, "%2d | ", value[17]); else fprintf(file, " . | "); /* overlay */ if (value[21]) fprintf(file, "%2d ", value[21]); else fprintf(file, " . "); /* underlay */ if (value[22]) fprintf(file, "%2d ", value[22]); else fprintf(file, " . "); /* layer swap */ if (value[23]) fprintf(file, "y "); else fprintf(file, " . "); fprintf(file, "|\n"); } /* print table footer */ fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); } else /* verbose */ { #if 0 fprintf(file, "\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); fprintf(file, " Opaque.\n"); } #endif } }
/////////////////////////////////////////////////////////////////////////////// // Select pixelformat with desired attributes // Returns the best available "regular" pixel format, and the best available // Multisampled pixelformat (0 if not available) void FindBestPF(HDC hDC, int *nRegularFormat, int *nMSFormat) { *nRegularFormat = 0; *nMSFormat = 0; // easy check, just look for the entrypoint if(gltIsWGLExtSupported(hDC, "WGL_ARB_pixel_format")) if(wglGetPixelFormatAttribivARB == NULL) wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB"); // First try to use new extended wgl way if(wglGetPixelFormatAttribivARB != NULL) { // Only care about these attributes int nBestMS = 0; int i; int iResults[9]; int iAttributes [9] = { WGL_SUPPORT_OPENGL_ARB, // 0 WGL_ACCELERATION_ARB, // 1 WGL_DRAW_TO_WINDOW_ARB, // 2 WGL_DOUBLE_BUFFER_ARB, // 3 WGL_PIXEL_TYPE_ARB, // 4 WGL_DEPTH_BITS_ARB, // 5 WGL_STENCIL_BITS_ARB, // 6 WGL_SAMPLE_BUFFERS_ARB, // 7 WGL_SAMPLES_ARB }; // 8 // How many pixelformats are there? int nFormatCount[] = { 0 }; int attrib[] = { WGL_NUMBER_PIXEL_FORMATS_ARB }; wglGetPixelFormatAttribivARB(hDC, 1, 0, 1, attrib, nFormatCount); // Loop through all the formats and look at each one for(i = 0; i < nFormatCount[0]; i++) { // Query pixel format wglGetPixelFormatAttribivARB(hDC, i+1, 0, 9, iAttributes, iResults); // Match? Must support OpenGL AND be Accelerated AND draw to Window if(iResults[0] == 1 && iResults[1] == WGL_FULL_ACCELERATION_ARB && iResults[2] == 1) if(iResults[3] == 1) // Double buffered if(iResults[4] == WGL_TYPE_RGBA_ARB) // Full Color if(iResults[5] >= 16) // Any Depth greater than 16 if(iResults[6] > 0) // Any Stencil depth (not zero) { // We have a candidate, look for most samples if multisampled if(iResults[7] == 1) // Multisampled { if(iResults[8] > nBestMS) // Look for most samples { *nMSFormat = i; // Multisamples nBestMS = iResults[8]; // Looking for the best } } else // Not multisampled { // Good enough for "regular". This will fall through *nRegularFormat = i; } } } } else { // Old fashioned way... // or multisample PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, // Full color 32, // Color depth 0,0,0,0,0,0,0, // Ignored 0,0,0,0, // Accumulation buffer 24, // Depth bits 8, // Stencil bits 0,0,0,0,0,0 }; // Some used, some not *nRegularFormat = ChoosePixelFormat(hDC, &pfd); } }
static int GLW_ChoosePFDEx( PIXELFORMATDESCRIPTOR *pPFD ) { //create a temporary window to grab a GL context and //enumerate from - SetPixelFormat restriction int x, y, w, h; int numFormats; int i; int ret = 0; HWND tmpWnd; HDC tmpDC; HGLRC tmpRC; WNDCLASS tmpClass; ATOM tmpClassAtom; WinVars_t *winVars = (WinVars_t*)ri.PlatformGetVars(); tmpClass.cbClsExtra = 0; tmpClass.cbWndExtra = 0; tmpClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); tmpClass.hCursor = LoadCursor( NULL, IDC_ARROW ); tmpClass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); tmpClass.hInstance = winVars->hInstance; tmpClass.lpfnWndProc = &DefWindowProc; tmpClass.lpszClassName = "GL_ENUM_WND"; tmpClass.lpszMenuName = NULL; tmpClass.style = CS_OWNDC; tmpClassAtom = RegisterClass( &tmpClass ); if( winVars->hWnd ) { RECT tmpRC; GetWindowRect( winVars->hWnd, &tmpRC ); x = tmpRC.left; y = tmpRC.top; w = tmpRC.right - tmpRC.left; h = tmpRC.bottom - tmpRC.top; } else { x = CW_USEDEFAULT; y = CW_USEDEFAULT; w = CW_USEDEFAULT; h = CW_USEDEFAULT; } tmpWnd = CreateWindow( MAKEINTATOM( tmpClassAtom ), "GL_ENUM_WND", WS_OVERLAPPEDWINDOW, x, y, w, h, NULL, NULL, winVars->hInstance, NULL ); tmpDC = GetDC( tmpWnd ); numFormats = DescribePixelFormat( tmpDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), NULL ); for( i = 1; i <= numFormats; i++ ) { PIXELFORMATDESCRIPTOR pfd; pfd.nSize = sizeof( pfd ); DescribePixelFormat( tmpDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfd ); if( pfd.dwFlags & PFD_SUPPORT_OPENGL ) { if( SetPixelFormat( tmpDC, i, &pfd ) ) break; } } if( i <= numFormats ) { tmpRC = wglCreateContext( tmpDC ); wglMakeCurrent( tmpDC, tmpRC ); if( glewInit() == GLEW_OK && WGLEW_ARB_pixel_format ) { PIXELFORMATDESCRIPTOR *pfds = (PIXELFORMATDESCRIPTOR*)ri.Hunk_AllocateTempMemory( sizeof( PIXELFORMATDESCRIPTOR ) * (numFormats + 1) ); int *samples = GLEW_ARB_multisample ? (int*)ri.Hunk_AllocateTempMemory( sizeof( int ) * (numFormats + 1) ) : NULL; for( i = 1; i <= numFormats; i++ ) { pfds[i].nSize = sizeof( PIXELFORMATDESCRIPTOR ); DescribePixelFormat( tmpDC, i, sizeof( PIXELFORMATDESCRIPTOR ), pfds + i ); if( samples ) { int qAttribs[2] = { WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB }; int vAttribs[2]; wglGetPixelFormatAttribivARB( tmpDC, i, 0, 2, qAttribs, vAttribs ); samples[i] = vAttribs[0] ? vAttribs[1] : 0; } } ret = GLW_PickPFD( pfds, samples, numFormats, pPFD ); if( samples ) ri.Hunk_FreeTempMemory( samples ); ri.Hunk_FreeTempMemory( pfds ); } wglMakeCurrent( NULL, NULL ); wglDeleteContext( tmpRC ); } ReleaseDC( tmpWnd, tmpDC ); DestroyWindow( tmpWnd ); UnregisterClass( MAKEINTATOM( tmpClassAtom ), winVars->hInstance ); return ret; }
void Win32PBuffer::createPBuffer() { // Process format int bits=0; bool isFloat=false; #if 0 bool hasAlpha=true; #endif switch(mFormat) { case PCT_BYTE: bits=8; isFloat=false; break; case PCT_SHORT: bits=16; isFloat=false; break; case PCT_FLOAT16: bits=16; isFloat=true; break; case PCT_FLOAT32: bits=32; isFloat=true; break; default: break; }; LogManager::getSingleton().logMessage( " Win32PBuffer::Creating PBuffer of format bits="+ StringConverter::toString(bits)+ " float="+StringConverter::toString(isFloat) ); HDC old_hdc = wglGetCurrentDC(); HGLRC old_context = wglGetCurrentContext(); // Bind to RGB or RGBA texture int bttype = 0; #if 0 if(mUseBind) { // Only provide bind type when actually binding bttype = PixelUtil::hasAlpha(mInternalFormat)? WGL_BIND_TO_TEXTURE_RGBA_ARB : WGL_BIND_TO_TEXTURE_RGB_ARB; } int texformat = hasAlpha? WGL_TEXTURE_RGBA_ARB : WGL_TEXTURE_RGB_ARB; #endif // Make a float buffer? int pixeltype = isFloat? WGL_TYPE_RGBA_FLOAT_ARB: WGL_TYPE_RGBA_ARB; int attrib[] = { WGL_RED_BITS_ARB,bits, WGL_GREEN_BITS_ARB,bits, WGL_BLUE_BITS_ARB,bits, WGL_ALPHA_BITS_ARB,bits, WGL_STENCIL_BITS_ARB,1, WGL_DEPTH_BITS_ARB,15, WGL_DRAW_TO_PBUFFER_ARB,true, WGL_SUPPORT_OPENGL_ARB,true, WGL_PIXEL_TYPE_ARB,pixeltype, //WGL_DOUBLE_BUFFER_ARB,true, //WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, // Make sure it is accelerated bttype,true, // must be last, as bttype can be zero 0 }; int pattrib_default[] = { 0 }; #if 0 int pattrib_bind[] = { WGL_TEXTURE_FORMAT_ARB, texformat, WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, WGL_PBUFFER_LARGEST_ARB, true, 0 }; #endif int format; unsigned int count; // Choose suitable pixel format wglChoosePixelFormatARB(old_hdc,attrib,NULL,1,&format,&count); if(count == 0) OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglChoosePixelFormatARB() failed", " Win32PBuffer::createPBuffer"); // Analyse pixel format const int piAttributes[]={ WGL_RED_BITS_ARB,WGL_GREEN_BITS_ARB,WGL_BLUE_BITS_ARB,WGL_ALPHA_BITS_ARB, WGL_DEPTH_BITS_ARB,WGL_STENCIL_BITS_ARB }; int piValues[sizeof(piAttributes)/sizeof(const int)]; wglGetPixelFormatAttribivARB(old_hdc,format,0,sizeof(piAttributes)/sizeof(const int),piAttributes,piValues); LogManager::getSingleton().stream() << " Win32PBuffer::PBuffer -- Chosen pixel format rgba=" << piValues[0] << "," << piValues[1] << "," << piValues[2] << "," << piValues[3] << " depth=" << piValues[4] << " stencil=" << piValues[5]; mPBuffer = wglCreatePbufferARB(old_hdc,format,mWidth,mHeight,pattrib_default); if(!mPBuffer) OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreatePbufferARB() failed", " Win32PBuffer::createPBuffer"); mHDC = wglGetPbufferDCARB(mPBuffer); if(!mHDC) { wglDestroyPbufferARB(mPBuffer); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglGetPbufferDCARB() failed", " Win32PBuffer::createPBuffer"); } mGlrc = wglCreateContext(mHDC); if(!mGlrc) { wglReleasePbufferDCARB(mPBuffer,mHDC); wglDestroyPbufferARB(mPBuffer); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreateContext() failed", " Win32PBuffer::createPBuffer"); } if(!wglShareLists(old_context,mGlrc)) { wglDeleteContext(mGlrc); wglReleasePbufferDCARB(mPBuffer,mHDC); wglDestroyPbufferARB(mPBuffer); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32PBuffer::createPBuffer"); } // Query real width and height int iWidth, iHeight; wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_WIDTH_ARB, &iWidth); wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_HEIGHT_ARB, &iHeight); mWidth = iWidth; mHeight = iHeight; LogManager::getSingleton().stream() << "Win32RenderTexture::PBuffer created -- Real dimensions " << mWidth << "x" << mHeight; }
bool OpenGLApp::initAPI(){ if (screen >= GetSystemMetrics(SM_CMONITORS)) screen = 0; int monitorCounter = screen; EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM) &monitorCounter); // TODO: Use this when saving out position? // HMONITOR hMonitor = MonitorFromWindow(m_handle->hWnd, MONITOR_DEFAULTTOPRIMARY); DWORD flags = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; int x, y; x = monInfo.rcMonitor.left; y = monInfo.rcMonitor.top; device.cb = sizeof(device); //TODO: Monitor count is not equal to device count? EnumDisplayDevices(NULL, 0/*screen*/, &device, 0); DEVMODE dm, tdm; memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(dm); dm.dmBitsPerPel = colorBits; dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; dm.dmPelsWidth = fullscreenWidth; dm.dmPelsHeight = fullscreenHeight; dm.dmDisplayFrequency = 60; // Find a suitable fullscreen format int i = 0; int targetHz = 85; char str[128]; resolution->clear(); while (EnumDisplaySettings((const char *) device.DeviceName, i, &tdm)){ if (int(tdm.dmBitsPerPel) == colorBits && tdm.dmPelsWidth >= 640 && tdm.dmPelsHeight >= 480){ sprintf(str, "%dx%d", tdm.dmPelsWidth, tdm.dmPelsHeight); int index = resolution->addItemUnique(str); if (int(tdm.dmPelsWidth) == fullscreenWidth && int(tdm.dmPelsHeight) == fullscreenHeight){ if (abs(int(tdm.dmDisplayFrequency) - targetHz) < abs(int(dm.dmDisplayFrequency) - targetHz)){ dm = tdm; } resolution->selectItem(index); } } i++; } if (fullscreen){ //TODO: Select correct monitor? //dm.dmFields |= DM_POSITION ; //dm.dmPosition.x = x; //dm.dmPosition.y = y; if (ChangeDisplaySettingsEx((const char *) device.DeviceName, &dm, NULL, CDS_FULLSCREEN, NULL) == DISP_CHANGE_SUCCESSFUL){ flags |= WS_POPUP; captureMouse(!configDialog->isVisible()); } else { ErrorMsg("Couldn't set fullscreen mode"); fullscreen = false; } } sprintf(str, "%s (%dx%d)", getTitle(), width, height); if (!fullscreen){ flags |= WS_OVERLAPPEDWINDOW; RECT wRect; wRect.left = 0; wRect.right = width; wRect.top = 0; wRect.bottom = height; AdjustWindowRect(&wRect, flags, FALSE); width = min(wRect.right - wRect.left, monInfo.rcWork.right - monInfo.rcWork.left); height = min(wRect.bottom - wRect.top, monInfo.rcWork.bottom - monInfo.rcWork.top); x = (monInfo.rcWork.left + monInfo.rcWork.right - width ) / 2; y = (monInfo.rcWork.top + monInfo.rcWork.bottom - height) / 2; } hwnd = CreateWindow("Humus", str, flags, x, y, width, height, HWND_DESKTOP, NULL, hInstance, NULL); PIXELFORMATDESCRIPTOR pfd = { sizeof (PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, colorBits, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, depthBits, stencilBits, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; hdc = GetDC(hwnd); int iAttribs[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_RED_BITS_ARB, 8, WGL_GREEN_BITS_ARB, 8, WGL_BLUE_BITS_ARB, 8, WGL_ALPHA_BITS_ARB, (colorBits > 24)? 8 : 0, WGL_DEPTH_BITS_ARB, depthBits, WGL_STENCIL_BITS_ARB, stencilBits, 0 }; int pixelFormats[256]; int bestFormat = 0; int bestSamples = 0; uint nPFormats; if (wgl_ext_ARB_pixel_format && wglChoosePixelFormatARB(hdc, iAttribs, NULL, elementsOf(pixelFormats), pixelFormats, &nPFormats) && nPFormats > 0){ int minDiff = 0x7FFFFFFF; int attrib = WGL_SAMPLES_ARB; int samples; // Find a multisample format as close as possible to the requested for (uint i = 0; i < nPFormats; i++){ wglGetPixelFormatAttribivARB(hdc, pixelFormats[i], 0, 1, &attrib, &samples); int diff = abs(antiAliasSamples - samples); if (diff < minDiff){ minDiff = diff; bestFormat = i; bestSamples = samples; } } } else { pixelFormats[0] = ChoosePixelFormat(hdc, &pfd); } antiAliasSamples = bestSamples; SetPixelFormat(hdc, pixelFormats[bestFormat], &pfd); if(wgl_ext_ARB_create_context) { glContext = wglCreateContextAttribsARB(hdc, 0, 0); } else { glContext = wglCreateContext(hdc); } wglMakeCurrent(hdc, glContext); ogl_LoadFunctions(); wgl_LoadFunctions(hdc); if (wgl_ext_ARB_multisample && antiAliasSamples > 0){ glEnable(GL_MULTISAMPLE); } if (fullscreen) captureMouse(!configDialog->isVisible()); renderer = new OpenGLRenderer(hdc, glContext); renderer->setViewport(width, height); antiAlias->selectItem(antiAliasSamples / 2); linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP); defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp); blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA); noDepthTest = renderer->addDepthState(false, false); noDepthWrite = renderer->addDepthState(true, false); cullNone = renderer->addRasterizerState(CULL_NONE); cullBack = renderer->addRasterizerState(CULL_BACK); cullFront = renderer->addRasterizerState(CULL_FRONT); return true; }
// Enumerate available pixel formats. Choose the best pixel format in // terms of color and depth buffer bits and then return all formats with // different multisampling settings. If there are more then one, then choose // the one with highest depth buffer size and lowest stencil and auxiliary // buffer sizes since we don't use them in Clonk. static std::vector<int> EnumeratePixelFormats(HDC hdc) { std::vector<int> result; if(!wglGetPixelFormatAttribivARB) return result; int n_formats; int attributes = WGL_NUMBER_PIXEL_FORMATS_ARB; if(!wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attributes, &n_formats)) return result; for(int i = 1; i < n_formats+1; ++i) { int new_attributes[] = { WGL_DRAW_TO_WINDOW_ARB, WGL_SUPPORT_OPENGL_ARB, WGL_DOUBLE_BUFFER_ARB, WGL_COLOR_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_AUX_BUFFERS_ARB, WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB }; const unsigned int nnew_attributes = sizeof(new_attributes)/sizeof(int); int new_results[nnew_attributes]; if(!wglGetPixelFormatAttribivARB(hdc, i, 0, nnew_attributes, new_attributes, new_results)) continue; if(!new_results[0] || !new_results[1] || !new_results[2]) continue; if(new_results[3] < 16 || new_results[4] < 16) continue; // require at least 16 bits per pixel in color and depth // For no MS we do find a pixel format with depth 32 on my (ck's) computer, // however, when choosing it then texturing does not work anymore. I am not // exactly sure what the cause of that is, so let's not choose that one for now. if(new_results[4] > 24) continue; // Multisampling with just one sample is equivalent to no-multisampling, // so don't include that in the result. if(new_results[7] == 1 && new_results[8] == 1) continue; if(result.empty()) { result.push_back(i); } else { int old_attributes[] = { WGL_COLOR_BITS_ARB }; const unsigned int nold_attributes = sizeof(old_attributes)/sizeof(int); int old_results[nold_attributes]; if(!wglGetPixelFormatAttribivARB(hdc, result[0], 0, nold_attributes, old_attributes, old_results)) continue; if(new_results[3] > old_results[0]) { result.clear(); result.push_back(i); } else if(new_results[3] == old_results[0]) { unsigned int j; for(j = 0; j < result.size(); ++j) { int equiv_attributes[] = { WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_AUX_BUFFERS_ARB, WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB }; const unsigned int nequiv_attributes = sizeof(equiv_attributes)/sizeof(int); int equiv_results[nequiv_attributes]; if(!wglGetPixelFormatAttribivARB(hdc, result[j], 0, nequiv_attributes, equiv_attributes, equiv_results)) continue; if(new_results[7] == equiv_results[3] && new_results[8] == equiv_results[4]) { if(new_results[4] > equiv_results[0] || (new_results[4] == equiv_results[0] && (new_results[5] < equiv_results[1] || (new_results[5] == equiv_results[1] && new_results[6] < equiv_results[2])))) result[j] = i; break; } } if(j == result.size()) result.push_back(i); } } } return result; }
int GHOST_ContextWGL::_choose_pixel_format_arb_2( bool stereoVisual, int numOfAASamples, bool needAlpha, bool needStencil, bool sRGB, int swapMethod) { std::vector<int> iAttributes; int iPixelFormat = 0; int samples; // guard against some insanely high number of samples if (numOfAASamples > 64) { fprintf(stderr, "Warning! Clamping number of samples to 64.\n"); samples = 64; } else { samples = numOfAASamples; } // request a format with as many samples as possible, but not more than requested while (samples >= 0) { makeAttribList( iAttributes, stereoVisual, samples, swapMethod, needAlpha, needStencil, sRGB); UINT nNumFormats; WIN32_CHK(wglChoosePixelFormatARB(m_hDC, &(iAttributes[0]), NULL, 1, &iPixelFormat, &nNumFormats)); /* total number of formats that match (regardless of size of iPixelFormat array) * see: WGL_ARB_pixel_format extension spec */ if (nNumFormats > 0) break; /* if not reset, then the state of iPixelFormat is undefined after call to wglChoosePixelFormatARB * see: WGL_ARB_pixel_format extension spec */ iPixelFormat = 0; samples--; } // check how many samples were actually gotten if (iPixelFormat != 0) { int iQuery[] = { WGL_SAMPLES_ARB }; int actualSamples; wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &actualSamples); if (actualSamples != numOfAASamples) { fprintf(stderr, "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " "Substituting one that uses %d samples.\n", numOfAASamples, actualSamples); m_numOfAASamples = actualSamples; // set context property to actual value } } return iPixelFormat; }
bool VideoSettings::GetCompatibleWinMode(VideoCaps caps) { #ifdef _WINDOWS if (!hasHardware) return false; // Ask the WGL for the clostest match to this pixel format if (!hDC) { wxLogMessage(wxT("Error: Attempted to Get a Compatible Window Mode Without a Valid Window")); //throw std::runtime_error("VideoSettings::GetCompatibleWinMode() : Attempted to Get a Compatible Window Mode Without a Valid Window"); return false; } std::vector<int> iAttributes; std::vector<int> results; unsigned int numformats; float fAtrributes[] = { 0,0}; iAttributes.push_back(WGL_DRAW_TO_WINDOW_ARB); iAttributes.push_back(GL_TRUE); iAttributes.push_back(WGL_ACCELERATION_ARB); iAttributes.push_back(caps.hwAcc); iAttributes.push_back(WGL_COLOR_BITS_ARB); iAttributes.push_back(caps.colour); // min color required iAttributes.push_back(WGL_ALPHA_BITS_ARB); iAttributes.push_back(caps.alpha); // min alpha bits iAttributes.push_back(WGL_DEPTH_BITS_ARB); iAttributes.push_back(caps.zBuffer); iAttributes.push_back(WGL_STENCIL_BITS_ARB); iAttributes.push_back(caps.stencil); if(caps.aaSamples != 0) { iAttributes.push_back(WGL_SAMPLE_BUFFERS_ARB); iAttributes.push_back(caps.sampleBuffer); iAttributes.push_back(WGL_SAMPLES_ARB); iAttributes.push_back(caps.aaSamples); } iAttributes.push_back(WGL_DOUBLE_BUFFER_ARB); iAttributes.push_back(caps.doubleBuffer); if(caps.accum != 0) { iAttributes.push_back(WGL_ACCUM_BITS_ARB); iAttributes.push_back(caps.accum); } iAttributes.push_back(0); iAttributes.push_back(0); int status = wglChoosePixelFormatARB(hDC, &iAttributes[0], fAtrributes, 1, &pixelFormat, &numformats); // find a matching format if (status == GL_TRUE && numformats) { // we have a matching format, extract the details iAttributes.clear(); iAttributes.push_back(WGL_COLOR_BITS_ARB); iAttributes.push_back(WGL_ALPHA_BITS_ARB); iAttributes.push_back(WGL_DEPTH_BITS_ARB); iAttributes.push_back(WGL_STENCIL_BITS_ARB); iAttributes.push_back(WGL_SAMPLE_BUFFERS_ARB); iAttributes.push_back(WGL_SAMPLES_ARB); iAttributes.push_back(WGL_DOUBLE_BUFFER_ARB); iAttributes.push_back(WGL_ACCUM_BITS_ARB); iAttributes.push_back(WGL_ACCELERATION_ARB); results.resize(iAttributes.size()); if(!wglGetPixelFormatAttribivARB(hDC, pixelFormat, PFD_MAIN_PLANE, (UINT)iAttributes.size(), &iAttributes[0], &results[0])) { //int i = GetLastError(); return false; } curCap.aaSamples = results[5]; curCap.accum = results[7]; curCap.alpha = results[1]; curCap.colour = results[0]; curCap.doubleBuffer = results[6]; curCap.sampleBuffer = results[4]; curCap.stencil = results[3]; curCap.zBuffer = results[2]; curCap.hwAcc = results[8]; for (size_t i=0; i<capsList.size(); i++) { if (capsList[i].colour == curCap.colour && capsList[i].zBuffer == curCap.zBuffer && capsList[i].alpha == curCap.alpha && capsList[i].hwAcc == curCap.hwAcc && capsList[i].doubleBuffer==curCap.doubleBuffer && capsList[i].sampleBuffer==curCap.sampleBuffer && capsList[i].aaSamples==curCap.aaSamples) { capIndex = (int)i; break; } } return true; } #endif return false; }
void VideoSettings::EnumDisplayModes() { #ifdef _WINDOWS if (!hasHardware) return; // Error check if (!hDC) { wxLogMessage(wxT("Error: Unable to enumerate display modes. Invalid HDC.")); return; } // This is where we do the grunt work of checking the caps // find out how many pixel formats we have size_t num_pfd = 0; std::vector<int> iAttributes; std::vector<int> results; iAttributes.push_back(WGL_NUMBER_PIXEL_FORMATS_ARB); results.resize(2); // 2 elements wglGetPixelFormatAttribivARB(hDC, 0, 0, 1, &iAttributes[0], &results[0]); // get the number of contexts we can create num_pfd = results[0]; iAttributes.clear(); results.clear(); // error check if (num_pfd == 0) { wxLogMessage(wxT("Error: Could not find any display modes. Video Card might not support the function.")); hasHardware = false; return; } iAttributes.push_back(WGL_DRAW_TO_WINDOW_ARB); iAttributes.push_back(WGL_STENCIL_BITS_ARB); iAttributes.push_back(WGL_ACCELERATION_ARB); iAttributes.push_back(WGL_DEPTH_BITS_ARB); iAttributes.push_back(WGL_SUPPORT_OPENGL_ARB); iAttributes.push_back(WGL_DOUBLE_BUFFER_ARB); iAttributes.push_back(WGL_PIXEL_TYPE_ARB); iAttributes.push_back(WGL_COLOR_BITS_ARB); iAttributes.push_back(WGL_ALPHA_BITS_ARB); iAttributes.push_back(WGL_ACCUM_BITS_ARB); if(glewIsSupported("GL_ARB_multisample")) { iAttributes.push_back(WGL_SAMPLE_BUFFERS_ARB); iAttributes.push_back(WGL_SAMPLES_ARB); } results.resize(iAttributes.size()); // Reset our list of card capabilities. capsList.clear(); for (size_t i=0; i<num_pfd; i++) { if(!wglGetPixelFormatAttribivARB(hDC, (int)i+1,0, (UINT)iAttributes.size(), &iAttributes[0], &results[0])) return; // once we make it here we can look at the pixel data to make sure this is a context we want to use // results[0] is WGL_DRAW_TO_WINDOW, since we only work in windowed mode, no need to return results for fullscreen mode // results[4] is WGL_SUPPORT_OPENGL, obvious if the mode doesn't support opengl then its useless to us. // results[3] is bitdepth, if it has a 0 bitdepth then its useless to us if(results[0] == GL_TRUE && results[4] == GL_TRUE && results[3]>0) { // what we have here is a contect which is drawable to a window, is in rgba format and is accelerated in some way // so now we pull the infomation, fill a structure and shove it into our map VideoCaps caps; if(glewIsSupported("GL_ARB_multisample")) { caps.sampleBuffer = results[10]; caps.aaSamples = results[11]; } else { caps.sampleBuffer = false; caps.aaSamples = 0; } caps.accum = results[9]; caps.alpha = results[8]; caps.colour = results[7]; //caps.pixelType = results[6]; /* WGL_TYPE_RGBA_ARB*/ caps.doubleBuffer = results[5]; caps.zBuffer = results[3]; caps.hwAcc = results[2]; /*WGL_FULL_ACCELERATION_ARB / WGL_GENERIC_ACCELERATION_ARB / WGL_NO_ACCELERATION_ARB;*/ caps.stencil = results[1]; capsList.push_back(caps); // insert into the map } } #endif }