2 * Copyright (C) 2012 Józef Kucia
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "d3dx9_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
27 DWORD num_render_targets
;
28 IDirect3DSurface9
**render_targets
;
29 IDirect3DSurface9
*depth_stencil
;
30 D3DVIEWPORT9 viewport
;
33 static HRESULT
device_state_init(IDirect3DDevice9
*device
, struct device_state
*state
)
39 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
40 if (FAILED(hr
)) return hr
;
42 state
->num_render_targets
= caps
.NumSimultaneousRTs
;
43 state
->render_targets
= malloc(state
->num_render_targets
* sizeof(IDirect3DSurface9
*));
44 if (!state
->render_targets
)
47 for (i
= 0; i
< state
->num_render_targets
; i
++)
48 state
->render_targets
[i
] = NULL
;
49 state
->depth_stencil
= NULL
;
53 static void device_state_capture(IDirect3DDevice9
*device
, struct device_state
*state
)
58 IDirect3DDevice9_GetViewport(device
, &state
->viewport
);
60 for (i
= 0; i
< state
->num_render_targets
; i
++)
62 hr
= IDirect3DDevice9_GetRenderTarget(device
, i
, &state
->render_targets
[i
]);
63 if (FAILED(hr
)) state
->render_targets
[i
] = NULL
;
66 hr
= IDirect3DDevice9_GetDepthStencilSurface(device
, &state
->depth_stencil
);
67 if (FAILED(hr
)) state
->depth_stencil
= NULL
;
70 static void device_state_restore(IDirect3DDevice9
*device
, struct device_state
*state
)
74 for (i
= 0; i
< state
->num_render_targets
; i
++)
76 IDirect3DDevice9_SetRenderTarget(device
, i
, state
->render_targets
[i
]);
77 if (state
->render_targets
[i
])
78 IDirect3DSurface9_Release(state
->render_targets
[i
]);
79 state
->render_targets
[i
] = NULL
;
82 IDirect3DDevice9_SetDepthStencilSurface(device
, state
->depth_stencil
);
83 if (state
->depth_stencil
)
85 IDirect3DSurface9_Release(state
->depth_stencil
);
86 state
->depth_stencil
= NULL
;
89 IDirect3DDevice9_SetViewport(device
, &state
->viewport
);
92 static void device_state_release(struct device_state
*state
)
96 for (i
= 0; i
< state
->num_render_targets
; i
++)
98 if (state
->render_targets
[i
])
99 IDirect3DSurface9_Release(state
->render_targets
[i
]);
102 free(state
->render_targets
);
104 if (state
->depth_stencil
) IDirect3DSurface9_Release(state
->depth_stencil
);
107 struct render_to_surface
109 ID3DXRenderToSurface ID3DXRenderToSurface_iface
;
112 IDirect3DDevice9
*device
;
115 IDirect3DSurface9
*dst_surface
;
117 IDirect3DSurface9
*render_target
;
118 IDirect3DSurface9
*depth_stencil
;
120 struct device_state previous_state
;
123 static inline struct render_to_surface
*impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface
*iface
)
125 return CONTAINING_RECORD(iface
, struct render_to_surface
, ID3DXRenderToSurface_iface
);
128 static HRESULT WINAPI
D3DXRenderToSurface_QueryInterface(ID3DXRenderToSurface
*iface
,
132 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
134 if (IsEqualGUID(riid
, &IID_ID3DXRenderToSurface
)
135 || IsEqualGUID(riid
, &IID_IUnknown
))
137 IUnknown_AddRef(iface
);
142 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
145 return E_NOINTERFACE
;
148 static ULONG WINAPI
D3DXRenderToSurface_AddRef(ID3DXRenderToSurface
*iface
)
150 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
151 ULONG ref
= InterlockedIncrement(&render
->ref
);
153 TRACE("%p increasing refcount to %lu.\n", iface
, ref
);
158 static ULONG WINAPI
D3DXRenderToSurface_Release(ID3DXRenderToSurface
*iface
)
160 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
161 ULONG ref
= InterlockedDecrement(&render
->ref
);
163 TRACE("%p decreasing refcount to %lu.\n", iface
, ref
);
167 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
169 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
170 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
172 device_state_release(&render
->previous_state
);
174 IDirect3DDevice9_Release(render
->device
);
182 static HRESULT WINAPI
D3DXRenderToSurface_GetDevice(ID3DXRenderToSurface
*iface
,
183 IDirect3DDevice9
**device
)
185 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
187 TRACE("iface %p, device %p.\n", iface
, device
);
189 if (!device
) return D3DERR_INVALIDCALL
;
191 IDirect3DDevice9_AddRef(render
->device
);
192 *device
= render
->device
;
196 static HRESULT WINAPI
D3DXRenderToSurface_GetDesc(ID3DXRenderToSurface
*iface
,
199 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
201 TRACE("iface %p, desc %p.\n", iface
, desc
);
203 if (!desc
) return D3DERR_INVALIDCALL
;
205 *desc
= render
->desc
;
209 static HRESULT WINAPI
D3DXRenderToSurface_BeginScene(ID3DXRenderToSurface
*iface
,
210 IDirect3DSurface9
*surface
,
211 const D3DVIEWPORT9
*viewport
)
213 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
215 IDirect3DDevice9
*device
;
216 D3DSURFACE_DESC surface_desc
;
217 HRESULT hr
= D3DERR_INVALIDCALL
;
218 D3DMULTISAMPLE_TYPE multi_sample_type
= D3DMULTISAMPLE_NONE
;
219 DWORD multi_sample_quality
= 0;
221 TRACE("iface %p, surface %p, viewport %p.\n", iface
, surface
, viewport
);
223 if (!surface
|| render
->dst_surface
) return D3DERR_INVALIDCALL
;
225 IDirect3DSurface9_GetDesc(surface
, &surface_desc
);
226 if (surface_desc
.Format
!= render
->desc
.Format
227 || surface_desc
.Width
!= render
->desc
.Width
228 || surface_desc
.Height
!= render
->desc
.Height
)
229 return D3DERR_INVALIDCALL
;
233 if (viewport
->X
> render
->desc
.Width
|| viewport
->Y
> render
->desc
.Height
234 || viewport
->X
+ viewport
->Width
> render
->desc
.Width
235 || viewport
->Y
+ viewport
->Height
> render
->desc
.Height
)
236 return D3DERR_INVALIDCALL
;
238 if (!(surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
239 && (viewport
->X
!= 0 || viewport
->Y
!= 0
240 || viewport
->Width
!= render
->desc
.Width
241 || viewport
->Height
!= render
->desc
.Height
))
242 return D3DERR_INVALIDCALL
;
245 device
= render
->device
;
247 device_state_capture(device
, &render
->previous_state
);
249 /* prepare for rendering to surface */
250 for (i
= 1; i
< render
->previous_state
.num_render_targets
; i
++)
251 IDirect3DDevice9_SetRenderTarget(device
, i
, NULL
);
253 if (surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
255 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, surface
);
256 multi_sample_type
= surface_desc
.MultiSampleType
;
257 multi_sample_quality
= surface_desc
.MultiSampleQuality
;
261 hr
= IDirect3DDevice9_CreateRenderTarget(device
, render
->desc
.Width
, render
->desc
.Height
,
262 render
->desc
.Format
, multi_sample_type
, multi_sample_quality
, FALSE
,
263 &render
->render_target
, NULL
);
264 if (FAILED(hr
)) goto cleanup
;
265 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, render
->render_target
);
268 if (FAILED(hr
)) goto cleanup
;
270 if (render
->desc
.DepthStencil
)
272 hr
= IDirect3DDevice9_CreateDepthStencilSurface(device
, render
->desc
.Width
, render
->desc
.Height
,
273 render
->desc
.DepthStencilFormat
, multi_sample_type
, multi_sample_quality
, TRUE
,
274 &render
->depth_stencil
, NULL
);
276 else render
->depth_stencil
= NULL
;
278 if (FAILED(hr
)) goto cleanup
;
280 hr
= IDirect3DDevice9_SetDepthStencilSurface(device
, render
->depth_stencil
);
281 if (FAILED(hr
)) goto cleanup
;
283 if (viewport
) IDirect3DDevice9_SetViewport(device
, viewport
);
285 IDirect3DSurface9_AddRef(surface
);
286 render
->dst_surface
= surface
;
287 return IDirect3DDevice9_BeginScene(device
);
290 device_state_restore(device
, &render
->previous_state
);
292 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
293 render
->dst_surface
= NULL
;
295 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
296 render
->render_target
= NULL
;
297 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
298 render
->depth_stencil
= NULL
;
303 static HRESULT WINAPI
D3DXRenderToSurface_EndScene(ID3DXRenderToSurface
*iface
,
306 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
309 TRACE("iface %p, filter %#lx.\n", iface
, filter
);
311 if (!render
->dst_surface
) return D3DERR_INVALIDCALL
;
313 hr
= IDirect3DDevice9_EndScene(render
->device
);
315 /* copy render target data to destination surface, if needed */
316 if (render
->render_target
)
318 hr
= D3DXLoadSurfaceFromSurface(render
->dst_surface
, NULL
, NULL
,
319 render
->render_target
, NULL
, NULL
, filter
, 0);
321 ERR("Copying render target data to surface failed, hr %#lx.\n", hr
);
324 device_state_restore(render
->device
, &render
->previous_state
);
326 /* release resources */
327 if (render
->render_target
)
329 IDirect3DSurface9_Release(render
->render_target
);
330 render
->render_target
= NULL
;
333 if (render
->depth_stencil
)
335 IDirect3DSurface9_Release(render
->depth_stencil
);
336 render
->depth_stencil
= NULL
;
339 IDirect3DSurface9_Release(render
->dst_surface
);
340 render
->dst_surface
= NULL
;
345 static HRESULT WINAPI
D3DXRenderToSurface_OnLostDevice(ID3DXRenderToSurface
*iface
)
347 FIXME("iface %p stub!\n", iface
);
351 static HRESULT WINAPI
D3DXRenderToSurface_OnResetDevice(ID3DXRenderToSurface
*iface
)
353 FIXME("iface %p stub!\n", iface
);
357 static const ID3DXRenderToSurfaceVtbl render_to_surface_vtbl
=
359 /* IUnknown methods */
360 D3DXRenderToSurface_QueryInterface
,
361 D3DXRenderToSurface_AddRef
,
362 D3DXRenderToSurface_Release
,
363 /* ID3DXRenderToSurface methods */
364 D3DXRenderToSurface_GetDevice
,
365 D3DXRenderToSurface_GetDesc
,
366 D3DXRenderToSurface_BeginScene
,
367 D3DXRenderToSurface_EndScene
,
368 D3DXRenderToSurface_OnLostDevice
,
369 D3DXRenderToSurface_OnResetDevice
372 HRESULT WINAPI
D3DXCreateRenderToSurface(IDirect3DDevice9
*device
,
377 D3DFORMAT depth_stencil_format
,
378 ID3DXRenderToSurface
**out
)
381 struct render_to_surface
*render
;
383 TRACE("device %p, width %u, height %u, format %#x, depth_stencil %#x, depth_stencil_format %#x, out %p.\n",
384 device
, width
, height
, format
, depth_stencil
, depth_stencil_format
, out
);
386 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
388 render
= malloc(sizeof(struct render_to_surface
));
389 if (!render
) return E_OUTOFMEMORY
;
391 render
->ID3DXRenderToSurface_iface
.lpVtbl
= &render_to_surface_vtbl
;
394 render
->desc
.Width
= width
;
395 render
->desc
.Height
= height
;
396 render
->desc
.Format
= format
;
397 render
->desc
.DepthStencil
= depth_stencil
;
398 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
400 render
->dst_surface
= NULL
;
401 render
->render_target
= NULL
;
402 render
->depth_stencil
= NULL
;
404 hr
= device_state_init(device
, &render
->previous_state
);
411 IDirect3DDevice9_AddRef(device
);
412 render
->device
= device
;
414 *out
= &render
->ID3DXRenderToSurface_iface
;
427 struct render_to_envmap
429 ID3DXRenderToEnvMap ID3DXRenderToEnvMap_iface
;
432 IDirect3DDevice9
*device
;
435 enum render_state state
;
436 struct device_state previous_device_state
;
438 D3DCUBEMAP_FACES face
;
441 IDirect3DSurface9
*render_target
;
442 IDirect3DSurface9
*depth_stencil
;
444 IDirect3DCubeTexture9
*dst_cube_texture
;
447 static void copy_render_target_to_cube_texture_face(IDirect3DCubeTexture9
*cube_texture
,
448 D3DCUBEMAP_FACES face
, IDirect3DSurface9
*render_target
, DWORD filter
)
451 IDirect3DSurface9
*cube_surface
;
453 IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture
, face
, 0, &cube_surface
);
455 hr
= D3DXLoadSurfaceFromSurface(cube_surface
, NULL
, NULL
, render_target
, NULL
, NULL
, filter
, 0);
457 ERR("Copying render target data to surface failed, hr %#lx.\n", hr
);
459 IDirect3DSurface9_Release(cube_surface
);
462 static inline struct render_to_envmap
*impl_from_ID3DXRenderToEnvMap(ID3DXRenderToEnvMap
*iface
)
464 return CONTAINING_RECORD(iface
, struct render_to_envmap
, ID3DXRenderToEnvMap_iface
);
467 static HRESULT WINAPI
D3DXRenderToEnvMap_QueryInterface(ID3DXRenderToEnvMap
*iface
,
471 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
473 if (IsEqualGUID(riid
, &IID_ID3DXRenderToEnvMap
)
474 || IsEqualGUID(riid
, &IID_IUnknown
))
476 IUnknown_AddRef(iface
);
481 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
484 return E_NOINTERFACE
;
487 static ULONG WINAPI
D3DXRenderToEnvMap_AddRef(ID3DXRenderToEnvMap
*iface
)
489 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
490 ULONG ref
= InterlockedIncrement(&render
->ref
);
492 TRACE("%p increasing refcount to %lu.\n", iface
, ref
);
497 static ULONG WINAPI
D3DXRenderToEnvMap_Release(ID3DXRenderToEnvMap
*iface
)
499 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
500 ULONG ref
= InterlockedDecrement(&render
->ref
);
502 TRACE("%p decreasing refcount to %lu.\n", iface
, ref
);
506 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
508 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
509 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
511 device_state_release(&render
->previous_device_state
);
513 IDirect3DDevice9_Release(render
->device
);
521 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDevice(ID3DXRenderToEnvMap
*iface
,
522 IDirect3DDevice9
**device
)
524 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
526 TRACE("iface %p, device %p.\n", iface
, device
);
528 if (!device
) return D3DERR_INVALIDCALL
;
530 IDirect3DDevice9_AddRef(render
->device
);
531 *device
= render
->device
;
535 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDesc(ID3DXRenderToEnvMap
*iface
,
538 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
540 TRACE("iface %p, desc %p.\n", iface
, desc
);
542 if (!desc
) return D3DERR_INVALIDCALL
;
544 *desc
= render
->desc
;
548 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginCube(ID3DXRenderToEnvMap
*iface
,
549 IDirect3DCubeTexture9
*texture
)
551 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
553 D3DSURFACE_DESC level_desc
;
555 TRACE("iface %p, texture %p.\n", iface
, texture
);
557 if (!texture
) return D3DERR_INVALIDCALL
;
559 if (render
->state
!= INITIAL
) return D3DERR_INVALIDCALL
;
561 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
562 if (level_desc
.Format
!= render
->desc
.Format
|| level_desc
.Width
!= render
->desc
.Size
)
563 return D3DERR_INVALIDCALL
;
565 if (!(level_desc
.Usage
& D3DUSAGE_RENDERTARGET
))
567 hr
= IDirect3DDevice9_CreateRenderTarget(render
->device
, level_desc
.Width
, level_desc
.Height
,
568 level_desc
.Format
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
569 TRUE
, &render
->render_target
, NULL
);
570 if (FAILED(hr
)) goto cleanup
;
571 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
574 if (render
->desc
.DepthStencil
)
576 hr
= IDirect3DDevice9_CreateDepthStencilSurface(render
->device
, level_desc
.Width
, level_desc
.Height
,
577 render
->desc
.DepthStencilFormat
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
578 TRUE
, &render
->depth_stencil
, NULL
);
579 if (FAILED(hr
)) goto cleanup
;
582 IDirect3DCubeTexture9_AddRef(texture
);
583 render
->dst_cube_texture
= texture
;
584 render
->state
= CUBE_BEGIN
;
588 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
589 render
->dst_cube_texture
= NULL
;
591 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
592 render
->render_target
= NULL
;
593 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
594 render
->depth_stencil
= NULL
;
599 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginSphere(ID3DXRenderToEnvMap
*iface
,
600 IDirect3DTexture9
*texture
)
602 FIXME("iface %p, texture %p stub!\n", iface
, texture
);
606 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginHemisphere(ID3DXRenderToEnvMap
*iface
,
607 IDirect3DTexture9
*pos_z_texture
,
608 IDirect3DTexture9
*neg_z_texture
)
610 FIXME("iface %p, pos_z_texture %p, neg_z_texture %p stub!\n", iface
, pos_z_texture
, neg_z_texture
);
614 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginParabolic(ID3DXRenderToEnvMap
*iface
,
615 IDirect3DTexture9
*pos_z_texture
,
616 IDirect3DTexture9
*neg_z_texture
)
618 FIXME("iface %p, pos_z_texture %p, neg_z_texture %p stub!\n", iface
, pos_z_texture
, neg_z_texture
);
622 static HRESULT WINAPI
D3DXRenderToEnvMap_Face(ID3DXRenderToEnvMap
*iface
,
623 D3DCUBEMAP_FACES face
,
626 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
630 TRACE("iface %p, face %u, filter %#lx.\n", iface
, face
, filter
);
632 if (render
->state
== CUBE_FACE
)
634 IDirect3DDevice9_EndScene(render
->device
);
635 if (render
->render_target
)
636 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
637 render
->render_target
, render
->filter
);
639 device_state_restore(render
->device
, &render
->previous_device_state
);
641 render
->state
= CUBE_BEGIN
;
643 else if (render
->state
!= CUBE_BEGIN
)
644 return D3DERR_INVALIDCALL
;
646 device_state_capture(render
->device
, &render
->previous_device_state
);
648 for (i
= 1; i
< render
->previous_device_state
.num_render_targets
; i
++)
649 IDirect3DDevice9_SetRenderTarget(render
->device
, i
, NULL
);
651 if (!render
->render_target
)
653 IDirect3DSurface9
*render_target
;
654 IDirect3DCubeTexture9_GetCubeMapSurface(render
->dst_cube_texture
, face
, 0, &render_target
);
655 hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render_target
);
656 IDirect3DSurface9_Release(render_target
);
658 else hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render
->render_target
);
660 if (FAILED(hr
)) goto cleanup
;
662 hr
= IDirect3DDevice9_SetDepthStencilSurface(render
->device
, render
->depth_stencil
);
663 if (FAILED(hr
)) goto cleanup
;
665 render
->state
= CUBE_FACE
;
667 render
->filter
= filter
;
668 return IDirect3DDevice9_BeginScene(render
->device
);
671 device_state_restore(render
->device
, &render
->previous_device_state
);
675 static HRESULT WINAPI
D3DXRenderToEnvMap_End(ID3DXRenderToEnvMap
*iface
,
678 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
680 TRACE("iface %p, filter %#lx.\n", iface
, filter
);
682 if (render
->state
== INITIAL
) return D3DERR_INVALIDCALL
;
684 if (render
->state
== CUBE_FACE
)
686 IDirect3DDevice9_EndScene(render
->device
);
687 if (render
->render_target
)
688 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
689 render
->render_target
, render
->filter
);
691 device_state_restore(render
->device
, &render
->previous_device_state
);
694 D3DXFilterTexture((IDirect3DBaseTexture9
*)render
->dst_cube_texture
, NULL
, 0, filter
);
696 if (render
->render_target
)
698 IDirect3DSurface9_Release(render
->render_target
);
699 render
->render_target
= NULL
;
702 if (render
->depth_stencil
)
704 IDirect3DSurface9_Release(render
->depth_stencil
);
705 render
->depth_stencil
= NULL
;
708 IDirect3DSurface9_Release(render
->dst_cube_texture
);
709 render
->dst_cube_texture
= NULL
;
711 render
->state
= INITIAL
;
715 static HRESULT WINAPI
D3DXRenderToEnvMap_OnLostDevice(ID3DXRenderToEnvMap
*iface
)
717 FIXME("iface %p stub!\n", iface
);
721 static HRESULT WINAPI
D3DXRenderToEnvMap_OnResetDevice(ID3DXRenderToEnvMap
*iface
)
723 FIXME("iface %p stub!\n", iface
);
727 static const ID3DXRenderToEnvMapVtbl render_to_envmap_vtbl
=
729 /* IUnknown methods */
730 D3DXRenderToEnvMap_QueryInterface
,
731 D3DXRenderToEnvMap_AddRef
,
732 D3DXRenderToEnvMap_Release
,
733 /* ID3DXRenderToEnvMap methods */
734 D3DXRenderToEnvMap_GetDevice
,
735 D3DXRenderToEnvMap_GetDesc
,
736 D3DXRenderToEnvMap_BeginCube
,
737 D3DXRenderToEnvMap_BeginSphere
,
738 D3DXRenderToEnvMap_BeginHemisphere
,
739 D3DXRenderToEnvMap_BeginParabolic
,
740 D3DXRenderToEnvMap_Face
,
741 D3DXRenderToEnvMap_End
,
742 D3DXRenderToEnvMap_OnLostDevice
,
743 D3DXRenderToEnvMap_OnResetDevice
746 HRESULT WINAPI
D3DXCreateRenderToEnvMap(IDirect3DDevice9
*device
,
751 D3DFORMAT depth_stencil_format
,
752 ID3DXRenderToEnvMap
**out
)
755 struct render_to_envmap
*render
;
757 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device
, size
, mip_levels
,
758 format
, depth_stencil
, depth_stencil_format
, out
);
760 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
762 hr
= D3DXCheckTextureRequirements(device
, &size
, &size
, &mip_levels
,
763 D3DUSAGE_RENDERTARGET
, &format
, D3DPOOL_DEFAULT
);
764 if (FAILED(hr
)) return hr
;
766 render
= malloc(sizeof(*render
));
767 if (!render
) return E_OUTOFMEMORY
;
769 render
->ID3DXRenderToEnvMap_iface
.lpVtbl
= &render_to_envmap_vtbl
;
772 render
->desc
.Size
= size
;
773 render
->desc
.MipLevels
= mip_levels
;
774 render
->desc
.Format
= format
;
775 render
->desc
.DepthStencil
= depth_stencil
;
776 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
778 render
->state
= INITIAL
;
779 render
->render_target
= NULL
;
780 render
->depth_stencil
= NULL
;
781 render
->dst_cube_texture
= NULL
;
783 hr
= device_state_init(device
, &render
->previous_device_state
);
790 IDirect3DDevice9_AddRef(device
);
791 render
->device
= device
;
793 *out
= &render
->ID3DXRenderToEnvMap_iface
;