comparison src/video/win32/SDL_d3drender.c @ 1975:ccef0d0c40c6

Added resize support for GDI and Direct3D renderers
author Sam Lantinga <slouken@libsdl.org>
date Mon, 07 Aug 2006 05:24:13 +0000
parents a788656ca29a
children b1620a317791
comparison
equal deleted inserted replaced
1974:70deaf574153 1975:ccef0d0c40c6
26 #include "SDL_win32video.h" 26 #include "SDL_win32video.h"
27 27
28 /* Direct3D renderer implementation */ 28 /* Direct3D renderer implementation */
29 29
30 static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags); 30 static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
31 static int D3D_DisplayModeChanged(SDL_Renderer * renderer);
31 static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); 32 static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
32 static int D3D_SetTexturePalette(SDL_Renderer * renderer, 33 static int D3D_SetTexturePalette(SDL_Renderer * renderer,
33 SDL_Texture * texture, 34 SDL_Texture * texture,
34 const SDL_Color * colors, int firstcolor, 35 const SDL_Color * colors, int firstcolor,
35 int ncolors); 36 int ncolors);
59 SDL_RenderDriver D3D_RenderDriver = { 60 SDL_RenderDriver D3D_RenderDriver = {
60 D3D_CreateRenderer, 61 D3D_CreateRenderer,
61 { 62 {
62 "d3d", 63 "d3d",
63 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | 64 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
64 SDL_RENDERER_PRESENTFLIP2 | sDL_RENDERER_PRESENTFLIP3 | 65 SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
65 SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC | 66 SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC |
66 SDL_RENDERER_ACCELERATED), 67 SDL_RENDERER_ACCELERATED),
67 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK | 68 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
68 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD | 69 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD |
69 SDL_TEXTUREBLENDMODE_MOD), 70 SDL_TEXTUREBLENDMODE_MOD),
88 }; 89 };
89 90
90 typedef struct 91 typedef struct
91 { 92 {
92 IDirect3DDevice9 *device; 93 IDirect3DDevice9 *device;
94 D3DPRESENT_PARAMETERS pparams;
93 SDL_bool beginScene; 95 SDL_bool beginScene;
94 } D3D_RenderData; 96 } D3D_RenderData;
95 97
96 typedef struct 98 typedef struct
97 { 99 {
180 default: 182 default:
181 error = "UNKNOWN"; 183 error = "UNKNOWN";
182 break; 184 break;
183 } 185 }
184 SDL_SetError("%s: %s", prefix, error); 186 SDL_SetError("%s: %s", prefix, error);
187 fprintf(stderr, "%s: %s\n", prefix, error);
185 } 188 }
186 189
187 static D3DFORMAT 190 static D3DFORMAT
188 PixelFormatToD3DFMT(Uint32 format) 191 PixelFormatToD3DFMT(Uint32 format)
189 { 192 {
251 D3D_DestroyRenderer(renderer); 254 D3D_DestroyRenderer(renderer);
252 SDL_OutOfMemory(); 255 SDL_OutOfMemory();
253 return NULL; 256 return NULL;
254 } 257 }
255 258
259 renderer->DisplayModeChanged = D3D_DisplayModeChanged;
256 renderer->CreateTexture = D3D_CreateTexture; 260 renderer->CreateTexture = D3D_CreateTexture;
257 renderer->SetTexturePalette = D3D_SetTexturePalette; 261 renderer->SetTexturePalette = D3D_SetTexturePalette;
258 renderer->GetTexturePalette = D3D_GetTexturePalette; 262 renderer->GetTexturePalette = D3D_GetTexturePalette;
259 renderer->UpdateTexture = D3D_UpdateTexture; 263 renderer->UpdateTexture = D3D_UpdateTexture;
260 renderer->LockTexture = D3D_LockTexture; 264 renderer->LockTexture = D3D_LockTexture;
274 SDL_zero(pparams); 278 SDL_zero(pparams);
275 pparams.BackBufferWidth = window->w; 279 pparams.BackBufferWidth = window->w;
276 pparams.BackBufferHeight = window->h; 280 pparams.BackBufferHeight = window->h;
277 if (window->flags & SDL_WINDOW_FULLSCREEN) { 281 if (window->flags & SDL_WINDOW_FULLSCREEN) {
278 pparams.BackBufferFormat = 282 pparams.BackBufferFormat =
279 PixelFormatToD3DFMT(display->fullscreen_mode->format); 283 PixelFormatToD3DFMT(display->fullscreen_mode.format);
280 } else { 284 } else {
281 pparams.BackBufferFormat = D3DFMT_UNKNOWN; 285 pparams.BackBufferFormat = D3DFMT_UNKNOWN;
282 } 286 }
283 if (flags & SDL_RENDERER_PRESENTFLIP2) { 287 if (flags & SDL_RENDERER_PRESENTFLIP2) {
284 pparams.BackBufferCount = 2; 288 pparams.BackBufferCount = 2;
294 pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; 298 pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
295 } 299 }
296 if (window->flags & SDL_WINDOW_FULLSCREEN) { 300 if (window->flags & SDL_WINDOW_FULLSCREEN) {
297 pparams.Windowed = FALSE; 301 pparams.Windowed = FALSE;
298 pparams.FullScreen_RefreshRateInHz = 302 pparams.FullScreen_RefreshRateInHz =
299 display->fullscreen_mode->refresh_rate; 303 display->fullscreen_mode.refresh_rate;
300 } else { 304 } else {
301 pparams.Windowed = TRUE; 305 pparams.Windowed = TRUE;
302 pparams.FullScreen_RefreshRateInHz = 0; 306 pparams.FullScreen_RefreshRateInHz = 0;
303 } 307 }
304 if (flags & SDL_RENDERER_PRESENTVSYNC) { 308 if (flags & SDL_RENDERER_PRESENTVSYNC) {
353 break; 357 break;
354 } 358 }
355 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { 359 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
356 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; 360 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
357 } 361 }
362 data->pparams = pparams;
358 363
359 IDirect3DDevice9_GetDeviceCaps(data->device, &caps); 364 IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
360 renderer->info.max_texture_width = caps.MaxTextureWidth; 365 renderer->info.max_texture_width = caps.MaxTextureWidth;
361 renderer->info.max_texture_height = caps.MaxTextureHeight; 366 renderer->info.max_texture_height = caps.MaxTextureHeight;
362 367
369 374
370 return renderer; 375 return renderer;
371 } 376 }
372 377
373 static int 378 static int
379 D3D_Reset(SDL_Renderer * renderer)
380 {
381 D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
382 HRESULT result;
383
384 result = IDirect3DDevice9_Reset(data->device, &data->pparams);
385 if (FAILED(result)) {
386 if (result == D3DERR_DEVICELOST) {
387 /* Don't worry about it, we'll reset later... */
388 return 0;
389 } else {
390 D3D_SetError("Reset()", result);
391 return -1;
392 }
393 }
394 IDirect3DDevice9_SetVertexShader(data->device, NULL);
395 IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_TEX1);
396 IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
397 D3DCULL_NONE);
398 IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
399 return 0;
400 }
401
402 static int
403 D3D_DisplayModeChanged(SDL_Renderer * renderer)
404 {
405 D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
406 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
407 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
408
409 data->pparams.BackBufferWidth = window->w;
410 data->pparams.BackBufferHeight = window->h;
411 if (window->flags & SDL_WINDOW_FULLSCREEN) {
412 data->pparams.BackBufferFormat =
413 PixelFormatToD3DFMT(display->fullscreen_mode.format);
414 } else {
415 data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
416 }
417 return D3D_Reset(renderer);
418 }
419
420 static int
374 D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 421 D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
375 { 422 {
376 D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; 423 D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
377 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 424 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
378 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 425 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
386 return -1; 433 return -1;
387 } 434 }
388 435
389 texture->driverdata = data; 436 texture->driverdata = data;
390 437
438 #if 1
439 /* FIXME: Do we want non-managed textures?
440 They need to be freed on device reset and then reloaded by the app...
441 */
442 texture->access = SDL_TEXTUREACCESS_LOCAL;
443 #endif
391 if (texture->access == SDL_TEXTUREACCESS_LOCAL) { 444 if (texture->access == SDL_TEXTUREACCESS_LOCAL) {
392 pool = D3DPOOL_MANAGED; 445 pool = D3DPOOL_MANAGED;
393 } else { 446 } else {
394 pool = D3DPOOL_DEFAULT; 447 pool = D3DPOOL_DEFAULT;
395 } 448 }
707 if (!data->beginScene) { 760 if (!data->beginScene) {
708 IDirect3DDevice9_EndScene(data->device); 761 IDirect3DDevice9_EndScene(data->device);
709 data->beginScene = SDL_TRUE; 762 data->beginScene = SDL_TRUE;
710 } 763 }
711 764
765 result = IDirect3DDevice9_TestCooperativeLevel(data->device);
766 if (result == D3DERR_DEVICELOST) {
767 /* We'll reset later */
768 return;
769 }
770 if (result == D3DERR_DEVICENOTRESET) {
771 D3D_Reset(renderer);
772 }
712 result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL); 773 result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
713 if (FAILED(result)) { 774 if (FAILED(result)) {
714 D3D_SetError("Present()", result); 775 D3D_SetError("Present()", result);
715 } 776 }
716 } 777 }
728 } 789 }
729 SDL_free(data); 790 SDL_free(data);
730 texture->driverdata = NULL; 791 texture->driverdata = NULL;
731 } 792 }
732 793
733 void 794 static void
734 D3D_DestroyRenderer(SDL_Renderer * renderer) 795 D3D_DestroyRenderer(SDL_Renderer * renderer)
735 { 796 {
736 D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; 797 D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
737 798
738 if (data) { 799 if (data) {