1 // SPDX-FileCopyrightText: Copyright 2014 Emil Velikov
2 // SPDX-License-Identifier: BSD-2-Clause
4 #include "c99_compat.h"
9 #include "wcore_error.h"
11 #include "win_platform.h"
13 #include "wgl_display.h"
14 #include "wgl_platform.h"
17 wgl_display_destroy(struct wcore_display
*wc_self
)
19 struct wgl_display
*self
= wgl_display(wc_self
);
24 ok
&= wglDeleteContext(self
->hglrc
);
28 ok
&= ReleaseDC(self
->hWnd
, self
->hDC
);
30 ok
&= DestroyWindow(self
->hWnd
);
38 wgl_display_create_window(struct wgl_platform
*plat
, struct wgl_display
*dpy
)
40 dpy
->hWnd
= CreateWindow(plat
->class_name
, NULL
,
41 WS_POPUPWINDOW
|WS_DISABLED
,
42 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
46 dpy
->hDC
= GetDC(dpy
->hWnd
);
54 wgl_display_choose_config(struct wgl_display
*dpy
)
56 // XXX: Is there a move common/appropriate pixelformat ?
57 PIXELFORMATDESCRIPTOR pfd
= {0};
60 pfd
.nSize
= sizeof(PIXELFORMATDESCRIPTOR
);
63 pfd
.dwFlags
= PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_WINDOW
| PFD_DOUBLEBUFFER
;
65 pfd
.iPixelType
= PFD_TYPE_RGBA
;
66 pfd
.iLayerType
= PFD_MAIN_PLANE
;
70 dpy
->pixel_format
= ChoosePixelFormat(dpy
->hDC
, &pfd
);
71 if (!dpy
->pixel_format
)
74 ok
= SetPixelFormat(dpy
->hDC
, dpy
->pixel_format
, &pfd
);
82 wgl_display_hardware_render(struct wgl_display
*dpy
)
85 #define GL_RENDERER 0x1F01
87 typedef unsigned int GLenum
;
88 typedef unsigned char GLubyte
;
89 typedef const GLubyte
* (__stdcall
*PFNGLGETSTRINGPROC
)(GLenum name
);
91 PFNGLGETSTRINGPROC glGetString_func
;
92 const GLubyte
*gl_renderer
;
94 glGetString_func
= win_platform_dlsym(dpy
->wcore
.platform
, WAFFLE_DL_OPENGL
,
96 if (!glGetString_func
)
99 gl_renderer
= glGetString_func(GL_RENDERER
);
101 // Bail out if we cannot retrieve the renderer string or if we're using GDI
102 if (!gl_renderer
|| strcasecmp((const char *)gl_renderer
, "GDI Generic") == 0)
109 wgl_display_set_extensions(struct wgl_display
*dpy
)
111 typedef const char * (__stdcall
*PFNWGLGETEXTENSIONSSTRINGARBPROC
)(HDC hdc
);
112 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_func
;
113 const char *extensions
;
115 wglGetExtensionsStringARB_func
= (void *)wglGetProcAddress("wglGetExtensionsStringARB");
116 if (!wglGetExtensionsStringARB_func
) {
117 wcore_errorf(WAFFLE_ERROR_UNKNOWN
,
118 "wglGetProcAddress(\"wglGetExtensionsStringARB\") failed");
122 extensions
= wglGetExtensionsStringARB_func(dpy
->hDC
);
125 wcore_errorf(WAFFLE_ERROR_UNKNOWN
,
126 "wglGetExtensionsStringARB failed");
130 dpy
->ARB_create_context
= waffle_is_extension_in_string(extensions
, "WGL_ARB_create_context");
131 dpy
->ARB_create_context_profile
= waffle_is_extension_in_string(extensions
, "WGL_ARB_create_context_profile");
132 dpy
->ARB_create_context_robustness
= waffle_is_extension_in_string(extensions
, "WGL_ARB_create_context_robustness");
133 dpy
->EXT_create_context_es_profile
= waffle_is_extension_in_string(extensions
, "WGL_EXT_create_context_es_profile");
135 // The WGL_EXT_create_context_es2_profile spec, version 5 2012/04/06,
136 // states that WGL_EXT_create_context_es_profile is an alias of
137 // WGL_EXT_create_context_es2_profile and requires that both names must be
138 // exported together for backwards compatibility with clients that expect
139 // the es2_profile name.
140 if (dpy
->EXT_create_context_es_profile
) {
141 dpy
->EXT_create_context_es2_profile
= true;
144 // Assume that WGL does not implement version 3 of the extension, in
145 // which case the ES contexts WGL is capable of creating is ES2.
146 dpy
->EXT_create_context_es2_profile
= waffle_is_extension_in_string(extensions
, "WGL_EXT_create_context_es2_profile");
149 dpy
->ARB_pixel_format
= waffle_is_extension_in_string(extensions
, "WGL_ARB_pixel_format");
155 wgl_display_set_func_ptrs(struct wgl_display
*dpy
)
157 if (dpy
->ARB_create_context
) {
158 dpy
->wglCreateContextAttribsARB
= (void *)wglGetProcAddress("wglCreateContextAttribsARB");
159 if (!dpy
->wglCreateContextAttribsARB
) {
160 wcore_errorf(WAFFLE_ERROR_UNKNOWN
,
161 "wglGetProcAddress(\"wglCreateContextAttribsARB\") failed");
166 if (dpy
->ARB_pixel_format
) {
167 dpy
->wglChoosePixelFormatARB
= (void *)wglGetProcAddress("wglChoosePixelFormatARB");
168 if (!dpy
->wglChoosePixelFormatARB
) {
169 wcore_errorf(WAFFLE_ERROR_UNKNOWN
,
170 "wglGetProcAddress(\"wglChoosePixelFormatARB\") failed");
178 struct wcore_display
*
179 wgl_display_connect(struct wcore_platform
*wc_plat
,
182 struct wgl_display
*self
;
185 self
= wcore_calloc(sizeof(*self
));
189 wcore_display_init(&self
->wcore
, wc_plat
);
191 ok
= wgl_display_create_window(wgl_platform(wc_plat
), self
);
195 ok
= wgl_display_choose_config(self
);
199 self
->hglrc
= wglCreateContext(self
->hDC
);
203 ok
= wglMakeCurrent(self
->hDC
, self
->hglrc
);
207 ok
= wgl_display_hardware_render(self
);
211 ok
= wgl_display_set_extensions(self
);
215 ok
= wgl_display_set_func_ptrs(self
);
219 ok
= wglMakeCurrent(NULL
, NULL
);
226 wgl_display_destroy(&self
->wcore
);
231 wgl_display_supports_context_api(struct wcore_display
*wc_self
,
234 struct wgl_display
*self
= wgl_display(wc_self
);
236 switch (context_api
) {
237 case WAFFLE_CONTEXT_OPENGL
:
239 case WAFFLE_CONTEXT_OPENGL_ES1
:
240 return self
->EXT_create_context_es_profile
;
241 case WAFFLE_CONTEXT_OPENGL_ES2
:
242 return self
->EXT_create_context_es2_profile
;
243 case WAFFLE_CONTEXT_OPENGL_ES3
:
244 return self
->EXT_create_context_es_profile
;