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