comparison src/video/wincommon/SDL_wingl.c @ 4042:f9d0b64cc7b9 SDL-1.2

I think this fixes bug #261 Make sure that you don't use a wgl function after the context is deleted.
author Sam Lantinga <slouken@libsdl.org>
date Wed, 11 Jul 2007 05:43:39 +0000
parents 5c6e937518c6
children 5c890883360f
comparison
equal deleted inserted replaced
4041:1c291c47cf1e 4042:f9d0b64cc7b9
107 } 107 }
108 108
109 return 0; 109 return 0;
110 } 110 }
111 111
112 static void Init_WGL_ARB_extensions(_THIS) 112 static int ChoosePixelFormatARB(_THIS, const int *iAttribs, const FLOAT *fAttribs)
113 { 113 {
114 HWND hwnd; 114 HWND hwnd;
115 HDC hdc; 115 HDC hdc;
116 HGLRC hglrc; 116 HGLRC hglrc;
117 int pformat;
118 const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0; 117 const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0;
119 const char *extensions; 118 const char *extensions;
120 119 int pformat = 0;
120 UINT matches = 0;
121
121 hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED, 122 hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED,
122 0, 0, 10, 10, 123 0, 0, 10, 10,
123 NULL, NULL, SDL_Instance, NULL); 124 NULL, NULL, SDL_Instance, NULL);
124 WIN_FlushMessageQueue(); 125 WIN_FlushMessageQueue();
125 126
126 hdc = GetDC(hwnd); 127 hdc = GetDC(hwnd);
127 128
128 pformat = ChoosePixelFormat(hdc, &GL_pfd); 129 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &GL_pfd), &GL_pfd);
129 SetPixelFormat(hdc, pformat, &GL_pfd);
130 130
131 hglrc = this->gl_data->wglCreateContext(hdc); 131 hglrc = this->gl_data->wglCreateContext(hdc);
132 if ( hglrc ) { 132 if ( hglrc ) {
133 this->gl_data->wglMakeCurrent(hdc, hglrc); 133 this->gl_data->wglMakeCurrent(hdc, hglrc);
134 } 134 }
142 extensions = NULL; 142 extensions = NULL;
143 } 143 }
144 144
145 this->gl_data->WGL_ARB_pixel_format = 0; 145 this->gl_data->WGL_ARB_pixel_format = 0;
146 if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) { 146 if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) {
147 this->gl_data->wglChoosePixelFormatARB = 147 BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
148 wglChoosePixelFormatARB =
148 (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) 149 (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *))
149 this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB"); 150 this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
150 this->gl_data->wglGetPixelFormatAttribivARB = 151 if( wglChoosePixelFormatARB &&
151 (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) 152 wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pformat, &matches) && pformat ) {
152 this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
153
154 if( (this->gl_data->wglChoosePixelFormatARB != NULL) &&
155 (this->gl_data->wglGetPixelFormatAttribivARB != NULL) ) {
156 this->gl_data->WGL_ARB_pixel_format = 1; 153 this->gl_data->WGL_ARB_pixel_format = 1;
157 } 154 }
158 } 155 }
159 156
160 if ( hglrc ) { 157 if ( hglrc ) {
162 this->gl_data->wglDeleteContext(hglrc); 159 this->gl_data->wglDeleteContext(hglrc);
163 } 160 }
164 ReleaseDC(hwnd, hdc); 161 ReleaseDC(hwnd, hdc);
165 DestroyWindow(hwnd); 162 DestroyWindow(hwnd);
166 WIN_FlushMessageQueue(); 163 WIN_FlushMessageQueue();
164
165 return pformat;
167 } 166 }
168 167
169 #endif /* SDL_VIDEO_OPENGL */ 168 #endif /* SDL_VIDEO_OPENGL */
170 169
171 int WIN_GL_SetupWindow(_THIS) 170 int WIN_GL_SetupWindow(_THIS)
186 if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) { 185 if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) {
187 return(-1); 186 return(-1);
188 } 187 }
189 } 188 }
190 189
190 /* Set up the pixel format descriptor with our needed format */
191 SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
192 GL_pfd.nSize = sizeof(GL_pfd);
193 GL_pfd.nVersion = 1;
194 GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
195 if ( this->gl_config.double_buffer ) {
196 GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
197 }
198 if ( this->gl_config.stereo ) {
199 GL_pfd.dwFlags |= PFD_STEREO;
200 }
201 GL_pfd.iPixelType = PFD_TYPE_RGBA;
202 GL_pfd.cColorBits = this->gl_config.buffer_size;
203 GL_pfd.cRedBits = this->gl_config.red_size;
204 GL_pfd.cGreenBits = this->gl_config.green_size;
205 GL_pfd.cBlueBits = this->gl_config.blue_size;
206 GL_pfd.cAlphaBits = this->gl_config.alpha_size;
207 GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
208 GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
209 GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
210 GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
211 GL_pfd.cAccumBits =
212 (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
213 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
214 GL_pfd.cDepthBits = this->gl_config.depth_size;
215 GL_pfd.cStencilBits = this->gl_config.stencil_size;
216
217 /* setup WGL_ARB_pixel_format attribs */
218 iAttr = &iAttribs[0];
219
220 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
221 *iAttr++ = GL_TRUE;
222 *iAttr++ = WGL_ACCELERATION_ARB;
223 *iAttr++ = WGL_FULL_ACCELERATION_ARB;
224 *iAttr++ = WGL_RED_BITS_ARB;
225 *iAttr++ = this->gl_config.red_size;
226 *iAttr++ = WGL_GREEN_BITS_ARB;
227 *iAttr++ = this->gl_config.green_size;
228 *iAttr++ = WGL_BLUE_BITS_ARB;
229 *iAttr++ = this->gl_config.blue_size;
230
231 if ( this->gl_config.alpha_size ) {
232 *iAttr++ = WGL_ALPHA_BITS_ARB;
233 *iAttr++ = this->gl_config.alpha_size;
234 }
235
236 *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
237 *iAttr++ = this->gl_config.double_buffer;
238
239 *iAttr++ = WGL_DEPTH_BITS_ARB;
240 *iAttr++ = this->gl_config.depth_size;
241
242 if ( this->gl_config.stencil_size ) {
243 *iAttr++ = WGL_STENCIL_BITS_ARB;
244 *iAttr++ = this->gl_config.stencil_size;
245 }
246
247 if ( this->gl_config.accum_red_size ) {
248 *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
249 *iAttr++ = this->gl_config.accum_red_size;
250 }
251
252 if ( this->gl_config.accum_green_size ) {
253 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
254 *iAttr++ = this->gl_config.accum_green_size;
255 }
256
257 if ( this->gl_config.accum_blue_size ) {
258 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
259 *iAttr++ = this->gl_config.accum_blue_size;
260 }
261
262 if ( this->gl_config.accum_alpha_size ) {
263 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
264 *iAttr++ = this->gl_config.accum_alpha_size;
265 }
266
267 if ( this->gl_config.stereo ) {
268 *iAttr++ = WGL_STEREO_ARB;
269 *iAttr++ = GL_TRUE;
270 }
271
272 if ( this->gl_config.multisamplebuffers ) {
273 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
274 *iAttr++ = this->gl_config.multisamplebuffers;
275 }
276
277 if ( this->gl_config.multisamplesamples ) {
278 *iAttr++ = WGL_SAMPLES_ARB;
279 *iAttr++ = this->gl_config.multisamplesamples;
280 }
281
282 if ( this->gl_config.accelerated >= 0 ) {
283 *iAttr++ = WGL_ACCELERATION_ARB;
284 *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB);
285 }
286
287 *iAttr = 0;
288
191 for ( i=0; ; ++i ) { 289 for ( i=0; ; ++i ) {
192 /* Get the window device context for our OpenGL drawing */ 290 /* Get the window device context for our OpenGL drawing */
193 GL_hdc = GetDC(SDL_Window); 291 GL_hdc = GetDC(SDL_Window);
194 if ( GL_hdc == NULL ) { 292 if ( GL_hdc == NULL ) {
195 SDL_SetError("Unable to get DC for SDL_Window"); 293 SDL_SetError("Unable to get DC for SDL_Window");
196 return(-1); 294 return(-1);
197 } 295 }
198 296
199 /* Set up the pixel format descriptor with our needed format */
200 SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
201 GL_pfd.nSize = sizeof(GL_pfd);
202 GL_pfd.nVersion = 1;
203 GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
204 if ( this->gl_config.double_buffer ) {
205 GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
206 }
207 if ( this->gl_config.stereo ) {
208 GL_pfd.dwFlags |= PFD_STEREO;
209 }
210 GL_pfd.iPixelType = PFD_TYPE_RGBA;
211 GL_pfd.cColorBits = this->gl_config.buffer_size;
212 GL_pfd.cRedBits = this->gl_config.red_size;
213 GL_pfd.cGreenBits = this->gl_config.green_size;
214 GL_pfd.cBlueBits = this->gl_config.blue_size;
215 GL_pfd.cAlphaBits = this->gl_config.alpha_size;
216 GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
217 GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
218 GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
219 GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
220 GL_pfd.cAccumBits =
221 (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
222 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
223 GL_pfd.cDepthBits = this->gl_config.depth_size;
224 GL_pfd.cStencilBits = this->gl_config.stencil_size;
225
226 /* initialize WGL_ARB_pixel_format */
227 Init_WGL_ARB_extensions(this);
228
229 /* setup WGL_ARB_pixel_format attribs */
230 iAttr = &iAttribs[0];
231
232 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
233 *iAttr++ = GL_TRUE;
234 *iAttr++ = WGL_ACCELERATION_ARB;
235 *iAttr++ = WGL_FULL_ACCELERATION_ARB;
236 *iAttr++ = WGL_RED_BITS_ARB;
237 *iAttr++ = this->gl_config.red_size;
238 *iAttr++ = WGL_GREEN_BITS_ARB;
239 *iAttr++ = this->gl_config.green_size;
240 *iAttr++ = WGL_BLUE_BITS_ARB;
241 *iAttr++ = this->gl_config.blue_size;
242
243 if ( this->gl_config.alpha_size ) {
244 *iAttr++ = WGL_ALPHA_BITS_ARB;
245 *iAttr++ = this->gl_config.alpha_size;
246 }
247
248 *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
249 *iAttr++ = this->gl_config.double_buffer;
250
251 *iAttr++ = WGL_DEPTH_BITS_ARB;
252 *iAttr++ = this->gl_config.depth_size;
253
254 if ( this->gl_config.stencil_size ) {
255 *iAttr++ = WGL_STENCIL_BITS_ARB;
256 *iAttr++ = this->gl_config.stencil_size;
257 }
258
259 if ( this->gl_config.accum_red_size ) {
260 *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
261 *iAttr++ = this->gl_config.accum_red_size;
262 }
263
264 if ( this->gl_config.accum_green_size ) {
265 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
266 *iAttr++ = this->gl_config.accum_green_size;
267 }
268
269 if ( this->gl_config.accum_blue_size ) {
270 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
271 *iAttr++ = this->gl_config.accum_blue_size;
272 }
273
274 if ( this->gl_config.accum_alpha_size ) {
275 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
276 *iAttr++ = this->gl_config.accum_alpha_size;
277 }
278
279 if ( this->gl_config.stereo ) {
280 *iAttr++ = WGL_STEREO_ARB;
281 *iAttr++ = GL_TRUE;
282 }
283
284 if ( this->gl_config.multisamplebuffers ) {
285 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
286 *iAttr++ = this->gl_config.multisamplebuffers;
287 }
288
289 if ( this->gl_config.multisamplesamples ) {
290 *iAttr++ = WGL_SAMPLES_ARB;
291 *iAttr++ = this->gl_config.multisamplesamples;
292 }
293
294 if ( this->gl_config.accelerated >= 0 ) {
295 *iAttr++ = WGL_ACCELERATION_ARB;
296 *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB);
297 }
298
299 *iAttr = 0;
300
301 /* Choose and set the closest available pixel format */ 297 /* Choose and set the closest available pixel format */
302 if ( !this->gl_data->WGL_ARB_pixel_format || 298 pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs);
303 !this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs, fAttribs, 1, &pixel_format, &matching) || 299 if ( !pixel_format ) {
304 !matching ) {
305 pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); 300 pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
306 this->gl_data->WGL_ARB_pixel_format = 0;
307 } 301 }
308 if ( !pixel_format ) { 302 if ( !pixel_format ) {
309 SDL_SetError("No matching GL pixel format available"); 303 SDL_SetError("No matching GL pixel format available");
310 return(-1); 304 return(-1);
311 } 305 }
333 if ( WIN_GL_MakeCurrent(this) < 0 ) { 327 if ( WIN_GL_MakeCurrent(this) < 0 ) {
334 return(-1); 328 return(-1);
335 } 329 }
336 gl_active = 1; 330 gl_active = 1;
337 331
332 /* Get the wglGetPixelFormatAttribivARB pointer for the context */
333 if ( this->gl_data->WGL_ARB_pixel_format ) {
334 this->gl_data->wglGetPixelFormatAttribivARB =
335 (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *))
336 this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
337 } else {
338 this->gl_data->wglGetPixelFormatAttribivARB = NULL;
339 }
340
338 /* Vsync control under Windows. Checking glGetString here is 341 /* Vsync control under Windows. Checking glGetString here is
339 * somewhat a documented and reliable hack - it was originally 342 * somewhat a documented and reliable hack - it was originally
340 * as a feature added by mistake, but since so many people rely 343 * as a feature added by mistake, but since so many people rely
341 * on it, it will not be removed. strstr should be safe here.*/ 344 * on it, it will not be removed. strstr should be safe here.*/
342 glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString"); 345 glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
414 return 0; 417 return 0;
415 } 418 }
416 return -1; 419 return -1;
417 } 420 }
418 421
419 if ( this->gl_data->WGL_ARB_pixel_format ) { 422 if ( this->gl_data->wglGetPixelFormatAttribivARB ) {
420 int wgl_attrib; 423 int wgl_attrib;
421 424
422 switch(attrib) { 425 switch(attrib) {
423 case SDL_GL_RED_SIZE: 426 case SDL_GL_RED_SIZE:
424 wgl_attrib = WGL_RED_BITS_ARB; 427 wgl_attrib = WGL_RED_BITS_ARB;
564 567
565 this->gl_data->wglGetProcAddress = NULL; 568 this->gl_data->wglGetProcAddress = NULL;
566 this->gl_data->wglCreateContext = NULL; 569 this->gl_data->wglCreateContext = NULL;
567 this->gl_data->wglDeleteContext = NULL; 570 this->gl_data->wglDeleteContext = NULL;
568 this->gl_data->wglMakeCurrent = NULL; 571 this->gl_data->wglMakeCurrent = NULL;
569 this->gl_data->wglChoosePixelFormatARB = NULL;
570 this->gl_data->wglGetPixelFormatAttribivARB = NULL; 572 this->gl_data->wglGetPixelFormatAttribivARB = NULL;
571 this->gl_data->wglSwapIntervalEXT = NULL; 573 this->gl_data->wglSwapIntervalEXT = NULL;
572 this->gl_data->wglGetSwapIntervalEXT = NULL; 574 this->gl_data->wglGetSwapIntervalEXT = NULL;
573 575
574 this->gl_config.dll_handle = NULL; 576 this->gl_config.dll_handle = NULL;