Mercurial > sdl-ios-xcode
comparison src/video/win32/SDL_d3drender.c @ 1907:06c27a737b7a
Streamlined the API a bit and optimized the software renderer.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 15 Jul 2006 09:46:36 +0000 |
parents | 36d52b1f0504 |
children | 83420da906a5 |
comparison
equal
deleted
inserted
replaced
1906:0c49855a7a3e | 1907:06c27a737b7a |
---|---|
48 static void SDL_D3D_UnlockTexture(SDL_Renderer * renderer, | 48 static void SDL_D3D_UnlockTexture(SDL_Renderer * renderer, |
49 SDL_Texture * texture); | 49 SDL_Texture * texture); |
50 static void SDL_D3D_DirtyTexture(SDL_Renderer * renderer, | 50 static void SDL_D3D_DirtyTexture(SDL_Renderer * renderer, |
51 SDL_Texture * texture, int numrects, | 51 SDL_Texture * texture, int numrects, |
52 const SDL_Rect * rects); | 52 const SDL_Rect * rects); |
53 static void SDL_D3D_SelectRenderTexture(SDL_Renderer * renderer, | |
54 SDL_Texture * texture); | |
55 static int SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, | 53 static int SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, |
56 Uint32 color); | 54 Uint32 color); |
57 static int SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | 55 static int SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, |
58 const SDL_Rect * srcrect, | 56 const SDL_Rect * srcrect, |
59 const SDL_Rect * dstrect, int blendMode, | 57 const SDL_Rect * dstrect, int blendMode, |
60 int scaleMode); | 58 int scaleMode); |
61 static int SDL_D3D_RenderReadPixels(SDL_Renderer * renderer, | |
62 const SDL_Rect * rect, void *pixels, | |
63 int pitch); | |
64 static int SDL_D3D_RenderWritePixels(SDL_Renderer * renderer, | |
65 const SDL_Rect * rect, | |
66 const void *pixels, int pitch); | |
67 static void SDL_D3D_RenderPresent(SDL_Renderer * renderer); | 59 static void SDL_D3D_RenderPresent(SDL_Renderer * renderer); |
68 static void SDL_D3D_DestroyTexture(SDL_Renderer * renderer, | 60 static void SDL_D3D_DestroyTexture(SDL_Renderer * renderer, |
69 SDL_Texture * texture); | 61 SDL_Texture * texture); |
70 static void SDL_D3D_DestroyRenderer(SDL_Renderer * renderer); | 62 static void SDL_D3D_DestroyRenderer(SDL_Renderer * renderer); |
71 | 63 |
74 SDL_D3D_CreateRenderer, | 66 SDL_D3D_CreateRenderer, |
75 { | 67 { |
76 "d3d", | 68 "d3d", |
77 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | | 69 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | |
78 SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | | 70 SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | |
79 SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), | 71 SDL_Renderer_PresentDiscard | SDL_Renderer_PresentVSync), |
80 (SDL_TextureBlendMode_None | | 72 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), /* FIXME */ |
81 SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), | 73 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), /* FIXME */ |
82 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), | |
83 12, | 74 12, |
84 { | 75 { |
85 SDL_PixelFormat_Index8, | 76 SDL_PixelFormat_Index8, |
86 SDL_PixelFormat_RGB332, | 77 SDL_PixelFormat_RGB332, |
87 SDL_PixelFormat_RGB444, | 78 SDL_PixelFormat_RGB444, |
99 }; | 90 }; |
100 | 91 |
101 typedef struct | 92 typedef struct |
102 { | 93 { |
103 IDirect3DDevice9 *device; | 94 IDirect3DDevice9 *device; |
104 IDirect3DSurface9 *surface; | |
105 IDirect3DSurface9 *offscreen; | |
106 SDL_bool beginScene; | 95 SDL_bool beginScene; |
107 } SDL_D3D_RenderData; | 96 } SDL_D3D_RenderData; |
108 | 97 |
109 typedef struct | 98 typedef struct |
110 { | 99 { |
248 SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; | 237 SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; |
249 SDL_Renderer *renderer; | 238 SDL_Renderer *renderer; |
250 SDL_D3D_RenderData *data; | 239 SDL_D3D_RenderData *data; |
251 HRESULT result; | 240 HRESULT result; |
252 D3DPRESENT_PARAMETERS pparams; | 241 D3DPRESENT_PARAMETERS pparams; |
242 IDirect3DSwapChain9 *chain; | |
253 | 243 |
254 renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer)); | 244 renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer)); |
255 if (!renderer) { | 245 if (!renderer) { |
256 SDL_OutOfMemory(); | 246 SDL_OutOfMemory(); |
257 return NULL; | 247 return NULL; |
271 renderer->GetTexturePalette = SDL_D3D_GetTexturePalette; | 261 renderer->GetTexturePalette = SDL_D3D_GetTexturePalette; |
272 renderer->UpdateTexture = SDL_D3D_UpdateTexture; | 262 renderer->UpdateTexture = SDL_D3D_UpdateTexture; |
273 renderer->LockTexture = SDL_D3D_LockTexture; | 263 renderer->LockTexture = SDL_D3D_LockTexture; |
274 renderer->UnlockTexture = SDL_D3D_UnlockTexture; | 264 renderer->UnlockTexture = SDL_D3D_UnlockTexture; |
275 renderer->DirtyTexture = SDL_D3D_DirtyTexture; | 265 renderer->DirtyTexture = SDL_D3D_DirtyTexture; |
276 renderer->SelectRenderTexture = SDL_D3D_SelectRenderTexture; | |
277 renderer->RenderFill = SDL_D3D_RenderFill; | 266 renderer->RenderFill = SDL_D3D_RenderFill; |
278 renderer->RenderCopy = SDL_D3D_RenderCopy; | 267 renderer->RenderCopy = SDL_D3D_RenderCopy; |
279 renderer->RenderReadPixels = SDL_D3D_RenderReadPixels; | |
280 renderer->RenderWritePixels = SDL_D3D_RenderWritePixels; | |
281 renderer->RenderPresent = SDL_D3D_RenderPresent; | 268 renderer->RenderPresent = SDL_D3D_RenderPresent; |
282 renderer->DestroyTexture = SDL_D3D_DestroyTexture; | 269 renderer->DestroyTexture = SDL_D3D_DestroyTexture; |
283 renderer->DestroyRenderer = SDL_D3D_DestroyRenderer; | 270 renderer->DestroyRenderer = SDL_D3D_DestroyRenderer; |
284 renderer->info = SDL_D3D_RenderDriver.info; | 271 renderer->info = SDL_D3D_RenderDriver.info; |
285 renderer->window = window->id; | 272 renderer->window = window->id; |
286 renderer->driverdata = data; | 273 renderer->driverdata = data; |
287 | 274 |
288 renderer->info.flags = SDL_Renderer_RenderTarget; | 275 renderer->info.flags = SDL_Renderer_Accelerated; |
289 | 276 |
290 SDL_zero(pparams); | 277 SDL_zero(pparams); |
291 pparams.BackBufferWidth = window->w; | 278 pparams.BackBufferWidth = window->w; |
292 pparams.BackBufferHeight = window->h; | 279 pparams.BackBufferHeight = window->h; |
293 if (window->flags & SDL_WINDOW_FULLSCREEN) { | 280 if (window->flags & SDL_WINDOW_FULLSCREEN) { |
315 display->fullscreen_mode->refresh_rate; | 302 display->fullscreen_mode->refresh_rate; |
316 } else { | 303 } else { |
317 pparams.Windowed = TRUE; | 304 pparams.Windowed = TRUE; |
318 pparams.FullScreen_RefreshRateInHz = 0; | 305 pparams.FullScreen_RefreshRateInHz = 0; |
319 } | 306 } |
320 pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; | 307 if (flags & SDL_Renderer_PresentVSync) { |
308 pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; | |
309 } else { | |
310 pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; | |
311 } | |
321 | 312 |
322 result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */ | 313 result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */ |
323 D3DDEVTYPE_HAL, | 314 D3DDEVTYPE_HAL, |
324 windowdata->hwnd, | 315 windowdata->hwnd, |
325 D3DCREATE_SOFTWARE_VERTEXPROCESSING, | 316 D3DCREATE_SOFTWARE_VERTEXPROCESSING, |
328 SDL_D3D_DestroyRenderer(renderer); | 319 SDL_D3D_DestroyRenderer(renderer); |
329 D3D_SetError("CreateDevice()", result); | 320 D3D_SetError("CreateDevice()", result); |
330 return NULL; | 321 return NULL; |
331 } | 322 } |
332 data->beginScene = SDL_TRUE; | 323 data->beginScene = SDL_TRUE; |
324 | |
325 /* Get presentation parameters to fill info */ | |
326 result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); | |
327 if (FAILED(result)) { | |
328 SDL_D3D_DestroyRenderer(renderer); | |
329 D3D_SetError("GetSwapChain()", result); | |
330 return NULL; | |
331 } | |
332 result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); | |
333 if (FAILED(result)) { | |
334 IDirect3DSwapChain9_Release(chain); | |
335 SDL_D3D_DestroyRenderer(renderer); | |
336 D3D_SetError("GetPresentParameters()", result); | |
337 return NULL; | |
338 } | |
339 IDirect3DSwapChain9_Release(chain); | |
340 switch (pparams.SwapEffect) { | |
341 case D3DSWAPEFFECT_COPY: | |
342 renderer->info.flags |= SDL_Renderer_PresentCopy; | |
343 break; | |
344 case D3DSWAPEFFECT_FLIP: | |
345 switch (pparams.BackBufferCount) { | |
346 case 2: | |
347 renderer->info.flags |= SDL_Renderer_PresentFlip2; | |
348 break; | |
349 case 3: | |
350 renderer->info.flags |= SDL_Renderer_PresentFlip3; | |
351 break; | |
352 } | |
353 break; | |
354 case D3DSWAPEFFECT_DISCARD: | |
355 renderer->info.flags |= SDL_Renderer_PresentDiscard; | |
356 break; | |
357 } | |
358 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { | |
359 renderer->info.flags |= SDL_Renderer_PresentVSync; | |
360 } | |
333 | 361 |
334 /* Set up parameters for rendering */ | 362 /* Set up parameters for rendering */ |
335 IDirect3DDevice9_SetVertexShader(data->device, NULL); | 363 IDirect3DDevice9_SetVertexShader(data->device, NULL); |
336 IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_TEX1); | 364 IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_TEX1); |
337 IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, | 365 IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, |
525 | 553 |
526 IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect); | 554 IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect); |
527 } | 555 } |
528 } | 556 } |
529 | 557 |
530 static void | |
531 SDL_D3D_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
532 { | |
533 SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; | |
534 | |
535 /* FIXME */ | |
536 } | |
537 | |
538 static int | 558 static int |
539 SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, | 559 SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, |
540 Uint32 color) | 560 Uint32 color) |
541 { | 561 { |
542 SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; | 562 SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; |
635 return -1; | 655 return -1; |
636 } | 656 } |
637 return 0; | 657 return 0; |
638 } | 658 } |
639 | 659 |
640 static int | |
641 SDL_D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
642 void *pixels, int pitch) | |
643 { | |
644 SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; | |
645 | |
646 /* FIXME */ | |
647 return 0; | |
648 } | |
649 | |
650 static int | |
651 SDL_D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
652 const void *pixels, int pitch) | |
653 { | |
654 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | |
655 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | |
656 SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; | |
657 RECT d3drect; | |
658 POINT point; | |
659 D3DLOCKED_RECT locked; | |
660 const Uint8 *src; | |
661 Uint8 *dst; | |
662 int row, length; | |
663 HRESULT result; | |
664 | |
665 if (!data->surface) { | |
666 result = | |
667 IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, | |
668 D3DBACKBUFFER_TYPE_MONO, | |
669 &data->surface); | |
670 if (FAILED(result)) { | |
671 D3D_SetError("GetBackBuffer()", result); | |
672 return -1; | |
673 } | |
674 } | |
675 if (!data->offscreen) { | |
676 result = | |
677 IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, | |
678 window->w, window->h, | |
679 PixelFormatToD3DFMT | |
680 (display-> | |
681 current_mode. | |
682 format), | |
683 D3DPOOL_SYSTEMMEM, | |
684 &data->offscreen, | |
685 NULL); | |
686 if (FAILED(result)) { | |
687 D3D_SetError("CreateOffscreenPlainSurface()", result); | |
688 return -1; | |
689 } | |
690 } | |
691 | |
692 d3drect.left = rect->x; | |
693 d3drect.right = rect->x + rect->w; | |
694 d3drect.top = rect->y; | |
695 d3drect.bottom = rect->y + rect->h; | |
696 | |
697 result = | |
698 IDirect3DSurface9_LockRect(data->offscreen, &locked, &d3drect, 0); | |
699 if (FAILED(result)) { | |
700 D3D_SetError("LockRect()", result); | |
701 return -1; | |
702 } | |
703 | |
704 src = pixels; | |
705 dst = locked.pBits; | |
706 length = rect->w * SDL_BYTESPERPIXEL(display->current_mode.format); | |
707 for (row = 0; row < rect->h; ++row) { | |
708 SDL_memcpy(dst, src, length); | |
709 src += pitch; | |
710 dst += locked.Pitch; | |
711 } | |
712 IDirect3DSurface9_UnlockRect(data->offscreen); | |
713 | |
714 point.x = rect->x; | |
715 point.y = rect->y; | |
716 result = | |
717 IDirect3DDevice9_UpdateSurface(data->device, data->offscreen, | |
718 &d3drect, data->surface, &point); | |
719 if (FAILED(result)) { | |
720 D3D_SetError("UpdateSurface()", result); | |
721 return -1; | |
722 } | |
723 | |
724 return 0; | |
725 } | |
726 | |
727 static void | 660 static void |
728 SDL_D3D_RenderPresent(SDL_Renderer * renderer) | 661 SDL_D3D_RenderPresent(SDL_Renderer * renderer) |
729 { | 662 { |
730 SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; | 663 SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; |
731 HRESULT result; | 664 HRESULT result; |
763 | 696 |
764 if (data) { | 697 if (data) { |
765 if (data->device) { | 698 if (data->device) { |
766 IDirect3DDevice9_Release(data->device); | 699 IDirect3DDevice9_Release(data->device); |
767 } | 700 } |
768 if (data->surface) { | |
769 IDirect3DSurface9_Release(data->surface); | |
770 } | |
771 if (data->offscreen) { | |
772 IDirect3DSurface9_Release(data->offscreen); | |
773 } | |
774 SDL_free(data); | 701 SDL_free(data); |
775 } | 702 } |
776 SDL_free(renderer); | 703 SDL_free(renderer); |
777 } | 704 } |
778 | 705 |