2 * Copyright (C) 2011 Morgan Armand <morgan.devel@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #ifndef GL_CONTEXT_FLAG_DEBUG_BIT
30 #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
32 #ifndef GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT
33 #define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
36 #ifndef GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
37 #define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
41 static LRESULT CALLBACK
52 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
59 context_error_to_string(DWORD error
)
62 case ERROR_INVALID_VERSION_ARB
: return "ERROR_INVALID_VERSION_ARB";
63 case ERROR_INVALID_PROFILE_ARB
: return "ERROR_INVALID_PROFILE_ARB";
64 case ERROR_INVALID_OPERATION
: return "ERROR_INVALID_OPERATION";
65 case ERROR_DC_NOT_FOUND
: return "ERROR_DC_NOT_FOUND";
66 case ERROR_INVALID_PIXEL_FORMAT
: return "ERROR_INVALID_PIXEL_FORMAT";
67 case ERROR_NO_SYSTEM_RESOURCES
: return "ERROR_NO_SYSTEM_RESOURCES";
68 case ERROR_INVALID_PARAMETER
: return "ERROR_INVALID_PARAMETER";
69 default: return "Unknown Error";
74 profile_mask_to_string(GLint profileMask
)
76 switch (profileMask
) {
77 case GL_CONTEXT_CORE_PROFILE_BIT
:
78 return "GL_CONTEXT_CORE_PROFILE_BIT";
79 case GL_CONTEXT_COMPATIBILITY_PROFILE_BIT
:
80 return "GL_CONTEXT_COMPATIBILITY_PROFILE_BIT";
87 context_flags_to_string(GLint flags
)
89 static char buf
[1000] = {0};
90 if (flags
& GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT
)
91 strcat(buf
, "GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT | ");
92 if (flags
& GL_CONTEXT_FLAG_DEBUG_BIT
)
93 strcat(buf
, "GL_CONTEXT_FLAG_DEBUG_BIT | ");
94 if (flags
& GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT
)
95 strcat(buf
, "GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT | ");
96 if (flags
& GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
)
97 strcat(buf
, "GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR | ");
101 /* rm the trailing " | " */
105 strcat(buf
, "(none)");
112 print_context_infos(void)
116 GLint profileMask
, flags
;
117 const char *version
, *vendor
, *renderer
;
119 fprintf(stdout
, "Context Informations\n");
121 version
= (const char *)glGetString(GL_VERSION
);
122 fprintf(stdout
, "GL_VERSION: %s\n", version
);
124 vendor
= (const char *)glGetString(GL_VENDOR
);
125 fprintf(stdout
, "GL_VENDOR: %s\n", vendor
);
127 renderer
= (const char *)glGetString(GL_RENDERER
);
128 fprintf(stdout
, "GL_RENDERER: %s\n", renderer
);
130 // Request informations with the new 3.x features.
131 if (sscanf(version
, "%d.%d", &majorVersion
, &minorVersion
) != 2)
134 if (majorVersion
>= 3) {
135 glGetIntegerv(GL_MAJOR_VERSION
, &majorVersion
);
136 glGetIntegerv(GL_MINOR_VERSION
, &minorVersion
);
137 fprintf(stdout
, "GL_MAJOR_VERSION: %d\n", majorVersion
);
138 fprintf(stdout
, "GL_MINOR_VERSION: %d\n", minorVersion
);
140 if (majorVersion
* 10 + minorVersion
>= 32) {
141 glGetIntegerv(GL_CONTEXT_PROFILE_MASK
, &profileMask
);
142 glGetIntegerv(GL_CONTEXT_FLAGS
, &flags
);
143 fprintf(stdout
, "GL_CONTEXT_PROFILE_MASK: %s\n",
144 profile_mask_to_string(profileMask
));
145 fprintf(stdout
, "GL_CONTEXT_FLAGS: %s\n",
146 context_flags_to_string(flags
));
149 /* Test if deprecated features work or generate an error */
150 while (glGetError() != GL_NO_ERROR
)
153 (void) glGenLists(1);
155 fprintf(stdout
, "glGenLists generated an error.\n");
158 fprintf(stdout
, "glGenLists generated no error.\n");
163 create_context(int majorVersion
, int minorVersion
, int profileMask
, int contextFlags
)
168 PIXELFORMATDESCRIPTOR pfd
;
171 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB
;
173 memset(&wc
, 0, sizeof(wc
));
174 wc
.style
= CS_OWNDC
| CS_HREDRAW
| CS_VREDRAW
;
175 wc
.lpfnWndProc
= WndProc
;
176 wc
.hIcon
= LoadIcon(NULL
, IDI_APPLICATION
);
177 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
178 wc
.hbrBackground
= (HBRUSH
) (COLOR_BTNFACE
+ 1);
179 wc
.lpszClassName
= "wglcontext";
181 if (!RegisterClass(&wc
)) {
182 fprintf(stderr
, "RegisterClass() failed\n");
186 win
= CreateWindowEx(0,
189 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
,
199 fprintf(stderr
, "CreateWindowEx() failed\n");
205 fprintf(stderr
, "GetDC() failed\n");
209 memset(&pfd
, 0, sizeof(pfd
));
210 pfd
.nSize
= sizeof(pfd
);
212 pfd
.dwFlags
= PFD_DOUBLEBUFFER
| PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
213 pfd
.iPixelType
= PFD_TYPE_RGBA
;
216 pfd
.iLayerType
= PFD_MAIN_PLANE
;
218 pixelFormat
= ChoosePixelFormat(hdc
, &pfd
);
220 fprintf(stderr
, "ChoosePixelFormat() failed\n");
224 if (!SetPixelFormat(hdc
, pixelFormat
, &pfd
)) {
225 fprintf(stderr
, "SetPixelFormat() failed\n");
229 tmp
= wglCreateContext(hdc
);
231 fprintf(stderr
, "wglCreateContext() failed\n");
235 if (!wglMakeCurrent(hdc
, tmp
)) {
236 fprintf(stderr
, "wglMakeCurrent() failed\n");
240 wglCreateContextAttribsARB
=
241 (PFNWGLCREATECONTEXTATTRIBSARBPROC
)wglGetProcAddress("wglCreateContextAttribsARB");
243 if (!wglCreateContextAttribsARB
) {
244 fprintf(stderr
, "wglCreateContextAttribsARB isn't supported\n");
250 attribsList
[i
++] = WGL_CONTEXT_MAJOR_VERSION_ARB
;
251 attribsList
[i
++] = majorVersion
;
252 attribsList
[i
++] = WGL_CONTEXT_MINOR_VERSION_ARB
;
253 attribsList
[i
++] = minorVersion
;
255 attribsList
[i
++] = WGL_CONTEXT_FLAGS_ARB
;
256 attribsList
[i
++] = contextFlags
;
259 attribsList
[i
++] = WGL_CONTEXT_PROFILE_MASK_ARB
;
260 attribsList
[i
++] = profileMask
;
262 attribsList
[i
++] = 0;
264 ctx
= wglCreateContextAttribsARB(hdc
, 0, attribsList
);
266 DWORD error
= GetLastError();
267 fprintf(stderr
, "wglCreateContextAttribsARB failed(): %s (0x%lx)\n",
268 context_error_to_string(error
), error
);
272 wglMakeCurrent(NULL
, NULL
);
273 wglDeleteContext(tmp
);
275 if (!wglMakeCurrent(hdc
, ctx
)) {
276 fprintf(stderr
, "wglMakeCurrent() failed\n");
280 print_context_infos();
286 fprintf(stdout
, "Usage: wglcontext [-h] [-major <major>] [-minor <minor>] [-core] [-compat] [-debug] [-forward]\n");
287 fprintf(stdout
, " -major : specify the major version you want\n");
288 fprintf(stdout
, " -minor : specify the minor version you want\n");
289 fprintf(stdout
, " -core : request a context implementing the core profile\n");
290 fprintf(stdout
, " -compat : request a context implementing the compatibility profile\n");
291 fprintf(stdout
, " -debug : request a debug context\n");
292 fprintf(stdout
, " -forward : request a forward-compatible context\n");
296 main(int argc
, char *argv
[])
299 int majorVersion
= 1, minorVersion
= 0;
300 int contextFlags
= 0x0;
301 int profileMask
= 0x0;
303 for (i
= 1; i
< argc
; i
++) {
304 if (strcmp(argv
[i
], "-h") == 0) {
308 else if (strcmp(argv
[i
], "-major") == 0 && i
+ 1 < argc
) {
309 majorVersion
= (int)strtol(argv
[i
+ 1], (char **)NULL
, 10);
312 else if (strcmp(argv
[i
], "-minor") == 0 && i
+ 1 < argc
) {
313 minorVersion
= (int)strtol(argv
[i
+ 1], (char **)NULL
, 10);
316 else if (strcmp(argv
[i
], "-core") == 0) {
317 profileMask
= WGL_CONTEXT_CORE_PROFILE_BIT_ARB
;
319 else if (strcmp(argv
[i
], "-compat") == 0) {
320 profileMask
= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
;
322 else if (strcmp(argv
[i
], "-debug") == 0) {
323 contextFlags
|= WGL_CONTEXT_DEBUG_BIT_ARB
;
325 else if (strcmp(argv
[i
], "-forward") == 0) {
326 contextFlags
|= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
;
334 create_context(majorVersion
, minorVersion
,
335 profileMask
, contextFlags
);