comparison src/video/wincommon/SDL_wingl.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 9d940db55a91
children
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
32 #if SDL_VIDEO_OPENGL 32 #if SDL_VIDEO_OPENGL
33 #define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL" 33 #define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
34 #endif 34 #endif
35 35
36 /* If setting the HDC fails, we may need to recreate the window (MSDN) */ 36 /* If setting the HDC fails, we may need to recreate the window (MSDN) */
37 static int WIN_GL_ResetWindow(_THIS) 37 static int
38 { 38 WIN_GL_ResetWindow(_THIS)
39 int status = 0; 39 {
40 40 int status = 0;
41 #ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */ 41
42 /* This doesn't work with DirectX code (see CVS comments) */ 42 #ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */
43 /* If we were passed a window, then we can't create a new one */ 43 /* This doesn't work with DirectX code (see CVS comments) */
44 if ( !SDL_windowid && SDL_strcmp(this->name, "windib") == 0 ) { 44 /* If we were passed a window, then we can't create a new one */
45 /* Save the existing window attributes */ 45 if (!SDL_windowid && SDL_strcmp(this->name, "windib") == 0) {
46 LONG style; 46 /* Save the existing window attributes */
47 RECT rect = { 0, 0, 0, 0 }; 47 LONG style;
48 style = GetWindowLong(SDL_Window, GWL_STYLE); 48 RECT rect = { 0, 0, 0, 0 };
49 GetWindowRect(SDL_Window, &rect); 49 style = GetWindowLong(SDL_Window, GWL_STYLE);
50 DestroyWindow(SDL_Window); 50 GetWindowRect(SDL_Window, &rect);
51 WIN_FlushMessageQueue(); 51 DestroyWindow(SDL_Window);
52 52 WIN_FlushMessageQueue();
53 SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, 53
54 style, 54 SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
55 rect.left, rect.top, 55 style,
56 (rect.right-rect.left)+1, 56 rect.left, rect.top,
57 (rect.top-rect.bottom)+1, 57 (rect.right - rect.left) + 1,
58 NULL, NULL, SDL_Instance, NULL); 58 (rect.top - rect.bottom) + 1,
59 WIN_FlushMessageQueue(); 59 NULL, NULL, SDL_Instance, NULL);
60 60 WIN_FlushMessageQueue();
61 if ( SDL_Window ) { 61
62 this->SetCaption(this, this->wm_title, this->wm_icon); 62 if (SDL_Window) {
63 } else { 63 this->SetCaption(this, this->wm_title, this->wm_icon);
64 SDL_SetError("Couldn't create window"); 64 } else {
65 status = -1; 65 SDL_SetError("Couldn't create window");
66 } 66 status = -1;
67 } else 67 }
68 } else
68 #endif /* !_WIN32_WCE */ 69 #endif /* !_WIN32_WCE */
69 { 70 {
70 SDL_SetError("Unable to reset window for OpenGL context"); 71 SDL_SetError("Unable to reset window for OpenGL context");
71 status = -1; 72 status = -1;
72 } 73 }
73 return(status); 74 return (status);
74 } 75 }
75 76
76 #if SDL_VIDEO_OPENGL 77 #if SDL_VIDEO_OPENGL
77 78
78 static int ExtensionSupported(const char *extension, const char *extensions) 79 static int
79 { 80 ExtensionSupported(const char *extension, const char *extensions)
80 const char *start; 81 {
81 const char *where, *terminator; 82 const char *start;
82 83 const char *where, *terminator;
83 /* Extension names should not have spaces. */ 84
84 where = SDL_strchr(extension, ' '); 85 /* Extension names should not have spaces. */
85 if ( where || *extension == '\0' ) 86 where = SDL_strchr(extension, ' ');
86 return 0; 87 if (where || *extension == '\0')
87 88 return 0;
88 if ( ! extensions ) 89
89 return 0; 90 if (!extensions)
90 91 return 0;
91 /* It takes a bit of care to be fool-proof about parsing the 92
92 * OpenGL extensions string. Don't be fooled by sub-strings, 93 /* It takes a bit of care to be fool-proof about parsing the
93 * etc. */ 94 * OpenGL extensions string. Don't be fooled by sub-strings,
94 95 * etc. */
95 start = extensions; 96
96 97 start = extensions;
97 for (;;) 98
98 { 99 for (;;) {
99 where = SDL_strstr(start, extension); 100 where = SDL_strstr(start, extension);
100 if (!where) break; 101 if (!where)
101 102 break;
102 terminator = where + SDL_strlen(extension); 103
103 if (where == start || *(where - 1) == ' ') 104 terminator = where + SDL_strlen(extension);
104 if (*terminator == ' ' || *terminator == '\0') return 1; 105 if (where == start || *(where - 1) == ' ')
105 106 if (*terminator == ' ' || *terminator == '\0')
106 start = terminator; 107 return 1;
107 } 108
108 109 start = terminator;
109 return 0; 110 }
110 } 111
111 112 return 0;
112 static void Init_WGL_ARB_extensions(_THIS) 113 }
113 { 114
114 HWND hwnd; 115 static void
115 HDC hdc; 116 Init_WGL_ARB_extensions(_THIS)
116 HGLRC hglrc; 117 {
117 int pformat; 118 HWND hwnd;
118 const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0; 119 HDC hdc;
119 const char *extensions; 120 HGLRC hglrc;
120 121 int pformat;
121 hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED, 122 const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
122 0, 0, 10, 10, 123 const char *extensions;
123 NULL, NULL, SDL_Instance, NULL); 124
124 WIN_FlushMessageQueue(); 125 hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED,
125 126 0, 0, 10, 10, NULL, NULL, SDL_Instance, NULL);
126 hdc = GetDC(hwnd); 127 WIN_FlushMessageQueue();
127 128
128 pformat = ChoosePixelFormat(hdc, &GL_pfd); 129 hdc = GetDC(hwnd);
129 SetPixelFormat(hdc, pformat, &GL_pfd); 130
130 131 pformat = ChoosePixelFormat(hdc, &GL_pfd);
131 hglrc = this->gl_data->wglCreateContext(hdc); 132 SetPixelFormat(hdc, pformat, &GL_pfd);
132 if ( hglrc ) { 133
133 this->gl_data->wglMakeCurrent(hdc, hglrc); 134 hglrc = this->gl_data->wglCreateContext(hdc);
134 } 135 if (hglrc) {
135 136 this->gl_data->wglMakeCurrent(hdc, hglrc);
136 wglGetExtensionsStringARB = (const char * (WINAPI *)(HDC)) 137 }
137 this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB"); 138
138 139 wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
139 if( wglGetExtensionsStringARB ) { 140 this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
140 extensions = wglGetExtensionsStringARB(hdc); 141
141 } else { 142 if (wglGetExtensionsStringARB) {
142 extensions = NULL; 143 extensions = wglGetExtensionsStringARB(hdc);
143 } 144 } else {
144 145 extensions = NULL;
145 this->gl_data->WGL_ARB_pixel_format = 0; 146 }
146 if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) { 147
147 this->gl_data->wglChoosePixelFormatARB = 148 this->gl_data->WGL_ARB_pixel_format = 0;
148 (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) 149 if (ExtensionSupported("WGL_ARB_pixel_format", extensions)) {
149 this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB"); 150 this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
150 this->gl_data->wglGetPixelFormatAttribivARB = 151 (HDC, const int *,
151 (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) 152 const FLOAT *, UINT, int *,
152 this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB"); 153 UINT *))
153 154 this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
154 if( (this->gl_data->wglChoosePixelFormatARB != NULL) && 155 this->gl_data->wglGetPixelFormatAttribivARB =
155 (this->gl_data->wglGetPixelFormatAttribivARB != NULL) ) { 156 (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
156 this->gl_data->WGL_ARB_pixel_format = 1; 157 this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
157 } 158
158 } 159 if ((this->gl_data->wglChoosePixelFormatARB != NULL) &&
159 160 (this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
160 if ( hglrc ) { 161 this->gl_data->WGL_ARB_pixel_format = 1;
161 this->gl_data->wglMakeCurrent(NULL, NULL); 162 }
162 this->gl_data->wglDeleteContext(hglrc); 163 }
163 } 164
164 ReleaseDC(hwnd, hdc); 165 if (hglrc) {
165 DestroyWindow(hwnd); 166 this->gl_data->wglMakeCurrent(NULL, NULL);
166 WIN_FlushMessageQueue(); 167 this->gl_data->wglDeleteContext(hglrc);
168 }
169 ReleaseDC(hwnd, hdc);
170 DestroyWindow(hwnd);
171 WIN_FlushMessageQueue();
167 } 172 }
168 173
169 #endif /* SDL_VIDEO_OPENGL */ 174 #endif /* SDL_VIDEO_OPENGL */
170 175
171 int WIN_GL_SetupWindow(_THIS) 176 int
172 { 177 WIN_GL_SetupWindow(_THIS)
173 int retval; 178 {
179 int retval;
174 #if SDL_VIDEO_OPENGL 180 #if SDL_VIDEO_OPENGL
175 int i; 181 int i;
176 unsigned int matching; 182 unsigned int matching;
177 int iAttribs[64]; 183 int iAttribs[64];
178 int *iAttr; 184 int *iAttr;
179 float fAttribs[1] = { 0 }; 185 float fAttribs[1] = { 0 };
180 const GLubyte *(WINAPI *glGetStringFunc)(GLenum); 186 const GLubyte *(WINAPI * glGetStringFunc) (GLenum);
181 const char *wglext; 187 const char *wglext;
182 188
183 /* load the gl driver from a default path */ 189 /* load the gl driver from a default path */
184 if ( ! this->gl_config.driver_loaded ) { 190 if (!this->gl_config.driver_loaded) {
185 /* no driver has been loaded, use default (ourselves) */ 191 /* no driver has been loaded, use default (ourselves) */
186 if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) { 192 if (WIN_GL_LoadLibrary(this, NULL) < 0) {
187 return(-1); 193 return (-1);
188 } 194 }
189 } 195 }
190 196
191 for ( i=0; ; ++i ) { 197 for (i = 0;; ++i) {
192 /* Get the window device context for our OpenGL drawing */ 198 /* Get the window device context for our OpenGL drawing */
193 GL_hdc = GetDC(SDL_Window); 199 GL_hdc = GetDC(SDL_Window);
194 if ( GL_hdc == NULL ) { 200 if (GL_hdc == NULL) {
195 SDL_SetError("Unable to get DC for SDL_Window"); 201 SDL_SetError("Unable to get DC for SDL_Window");
196 return(-1); 202 return (-1);
197 } 203 }
198 204
199 /* Set up the pixel format descriptor with our needed format */ 205 /* Set up the pixel format descriptor with our needed format */
200 SDL_memset(&GL_pfd, 0, sizeof(GL_pfd)); 206 SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
201 GL_pfd.nSize = sizeof(GL_pfd); 207 GL_pfd.nSize = sizeof(GL_pfd);
202 GL_pfd.nVersion = 1; 208 GL_pfd.nVersion = 1;
203 GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); 209 GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
204 if ( this->gl_config.double_buffer ) { 210 if (this->gl_config.double_buffer) {
205 GL_pfd.dwFlags |= PFD_DOUBLEBUFFER; 211 GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
206 } 212 }
207 if ( this->gl_config.stereo ) { 213 if (this->gl_config.stereo) {
208 GL_pfd.dwFlags |= PFD_STEREO; 214 GL_pfd.dwFlags |= PFD_STEREO;
209 } 215 }
210 GL_pfd.iPixelType = PFD_TYPE_RGBA; 216 GL_pfd.iPixelType = PFD_TYPE_RGBA;
211 GL_pfd.cColorBits = this->gl_config.buffer_size; 217 GL_pfd.cColorBits = this->gl_config.buffer_size;
212 GL_pfd.cRedBits = this->gl_config.red_size; 218 GL_pfd.cRedBits = this->gl_config.red_size;
213 GL_pfd.cGreenBits = this->gl_config.green_size; 219 GL_pfd.cGreenBits = this->gl_config.green_size;
214 GL_pfd.cBlueBits = this->gl_config.blue_size; 220 GL_pfd.cBlueBits = this->gl_config.blue_size;
215 GL_pfd.cAlphaBits = this->gl_config.alpha_size; 221 GL_pfd.cAlphaBits = this->gl_config.alpha_size;
216 GL_pfd.cAccumRedBits = this->gl_config.accum_red_size; 222 GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
217 GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size; 223 GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
218 GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size; 224 GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
219 GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size; 225 GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
220 GL_pfd.cAccumBits = 226 GL_pfd.cAccumBits =
221 (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits + 227 (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
222 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits); 228 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
223 GL_pfd.cDepthBits = this->gl_config.depth_size; 229 GL_pfd.cDepthBits = this->gl_config.depth_size;
224 GL_pfd.cStencilBits = this->gl_config.stencil_size; 230 GL_pfd.cStencilBits = this->gl_config.stencil_size;
225 231
226 /* initialize WGL_ARB_pixel_format */ 232 /* initialize WGL_ARB_pixel_format */
227 Init_WGL_ARB_extensions(this); 233 Init_WGL_ARB_extensions(this);
228 234
229 /* setup WGL_ARB_pixel_format attribs */ 235 /* setup WGL_ARB_pixel_format attribs */
230 iAttr = &iAttribs[0]; 236 iAttr = &iAttribs[0];
231 237
232 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; 238 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
233 *iAttr++ = GL_TRUE; 239 *iAttr++ = GL_TRUE;
234 *iAttr++ = WGL_ACCELERATION_ARB; 240 *iAttr++ = WGL_ACCELERATION_ARB;
235 *iAttr++ = WGL_FULL_ACCELERATION_ARB; 241 *iAttr++ = WGL_FULL_ACCELERATION_ARB;
236 *iAttr++ = WGL_RED_BITS_ARB; 242 *iAttr++ = WGL_RED_BITS_ARB;
237 *iAttr++ = this->gl_config.red_size; 243 *iAttr++ = this->gl_config.red_size;
238 *iAttr++ = WGL_GREEN_BITS_ARB; 244 *iAttr++ = WGL_GREEN_BITS_ARB;
239 *iAttr++ = this->gl_config.green_size; 245 *iAttr++ = this->gl_config.green_size;
240 *iAttr++ = WGL_BLUE_BITS_ARB; 246 *iAttr++ = WGL_BLUE_BITS_ARB;
241 *iAttr++ = this->gl_config.blue_size; 247 *iAttr++ = this->gl_config.blue_size;
242 248
243 if ( this->gl_config.alpha_size ) { 249 if (this->gl_config.alpha_size) {
244 *iAttr++ = WGL_ALPHA_BITS_ARB; 250 *iAttr++ = WGL_ALPHA_BITS_ARB;
245 *iAttr++ = this->gl_config.alpha_size; 251 *iAttr++ = this->gl_config.alpha_size;
246 } 252 }
247 253
248 *iAttr++ = WGL_DOUBLE_BUFFER_ARB; 254 *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
249 *iAttr++ = this->gl_config.double_buffer; 255 *iAttr++ = this->gl_config.double_buffer;
250 256
251 *iAttr++ = WGL_DEPTH_BITS_ARB; 257 *iAttr++ = WGL_DEPTH_BITS_ARB;
252 *iAttr++ = this->gl_config.depth_size; 258 *iAttr++ = this->gl_config.depth_size;
253 259
254 if ( this->gl_config.stencil_size ) { 260 if (this->gl_config.stencil_size) {
255 *iAttr++ = WGL_STENCIL_BITS_ARB; 261 *iAttr++ = WGL_STENCIL_BITS_ARB;
256 *iAttr++ = this->gl_config.stencil_size; 262 *iAttr++ = this->gl_config.stencil_size;
257 } 263 }
258 264
259 if ( this->gl_config.accum_red_size ) { 265 if (this->gl_config.accum_red_size) {
260 *iAttr++ = WGL_ACCUM_RED_BITS_ARB; 266 *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
261 *iAttr++ = this->gl_config.accum_red_size; 267 *iAttr++ = this->gl_config.accum_red_size;
262 } 268 }
263 269
264 if ( this->gl_config.accum_green_size ) { 270 if (this->gl_config.accum_green_size) {
265 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; 271 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
266 *iAttr++ = this->gl_config.accum_green_size; 272 *iAttr++ = this->gl_config.accum_green_size;
267 } 273 }
268 274
269 if ( this->gl_config.accum_blue_size ) { 275 if (this->gl_config.accum_blue_size) {
270 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; 276 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
271 *iAttr++ = this->gl_config.accum_blue_size; 277 *iAttr++ = this->gl_config.accum_blue_size;
272 } 278 }
273 279
274 if ( this->gl_config.accum_alpha_size ) { 280 if (this->gl_config.accum_alpha_size) {
275 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; 281 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
276 *iAttr++ = this->gl_config.accum_alpha_size; 282 *iAttr++ = this->gl_config.accum_alpha_size;
277 } 283 }
278 284
279 if ( this->gl_config.stereo ) { 285 if (this->gl_config.stereo) {
280 *iAttr++ = WGL_STEREO_ARB; 286 *iAttr++ = WGL_STEREO_ARB;
281 *iAttr++ = GL_TRUE; 287 *iAttr++ = GL_TRUE;
282 } 288 }
283 289
284 if ( this->gl_config.multisamplebuffers ) { 290 if (this->gl_config.multisamplebuffers) {
285 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; 291 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
286 *iAttr++ = this->gl_config.multisamplebuffers; 292 *iAttr++ = this->gl_config.multisamplebuffers;
287 } 293 }
288 294
289 if ( this->gl_config.multisamplesamples ) { 295 if (this->gl_config.multisamplesamples) {
290 *iAttr++ = WGL_SAMPLES_ARB; 296 *iAttr++ = WGL_SAMPLES_ARB;
291 *iAttr++ = this->gl_config.multisamplesamples; 297 *iAttr++ = this->gl_config.multisamplesamples;
292 } 298 }
293 299
294 if ( this->gl_config.accelerated >= 0 ) { 300 if (this->gl_config.accelerated >= 0) {
295 *iAttr++ = WGL_ACCELERATION_ARB; 301 *iAttr++ = WGL_ACCELERATION_ARB;
296 *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB); 302 *iAttr++ =
297 } 303 (this->gl_config.
298 304 accelerated ? WGL_GENERIC_ACCELERATION_ARB :
299 *iAttr = 0; 305 WGL_NO_ACCELERATION_ARB);
300 306 }
301 /* Choose and set the closest available pixel format */ 307
302 if ( !this->gl_data->WGL_ARB_pixel_format || 308 *iAttr = 0;
303 !this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs, fAttribs, 1, &pixel_format, &matching) || 309
304 !matching ) { 310 /* Choose and set the closest available pixel format */
305 pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); 311 if (!this->gl_data->WGL_ARB_pixel_format ||
306 this->gl_data->WGL_ARB_pixel_format = 0; 312 !this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs,
307 } 313 fAttribs, 1,
308 if ( !pixel_format ) { 314 &pixel_format, &matching)
309 SDL_SetError("No matching GL pixel format available"); 315 || !matching) {
310 return(-1); 316 pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
311 } 317 this->gl_data->WGL_ARB_pixel_format = 0;
312 if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) { 318 }
313 if ( i == 0 ) { 319 if (!pixel_format) {
314 /* First time through, try resetting the window */ 320 SDL_SetError("No matching GL pixel format available");
315 if ( WIN_GL_ResetWindow(this) < 0 ) { 321 return (-1);
316 return(-1); 322 }
317 } 323 if (!SetPixelFormat(GL_hdc, pixel_format, &GL_pfd)) {
318 continue; 324 if (i == 0) {
319 } 325 /* First time through, try resetting the window */
320 SDL_SetError("Unable to set HDC pixel format"); 326 if (WIN_GL_ResetWindow(this) < 0) {
321 return(-1); 327 return (-1);
322 } 328 }
323 /* We either succeeded or failed by this point */ 329 continue;
324 break; 330 }
325 } 331 SDL_SetError("Unable to set HDC pixel format");
326 DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd); 332 return (-1);
327 333 }
328 GL_hrc = this->gl_data->wglCreateContext(GL_hdc); 334 /* We either succeeded or failed by this point */
329 if ( GL_hrc == NULL ) { 335 break;
330 SDL_SetError("Unable to create GL context"); 336 }
331 return(-1); 337 DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
332 } 338
333 if ( WIN_GL_MakeCurrent(this) < 0 ) { 339 GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
334 return(-1); 340 if (GL_hrc == NULL) {
335 } 341 SDL_SetError("Unable to create GL context");
336 gl_active = 1; 342 return (-1);
337 343 }
338 /* Vsync control under Windows. Checking glGetString here is 344 if (WIN_GL_MakeCurrent(this) < 0) {
339 * somewhat a documented and reliable hack - it was originally 345 return (-1);
340 * as a feature added by mistake, but since so many people rely 346 }
341 * on it, it will not be removed. strstr should be safe here.*/ 347 gl_active = 1;
342 glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString"); 348
343 if ( glGetStringFunc ) { 349 /* Vsync control under Windows. Checking glGetString here is
344 wglext = (const char *)glGetStringFunc(GL_EXTENSIONS); 350 * somewhat a documented and reliable hack - it was originally
345 } else { 351 * as a feature added by mistake, but since so many people rely
346 /* Uh oh, something is seriously wrong here... */ 352 * on it, it will not be removed. strstr should be safe here.*/
347 wglext = NULL; 353 glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
348 } 354 if (glGetStringFunc) {
349 if ( wglext && SDL_strstr(wglext, "WGL_EXT_swap_control") ) { 355 wglext = (const char *) glGetStringFunc(GL_EXTENSIONS);
350 this->gl_data->wglSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT"); 356 } else {
351 this->gl_data->wglGetSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT"); 357 /* Uh oh, something is seriously wrong here... */
352 } else { 358 wglext = NULL;
353 this->gl_data->wglSwapIntervalEXT = NULL; 359 }
354 this->gl_data->wglGetSwapIntervalEXT = NULL; 360 if (wglext && SDL_strstr(wglext, "WGL_EXT_swap_control")) {
355 } 361 this->gl_data->wglSwapIntervalEXT =
356 if ( this->gl_config.swap_control >= 0 ) { 362 WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT");
357 if ( this->gl_data->wglSwapIntervalEXT ) { 363 this->gl_data->wglGetSwapIntervalEXT =
358 this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control); 364 WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT");
359 } 365 } else {
360 } 366 this->gl_data->wglSwapIntervalEXT = NULL;
367 this->gl_data->wglGetSwapIntervalEXT = NULL;
368 }
369 if (this->gl_config.swap_control >= 0) {
370 if (this->gl_data->wglSwapIntervalEXT) {
371 this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
372 }
373 }
361 #else 374 #else
362 SDL_SetError("WIN driver not configured with OpenGL"); 375 SDL_SetError("WIN driver not configured with OpenGL");
363 #endif 376 #endif
364 if ( gl_active ) { 377 if (gl_active) {
365 retval = 0; 378 retval = 0;
366 } else { 379 } else {
367 retval = -1; 380 retval = -1;
368 } 381 }
369 return(retval); 382 return (retval);
370 } 383 }
371 384
372 void WIN_GL_ShutDown(_THIS) 385 void
386 WIN_GL_ShutDown(_THIS)
373 { 387 {
374 #if SDL_VIDEO_OPENGL 388 #if SDL_VIDEO_OPENGL
375 /* Clean up OpenGL */ 389 /* Clean up OpenGL */
376 if ( GL_hrc ) { 390 if (GL_hrc) {
377 this->gl_data->wglMakeCurrent(NULL, NULL); 391 this->gl_data->wglMakeCurrent(NULL, NULL);
378 this->gl_data->wglDeleteContext(GL_hrc); 392 this->gl_data->wglDeleteContext(GL_hrc);
379 GL_hrc = NULL; 393 GL_hrc = NULL;
380 } 394 }
381 if ( GL_hdc ) { 395 if (GL_hdc) {
382 ReleaseDC(SDL_Window, GL_hdc); 396 ReleaseDC(SDL_Window, GL_hdc);
383 GL_hdc = NULL; 397 GL_hdc = NULL;
384 } 398 }
385 gl_active = 0; 399 gl_active = 0;
386 400
387 WIN_GL_UnloadLibrary(this); 401 WIN_GL_UnloadLibrary(this);
388 #endif /* SDL_VIDEO_OPENGL */ 402 #endif /* SDL_VIDEO_OPENGL */
389 } 403 }
390 404
391 #if SDL_VIDEO_OPENGL 405 #if SDL_VIDEO_OPENGL
392 406
393 /* Make the current context active */ 407 /* Make the current context active */
394 int WIN_GL_MakeCurrent(_THIS) 408 int
395 { 409 WIN_GL_MakeCurrent(_THIS)
396 int retval; 410 {
397 411 int retval;
398 retval = 0; 412
399 if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) { 413 retval = 0;
400 SDL_SetError("Unable to make GL context current"); 414 if (!this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc)) {
401 retval = -1; 415 SDL_SetError("Unable to make GL context current");
402 } 416 retval = -1;
403 return(retval); 417 }
418 return (retval);
404 } 419 }
405 420
406 /* Get attribute data from glX. */ 421 /* Get attribute data from glX. */
407 int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) 422 int
408 { 423 WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value)
409 int retval; 424 {
410 425 int retval;
411 if ( this->gl_data->WGL_ARB_pixel_format ) { 426
412 int wgl_attrib; 427 if (this->gl_data->WGL_ARB_pixel_format) {
413 428 int wgl_attrib;
414 switch(attrib) { 429
415 case SDL_GL_RED_SIZE: 430 switch (attrib) {
416 wgl_attrib = WGL_RED_BITS_ARB; 431 case SDL_GL_RED_SIZE:
417 break; 432 wgl_attrib = WGL_RED_BITS_ARB;
418 case SDL_GL_GREEN_SIZE: 433 break;
419 wgl_attrib = WGL_GREEN_BITS_ARB; 434 case SDL_GL_GREEN_SIZE:
420 break; 435 wgl_attrib = WGL_GREEN_BITS_ARB;
421 case SDL_GL_BLUE_SIZE: 436 break;
422 wgl_attrib = WGL_BLUE_BITS_ARB; 437 case SDL_GL_BLUE_SIZE:
423 break; 438 wgl_attrib = WGL_BLUE_BITS_ARB;
424 case SDL_GL_ALPHA_SIZE: 439 break;
425 wgl_attrib = WGL_ALPHA_BITS_ARB; 440 case SDL_GL_ALPHA_SIZE:
426 break; 441 wgl_attrib = WGL_ALPHA_BITS_ARB;
427 case SDL_GL_DOUBLEBUFFER: 442 break;
428 wgl_attrib = WGL_DOUBLE_BUFFER_ARB; 443 case SDL_GL_DOUBLEBUFFER:
429 break; 444 wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
430 case SDL_GL_BUFFER_SIZE: 445 break;
431 wgl_attrib = WGL_COLOR_BITS_ARB; 446 case SDL_GL_BUFFER_SIZE:
432 break; 447 wgl_attrib = WGL_COLOR_BITS_ARB;
433 case SDL_GL_DEPTH_SIZE: 448 break;
434 wgl_attrib = WGL_DEPTH_BITS_ARB; 449 case SDL_GL_DEPTH_SIZE:
435 break; 450 wgl_attrib = WGL_DEPTH_BITS_ARB;
436 case SDL_GL_STENCIL_SIZE: 451 break;
437 wgl_attrib = WGL_STENCIL_BITS_ARB; 452 case SDL_GL_STENCIL_SIZE:
438 break; 453 wgl_attrib = WGL_STENCIL_BITS_ARB;
439 case SDL_GL_ACCUM_RED_SIZE: 454 break;
440 wgl_attrib = WGL_ACCUM_RED_BITS_ARB; 455 case SDL_GL_ACCUM_RED_SIZE:
441 break; 456 wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
442 case SDL_GL_ACCUM_GREEN_SIZE: 457 break;
443 wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB; 458 case SDL_GL_ACCUM_GREEN_SIZE:
444 break; 459 wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
445 case SDL_GL_ACCUM_BLUE_SIZE: 460 break;
446 wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB; 461 case SDL_GL_ACCUM_BLUE_SIZE:
447 break; 462 wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
448 case SDL_GL_ACCUM_ALPHA_SIZE: 463 break;
449 wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB; 464 case SDL_GL_ACCUM_ALPHA_SIZE:
450 break; 465 wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
451 case SDL_GL_STEREO: 466 break;
452 wgl_attrib = WGL_STEREO_ARB; 467 case SDL_GL_STEREO:
453 break; 468 wgl_attrib = WGL_STEREO_ARB;
454 case SDL_GL_MULTISAMPLEBUFFERS: 469 break;
455 wgl_attrib = WGL_SAMPLE_BUFFERS_ARB; 470 case SDL_GL_MULTISAMPLEBUFFERS:
456 break; 471 wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
457 case SDL_GL_MULTISAMPLESAMPLES: 472 break;
458 wgl_attrib = WGL_SAMPLES_ARB; 473 case SDL_GL_MULTISAMPLESAMPLES:
459 break; 474 wgl_attrib = WGL_SAMPLES_ARB;
460 case SDL_GL_ACCELERATED_VISUAL: 475 break;
461 wgl_attrib = WGL_ACCELERATION_ARB; 476 case SDL_GL_ACCELERATED_VISUAL:
462 this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value); 477 wgl_attrib = WGL_ACCELERATION_ARB;
463 if ( *value == WGL_NO_ACCELERATION_ARB ) { 478 this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format,
464 *value = SDL_FALSE; 479 0, 1, &wgl_attrib,
465 } else { 480 value);
466 *value = SDL_TRUE; 481 if (*value == WGL_NO_ACCELERATION_ARB) {
467 } 482 *value = SDL_FALSE;
468 return 0; 483 } else {
469 break; 484 *value = SDL_TRUE;
470 case SDL_GL_SWAP_CONTROL: 485 }
471 if ( this->gl_data->wglGetSwapIntervalEXT ) { 486 return 0;
472 *value = this->gl_data->wglGetSwapIntervalEXT(); 487 break;
473 return 0; 488 case SDL_GL_SWAP_CONTROL:
474 } else { 489 if (this->gl_data->wglGetSwapIntervalEXT) {
475 return -1; 490 *value = this->gl_data->wglGetSwapIntervalEXT();
476 } 491 return 0;
477 break; 492 } else {
478 default: 493 return -1;
479 return(-1); 494 }
480 } 495 break;
481 this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value); 496 default:
482 497 return (-1);
483 return 0; 498 }
484 } 499 this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0,
485 500 1, &wgl_attrib, value);
486 retval = 0; 501
487 switch ( attrib ) { 502 return 0;
488 case SDL_GL_RED_SIZE: 503 }
489 *value = GL_pfd.cRedBits; 504
490 break; 505 retval = 0;
491 case SDL_GL_GREEN_SIZE: 506 switch (attrib) {
492 *value = GL_pfd.cGreenBits; 507 case SDL_GL_RED_SIZE:
493 break; 508 *value = GL_pfd.cRedBits;
494 case SDL_GL_BLUE_SIZE: 509 break;
495 *value = GL_pfd.cBlueBits; 510 case SDL_GL_GREEN_SIZE:
496 break; 511 *value = GL_pfd.cGreenBits;
497 case SDL_GL_ALPHA_SIZE: 512 break;
498 *value = GL_pfd.cAlphaBits; 513 case SDL_GL_BLUE_SIZE:
499 break; 514 *value = GL_pfd.cBlueBits;
500 case SDL_GL_DOUBLEBUFFER: 515 break;
501 if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) { 516 case SDL_GL_ALPHA_SIZE:
502 *value = 1; 517 *value = GL_pfd.cAlphaBits;
503 } else { 518 break;
504 *value = 0; 519 case SDL_GL_DOUBLEBUFFER:
505 } 520 if (GL_pfd.dwFlags & PFD_DOUBLEBUFFER) {
506 break; 521 *value = 1;
507 case SDL_GL_BUFFER_SIZE: 522 } else {
508 *value = GL_pfd.cColorBits; 523 *value = 0;
509 break; 524 }
510 case SDL_GL_DEPTH_SIZE: 525 break;
511 *value = GL_pfd.cDepthBits; 526 case SDL_GL_BUFFER_SIZE:
512 break; 527 *value = GL_pfd.cColorBits;
513 case SDL_GL_STENCIL_SIZE: 528 break;
514 *value = GL_pfd.cStencilBits; 529 case SDL_GL_DEPTH_SIZE:
515 break; 530 *value = GL_pfd.cDepthBits;
516 case SDL_GL_ACCUM_RED_SIZE: 531 break;
517 *value = GL_pfd.cAccumRedBits; 532 case SDL_GL_STENCIL_SIZE:
518 break; 533 *value = GL_pfd.cStencilBits;
519 case SDL_GL_ACCUM_GREEN_SIZE: 534 break;
520 *value = GL_pfd.cAccumGreenBits; 535 case SDL_GL_ACCUM_RED_SIZE:
521 break; 536 *value = GL_pfd.cAccumRedBits;
522 case SDL_GL_ACCUM_BLUE_SIZE: 537 break;
523 *value = GL_pfd.cAccumBlueBits; 538 case SDL_GL_ACCUM_GREEN_SIZE:
524 break; 539 *value = GL_pfd.cAccumGreenBits;
525 case SDL_GL_ACCUM_ALPHA_SIZE: 540 break;
526 *value = GL_pfd.cAccumAlphaBits; 541 case SDL_GL_ACCUM_BLUE_SIZE:
527 break; 542 *value = GL_pfd.cAccumBlueBits;
528 case SDL_GL_STEREO: 543 break;
529 if ( GL_pfd.dwFlags & PFD_STEREO ) { 544 case SDL_GL_ACCUM_ALPHA_SIZE:
530 *value = 1; 545 *value = GL_pfd.cAccumAlphaBits;
531 } else { 546 break;
532 *value = 0; 547 case SDL_GL_STEREO:
533 } 548 if (GL_pfd.dwFlags & PFD_STEREO) {
534 break; 549 *value = 1;
535 case SDL_GL_MULTISAMPLEBUFFERS: 550 } else {
536 *value = 0; 551 *value = 0;
537 break; 552 }
538 case SDL_GL_MULTISAMPLESAMPLES: 553 break;
539 *value = 1; 554 case SDL_GL_MULTISAMPLEBUFFERS:
540 break; 555 *value = 0;
541 case SDL_GL_SWAP_CONTROL: 556 break;
542 if ( this->gl_data->wglGetSwapIntervalEXT ) { 557 case SDL_GL_MULTISAMPLESAMPLES:
543 *value = this->gl_data->wglGetSwapIntervalEXT(); 558 *value = 1;
544 return 0; 559 break;
545 } else { 560 case SDL_GL_SWAP_CONTROL:
546 return -1; 561 if (this->gl_data->wglGetSwapIntervalEXT) {
547 } 562 *value = this->gl_data->wglGetSwapIntervalEXT();
548 break; 563 return 0;
549 default: 564 } else {
550 retval = -1; 565 return -1;
551 break; 566 }
552 } 567 break;
553 return retval; 568 default:
554 } 569 retval = -1;
555 570 break;
556 void WIN_GL_SwapBuffers(_THIS) 571 }
557 { 572 return retval;
558 SwapBuffers(GL_hdc); 573 }
559 } 574
560 575 void
561 void WIN_GL_UnloadLibrary(_THIS) 576 WIN_GL_SwapBuffers(_THIS)
562 { 577 {
563 if ( this->gl_config.driver_loaded ) { 578 SwapBuffers(GL_hdc);
564 FreeLibrary((HMODULE)this->gl_config.dll_handle); 579 }
565 580
566 this->gl_data->wglGetProcAddress = NULL; 581 void
567 this->gl_data->wglCreateContext = NULL; 582 WIN_GL_UnloadLibrary(_THIS)
568 this->gl_data->wglDeleteContext = NULL; 583 {
569 this->gl_data->wglMakeCurrent = NULL; 584 if (this->gl_config.driver_loaded) {
570 this->gl_data->wglChoosePixelFormatARB = NULL; 585 FreeLibrary((HMODULE) this->gl_config.dll_handle);
571 this->gl_data->wglGetPixelFormatAttribivARB = NULL; 586
572 this->gl_data->wglSwapIntervalEXT = NULL; 587 this->gl_data->wglGetProcAddress = NULL;
573 this->gl_data->wglGetSwapIntervalEXT = NULL; 588 this->gl_data->wglCreateContext = NULL;
574 589 this->gl_data->wglDeleteContext = NULL;
575 this->gl_config.dll_handle = NULL; 590 this->gl_data->wglMakeCurrent = NULL;
576 this->gl_config.driver_loaded = 0; 591 this->gl_data->wglChoosePixelFormatARB = NULL;
577 } 592 this->gl_data->wglGetPixelFormatAttribivARB = NULL;
593 this->gl_data->wglSwapIntervalEXT = NULL;
594 this->gl_data->wglGetSwapIntervalEXT = NULL;
595
596 this->gl_config.dll_handle = NULL;
597 this->gl_config.driver_loaded = 0;
598 }
578 } 599 }
579 600
580 /* Passing a NULL path means load pointers from the application */ 601 /* Passing a NULL path means load pointers from the application */
581 int WIN_GL_LoadLibrary(_THIS, const char* path) 602 int
582 { 603 WIN_GL_LoadLibrary(_THIS, const char *path)
583 HMODULE handle; 604 {
584 605 HMODULE handle;
585 if ( gl_active ) { 606
586 SDL_SetError("OpenGL context already created"); 607 if (gl_active) {
587 return -1; 608 SDL_SetError("OpenGL context already created");
588 } 609 return -1;
589 610 }
590 if ( path == NULL ) { 611
591 path = DEFAULT_GL_DRIVER_PATH; 612 if (path == NULL) {
592 } 613 path = DEFAULT_GL_DRIVER_PATH;
593 handle = LoadLibrary(path); 614 }
594 if ( handle == NULL ) { 615 handle = LoadLibrary(path);
595 SDL_SetError("Could not load OpenGL library"); 616 if (handle == NULL) {
596 return -1; 617 SDL_SetError("Could not load OpenGL library");
597 } 618 return -1;
598 619 }
599 /* Unload the old driver and reset the pointers */ 620
600 WIN_GL_UnloadLibrary(this); 621 /* Unload the old driver and reset the pointers */
601 622 WIN_GL_UnloadLibrary(this);
602 /* Load new function pointers */ 623
603 SDL_memset(this->gl_data, 0, sizeof(*this->gl_data)); 624 /* Load new function pointers */
604 this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *)) 625 SDL_memset(this->gl_data, 0, sizeof(*this->gl_data));
605 GetProcAddress(handle, "wglGetProcAddress"); 626 this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
606 this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC)) 627 GetProcAddress(handle, "wglGetProcAddress");
607 GetProcAddress(handle, "wglCreateContext"); 628 this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
608 this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC)) 629 GetProcAddress(handle, "wglCreateContext");
609 GetProcAddress(handle, "wglDeleteContext"); 630 this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
610 this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC)) 631 GetProcAddress(handle, "wglDeleteContext");
611 GetProcAddress(handle, "wglMakeCurrent"); 632 this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
612 this->gl_data->wglSwapIntervalEXT = (void (WINAPI *)(int)) 633 GetProcAddress(handle, "wglMakeCurrent");
613 GetProcAddress(handle, "wglSwapIntervalEXT"); 634 this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int))
614 this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *)(void)) 635 GetProcAddress(handle, "wglSwapIntervalEXT");
615 GetProcAddress(handle, "wglGetSwapIntervalEXT"); 636 this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void))
616 637 GetProcAddress(handle, "wglGetSwapIntervalEXT");
617 if ( (this->gl_data->wglGetProcAddress == NULL) || 638
618 (this->gl_data->wglCreateContext == NULL) || 639 if ((this->gl_data->wglGetProcAddress == NULL) ||
619 (this->gl_data->wglDeleteContext == NULL) || 640 (this->gl_data->wglCreateContext == NULL) ||
620 (this->gl_data->wglMakeCurrent == NULL) ) { 641 (this->gl_data->wglDeleteContext == NULL) ||
621 SDL_SetError("Could not retrieve OpenGL functions"); 642 (this->gl_data->wglMakeCurrent == NULL)) {
622 FreeLibrary(handle); 643 SDL_SetError("Could not retrieve OpenGL functions");
623 return -1; 644 FreeLibrary(handle);
624 } 645 return -1;
625 646 }
626 this->gl_config.dll_handle = handle; 647
627 SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path)); 648 this->gl_config.dll_handle = handle;
628 this->gl_config.driver_loaded = 1; 649 SDL_strlcpy(this->gl_config.driver_path, path,
629 return 0; 650 SDL_arraysize(this->gl_config.driver_path));
630 } 651 this->gl_config.driver_loaded = 1;
631 652 return 0;
632 void *WIN_GL_GetProcAddress(_THIS, const char* proc) 653 }
633 { 654
634 void *func; 655 void *
635 656 WIN_GL_GetProcAddress(_THIS, const char *proc)
636 /* This is to pick up extensions */ 657 {
637 func = this->gl_data->wglGetProcAddress(proc); 658 void *func;
638 if ( ! func ) { 659
639 /* This is probably a normal GL function */ 660 /* This is to pick up extensions */
640 func = GetProcAddress(this->gl_config.dll_handle, proc); 661 func = this->gl_data->wglGetProcAddress(proc);
641 } 662 if (!func) {
642 return func; 663 /* This is probably a normal GL function */
664 func = GetProcAddress(this->gl_config.dll_handle, proc);
665 }
666 return func;
643 } 667 }
644 668
645 #endif /* SDL_VIDEO_OPENGL */ 669 #endif /* SDL_VIDEO_OPENGL */
670
671 /* vi: set ts=4 sw=4 expandtab: */