6 #include <allegro/internal/aintern.h> 14 static BITMAP *allegro_gl_win_init_windowed(
int w,
int h,
int v_w,
int v_h,
16 static BITMAP *allegro_gl_win_init_fullscreen(
int w,
int h,
int v_w,
int v_h,
18 static void allegro_gl_win_exit(
struct BITMAP *b);
19 static GFX_MODE_LIST* allegro_gl_win_fetch_mode_list(
void);
21 static struct allegro_gl_driver allegro_gl_win;
23 #define PREFIX_I "agl-win INFO: " 24 #define PREFIX_W "agl-win WARNING: " 25 #define PREFIX_E "agl-win ERROR: " 32 GFX_DRIVER gfx_allegro_gl_windowed = {
36 "AllegroGL Windowed (Win32)",
37 allegro_gl_win_init_windowed,
48 allegro_gl_set_mouse_sprite,
49 allegro_gl_show_mouse,
50 allegro_gl_hide_mouse,
51 allegro_gl_move_mouse,
52 allegro_gl_drawing_mode,
54 allegro_gl_set_blender_mode,
67 GFX_DRIVER gfx_allegro_gl_fullscreen = {
71 "AllegroGL Fullscreen (Win32)",
72 allegro_gl_win_init_fullscreen,
83 allegro_gl_set_mouse_sprite,
84 allegro_gl_show_mouse,
85 allegro_gl_hide_mouse,
86 allegro_gl_move_mouse,
87 allegro_gl_drawing_mode,
89 allegro_gl_set_blender_mode,
90 allegro_gl_win_fetch_mode_list,
109 HDC __allegro_gl_hdc = NULL;
114 static HGLRC allegro_glrc = NULL;
117 static int fullscreen = 0;
120 static HWND wnd = NULL;
123 static int initialized = 0;
128 static DWORD style_saved, exstyle_saved;
129 static DEVMODE dm_saved;
130 static int test_windows_created = 0;
131 static int new_w = 0, new_h = 0;
133 static PIXELFORMATDESCRIPTOR pfd = {
134 sizeof(PIXELFORMATDESCRIPTOR),
158 static void log_win32_msg(
const char *prefix,
const char *func,
159 const char *error_msg, DWORD err) {
161 char *err_msg = NULL;
162 BOOL free_msg = TRUE;
168 if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
169 | FORMAT_MESSAGE_FROM_SYSTEM
170 | FORMAT_MESSAGE_IGNORE_INSERTS,
172 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
173 (LPTSTR) &err_msg, 0, NULL)) {
174 err_msg =
"(Unable to decode error code) ";
179 if (err_msg && strlen(err_msg) > 1)
180 *(err_msg + strlen(err_msg) - 2) =
'\0';
182 TRACE(
"%s%s(): %s %s (0x%08lx)\n", prefix, func,
183 error_msg ? error_msg :
"",
184 err_msg ? err_msg :
"(null)",
197 static void log_win32_error(
const char *func,
const char *error_msg,
199 log_win32_msg(PREFIX_E, func, error_msg, err);
205 static void log_win32_warning(
const char *func,
const char *error_msg,
207 log_win32_msg(PREFIX_W, func, error_msg, err);
213 static void log_win32_note(
const char *func,
const char *error_msg, DWORD err) {
214 log_win32_msg(PREFIX_I, func, error_msg, err);
220 #define ALLEGROGL_TEST_WINDOW_CLASS "AllegroGLTestWindow" 226 static int register_test_window()
230 memset(&wc, 0,
sizeof(wc));
231 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
232 wc.lpfnWndProc = DefWindowProc;
233 wc.hInstance = GetModuleHandle(NULL);
234 wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION);
235 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
236 wc.lpszClassName = ALLEGROGL_TEST_WINDOW_CLASS;
238 if (!RegisterClass(&wc)) {
239 DWORD err = GetLastError();
241 if (err != ERROR_CLASS_ALREADY_EXISTS) {
242 log_win32_error(
"register_test_window",
243 "Unable to register the window class!", err);
258 static HWND create_test_window()
260 HWND wnd = CreateWindow(ALLEGROGL_TEST_WINDOW_CLASS,
261 "AllegroGL Test Window",
262 WS_POPUP | WS_CLIPCHILDREN,
265 GetModuleHandle(NULL),
269 log_win32_error(
"create_test_window",
270 "Unable to create a test window!", GetLastError());
274 test_windows_created++;
281 static void print_pixel_format(
struct allegro_gl_display_info *dinfo) {
287 TRACE(PREFIX_I
"Acceleration: %s\n", ((dinfo->rmethod == 0) ?
"No" 288 : ((dinfo->rmethod == 1) ?
"Yes" :
"Unknown")));
289 TRACE(PREFIX_I
"RGBA: %i.%i.%i.%i\n", dinfo->pixel_size.rgba.r,
290 dinfo->pixel_size.rgba.g, dinfo->pixel_size.rgba.b,
291 dinfo->pixel_size.rgba.a);
293 TRACE(PREFIX_I
"Accum: %i.%i.%i.%i\n", dinfo->accum_size.rgba.r,
294 dinfo->accum_size.rgba.g, dinfo->accum_size.rgba.b,
295 dinfo->accum_size.rgba.a);
297 TRACE(PREFIX_I
"DblBuf: %i Zbuf: %i Stereo: %i Aux: %i Stencil: %i\n",
298 dinfo->doublebuffered, dinfo->depth_size, dinfo->stereo,
299 dinfo->aux_buffers, dinfo->stencil_size);
301 TRACE(PREFIX_I
"Shift: %i.%i.%i.%i\n", dinfo->r_shift, dinfo->g_shift,
302 dinfo->b_shift, dinfo->a_shift);
304 TRACE(PREFIX_I
"Sample Buffers: %i Samples: %i\n",
305 dinfo->sample_buffers, dinfo->samples);
307 TRACE(PREFIX_I
"Decoded bpp: %i\n", dinfo->colour_depth);
315 static int decode_pixel_format(PIXELFORMATDESCRIPTOR * pfd, HDC hdc,
int format,
316 struct allegro_gl_display_info *dinfo,
319 TRACE(PREFIX_I
"Decoding: \n");
321 if (!(pfd->dwFlags & PFD_SUPPORT_OPENGL)) {
322 TRACE(PREFIX_I
"OpenGL Unsupported\n");
325 if (pfd->iPixelType != PFD_TYPE_RGBA) {
326 TRACE(PREFIX_I
"Not RGBA mode\n");
330 if ((pfd->cColorBits != desktop_depth)
331 && (pfd->cColorBits != 32 || desktop_depth < 24)) {
332 TRACE(PREFIX_I
"Current color depth != " 333 "pixel format color depth\n");
339 if (((pfd->dwFlags & PFD_GENERIC_ACCELERATED)
340 && (pfd->dwFlags & PFD_GENERIC_FORMAT))
341 || (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED)
342 && !(pfd->dwFlags & PFD_GENERIC_FORMAT)))
349 dinfo->pixel_size.rgba.r = pfd->cRedBits;
350 dinfo->pixel_size.rgba.g = pfd->cGreenBits;
351 dinfo->pixel_size.rgba.b = pfd->cBlueBits;
352 dinfo->pixel_size.rgba.a = pfd->cAlphaBits;
355 dinfo->accum_size.rgba.r = pfd->cAccumRedBits;
356 dinfo->accum_size.rgba.g = pfd->cAccumGreenBits;
357 dinfo->accum_size.rgba.b = pfd->cAccumBlueBits;
358 dinfo->accum_size.rgba.a = pfd->cAccumAlphaBits;
361 dinfo->doublebuffered = pfd->dwFlags & PFD_DOUBLEBUFFER;
362 dinfo->stereo = pfd->dwFlags & PFD_STEREO;
363 dinfo->aux_buffers = pfd->cAuxBuffers;
364 dinfo->depth_size = pfd->cDepthBits;
365 dinfo->stencil_size = pfd->cStencilBits;
368 dinfo->r_shift = pfd->cRedShift;
369 dinfo->g_shift = pfd->cGreenShift;
370 dinfo->b_shift = pfd->cBlueShift;
371 dinfo->a_shift = pfd->cAlphaShift;
376 dinfo->sample_buffers = 0;
382 dinfo->float_color = 0;
383 dinfo->float_depth = 0;
387 dinfo->colour_depth = 0;
388 if (dinfo->pixel_size.rgba.r == 5 && dinfo->pixel_size.rgba.b == 5) {
389 if (dinfo->pixel_size.rgba.g == 5)
390 dinfo->colour_depth = 15;
391 if (dinfo->pixel_size.rgba.g == 6)
392 dinfo->colour_depth = 16;
394 if (dinfo->pixel_size.rgba.r == 8
395 && dinfo->pixel_size.rgba.g == 8 && dinfo->pixel_size.rgba.b == 8) {
396 if (dinfo->pixel_size.rgba.a == 8)
397 dinfo->colour_depth = 32;
399 dinfo->colour_depth = 24;
403 dinfo->allegro_format = (dinfo->colour_depth != 0)
404 && (dinfo->g_shift == dinfo->pixel_size.rgba.b)
405 && (dinfo->r_shift * dinfo->b_shift == 0)
406 && (dinfo->r_shift + dinfo->b_shift ==
407 dinfo->pixel_size.rgba.b + dinfo->pixel_size.rgba.g);
417 static int decode_pixel_format_attrib(
struct allegro_gl_display_info *dinfo,
418 int num_attribs,
const int *attrib,
const int *value,
422 TRACE(PREFIX_I
"Decoding: \n");
425 dinfo->sample_buffers = 0;
426 dinfo->float_depth = 0;
427 dinfo->float_color = 0;
429 for (i = 0; i < num_attribs; i++) {
434 if (attrib[i] == WGL_SUPPORT_OPENGL_ARB && value[i] == 0) {
435 TRACE(PREFIX_I
"OpenGL Unsupported\n");
438 else if (attrib[i] == WGL_DRAW_TO_WINDOW_ARB && value[i] == 0) {
439 TRACE(PREFIX_I
"Can't draw to window\n");
442 else if (attrib[i] == WGL_PIXEL_TYPE_ARB &&
443 (value[i] != WGL_TYPE_RGBA_ARB
444 && value[i] != WGL_TYPE_RGBA_FLOAT_ARB)) {
445 TRACE(PREFIX_I
"Not RGBA mode\n");
449 else if (attrib[i] == WGL_COLOR_BITS_ARB) {
450 if ((value[i] != desktop_depth)
451 && (value[i] != 32 || desktop_depth < 24)) {
452 TRACE(PREFIX_I
"Current color depth != " 453 "pixel format color depth\n");
458 else if (attrib[i] == WGL_ACCELERATION_ARB) {
459 dinfo->rmethod = (value[i] == WGL_NO_ACCELERATION_ARB) ? 0 : 1;
462 else if (attrib[i] == WGL_RED_BITS_ARB) {
463 dinfo->pixel_size.rgba.r = value[i];
465 else if (attrib[i] == WGL_GREEN_BITS_ARB) {
466 dinfo->pixel_size.rgba.g = value[i];
468 else if (attrib[i] == WGL_BLUE_BITS_ARB) {
469 dinfo->pixel_size.rgba.b = value[i];
471 else if (attrib[i] == WGL_ALPHA_BITS_ARB) {
472 dinfo->pixel_size.rgba.a = value[i];
475 else if (attrib[i] == WGL_RED_SHIFT_ARB) {
476 dinfo->r_shift = value[i];
478 else if (attrib[i] == WGL_GREEN_SHIFT_ARB) {
479 dinfo->g_shift = value[i];
481 else if (attrib[i] == WGL_BLUE_SHIFT_ARB) {
482 dinfo->b_shift = value[i];
484 else if (attrib[i] == WGL_ALPHA_SHIFT_ARB) {
485 dinfo->a_shift = value[i];
489 else if (attrib[i] == WGL_ACCUM_RED_BITS_ARB) {
490 dinfo->accum_size.rgba.r = value[i];
492 else if (attrib[i] == WGL_ACCUM_GREEN_BITS_ARB) {
493 dinfo->accum_size.rgba.g = value[i];
495 else if (attrib[i] == WGL_ACCUM_BLUE_BITS_ARB) {
496 dinfo->accum_size.rgba.b = value[i];
498 else if (attrib[i] == WGL_ACCUM_ALPHA_BITS_ARB) {
499 dinfo->accum_size.rgba.a = value[i];
502 else if (attrib[i] == WGL_DOUBLE_BUFFER_ARB) {
503 dinfo->doublebuffered = value[i];
505 else if (attrib[i] == WGL_STEREO_ARB) {
506 dinfo->stereo = value[i];
508 else if (attrib[i] == WGL_AUX_BUFFERS_ARB) {
509 dinfo->aux_buffers = value[i];
511 else if (attrib[i] == WGL_DEPTH_BITS_ARB) {
512 dinfo->depth_size = value[i];
514 else if (attrib[i] == WGL_STENCIL_BITS_ARB) {
515 dinfo->stencil_size = value[i];
518 else if (attrib[i] == WGL_SAMPLE_BUFFERS_ARB) {
519 dinfo->sample_buffers = value[i];
521 else if (attrib[i] == WGL_SAMPLES_ARB) {
522 dinfo->samples = value[i];
525 if (attrib[i] == WGL_PIXEL_TYPE_ARB
526 && value[i] == WGL_TYPE_RGBA_FLOAT_ARB) {
527 dinfo->float_color = TRUE;
530 else if (attrib[i] == WGL_DEPTH_FLOAT_EXT) {
531 dinfo->float_depth = value[i];
537 dinfo->colour_depth = 0;
538 if (dinfo->pixel_size.rgba.r == 5 && dinfo->pixel_size.rgba.b == 5) {
539 if (dinfo->pixel_size.rgba.g == 5)
540 dinfo->colour_depth = 15;
541 if (dinfo->pixel_size.rgba.g == 6)
542 dinfo->colour_depth = 16;
544 if (dinfo->pixel_size.rgba.r == 8
545 && dinfo->pixel_size.rgba.g == 8 && dinfo->pixel_size.rgba.b == 8) {
546 if (dinfo->pixel_size.rgba.a == 8)
547 dinfo->colour_depth = 32;
549 dinfo->colour_depth = 24;
552 dinfo->allegro_format = (dinfo->colour_depth != 0)
553 && (dinfo->g_shift == dinfo->pixel_size.rgba.b)
554 && (dinfo->r_shift * dinfo->b_shift == 0)
555 && (dinfo->r_shift + dinfo->b_shift ==
556 dinfo->pixel_size.rgba.b + dinfo->pixel_size.rgba.g);
563 typedef struct format_t {
571 static int select_pixel_format_sorter(
const void *p0,
const void *p1) {
572 format_t *f0 = (format_t*)p0;
573 format_t *f1 = (format_t*)p1;
575 if (f0->score == f1->score) {
578 else if (f0->score > f1->score) {
589 int describe_pixel_format_old(HDC dc,
int fmt,
int desktop_depth,
590 format_t *formats,
int *num_formats,
591 struct allegro_gl_display_info *pdinfo) {
593 struct allegro_gl_display_info dinfo;
594 PIXELFORMATDESCRIPTOR pfd;
597 int result = DescribePixelFormat(dc, fmt,
sizeof(pfd), &pfd);
605 log_win32_warning(
"describe_pixel_format_old",
606 "DescribePixelFormat() failed!", GetLastError());
610 result = !decode_pixel_format(&pfd, dc, fmt, &dinfo, desktop_depth);
613 print_pixel_format(&dinfo);
614 score = __allegro_gl_score_config(fmt, &dinfo);
621 if (formats && num_formats) {
622 formats[*num_formats].score = score;
623 formats[*num_formats].format = fmt;
636 static AGL_GetPixelFormatAttribivARB_t __wglGetPixelFormatAttribivARB = NULL;
637 static AGL_GetPixelFormatAttribivEXT_t __wglGetPixelFormatAttribivEXT = NULL;
642 int describe_pixel_format_new(HDC dc,
int fmt,
int desktop_depth,
643 format_t *formats,
int *num_formats,
644 struct allegro_gl_display_info *pdinfo) {
646 struct allegro_gl_display_info dinfo;
653 WGL_SUPPORT_OPENGL_ARB,
654 WGL_DRAW_TO_WINDOW_ARB,
656 WGL_ACCELERATION_ARB,
657 WGL_DOUBLE_BUFFER_ARB,
668 WGL_STENCIL_BITS_ARB,
671 WGL_ACCUM_RED_BITS_ARB,
672 WGL_ACCUM_GREEN_BITS_ARB,
673 WGL_ACCUM_BLUE_BITS_ARB,
674 WGL_ACCUM_ALPHA_BITS_ARB,
688 const int num_attribs =
sizeof(attrib) /
sizeof(attrib[0]);
689 int *value = (
int*)malloc(
sizeof(
int) * num_attribs);
692 int old_valid = __allegro_gl_valid_context;
696 TRACE(PREFIX_E
"describe_pixel_format_new(): Unable to allocate " 697 "memory for pixel format descriptor!\n");
711 __allegro_gl_valid_context = 1;
713 attrib[num_attribs - 3] = WGL_SAMPLE_BUFFERS_ARB;
714 attrib[num_attribs - 2] = WGL_SAMPLES_ARB;
717 attrib[num_attribs - 1] = WGL_DEPTH_FLOAT_EXT;
719 __allegro_gl_valid_context = old_valid;
723 if (__wglGetPixelFormatAttribivARB) {
724 ret = __wglGetPixelFormatAttribivARB(dc, fmt, 0, num_attribs,
727 else if (__wglGetPixelFormatAttribivEXT) {
728 ret = __wglGetPixelFormatAttribivEXT(dc, fmt, 0, num_attribs,
737 log_win32_error(
"describe_pixel_format_new",
738 "wglGetPixelFormatAttrib failed!", GetLastError());
744 result = !decode_pixel_format_attrib(&dinfo, num_attribs, attrib, value,
749 print_pixel_format(&dinfo);
750 score = __allegro_gl_score_config(fmt, &dinfo);
757 if (formats && num_formats) {
758 formats[*num_formats].score = score;
759 formats[*num_formats].format = fmt;
773 int get_num_pixel_formats(HDC dc,
int *new_pf_code) {
778 if (new_pf_code && *new_pf_code) {
782 TRACE(PREFIX_I
"get_num_pixel_formats(): Attempting to use WGL_pf.\n");
783 attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB;
784 if ((__wglGetPixelFormatAttribivARB
785 && __wglGetPixelFormatAttribivARB(dc, 0, 0, 1, attrib, value)
787 || (__wglGetPixelFormatAttribivEXT
788 && __wglGetPixelFormatAttribivEXT(dc, 0, 0, 1, attrib, value)
790 log_win32_note(
"get_num_pixel_formats",
791 "WGL_ARB/EXT_pixel_format use failed!", GetLastError());
799 if (!new_pf_code || !*new_pf_code) {
800 PIXELFORMATDESCRIPTOR pfd;
803 TRACE(PREFIX_I
"get_num_pixel_formats(): Using DescribePixelFormat.\n");
804 ret = DescribePixelFormat(dc, 1,
sizeof(pfd), &pfd);
807 log_win32_error(
"get_num_pixel_formats",
808 "DescribePixelFormat failed!", GetLastError());
820 static int select_pixel_format(PIXELFORMATDESCRIPTOR * pfd)
823 int result, maxindex;
830 format_t *format = NULL;
835 __allegro_gl_reset_scorer();
838 desktop_depth = desktop_color_depth();
840 if (register_test_window() < 0) {
844 testwnd = create_test_window();
850 testdc = GetDC(testwnd);
853 TRACE(PREFIX_I
"select_pixel_format(): Trying to set up temporary RC\n");
855 HDC old_dc = __allegro_gl_hdc;
856 int old_valid = __allegro_gl_valid_context;
857 PIXELFORMATDESCRIPTOR pfd;
865 memset(&pfd, 0,
sizeof(pfd));
866 pfd.nSize =
sizeof(pfd);
867 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
868 | PFD_DOUBLEBUFFER_DONTCARE | PFD_STEREO_DONTCARE;
869 pfd.iPixelType = PFD_TYPE_RGBA;
870 pfd.iLayerType = PFD_MAIN_PLANE;
873 TRACE(PREFIX_I
"select_pixel_format(): ChoosePixelFormat()\n");
874 pf = ChoosePixelFormat(testdc, &pfd);
877 log_win32_warning(
"select_pixel_format",
878 "Unable to chose a temporary pixel format!",
884 TRACE(PREFIX_I
"select_pixel_format(): SetPixelFormat()\n");
885 memset(&pfd, 0,
sizeof(pfd));
886 if (!SetPixelFormat(testdc, pf, &pfd)) {
887 log_win32_warning(
"select_pixel_format",
888 "Unable to set a temporary pixel format!",
893 TRACE(PREFIX_I
"select_pixel_format(): CreateContext()\n");
894 testrc = wglCreateContext(testdc);
897 log_win32_warning(
"select_pixel_format",
898 "Unable to create a render context!",
903 TRACE(PREFIX_I
"select_pixel_format(): MakeCurrent()\n");
904 if (!wglMakeCurrent(testdc, testrc)) {
905 log_win32_warning(
"select_pixel_format",
906 "Unable to set the render context as current!",
911 __allegro_gl_hdc = testdc;
912 __allegro_gl_valid_context = TRUE;
918 TRACE(PREFIX_I
"select_pixel_format(): GetExtensionsStringARB()\n");
919 if (strstr((AL_CONST
char*)glGetString(GL_VENDOR),
"NVIDIA")) {
920 AGL_GetExtensionsStringARB_t __wglGetExtensionsStringARB = NULL;
922 __wglGetExtensionsStringARB = (AGL_GetExtensionsStringARB_t)
923 wglGetProcAddress(
"wglGetExtensionsStringARB");
925 TRACE(PREFIX_I
"select_pixel_format(): Querying for " 926 "WGL_ARB_extension_string\n");
928 if (__wglGetExtensionsStringARB) {
929 TRACE(PREFIX_I
"select_pixel_format(): Calling " 930 "__wglGetExtensionsStringARB\n");
931 __wglGetExtensionsStringARB(testdc);
939 TRACE(PREFIX_I
"select_pixel_format(): WGL_ARB/EXT_pf unsupported.\n");
946 TRACE(PREFIX_I
"select_pixel_format(): GetProcAddress()\n");
947 __wglGetPixelFormatAttribivARB = (AGL_GetPixelFormatAttribivARB_t)
948 wglGetProcAddress(
"wglGetPixelFormatAttribivARB");
949 __wglGetPixelFormatAttribivEXT = (AGL_GetPixelFormatAttribivEXT_t)
950 wglGetProcAddress(
"wglGetPixelFormatAttribivEXT");
952 if (!__wglGetPixelFormatAttribivARB
953 && !__wglGetPixelFormatAttribivEXT) {
954 TRACE(PREFIX_E
"select_pixel_format(): WGL_ARB/EXT_pf not " 955 "correctly supported!\n");
963 wglMakeCurrent(NULL, NULL);
965 wglDeleteContext(testrc);
969 __wglGetPixelFormatAttribivARB = NULL;
970 __wglGetPixelFormatAttribivEXT = NULL;
972 __allegro_gl_hdc = old_dc;
973 __allegro_gl_valid_context = old_valid;
976 maxindex = get_num_pixel_formats(testdc, &new_pf_code);
981 if (!new_pf_code && testrc) {
982 TRACE(PREFIX_W
"select_pixel_format(): WGL_ARB_pf call failed - " 983 "reverted to plain old WGL.\n");
984 wglMakeCurrent(NULL, NULL);
985 wglDeleteContext(testrc);
987 __wglGetPixelFormatAttribivARB = NULL;
988 __wglGetPixelFormatAttribivEXT = NULL;
991 TRACE(PREFIX_I
"select_pixel_format(): %i formats.\n", maxindex);
994 TRACE(PREFIX_E
"select_pixel_format(): Didn't find any pixel " 995 "formats at all!\n");
999 format = malloc((maxindex + 1) *
sizeof(format_t));
1002 TRACE(PREFIX_E
"select_pixel_format(): Unable to allocate memory for " 1003 "pixel format scores!\n");
1008 TRACE(PREFIX_I
"select_pixel_format(): Testing pixel formats:\n");
1009 for (i = 1; i <= maxindex; i++) {
1011 int use_old = !new_pf_code;
1013 TRACE(PREFIX_I
"Format %i:\n", i);
1016 if (describe_pixel_format_new(testdc, i, desktop_depth,
1017 format, &num_formats, NULL) < 0) {
1018 TRACE(PREFIX_W
"select_pixel_format(): Wasn't able to use " 1019 "WGL_PixelFormat - reverting to old WGL code.\n");
1025 if (describe_pixel_format_old(testdc, i, desktop_depth,
1026 format, &num_formats, NULL) < 0) {
1027 TRACE(PREFIX_W
"select_pixel_format(): Unable to rely on " 1028 "unextended WGL to describe this pixelformat.\n");
1034 wglMakeCurrent(NULL, NULL);
1035 wglDeleteContext(testrc);
1039 ReleaseDC(testwnd, testdc);
1041 DestroyWindow(testwnd);
1045 if (num_formats < 1) {
1046 TRACE(PREFIX_E
"select_pixel_format(): Didn't find any available " 1047 "pixel formats!\n");
1051 qsort(format, num_formats,
sizeof(format_t), select_pixel_format_sorter);
1056 for (i = 0; i < num_formats ; i++) {
1060 testwnd = create_test_window();
1061 testdc = GetDC(testwnd);
1063 if (SetPixelFormat(testdc, format[i].format, pfd)) {
1064 rc = wglCreateContext(testdc);
1066 TRACE(PREFIX_I
"select_pixel_format(): Unable to create RC!\n");
1069 if (wglMakeCurrent(testdc, rc)) {
1070 wglMakeCurrent(NULL, NULL);
1071 wglDeleteContext(rc);
1074 TRACE(PREFIX_I
"select_pixel_format(): Best config is: %i" 1075 "\n", format[i].format);
1080 if (!DescribePixelFormat(testdc, format[i].format,
1081 sizeof *pfd, pfd)) {
1082 TRACE(PREFIX_E
"Cannot describe this pixel format\n");
1083 ReleaseDC(testwnd, testdc);
1084 DestroyWindow(testwnd);
1090 ReleaseDC(testwnd, testdc);
1091 DestroyWindow(testwnd);
1093 result = format[i].format;
1099 wglMakeCurrent(NULL, NULL);
1100 wglDeleteContext(rc);
1102 log_win32_warning(
"select_pixel_format",
1103 "Couldn't make the temporary render context " 1104 "current for the this pixel format.",
1110 log_win32_note(
"select_pixel_format",
1111 "Unable to set pixel format!", GetLastError());
1114 ReleaseDC(testwnd, testdc);
1115 DestroyWindow(testwnd);
1120 TRACE(PREFIX_E
"select_pixel_format(): All modes have failed...\n");
1126 wglMakeCurrent(NULL, NULL);
1128 wglDeleteContext(testrc);
1132 ReleaseDC(testwnd, testdc);
1133 DestroyWindow(testwnd);
1141 static void allegrogl_init_window(
int w,
int h, DWORD style, DWORD exstyle)
1145 #define req __allegro_gl_required_settings 1146 #define sug __allegro_gl_suggested_settings 1151 x = allegro_gl_display_info.x;
1153 y = allegro_gl_display_info.y;
1162 rect.bottom = y + h;
1172 style_saved = GetWindowLong(wnd, GWL_STYLE);
1173 exstyle_saved = GetWindowLong(wnd, GWL_EXSTYLE);
1176 SetWindowLong(wnd, GWL_STYLE, style);
1177 SetWindowLong(wnd, GWL_EXSTYLE, exstyle);
1180 AdjustWindowRectEx(&rect, style, FALSE, exstyle);
1184 SetWindowPos(wnd, 0, rect.left, rect.top,
1185 rect.right - rect.left, rect.bottom - rect.top,
1186 SWP_NOZORDER | SWP_FRAMECHANGED);
1193 static BITMAP *allegro_gl_create_screen (GFX_DRIVER *drv,
int w,
int h,
1197 int is_linear = drv->linear;
1200 bmp = _make_bitmap (w, h, 0, drv, depth, 0);
1206 bmp->id = BMP_ID_VIDEO | 1000;
1207 drv->linear = is_linear;
1216 static LRESULT CALLBACK dummy_wnd_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
1218 return DefWindowProc(wnd, message, wparam, lparam);
1221 static HWND dummy_wnd;
1223 static void dummy_window(
void)
1227 wnd_class.style = CS_HREDRAW | CS_VREDRAW;
1228 wnd_class.lpfnWndProc = dummy_wnd_proc;
1229 wnd_class.cbClsExtra = 0;
1230 wnd_class.cbWndExtra = 0;
1231 wnd_class.hInstance = GetModuleHandle(NULL);
1232 wnd_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
1233 wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
1234 wnd_class.hbrBackground = NULL;
1235 wnd_class.lpszMenuName = NULL;
1236 wnd_class.lpszClassName =
"allegro focus";
1238 RegisterClass(&wnd_class);
1240 dummy_wnd = CreateWindow(
"allegro focus",
"Allegro", WS_POPUP | WS_VISIBLE,
1242 NULL, NULL, GetModuleHandle(NULL), NULL);
1244 ShowWindow(dummy_wnd, SW_SHOWNORMAL);
1245 SetForegroundWindow(dummy_wnd);
1248 static void remove_dummy_window(
void)
1250 DestroyWindow(dummy_wnd);
1251 UnregisterClass(
"allegro focus", GetModuleHandle(NULL));
1255 static BITMAP *allegro_gl_win_init(
int w,
int h,
int v_w,
int v_h)
1257 static int first_time = 1;
1259 DWORD style=0, exstyle=0;
1260 int refresh_rate = _refresh_rate_request;
1268 if ((v_w != 0 && v_w != w) || (v_h != 0 && v_h != h)) {
1269 TRACE(PREFIX_E
"win_init(): Virtual screens are not supported in " 1275 __allegro_gl_fill_in_info();
1280 desktop_depth = desktop_color_depth();
1282 if (desktop_depth < 15)
1285 TRACE(PREFIX_I
"win_init(): Requested color depth: %i " 1286 "Desktop color depth: %i\n", allegro_gl_display_info.colour_depth,
1294 if (fullscreen) dummy_window();
1300 gfx_allegro_gl_fullscreen.w = w;
1301 gfx_allegro_gl_fullscreen.h = h;
1304 gfx_allegro_gl_windowed.w = w;
1305 gfx_allegro_gl_windowed.h = h;
1314 win_set_window(NULL);
1319 wnd = win_get_window();
1325 style = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
1326 exstyle = WS_EX_APPWINDOW | WS_EX_TOPMOST;
1329 style = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_CLIPCHILDREN
1331 exstyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
1334 TRACE(PREFIX_I
"win_init(): Setting up window.\n");
1335 allegrogl_init_window(w, h, style, exstyle);
1337 __allegro_gl_hdc = GetDC(wnd);
1338 if (!__allegro_gl_hdc) {
1342 TRACE(PREFIX_I
"win_init(): Driver selected fullscreen: %s\n",
1343 fullscreen ?
"Yes" :
"No");
1348 DEVMODE fallback_dm;
1349 int fallback_dm_valid = 0;
1351 int bpp_to_check[] = {16, 32, 24, 15, 0};
1352 int bpp_checked[] = {0, 0, 0, 0, 0};
1354 int i, j, result, modeswitch, done = 0;
1356 for (j = 0; j < 4; j++)
1365 dm.dmSize =
sizeof(DEVMODE);
1366 dm_saved.dmSize =
sizeof(DEVMODE);
1369 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm_saved);
1370 dm.dmBitsPerPel = desktop_depth;
1374 if (!bpp_to_check[bpp_index])
1376 TRACE(PREFIX_E
"win_init(): No more color depths to test.\n" 1377 "\tUnable to find appropriate full screen mode and pixel " 1382 TRACE(PREFIX_I
"win_init(): Testing color depth: %i\n",
1383 bpp_to_check[bpp_index]);
1385 memset(&dm, 0,
sizeof(DEVMODE));
1386 dm.dmSize =
sizeof(DEVMODE);
1391 modeswitch = EnumDisplaySettings(NULL, i, &dm);
1395 if ((dm.dmPelsWidth == (
unsigned) w)
1396 && (dm.dmPelsHeight == (
unsigned) h)
1397 && (dm.dmBitsPerPel == (
unsigned) bpp_to_check[bpp_index])
1398 && (dm.dmDisplayFrequency != (
unsigned) refresh_rate)) {
1404 if (!fallback_dm_valid) {
1406 fallback_dm_valid = 1;
1408 else if (dm.dmDisplayFrequency >= 60) {
1409 if (dm.dmDisplayFrequency < fallback_dm.dmDisplayFrequency) {
1417 while ((dm.dmPelsWidth != (
unsigned) w)
1418 || (dm.dmPelsHeight != (
unsigned) h)
1419 || (dm.dmBitsPerPel != (
unsigned) bpp_to_check[bpp_index])
1420 || (dm.dmDisplayFrequency != (
unsigned) refresh_rate));
1422 if (!modeswitch && !fallback_dm_valid) {
1423 TRACE(PREFIX_I
"win_init(): Unable to set mode, continuing " 1424 "with next color depth\n");
1427 if (!modeswitch && fallback_dm_valid)
1430 TRACE(PREFIX_I
"win_init(): bpp_to_check[bpp_index] = %i\n",
1431 bpp_to_check[bpp_index]);
1432 TRACE(PREFIX_I
"win_init(): dm.dmBitsPerPel = %i\n",
1433 (
int)dm.dmBitsPerPel);
1435 dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL
1436 | DM_DISPLAYFREQUENCY;
1438 result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
1440 if (result == DISP_CHANGE_SUCCESSFUL)
1442 TRACE(PREFIX_I
"win_init(): Setting pixel format.\n");
1443 pf = select_pixel_format(&pfd);
1445 TRACE(PREFIX_I
"mode found\n");
1446 _set_current_refresh_rate(dm.dmDisplayFrequency);
1450 TRACE(PREFIX_I
"win_init(): Couldn't find compatible " 1451 "GL context. Trying another screen mode.\n");
1456 fallback_dm_valid = 0;
1457 bpp_checked[bpp_index] = 1;
1460 while (bpp_checked[bpp_index]) {
1468 memset(&dm, 0,
sizeof(DEVMODE));
1469 dm.dmSize =
sizeof(DEVMODE);
1470 if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) != 0) {
1471 _set_current_refresh_rate(dm.dmDisplayFrequency);
1476 TRACE(PREFIX_I
"win_init(): Setting pixel format.\n");
1477 pf = select_pixel_format(&pfd);
1483 if (!SetPixelFormat(__allegro_gl_hdc, pf, &pfd)) {
1484 log_win32_error(
"win_init",
1485 "Unable to set pixel format.",
1491 allegro_glrc = wglCreateContext(__allegro_gl_hdc);
1493 if (!allegro_glrc) {
1494 log_win32_error(
"win_init",
1495 "Unable to create a render context!",
1499 if (!wglMakeCurrent(__allegro_gl_hdc, allegro_glrc)) {
1500 log_win32_error(
"win_init",
1501 "Unable to make the context current!",
1507 if (__wglGetPixelFormatAttribivARB || __wglGetPixelFormatAttribivEXT) {
1508 describe_pixel_format_new(__allegro_gl_hdc, pf, desktop_depth,
1509 NULL, NULL, &allegro_gl_display_info);
1512 describe_pixel_format_old(__allegro_gl_hdc, pf, desktop_depth,
1513 NULL, NULL, &allegro_gl_display_info);
1517 __allegro_gl_set_allegro_image_format(FALSE);
1518 set_color_depth(allegro_gl_display_info.colour_depth);
1519 allegro_gl_display_info.w = w;
1520 allegro_gl_display_info.h = h;
1536 #define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 1537 #define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 1539 SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,
1540 0, (LPVOID)&lock_time, 0);
1541 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,
1543 SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
1546 ShowWindow(wnd, SW_SHOWNORMAL);
1547 SetForegroundWindow(wnd);
1552 while (GetForegroundWindow() != wnd) {
1554 SetForegroundWindow(wnd);
1559 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,
1560 0, (LPVOID)lock_time,
1561 SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
1563 #undef SPI_GETFOREGROUNDLOCKTIMEOUT 1564 #undef SPI_SETFOREGROUNDLOCKTIMEOUT 1579 ChangeDisplaySettings(NULL, 0);
1584 TRACE(PREFIX_I
"win_init(): GLScreen: %ix%ix%i\n",
1589 __allegro_gl_valid_context = TRUE;
1590 __allegro_gl_driver = &allegro_gl_win;
1594 TRACE(PREFIX_I
"OpenGL Version: %s\n", (AL_CONST
char*)glGetString(GL_VERSION));
1595 TRACE(PREFIX_I
"Vendor: %s\n", (AL_CONST
char*)glGetString(GL_VENDOR));
1596 TRACE(PREFIX_I
"Renderer: %s\n\n", (AL_CONST
char*)glGetString(GL_RENDERER));
1599 allegro_gl_info.is_mesa_driver = FALSE;
1600 if (strstr((AL_CONST
char*)glGetString(GL_VERSION),
"Mesa")) {
1601 AGL_LOG(1,
"OpenGL driver based on Mesa\n");
1602 allegro_gl_info.is_mesa_driver = TRUE;
1606 __allegro_gl_manage_extensions();
1614 if (wglGetExtensionsStringARB) {
1615 AGL_LOG(1,
"WGL Extensions :\n");
1617 __allegro_gl_print_extensions((AL_CONST
char*)wglGetExtensionsStringARB(wglGetCurrentDC()));
1621 TRACE(PREFIX_I
"win_init(): No WGL Extensions available\n");
1624 gfx_capabilities |= GFX_HW_CURSOR;
1629 glViewport(0, 0, SCREEN_W, SCREEN_H);
1630 glMatrixMode(GL_PROJECTION);
1632 glMatrixMode(GL_MODELVIEW);
1639 glSampleCoverage(1.0, GL_FALSE);
1641 glSampleCoverageARB(1.0, GL_FALSE);
1645 glBindTexture(GL_TEXTURE_2D, 0);
1650 remove_dummy_window();
1656 wglDeleteContext(allegro_glrc);
1658 if (__allegro_gl_hdc) {
1659 ReleaseDC(wnd, __allegro_gl_hdc);
1661 __allegro_gl_hdc = NULL;
1662 ChangeDisplaySettings(NULL, 0);
1663 allegro_gl_win_exit(NULL);
1670 static BITMAP *allegro_gl_win_init_windowed(
int w,
int h,
int v_w,
int v_h,
1674 return allegro_gl_win_init(w, h, v_w, v_h);
1679 static BITMAP *allegro_gl_win_init_fullscreen(
int w,
int h,
int v_w,
int v_h,
1683 return allegro_gl_win_init(w, h, v_w, v_h);
1688 static void allegro_gl_win_exit(
struct BITMAP *b)
1694 __allegro_gl_unmanage_extensions();
1697 wglDeleteContext(allegro_glrc);
1698 allegro_glrc = NULL;
1701 if (__allegro_gl_hdc) {
1702 ReleaseDC(wnd, __allegro_gl_hdc);
1703 __allegro_gl_hdc = NULL;
1706 if (fullscreen && initialized) {
1708 ChangeDisplaySettings(NULL, 0);
1709 _set_current_refresh_rate(0);
1720 system_driver->restore_console_state();
1723 SetWindowLong(wnd, GWL_STYLE, style_saved);
1724 SetWindowLong(wnd, GWL_EXSTYLE, exstyle_saved);
1725 SetWindowPos(wnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
1726 | SWP_FRAMECHANGED);
1728 __allegro_gl_valid_context = FALSE;
1737 static int is_mode_entry_unique(GFX_MODE_LIST *mode_list, DEVMODE *dm) {
1740 for (i = 0; i < mode_list->num_modes; ++i) {
1741 if (mode_list->mode[i].width == (
int)dm->dmPelsWidth
1742 && mode_list->mode[i].height == (
int)dm->dmPelsHeight
1743 && mode_list->mode[i].bpp == (
int)dm->dmBitsPerPel)
1753 static GFX_MODE_LIST* allegro_gl_win_fetch_mode_list(
void)
1756 GFX_MODE_LIST *mode_list;
1759 dm.dmSize =
sizeof(DEVMODE);
1762 mode_list = malloc(
sizeof(GFX_MODE_LIST));
1770 mode_list->mode = malloc(
sizeof(GFX_MODE));
1771 if (!mode_list->mode) {
1775 mode_list->mode[0].width = 0;
1776 mode_list->mode[0].height = 0;
1777 mode_list->mode[0].bpp = 0;
1778 mode_list->num_modes = 0;
1782 while (EnumDisplaySettings(NULL, c, &dm)) {
1783 mode_list->mode = realloc(mode_list->mode,
1784 sizeof(GFX_MODE) * (modes_count + 2));
1785 if (!mode_list->mode) {
1793 if (dm.dmBitsPerPel > 8 && is_mode_entry_unique(mode_list, &dm)) {
1794 mode_list->mode[modes_count].width = dm.dmPelsWidth;
1795 mode_list->mode[modes_count].height = dm.dmPelsHeight;
1796 mode_list->mode[modes_count].bpp = dm.dmBitsPerPel;
1798 mode_list->mode[modes_count].width = 0;
1799 mode_list->mode[modes_count].height = 0;
1800 mode_list->mode[modes_count].bpp = 0;
1801 mode_list->num_modes = modes_count;
1814 static void flip(
void)
1816 SwapBuffers(__allegro_gl_hdc);
1821 static void gl_on(
void)
1828 static void gl_off(
void)
1837 static struct allegro_gl_driver allegro_gl_win = {
1838 flip, gl_on, gl_off, NULL
#define GFX_OPENGL_FULLSCREEN
Fullscreen OpenGL graphics driver for Allegro.
float allegro_gl_opengl_version(void)
Returns the OpenGL version number of the client (the computer the program is running on)...
int allegro_gl_get(int option)
Reads the setting of a configuration option.
struct AGL_EXTENSION_LIST_GL allegro_gl_extensions_GL
List of OpenGL extensions supported by AllegroGL.
#define AGL_WINDOW_X
Requests a placement of the window to a specified pixel location.
#define AGL_WINDOW_Y
Same as AGL_WINDOW_X, but for the y-axis.
#define AGL_COLOR_DEPTH
Specify the total color depth of the frame buffer.
#define GFX_OPENGL_WINDOWED
Windowed OpenGL graphics driver for Allegro.
void allegro_gl_destroy_video_bitmap(BITMAP *bmp)
destroy_video_bitmap() overload.
int allegro_gl_is_extension_supported(AL_CONST char *extension)
This function is an helper to determine whether an OpenGL extension is available or not...
Main header file for AllegroGL.
BITMAP * allegro_gl_screen
Direct-mode GL `screen' bitmap.
BITMAP * allegro_gl_create_video_bitmap(int w, int h)
create_video_bitmap() overload.