| /* |
| * Some tests for OpenGL functions |
| * |
| * Copyright (C) 2007 Roderick Colenbrander |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include <windows.h> |
| #include <wingdi.h> |
| #include "wine/test.h" |
| |
| #define MAX_FORMATS 256 |
| typedef void* HPBUFFERARB; |
| |
| /* WGL_ARB_extensions_string */ |
| static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC); |
| static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC); |
| |
| /* WGL_ARB_pixel_format */ |
| static BOOL (WINAPI *pwglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *); |
| |
| /* WGL_ARB_pbuffer */ |
| #define WGL_DRAW_TO_PBUFFER_ARB 0x202D |
| static HPBUFFERARB* (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *); |
| static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB); |
| |
| static const char* wgl_extensions = NULL; |
| |
| static void init_functions(void) |
| { |
| /* WGL_ARB_extensions_string */ |
| pwglGetExtensionsStringARB = (void*)wglGetProcAddress("wglGetExtensionsStringARB"); |
| |
| /* WGL_ARB_pixel_format */ |
| pwglChoosePixelFormatARB = (void*)wglGetProcAddress("wglChoosePixelFormatARB"); |
| |
| /* WGL_ARB_pbuffer */ |
| pwglCreatePbufferARB = (void*)wglGetProcAddress("wglCreatePbufferARB"); |
| pwglGetPbufferDCARB = (void*)wglGetProcAddress("wglGetPbufferDCARB"); |
| pwglReleasePbufferDCARB = (void*)wglGetProcAddress("wglReleasePbufferDCARB"); |
| } |
| |
| static void test_pbuffers(HDC hdc) |
| { |
| const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */ |
| 0 }; |
| int iFormats[MAX_FORMATS]; |
| unsigned int nOnscreenFormats; |
| unsigned int nFormats; |
| int i, res; |
| int iPixelFormat = 0; |
| |
| nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL); |
| |
| /* When you want to render to a pbuffer you need to call wglGetPbufferDCARB which |
| * returns a 'magic' HDC which you can then pass to wglMakeCurrent to switch rendering |
| * to the pbuffer. Below some tests are performed on what happens if you use standard WGL calls |
| * on this 'magic' HDC for both a pixelformat that support onscreen and offscreen rendering |
| * and a pixelformat that's only available for offscreen rendering (this means that only |
| * wglChoosePixelFormatARB and friends know about the format. |
| * |
| * The first thing we need are pixelformats with pbuffer capabilites. |
| */ |
| res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats); |
| if(res <= 0) |
| { |
| skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n"); |
| return; |
| } |
| trace("nOnscreenFormats: %d\n", nOnscreenFormats); |
| trace("Total number of pbuffer capable pixelformats: %d\n", nFormats); |
| |
| /* Try to select an onscreen pixelformat out of the list */ |
| for(i=0; i < nFormats; i++) |
| { |
| /* Check if the format is onscreen, if it is choose it */ |
| if(iFormats[i] <= nOnscreenFormats) |
| { |
| iPixelFormat = iFormats[i]; |
| trace("Selected iPixelFormat=%d\n", iPixelFormat); |
| break; |
| } |
| } |
| |
| /* A video driver supports a large number of onscreen and offscreen pixelformats. |
| * The traditional WGL calls only see a subset of the whole pixelformat list. First |
| * of all they only see the onscreen formats (the offscreen formats are at the end of the |
| * pixelformat list) and second extended pixelformat capabilities are hidden from the |
| * standard WGL calls. Only functions that depend on WGL_ARB_pixel_format can see them. |
| * |
| * Below we check if the pixelformat is also supported onscreen. |
| */ |
| if(iPixelFormat != 0) |
| { |
| HDC pbuffer_hdc; |
| HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL); |
| if(!pbuffer) |
| skip("Pbuffer creation failed!\n"); |
| |
| /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */ |
| pbuffer_hdc = pwglGetPbufferDCARB(pbuffer); |
| res = GetPixelFormat(pbuffer_hdc); |
| ok(res == iPixelFormat, "Unexpected iPixelFormat=%d returned by GetPixelFormat for format %d\n", res, iPixelFormat); |
| trace("iPixelFormat returned by GetPixelFormat: %d\n", res); |
| trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat); |
| |
| pwglReleasePbufferDCARB(pbuffer, hdc); |
| } |
| else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n"); |
| |
| /* Search for a real offscreen format */ |
| for(i=0, iPixelFormat=0; i<nFormats; i++) |
| { |
| if(iFormats[i] > nOnscreenFormats) |
| { |
| iPixelFormat = iFormats[i]; |
| trace("Selected iPixelFormat: %d\n", iPixelFormat); |
| break; |
| } |
| } |
| |
| if(iPixelFormat != 0) |
| { |
| HDC pbuffer_hdc; |
| HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL); |
| if(!pbuffer) |
| skip("Pbuffer creation failed!\n"); |
| |
| /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */ |
| pbuffer_hdc = pwglGetPbufferDCARB(pbuffer); |
| res = GetPixelFormat(pbuffer_hdc); |
| |
| ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat); |
| trace("iPixelFormat returned by GetPixelFormat: %d\n", res); |
| trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat); |
| pwglReleasePbufferDCARB(pbuffer, hdc); |
| } |
| else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n"); |
| } |
| |
| START_TEST(opengl) |
| { |
| HWND hwnd; |
| PIXELFORMATDESCRIPTOR pfd = { |
| sizeof(PIXELFORMATDESCRIPTOR), |
| 1, /* version */ |
| PFD_DRAW_TO_WINDOW | |
| PFD_SUPPORT_OPENGL | |
| PFD_DOUBLEBUFFER, |
| PFD_TYPE_RGBA, |
| 24, /* 24-bit color depth */ |
| 0, 0, 0, 0, 0, 0, /* color bits */ |
| 0, /* alpha buffer */ |
| 0, /* shift bit */ |
| 0, /* accumulation buffer */ |
| 0, 0, 0, 0, /* accum bits */ |
| 32, /* z-buffer */ |
| 0, /* stencil buffer */ |
| 0, /* auxiliary buffer */ |
| PFD_MAIN_PLANE, /* main layer */ |
| 0, /* reserved */ |
| 0, 0, 0 /* layer masks */ |
| }; |
| |
| hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW, |
| 10, 10, 200, 200, NULL, NULL, NULL, NULL); |
| ok(hwnd != NULL, "err: %d\n", GetLastError()); |
| if (hwnd) |
| { |
| HDC hdc; |
| int iPixelFormat, res; |
| HGLRC hglrc; |
| ShowWindow(hwnd, SW_SHOW); |
| |
| hdc = GetDC(hwnd); |
| |
| iPixelFormat = ChoosePixelFormat(hdc, &pfd); |
| ok(iPixelFormat > 0, "No pixelformat found!\n"); /* This should never happen as ChoosePixelFormat always returns a closest match */ |
| |
| res = SetPixelFormat(hdc, iPixelFormat, &pfd); |
| ok(res, "SetPixelformat failed: %x\n", GetLastError()); |
| |
| hglrc = wglCreateContext(hdc); |
| res = wglMakeCurrent(hdc, hglrc); |
| ok(res, "wglMakeCurrent failed!\n"); |
| init_functions(); |
| |
| wgl_extensions = pwglGetExtensionsStringARB(hdc); |
| if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n"); |
| |
| if(strstr(wgl_extensions, "WGL_ARB_pbuffer")) |
| test_pbuffers(hdc); |
| else |
| trace("WGL_ARB_pbuffer not supported, skipping pbuffer test\n"); |
| |
| DestroyWindow(hwnd); |
| } |
| } |