This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_d3drender.c
881 lines (795 loc) · 28.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#if SDL_VIDEO_RENDER_D3D
#include "SDL_win32video.h"
/* Direct3D renderer implementation */
30
static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
31
static int D3D_DisplayModeChanged(SDL_Renderer * renderer);
32
33
34
35
36
37
38
39
static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int D3D_SetTexturePalette(SDL_Renderer * renderer,
SDL_Texture * texture,
const SDL_Color * colors, int firstcolor,
int ncolors);
static int D3D_GetTexturePalette(SDL_Renderer * renderer,
SDL_Texture * texture, SDL_Color * colors,
int firstcolor, int ncolors);
40
41
42
43
44
45
46
47
static int D3D_SetTextureColorMod(SDL_Renderer * renderer,
SDL_Texture * texture);
static int D3D_SetTextureAlphaMod(SDL_Renderer * renderer,
SDL_Texture * texture);
static int D3D_SetTextureBlendMode(SDL_Renderer * renderer,
SDL_Texture * texture);
static int D3D_SetTextureScaleMode(SDL_Renderer * renderer,
SDL_Texture * texture);
48
49
50
51
52
53
54
55
56
static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels,
int pitch);
static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, int markDirty,
void **pixels, int *pitch);
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
int numrects, const SDL_Rect * rects);
57
58
static int D3D_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
Uint8 a, const SDL_Rect * rect);
59
static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
60
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
61
62
63
64
65
66
67
68
static void D3D_RenderPresent(SDL_Renderer * renderer);
static void D3D_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
static void D3D_DestroyRenderer(SDL_Renderer * renderer);
SDL_RenderDriver D3D_RenderDriver = {
D3D_CreateRenderer,
69
70
{
"d3d",
71
(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
72
SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
73
74
SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC |
SDL_RENDERER_ACCELERATED),
75
76
(SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
SDL_TEXTUREMODULATE_ALPHA),
77
78
79
80
81
(SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD |
SDL_TEXTUREBLENDMODE_MOD),
(SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST),
82
12,
83
{
84
85
86
87
88
89
90
91
92
93
94
95
SDL_PIXELFORMAT_INDEX8,
SDL_PIXELFORMAT_RGB332,
SDL_PIXELFORMAT_RGB444,
SDL_PIXELFORMAT_RGB555,
SDL_PIXELFORMAT_ARGB4444,
SDL_PIXELFORMAT_ARGB1555,
SDL_PIXELFORMAT_RGB565,
SDL_PIXELFORMAT_RGB888,
SDL_PIXELFORMAT_ARGB8888,
SDL_PIXELFORMAT_ARGB2101010,
SDL_PIXELFORMAT_UYVY,
SDL_PIXELFORMAT_YUY2},
96
97
98
99
100
101
102
0,
0}
};
typedef struct
{
IDirect3DDevice9 *device;
103
D3DPRESENT_PARAMETERS pparams;
104
SDL_bool beginScene;
105
} D3D_RenderData;
106
107
108
typedef struct
{
109
IDirect3DTexture9 *texture;
110
} D3D_TextureData;
111
112
113
114
typedef struct
{
float x, y, z;
115
float rhw;
116
DWORD color;
117
float u, v;
118
119
} Vertex;
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
static void
D3D_SetError(const char *prefix, HRESULT result)
{
const char *error;
switch (result) {
case D3DERR_WRONGTEXTUREFORMAT:
error = "WRONGTEXTUREFORMAT";
break;
case D3DERR_UNSUPPORTEDCOLOROPERATION:
error = "UNSUPPORTEDCOLOROPERATION";
break;
case D3DERR_UNSUPPORTEDCOLORARG:
error = "UNSUPPORTEDCOLORARG";
break;
case D3DERR_UNSUPPORTEDALPHAOPERATION:
error = "UNSUPPORTEDALPHAOPERATION";
break;
case D3DERR_UNSUPPORTEDALPHAARG:
error = "UNSUPPORTEDALPHAARG";
break;
case D3DERR_TOOMANYOPERATIONS:
error = "TOOMANYOPERATIONS";
break;
case D3DERR_CONFLICTINGTEXTUREFILTER:
error = "CONFLICTINGTEXTUREFILTER";
break;
case D3DERR_UNSUPPORTEDFACTORVALUE:
error = "UNSUPPORTEDFACTORVALUE";
break;
case D3DERR_CONFLICTINGRENDERSTATE:
error = "CONFLICTINGRENDERSTATE";
break;
case D3DERR_UNSUPPORTEDTEXTUREFILTER:
error = "UNSUPPORTEDTEXTUREFILTER";
break;
case D3DERR_CONFLICTINGTEXTUREPALETTE:
error = "CONFLICTINGTEXTUREPALETTE";
break;
case D3DERR_DRIVERINTERNALERROR:
error = "DRIVERINTERNALERROR";
break;
case D3DERR_NOTFOUND:
error = "NOTFOUND";
break;
case D3DERR_MOREDATA:
error = "MOREDATA";
break;
case D3DERR_DEVICELOST:
error = "DEVICELOST";
break;
case D3DERR_DEVICENOTRESET:
error = "DEVICENOTRESET";
break;
case D3DERR_NOTAVAILABLE:
error = "NOTAVAILABLE";
break;
case D3DERR_OUTOFVIDEOMEMORY:
error = "OUTOFVIDEOMEMORY";
break;
case D3DERR_INVALIDDEVICE:
error = "INVALIDDEVICE";
break;
case D3DERR_INVALIDCALL:
error = "INVALIDCALL";
break;
case D3DERR_DRIVERINVALIDCALL:
error = "DRIVERINVALIDCALL";
break;
case D3DERR_WASSTILLDRAWING:
error = "WASSTILLDRAWING";
break;
default:
error = "UNKNOWN";
break;
}
SDL_SetError("%s: %s", prefix, error);
}
199
200
static D3DFORMAT
PixelFormatToD3DFMT(Uint32 format)
201
{
202
switch (format) {
203
case SDL_PIXELFORMAT_INDEX8:
204
return D3DFMT_P8;
205
case SDL_PIXELFORMAT_RGB332:
206
return D3DFMT_R3G3B2;
207
case SDL_PIXELFORMAT_RGB444:
208
return D3DFMT_X4R4G4B4;
209
case SDL_PIXELFORMAT_RGB555:
210
return D3DFMT_X1R5G5B5;
211
case SDL_PIXELFORMAT_ARGB4444:
212
return D3DFMT_A4R4G4B4;
213
case SDL_PIXELFORMAT_ARGB1555:
214
return D3DFMT_A1R5G5B5;
215
case SDL_PIXELFORMAT_RGB565:
216
return D3DFMT_R5G6B5;
217
case SDL_PIXELFORMAT_RGB888:
218
return D3DFMT_X8R8G8B8;
219
case SDL_PIXELFORMAT_ARGB8888:
220
return D3DFMT_A8R8G8B8;
221
case SDL_PIXELFORMAT_ARGB2101010:
222
return D3DFMT_A2R10G10B10;
223
case SDL_PIXELFORMAT_UYVY:
224
return D3DFMT_UYVY;
225
case SDL_PIXELFORMAT_YUY2:
226
227
228
229
return D3DFMT_YUY2;
default:
return D3DFMT_UNKNOWN;
}
230
231
232
233
234
235
236
237
}
void
D3D_AddRenderDriver(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
if (data->d3d) {
238
SDL_AddRenderDriver(0, &D3D_RenderDriver);
239
240
241
242
}
}
SDL_Renderer *
243
D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
244
245
246
247
248
{
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata;
SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
SDL_Renderer *renderer;
249
D3D_RenderData *data;
250
251
HRESULT result;
D3DPRESENT_PARAMETERS pparams;
252
IDirect3DSwapChain9 *chain;
253
D3DCAPS9 caps;
254
255
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
256
257
258
259
260
if (!renderer) {
SDL_OutOfMemory();
return NULL;
}
261
data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data));
262
if (!data) {
263
D3D_DestroyRenderer(renderer);
264
265
266
267
SDL_OutOfMemory();
return NULL;
}
268
renderer->DisplayModeChanged = D3D_DisplayModeChanged;
269
270
271
renderer->CreateTexture = D3D_CreateTexture;
renderer->SetTexturePalette = D3D_SetTexturePalette;
renderer->GetTexturePalette = D3D_GetTexturePalette;
272
273
274
275
renderer->SetTextureColorMod = D3D_SetTextureColorMod;
renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod;
renderer->SetTextureBlendMode = D3D_SetTextureBlendMode;
renderer->SetTextureScaleMode = D3D_SetTextureScaleMode;
276
277
278
279
280
281
282
283
284
285
renderer->UpdateTexture = D3D_UpdateTexture;
renderer->LockTexture = D3D_LockTexture;
renderer->UnlockTexture = D3D_UnlockTexture;
renderer->DirtyTexture = D3D_DirtyTexture;
renderer->RenderFill = D3D_RenderFill;
renderer->RenderCopy = D3D_RenderCopy;
renderer->RenderPresent = D3D_RenderPresent;
renderer->DestroyTexture = D3D_DestroyTexture;
renderer->DestroyRenderer = D3D_DestroyRenderer;
renderer->info = D3D_RenderDriver.info;
286
287
288
renderer->window = window->id;
renderer->driverdata = data;
289
renderer->info.flags = SDL_RENDERER_ACCELERATED;
290
291
292
293
SDL_zero(pparams);
pparams.BackBufferWidth = window->w;
pparams.BackBufferHeight = window->h;
294
295
if (window->flags & SDL_WINDOW_FULLSCREEN) {
pparams.BackBufferFormat =
296
PixelFormatToD3DFMT(display->fullscreen_mode.format);
297
298
299
} else {
pparams.BackBufferFormat = D3DFMT_UNKNOWN;
}
300
if (flags & SDL_RENDERER_PRESENTFLIP2) {
301
302
pparams.BackBufferCount = 2;
pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
303
} else if (flags & SDL_RENDERER_PRESENTFLIP3) {
304
305
pparams.BackBufferCount = 3;
pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
306
} else if (flags & SDL_RENDERER_PRESENTCOPY) {
307
308
309
310
311
312
313
314
pparams.BackBufferCount = 1;
pparams.SwapEffect = D3DSWAPEFFECT_COPY;
} else {
pparams.BackBufferCount = 1;
pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
}
if (window->flags & SDL_WINDOW_FULLSCREEN) {
pparams.Windowed = FALSE;
315
pparams.FullScreen_RefreshRateInHz =
316
display->fullscreen_mode.refresh_rate;
317
318
} else {
pparams.Windowed = TRUE;
319
pparams.FullScreen_RefreshRateInHz = 0;
320
}
321
if (flags & SDL_RENDERER_PRESENTVSYNC) {
322
323
324
325
pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
} else {
pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}
326
327
328
329
330
331
332
result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */
D3DDEVTYPE_HAL,
windowdata->hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&pparams, &data->device);
if (FAILED(result)) {
333
D3D_DestroyRenderer(renderer);
334
335
336
337
338
D3D_SetError("CreateDevice()", result);
return NULL;
}
data->beginScene = SDL_TRUE;
339
340
341
/* Get presentation parameters to fill info */
result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
if (FAILED(result)) {
342
D3D_DestroyRenderer(renderer);
343
344
345
346
347
348
D3D_SetError("GetSwapChain()", result);
return NULL;
}
result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
if (FAILED(result)) {
IDirect3DSwapChain9_Release(chain);
349
D3D_DestroyRenderer(renderer);
350
351
352
353
354
355
D3D_SetError("GetPresentParameters()", result);
return NULL;
}
IDirect3DSwapChain9_Release(chain);
switch (pparams.SwapEffect) {
case D3DSWAPEFFECT_COPY:
356
renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
357
358
359
360
break;
case D3DSWAPEFFECT_FLIP:
switch (pparams.BackBufferCount) {
case 2:
361
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
362
363
break;
case 3:
364
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
365
366
367
368
break;
}
break;
case D3DSWAPEFFECT_DISCARD:
369
renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD;
370
371
372
break;
}
if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
373
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
374
}
375
data->pparams = pparams;
376
377
378
379
IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
renderer->info.max_texture_width = caps.MaxTextureWidth;
renderer->info.max_texture_height = caps.MaxTextureHeight;
380
381
/* Set up parameters for rendering */
382
IDirect3DDevice9_SetVertexShader(data->device, NULL);
383
384
IDirect3DDevice9_SetFVF(data->device,
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
385
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
386
387
IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
D3DCULL_NONE);
388
IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
389
390
391
392
393
394
395
396
397
398
399
400
401
402
/* Enable color modulation by diffuse color */
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP,
D3DTOP_MODULATE);
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1,
D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2,
D3DTA_DIFFUSE);
/* Enable alpha modulation by diffuse alpha */
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP,
D3DTOP_MODULATE);
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1,
D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
D3DTA_DIFFUSE);
403
404
405
406
407
/* Disable second texture stage, since we're done */
IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
D3DTOP_DISABLE);
IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
D3DTOP_DISABLE);
408
409
410
411
return renderer;
}
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
static int
D3D_Reset(SDL_Renderer * renderer)
{
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
HRESULT result;
result = IDirect3DDevice9_Reset(data->device, &data->pparams);
if (FAILED(result)) {
if (result == D3DERR_DEVICELOST) {
/* Don't worry about it, we'll reset later... */
return 0;
} else {
D3D_SetError("Reset()", result);
return -1;
}
}
IDirect3DDevice9_SetVertexShader(data->device, NULL);
429
430
IDirect3DDevice9_SetFVF(data->device,
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
D3DCULL_NONE);
IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
return 0;
}
static int
D3D_DisplayModeChanged(SDL_Renderer * renderer)
{
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
data->pparams.BackBufferWidth = window->w;
data->pparams.BackBufferHeight = window->h;
if (window->flags & SDL_WINDOW_FULLSCREEN) {
data->pparams.BackBufferFormat =
PixelFormatToD3DFMT(display->fullscreen_mode.format);
} else {
data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
}
return D3D_Reset(renderer);
}
455
static int
456
D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
457
{
458
D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
459
460
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
461
D3D_TextureData *data;
462
HRESULT result;
463
464
data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data));
465
466
467
468
469
470
471
if (!data) {
SDL_OutOfMemory();
return -1;
}
texture->driverdata = data;
472
473
474
475
result =
IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
texture->h, 1, 0,
PixelFormatToD3DFMT(texture->format),
476
D3DPOOL_MANAGED, &data->texture, NULL);
477
478
479
480
481
482
if (FAILED(result)) {
D3D_SetError("CreateTexture()", result);
return -1;
}
return 0;
483
484
485
}
static int
486
487
D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Color * colors, int firstcolor, int ncolors)
488
{
489
490
D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
491
492
return 0;
493
494
495
}
static int
496
497
D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
SDL_Color * colors, int firstcolor, int ncolors)
498
{
499
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
500
501
return 0;
502
503
}
504
505
506
static int
D3D_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
{
507
return 0;
508
509
510
511
512
}
static int
D3D_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
{
513
return 0;
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
}
static int
D3D_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
{
switch (texture->blendMode) {
case SDL_TEXTUREBLENDMODE_NONE:
case SDL_TEXTUREBLENDMODE_MASK:
case SDL_TEXTUREBLENDMODE_BLEND:
case SDL_TEXTUREBLENDMODE_ADD:
case SDL_TEXTUREBLENDMODE_MOD:
return 0;
default:
SDL_Unsupported();
texture->blendMode = SDL_TEXTUREBLENDMODE_NONE;
return -1;
}
}
static int
D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
{
switch (texture->scaleMode) {
case SDL_TEXTURESCALEMODE_NONE:
case SDL_TEXTURESCALEMODE_FAST:
case SDL_TEXTURESCALEMODE_SLOW:
case SDL_TEXTURESCALEMODE_BEST:
return 0;
default:
SDL_Unsupported();
texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
return -1;
}
return 0;
}
550
static int
551
552
D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
553
{
554
555
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
556
557
558
559
560
561
562
IDirect3DTexture9 *temp;
RECT d3drect;
D3DLOCKED_RECT locked;
const Uint8 *src;
Uint8 *dst;
int row, length;
HRESULT result;
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
result =
IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
texture->h, 1, 0,
PixelFormatToD3DFMT(texture->format),
D3DPOOL_SYSTEMMEM, &temp, NULL);
if (FAILED(result)) {
D3D_SetError("CreateTexture()", result);
return -1;
}
d3drect.left = rect->x;
d3drect.right = rect->x + rect->w;
d3drect.top = rect->y;
d3drect.bottom = rect->y + rect->h;
result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
if (FAILED(result)) {
IDirect3DTexture9_Release(temp);
D3D_SetError("LockRect()", result);
return -1;
}
585
586
587
588
589
590
591
592
src = pixels;
dst = locked.pBits;
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += locked.Pitch;
593
}
594
595
596
597
598
599
600
601
602
603
604
605
606
IDirect3DTexture9_UnlockRect(temp, 0);
result =
IDirect3DDevice9_UpdateTexture(renderdata->device,
(IDirect3DBaseTexture9 *) temp,
(IDirect3DBaseTexture9 *) data->
texture);
IDirect3DTexture9_Release(temp);
if (FAILED(result)) {
D3D_SetError("UpdateTexture()", result);
return -1;
}
return 0;
607
608
609
}
static int
610
611
612
D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, int markDirty, void **pixels,
int *pitch)
613
{
614
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
615
616
617
RECT d3drect;
D3DLOCKED_RECT locked;
HRESULT result;
618
619
620
621
622
623
624
625
626
627
628
d3drect.left = rect->x;
d3drect.right = rect->x + rect->w;
d3drect.top = rect->y;
d3drect.bottom = rect->y + rect->h;
result =
IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
markDirty ? 0 : D3DLOCK_NO_DIRTY_UPDATE);
if (FAILED(result)) {
D3D_SetError("LockRect()", result);
629
return -1;
630
}
631
632
633
*pixels = locked.pBits;
*pitch = locked.Pitch;
return 0;
634
635
636
}
static void
637
D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
638
{
639
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
640
641
IDirect3DTexture9_UnlockRect(data->texture, 0);
642
643
644
}
static void
645
646
D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
const SDL_Rect * rects)
647
{
648
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
649
650
651
652
653
654
655
656
657
658
659
660
661
RECT d3drect;
int i;
for (i = 0; i < numrects; ++i) {
const SDL_Rect *rect = &rects[i];
d3drect.left = rect->x;
d3drect.right = rect->x + rect->w;
d3drect.top = rect->y;
d3drect.bottom = rect->y + rect->h;
IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
}
662
663
664
}
static int
665
666
D3D_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a,
const SDL_Rect * rect)
667
{
668
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
669
D3DRECT d3drect;
670
HRESULT result;
671
672
673
674
675
if (data->beginScene) {
IDirect3DDevice9_BeginScene(data->device);
data->beginScene = SDL_FALSE;
}
676
677
d3drect.x1 = rect->x;
678
d3drect.x2 = rect->x + rect->w;
679
d3drect.y1 = rect->y;
680
d3drect.y2 = rect->y + rect->h;
681
682
683
result =
IDirect3DDevice9_Clear(data->device, 1, &d3drect, D3DCLEAR_TARGET,
684
D3DCOLOR_ARGB(a, r, g, b), 1.0f, 0);
685
686
687
688
if (FAILED(result)) {
D3D_SetError("Clear()", result);
return -1;
}
689
690
691
692
return 0;
}
static int
693
D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
694
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
695
{
696
697
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
698
float minx, miny, maxx, maxy;
699
float minu, maxu, minv, maxv;
700
DWORD color;
701
702
Vertex vertices[4];
HRESULT result;
703
704
705
706
707
if (data->beginScene) {
IDirect3DDevice9_BeginScene(data->device);
data->beginScene = SDL_FALSE;
}
708
709
710
711
712
minx = (float) dstrect->x - 0.5f;
miny = (float) dstrect->y - 0.5f;
maxx = (float) dstrect->x + dstrect->w - 0.5f;
maxy = (float) dstrect->y + dstrect->h - 0.5f;
713
714
715
716
717
minu = (float) srcrect->x / texture->w;
maxu = (float) (srcrect->x + srcrect->w) / texture->w;
minv = (float) srcrect->y / texture->h;
maxv = (float) (srcrect->y + srcrect->h) / texture->h;
718
719
720
color = D3DCOLOR_ARGB(texture->a, texture->r, texture->g, texture->b);
721
722
723
vertices[0].x = minx;
vertices[0].y = miny;
vertices[0].z = 0.0f;
724
vertices[0].rhw = 1.0f;
725
vertices[0].color = color;
726
727
728
vertices[0].u = minu;
vertices[0].v = minv;
729
730
731
vertices[1].x = maxx;
vertices[1].y = miny;
vertices[1].z = 0.0f;
732
vertices[1].rhw = 1.0f;
733
vertices[1].color = color;
734
735
736
vertices[1].u = maxu;
vertices[1].v = minv;
737
738
739
vertices[2].x = maxx;
vertices[2].y = maxy;
vertices[2].z = 0.0f;
740
vertices[2].rhw = 1.0f;
741
vertices[2].color = color;
742
743
744
vertices[2].u = maxu;
vertices[2].v = maxv;
745
746
747
vertices[3].x = minx;
vertices[3].y = maxy;
vertices[3].z = 0.0f;
748
vertices[3].rhw = 1.0f;
749
vertices[3].color = color;
750
751
vertices[3].u = minu;
vertices[3].v = maxv;
752
753
switch (texture->blendMode) {
754
case SDL_TEXTUREBLENDMODE_NONE:
755
756
757
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
FALSE);
break;
758
759
case SDL_TEXTUREBLENDMODE_MASK:
case SDL_TEXTUREBLENDMODE_BLEND:
760
761
762
763
764
765
766
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
TRUE);
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
D3DBLEND_SRCALPHA);
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
D3DBLEND_INVSRCALPHA);
break;
767
case SDL_TEXTUREBLENDMODE_ADD:
768
769
770
771
772
773
774
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
TRUE);
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
D3DBLEND_SRCALPHA);
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
D3DBLEND_ONE);
break;
775
case SDL_TEXTUREBLENDMODE_MOD:
776
777
778
779
780
781
782
783
784
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
TRUE);
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
D3DBLEND_ZERO);
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
D3DBLEND_SRCCOLOR);
break;
}
785
switch (texture->scaleMode) {
786
787
case SDL_TEXTURESCALEMODE_NONE:
case SDL_TEXTURESCALEMODE_FAST:
788
789
790
791
792
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
D3DTEXF_POINT);
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
D3DTEXF_POINT);
break;
793
case SDL_TEXTURESCALEMODE_SLOW:
794
795
796
797
798
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
D3DTEXF_LINEAR);
break;
799
case SDL_TEXTURESCALEMODE_BEST:
800
801
802
803
804
805
806
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
D3DTEXF_GAUSSIANQUAD);
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
D3DTEXF_GAUSSIANQUAD);
break;
}
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
result =
IDirect3DDevice9_SetTexture(data->device, 0,
(IDirect3DBaseTexture9 *) texturedata->
texture);
if (FAILED(result)) {
D3D_SetError("SetTexture()", result);
return -1;
}
result =
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
vertices, sizeof(*vertices));
if (FAILED(result)) {
D3D_SetError("DrawPrimitiveUP()", result);
return -1;
}
822
823
824
825
return 0;
}
static void
826
D3D_RenderPresent(SDL_Renderer * renderer)
827
{
828
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
829
830
831
832
833
834
835
HRESULT result;
if (!data->beginScene) {
IDirect3DDevice9_EndScene(data->device);
data->beginScene = SDL_TRUE;
}
836
837
838
839
840
841
842
843
result = IDirect3DDevice9_TestCooperativeLevel(data->device);
if (result == D3DERR_DEVICELOST) {
/* We'll reset later */
return;
}
if (result == D3DERR_DEVICENOTRESET) {
D3D_Reset(renderer);
}
844
845
846
847
result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
if (FAILED(result)) {
D3D_SetError("Present()", result);
}
848
849
850
}
static void
851
D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
852
{
853
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
854
855
856
857
if (!data) {
return;
}
858
859
860
if (data->texture) {
IDirect3DTexture9_Release(data->texture);
}
861
862
863
864
SDL_free(data);
texture->driverdata = NULL;
}
865
static void
866
D3D_DestroyRenderer(SDL_Renderer * renderer)
867
{
868
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
869
870
if (data) {
871
872
873
if (data->device) {
IDirect3DDevice9_Release(data->device);
}
874
875
876
877
878
879
880
881
SDL_free(data);
}
SDL_free(renderer);
}
#endif /* SDL_VIDEO_RENDER_D3D */
/* vi: set ts=4 sw=4 expandtab: */