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
20 #include "d3dx9_36_private.h"
24 DWORD num_render_targets
;
25 IDirect3DSurface9
**render_targets
;
26 IDirect3DSurface9
*depth_stencil
;
27 D3DVIEWPORT9 viewport
;
30 static HRESULT
device_state_init(IDirect3DDevice9
*device
, struct device_state
*state
)
36 hr
= IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
37 if (FAILED(hr
)) return hr
;
39 state
->num_render_targets
= caps
.NumSimultaneousRTs
;
40 state
->render_targets
= HeapAlloc(GetProcessHeap(), 0,
41 state
->num_render_targets
* sizeof(IDirect3DSurface9
*));
42 if (!state
->render_targets
)
45 for (i
= 0; i
< state
->num_render_targets
; i
++)
46 state
->render_targets
[i
] = NULL
;
47 state
->depth_stencil
= NULL
;
51 static void device_state_capture(IDirect3DDevice9
*device
, struct device_state
*state
)
56 IDirect3DDevice9_GetViewport(device
, &state
->viewport
);
58 for (i
= 0; i
< state
->num_render_targets
; i
++)
60 hr
= IDirect3DDevice9_GetRenderTarget(device
, i
, &state
->render_targets
[i
]);
61 if (FAILED(hr
)) state
->render_targets
[i
] = NULL
;
64 hr
= IDirect3DDevice9_GetDepthStencilSurface(device
, &state
->depth_stencil
);
65 if (FAILED(hr
)) state
->depth_stencil
= NULL
;
68 static void device_state_restore(IDirect3DDevice9
*device
, struct device_state
*state
)
72 for (i
= 0; i
< state
->num_render_targets
; i
++)
74 IDirect3DDevice9_SetRenderTarget(device
, i
, state
->render_targets
[i
]);
75 if (state
->render_targets
[i
])
76 IDirect3DSurface9_Release(state
->render_targets
[i
]);
77 state
->render_targets
[i
] = NULL
;
80 IDirect3DDevice9_SetDepthStencilSurface(device
, state
->depth_stencil
);
81 if (state
->depth_stencil
)
83 IDirect3DSurface9_Release(state
->depth_stencil
);
84 state
->depth_stencil
= NULL
;
87 IDirect3DDevice9_SetViewport(device
, &state
->viewport
);
90 static void device_state_release(struct device_state
*state
)
94 for (i
= 0; i
< state
->num_render_targets
; i
++)
96 if (state
->render_targets
[i
])
97 IDirect3DSurface9_Release(state
->render_targets
[i
]);
100 HeapFree(GetProcessHeap(), 0, state
->render_targets
);
102 if (state
->depth_stencil
) IDirect3DSurface9_Release(state
->depth_stencil
);
105 struct render_to_surface
107 ID3DXRenderToSurface ID3DXRenderToSurface_iface
;
110 IDirect3DDevice9
*device
;
113 IDirect3DSurface9
*dst_surface
;
115 IDirect3DSurface9
*render_target
;
116 IDirect3DSurface9
*depth_stencil
;
118 struct device_state previous_state
;
121 static inline struct render_to_surface
*impl_from_ID3DXRenderToSurface(ID3DXRenderToSurface
*iface
)
123 return CONTAINING_RECORD(iface
, struct render_to_surface
, ID3DXRenderToSurface_iface
);
126 static HRESULT WINAPI
D3DXRenderToSurface_QueryInterface(ID3DXRenderToSurface
*iface
,
130 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
132 if (IsEqualGUID(riid
, &IID_ID3DXRenderToSurface
)
133 || IsEqualGUID(riid
, &IID_IUnknown
))
135 IUnknown_AddRef(iface
);
140 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
143 return E_NOINTERFACE
;
146 static ULONG WINAPI
D3DXRenderToSurface_AddRef(ID3DXRenderToSurface
*iface
)
148 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
149 ULONG ref
= InterlockedIncrement(&render
->ref
);
151 TRACE("%p increasing refcount to %u\n", iface
, ref
);
156 static ULONG WINAPI
D3DXRenderToSurface_Release(ID3DXRenderToSurface
*iface
)
158 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
159 ULONG ref
= InterlockedDecrement(&render
->ref
);
161 TRACE("%p decreasing refcount to %u\n", iface
, ref
);
165 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
167 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
168 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
170 device_state_release(&render
->previous_state
);
172 IDirect3DDevice9_Release(render
->device
);
174 HeapFree(GetProcessHeap(), 0, render
);
180 static HRESULT WINAPI
D3DXRenderToSurface_GetDevice(ID3DXRenderToSurface
*iface
,
181 IDirect3DDevice9
**device
)
183 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
185 TRACE("(%p)->(%p)\n", iface
, device
);
187 if (!device
) return D3DERR_INVALIDCALL
;
189 IDirect3DDevice9_AddRef(render
->device
);
190 *device
= render
->device
;
194 static HRESULT WINAPI
D3DXRenderToSurface_GetDesc(ID3DXRenderToSurface
*iface
,
197 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
199 TRACE("(%p)->(%p)\n", iface
, desc
);
201 if (!desc
) return D3DERR_INVALIDCALL
;
203 *desc
= render
->desc
;
207 static HRESULT WINAPI
D3DXRenderToSurface_BeginScene(ID3DXRenderToSurface
*iface
,
208 IDirect3DSurface9
*surface
,
209 const D3DVIEWPORT9
*viewport
)
211 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
213 IDirect3DDevice9
*device
;
214 D3DSURFACE_DESC surface_desc
;
215 HRESULT hr
= D3DERR_INVALIDCALL
;
216 D3DMULTISAMPLE_TYPE multi_sample_type
= D3DMULTISAMPLE_NONE
;
217 DWORD multi_sample_quality
= 0;
219 TRACE("(%p)->(%p, %p)\n", iface
, surface
, viewport
);
221 if (!surface
|| render
->dst_surface
) return D3DERR_INVALIDCALL
;
223 IDirect3DSurface9_GetDesc(surface
, &surface_desc
);
224 if (surface_desc
.Format
!= render
->desc
.Format
225 || surface_desc
.Width
!= render
->desc
.Width
226 || surface_desc
.Height
!= render
->desc
.Height
)
227 return D3DERR_INVALIDCALL
;
231 if (viewport
->X
> render
->desc
.Width
|| viewport
->Y
> render
->desc
.Height
232 || viewport
->X
+ viewport
->Width
> render
->desc
.Width
233 || viewport
->Y
+ viewport
->Height
> render
->desc
.Height
)
234 return D3DERR_INVALIDCALL
;
236 if (!(surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
237 && (viewport
->X
!= 0 || viewport
->Y
!= 0
238 || viewport
->Width
!= render
->desc
.Width
239 || viewport
->Height
!= render
->desc
.Height
))
240 return D3DERR_INVALIDCALL
;
243 device
= render
->device
;
245 device_state_capture(device
, &render
->previous_state
);
247 /* prepare for rendering to surface */
248 for (i
= 1; i
< render
->previous_state
.num_render_targets
; i
++)
249 IDirect3DDevice9_SetRenderTarget(device
, i
, NULL
);
251 if (surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
)
253 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, surface
);
254 multi_sample_type
= surface_desc
.MultiSampleType
;
255 multi_sample_quality
= surface_desc
.MultiSampleQuality
;
259 hr
= IDirect3DDevice9_CreateRenderTarget(device
, render
->desc
.Width
, render
->desc
.Height
,
260 render
->desc
.Format
, multi_sample_type
, multi_sample_quality
, FALSE
,
261 &render
->render_target
, NULL
);
262 if (FAILED(hr
)) goto cleanup
;
263 hr
= IDirect3DDevice9_SetRenderTarget(device
, 0, render
->render_target
);
266 if (FAILED(hr
)) goto cleanup
;
268 if (render
->desc
.DepthStencil
)
270 hr
= IDirect3DDevice9_CreateDepthStencilSurface(device
, render
->desc
.Width
, render
->desc
.Height
,
271 render
->desc
.DepthStencilFormat
, multi_sample_type
, multi_sample_quality
, TRUE
,
272 &render
->depth_stencil
, NULL
);
274 else render
->depth_stencil
= NULL
;
276 if (FAILED(hr
)) goto cleanup
;
278 hr
= IDirect3DDevice9_SetDepthStencilSurface(device
, render
->depth_stencil
);
279 if (FAILED(hr
)) goto cleanup
;
281 if (viewport
) IDirect3DDevice9_SetViewport(device
, viewport
);
283 IDirect3DSurface9_AddRef(surface
);
284 render
->dst_surface
= surface
;
285 return IDirect3DDevice9_BeginScene(device
);
288 device_state_restore(device
, &render
->previous_state
);
290 if (render
->dst_surface
) IDirect3DSurface9_Release(render
->dst_surface
);
291 render
->dst_surface
= NULL
;
293 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
294 render
->render_target
= NULL
;
295 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
296 render
->depth_stencil
= NULL
;
301 static HRESULT WINAPI
D3DXRenderToSurface_EndScene(ID3DXRenderToSurface
*iface
,
304 struct render_to_surface
*render
= impl_from_ID3DXRenderToSurface(iface
);
307 TRACE("(%p)->(%#x)\n", iface
, filter
);
309 if (!render
->dst_surface
) return D3DERR_INVALIDCALL
;
311 hr
= IDirect3DDevice9_EndScene(render
->device
);
313 /* copy render target data to destination surface, if needed */
314 if (render
->render_target
)
316 hr
= D3DXLoadSurfaceFromSurface(render
->dst_surface
, NULL
, NULL
,
317 render
->render_target
, NULL
, NULL
, filter
, 0);
318 if (FAILED(hr
)) ERR("Copying render target data to surface failed %#x\n", hr
);
321 device_state_restore(render
->device
, &render
->previous_state
);
323 /* release resources */
324 if (render
->render_target
)
326 IDirect3DSurface9_Release(render
->render_target
);
327 render
->render_target
= NULL
;
330 if (render
->depth_stencil
)
332 IDirect3DSurface9_Release(render
->depth_stencil
);
333 render
->depth_stencil
= NULL
;
336 IDirect3DSurface9_Release(render
->dst_surface
);
337 render
->dst_surface
= NULL
;
342 static HRESULT WINAPI
D3DXRenderToSurface_OnLostDevice(ID3DXRenderToSurface
*iface
)
344 FIXME("(%p)->(): stub\n", iface
);
348 static HRESULT WINAPI
D3DXRenderToSurface_OnResetDevice(ID3DXRenderToSurface
*iface
)
350 FIXME("(%p)->(): stub\n", iface
);
354 static const ID3DXRenderToSurfaceVtbl render_to_surface_vtbl
=
356 /* IUnknown methods */
357 D3DXRenderToSurface_QueryInterface
,
358 D3DXRenderToSurface_AddRef
,
359 D3DXRenderToSurface_Release
,
360 /* ID3DXRenderToSurface methods */
361 D3DXRenderToSurface_GetDevice
,
362 D3DXRenderToSurface_GetDesc
,
363 D3DXRenderToSurface_BeginScene
,
364 D3DXRenderToSurface_EndScene
,
365 D3DXRenderToSurface_OnLostDevice
,
366 D3DXRenderToSurface_OnResetDevice
369 HRESULT WINAPI
D3DXCreateRenderToSurface(IDirect3DDevice9
*device
,
374 D3DFORMAT depth_stencil_format
,
375 ID3DXRenderToSurface
**out
)
378 struct render_to_surface
*render
;
380 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device
, width
, height
, format
,
381 depth_stencil
, depth_stencil_format
, out
);
383 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
385 render
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_surface
));
386 if (!render
) return E_OUTOFMEMORY
;
388 render
->ID3DXRenderToSurface_iface
.lpVtbl
= &render_to_surface_vtbl
;
391 render
->desc
.Width
= width
;
392 render
->desc
.Height
= height
;
393 render
->desc
.Format
= format
;
394 render
->desc
.DepthStencil
= depth_stencil
;
395 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
397 render
->dst_surface
= NULL
;
398 render
->render_target
= NULL
;
399 render
->depth_stencil
= NULL
;
401 hr
= device_state_init(device
, &render
->previous_state
);
404 HeapFree(GetProcessHeap(), 0, render
);
408 IDirect3DDevice9_AddRef(device
);
409 render
->device
= device
;
411 *out
= &render
->ID3DXRenderToSurface_iface
;
424 struct render_to_envmap
426 ID3DXRenderToEnvMap ID3DXRenderToEnvMap_iface
;
429 IDirect3DDevice9
*device
;
432 enum render_state state
;
433 struct device_state previous_device_state
;
435 D3DCUBEMAP_FACES face
;
438 IDirect3DSurface9
*render_target
;
439 IDirect3DSurface9
*depth_stencil
;
441 IDirect3DCubeTexture9
*dst_cube_texture
;
444 static void copy_render_target_to_cube_texture_face(IDirect3DCubeTexture9
*cube_texture
,
445 D3DCUBEMAP_FACES face
, IDirect3DSurface9
*render_target
, DWORD filter
)
448 IDirect3DSurface9
*cube_surface
;
450 IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture
, face
, 0, &cube_surface
);
452 hr
= D3DXLoadSurfaceFromSurface(cube_surface
, NULL
, NULL
, render_target
, NULL
, NULL
, filter
, 0);
453 if (FAILED(hr
)) ERR("Copying render target data to surface failed %#x\n", hr
);
455 IDirect3DSurface9_Release(cube_surface
);
458 static inline struct render_to_envmap
*impl_from_ID3DXRenderToEnvMap(ID3DXRenderToEnvMap
*iface
)
460 return CONTAINING_RECORD(iface
, struct render_to_envmap
, ID3DXRenderToEnvMap_iface
);
463 static HRESULT WINAPI
D3DXRenderToEnvMap_QueryInterface(ID3DXRenderToEnvMap
*iface
,
467 TRACE("iface %p, riid %s, out %p\n", iface
, debugstr_guid(riid
), out
);
469 if (IsEqualGUID(riid
, &IID_ID3DXRenderToEnvMap
)
470 || IsEqualGUID(riid
, &IID_IUnknown
))
472 IUnknown_AddRef(iface
);
477 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
480 return E_NOINTERFACE
;
483 static ULONG WINAPI
D3DXRenderToEnvMap_AddRef(ID3DXRenderToEnvMap
*iface
)
485 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
486 ULONG ref
= InterlockedIncrement(&render
->ref
);
488 TRACE("%p increasing refcount to %u\n", iface
, ref
);
493 static ULONG WINAPI
D3DXRenderToEnvMap_Release(ID3DXRenderToEnvMap
*iface
)
495 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
496 ULONG ref
= InterlockedDecrement(&render
->ref
);
498 TRACE("%p decreasing refcount to %u\n", iface
, ref
);
502 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
504 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
505 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
507 device_state_release(&render
->previous_device_state
);
509 IDirect3DDevice9_Release(render
->device
);
511 HeapFree(GetProcessHeap(), 0, render
);
517 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDevice(ID3DXRenderToEnvMap
*iface
,
518 IDirect3DDevice9
**device
)
520 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
522 TRACE("(%p)->(%p)\n", iface
, device
);
524 if (!device
) return D3DERR_INVALIDCALL
;
526 IDirect3DDevice9_AddRef(render
->device
);
527 *device
= render
->device
;
531 static HRESULT WINAPI
D3DXRenderToEnvMap_GetDesc(ID3DXRenderToEnvMap
*iface
,
534 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
536 TRACE("(%p)->(%p)\n", iface
, desc
);
538 if (!desc
) return D3DERR_INVALIDCALL
;
540 *desc
= render
->desc
;
544 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginCube(ID3DXRenderToEnvMap
*iface
,
545 IDirect3DCubeTexture9
*texture
)
547 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
549 D3DSURFACE_DESC level_desc
;
551 TRACE("(%p)->(%p)\n", iface
, texture
);
553 if (!texture
) return D3DERR_INVALIDCALL
;
555 if (render
->state
!= INITIAL
) return D3DERR_INVALIDCALL
;
557 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
558 if (level_desc
.Format
!= render
->desc
.Format
|| level_desc
.Width
!= render
->desc
.Size
)
559 return D3DERR_INVALIDCALL
;
561 if (!(level_desc
.Usage
& D3DUSAGE_RENDERTARGET
))
563 hr
= IDirect3DDevice9_CreateRenderTarget(render
->device
, level_desc
.Width
, level_desc
.Height
,
564 level_desc
.Format
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
565 TRUE
, &render
->render_target
, NULL
);
566 if (FAILED(hr
)) goto cleanup
;
567 IDirect3DCubeTexture9_GetLevelDesc(texture
, 0, &level_desc
);
570 if (render
->desc
.DepthStencil
)
572 hr
= IDirect3DDevice9_CreateDepthStencilSurface(render
->device
, level_desc
.Width
, level_desc
.Height
,
573 render
->desc
.DepthStencilFormat
, level_desc
.MultiSampleType
, level_desc
.MultiSampleQuality
,
574 TRUE
, &render
->depth_stencil
, NULL
);
575 if (FAILED(hr
)) goto cleanup
;
578 IDirect3DCubeTexture9_AddRef(texture
);
579 render
->dst_cube_texture
= texture
;
580 render
->state
= CUBE_BEGIN
;
584 if (render
->dst_cube_texture
) IDirect3DSurface9_Release(render
->dst_cube_texture
);
585 render
->dst_cube_texture
= NULL
;
587 if (render
->render_target
) IDirect3DSurface9_Release(render
->render_target
);
588 render
->render_target
= NULL
;
589 if (render
->depth_stencil
) IDirect3DSurface9_Release(render
->depth_stencil
);
590 render
->depth_stencil
= NULL
;
595 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginSphere(ID3DXRenderToEnvMap
*iface
,
596 IDirect3DTexture9
*texture
)
598 FIXME("(%p)->(%p): stub\n", iface
, texture
);
602 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginHemisphere(ID3DXRenderToEnvMap
*iface
,
603 IDirect3DTexture9
*pos_z_texture
,
604 IDirect3DTexture9
*neg_z_texture
)
606 FIXME("(%p)->(%p, %p): stub\n", iface
, pos_z_texture
, neg_z_texture
);
610 static HRESULT WINAPI
D3DXRenderToEnvMap_BeginParabolic(ID3DXRenderToEnvMap
*iface
,
611 IDirect3DTexture9
*pos_z_texture
,
612 IDirect3DTexture9
*neg_z_texture
)
614 FIXME("(%p)->(%p, %p): stub\n", iface
, pos_z_texture
, neg_z_texture
);
618 static HRESULT WINAPI
D3DXRenderToEnvMap_Face(ID3DXRenderToEnvMap
*iface
,
619 D3DCUBEMAP_FACES face
,
622 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
626 TRACE("(%p)->(%u, %#x)\n", iface
, face
, filter
);
628 if (render
->state
== CUBE_FACE
)
630 IDirect3DDevice9_EndScene(render
->device
);
631 if (render
->render_target
)
632 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
633 render
->render_target
, render
->filter
);
635 device_state_restore(render
->device
, &render
->previous_device_state
);
637 render
->state
= CUBE_BEGIN
;
639 else if (render
->state
!= CUBE_BEGIN
)
640 return D3DERR_INVALIDCALL
;
642 device_state_capture(render
->device
, &render
->previous_device_state
);
644 for (i
= 1; i
< render
->previous_device_state
.num_render_targets
; i
++)
645 IDirect3DDevice9_SetRenderTarget(render
->device
, i
, NULL
);
647 if (!render
->render_target
)
649 IDirect3DSurface9
*render_target
;
650 IDirect3DCubeTexture9_GetCubeMapSurface(render
->dst_cube_texture
, face
, 0, &render_target
);
651 hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render_target
);
652 IDirect3DSurface9_Release(render_target
);
654 else hr
= IDirect3DDevice9_SetRenderTarget(render
->device
, 0, render
->render_target
);
656 if (FAILED(hr
)) goto cleanup
;
658 hr
= IDirect3DDevice9_SetDepthStencilSurface(render
->device
, render
->depth_stencil
);
659 if (FAILED(hr
)) goto cleanup
;
661 render
->state
= CUBE_FACE
;
663 render
->filter
= filter
;
664 return IDirect3DDevice9_BeginScene(render
->device
);
667 device_state_restore(render
->device
, &render
->previous_device_state
);
671 static HRESULT WINAPI
D3DXRenderToEnvMap_End(ID3DXRenderToEnvMap
*iface
,
674 struct render_to_envmap
*render
= impl_from_ID3DXRenderToEnvMap(iface
);
676 TRACE("(%p)->(%#x)\n", iface
, filter
);
678 if (render
->state
== INITIAL
) return D3DERR_INVALIDCALL
;
680 if (render
->state
== CUBE_FACE
)
682 IDirect3DDevice9_EndScene(render
->device
);
683 if (render
->render_target
)
684 copy_render_target_to_cube_texture_face(render
->dst_cube_texture
, render
->face
,
685 render
->render_target
, render
->filter
);
687 device_state_restore(render
->device
, &render
->previous_device_state
);
690 D3DXFilterTexture((IDirect3DBaseTexture9
*)render
->dst_cube_texture
, NULL
, 0, filter
);
692 if (render
->render_target
)
694 IDirect3DSurface9_Release(render
->render_target
);
695 render
->render_target
= NULL
;
698 if (render
->depth_stencil
)
700 IDirect3DSurface9_Release(render
->depth_stencil
);
701 render
->depth_stencil
= NULL
;
704 IDirect3DSurface9_Release(render
->dst_cube_texture
);
705 render
->dst_cube_texture
= NULL
;
707 render
->state
= INITIAL
;
711 static HRESULT WINAPI
D3DXRenderToEnvMap_OnLostDevice(ID3DXRenderToEnvMap
*iface
)
713 FIXME("(%p)->(): stub\n", iface
);
717 static HRESULT WINAPI
D3DXRenderToEnvMap_OnResetDevice(ID3DXRenderToEnvMap
*iface
)
719 FIXME("(%p)->(): stub\n", iface
);
723 static const ID3DXRenderToEnvMapVtbl render_to_envmap_vtbl
=
725 /* IUnknown methods */
726 D3DXRenderToEnvMap_QueryInterface
,
727 D3DXRenderToEnvMap_AddRef
,
728 D3DXRenderToEnvMap_Release
,
729 /* ID3DXRenderToEnvMap methods */
730 D3DXRenderToEnvMap_GetDevice
,
731 D3DXRenderToEnvMap_GetDesc
,
732 D3DXRenderToEnvMap_BeginCube
,
733 D3DXRenderToEnvMap_BeginSphere
,
734 D3DXRenderToEnvMap_BeginHemisphere
,
735 D3DXRenderToEnvMap_BeginParabolic
,
736 D3DXRenderToEnvMap_Face
,
737 D3DXRenderToEnvMap_End
,
738 D3DXRenderToEnvMap_OnLostDevice
,
739 D3DXRenderToEnvMap_OnResetDevice
742 HRESULT WINAPI
D3DXCreateRenderToEnvMap(IDirect3DDevice9
*device
,
747 D3DFORMAT depth_stencil_format
,
748 ID3DXRenderToEnvMap
**out
)
751 struct render_to_envmap
*render
;
753 TRACE("(%p, %u, %u, %#x, %d, %#x, %p)\n", device
, size
, mip_levels
,
754 format
, depth_stencil
, depth_stencil_format
, out
);
756 if (!device
|| !out
) return D3DERR_INVALIDCALL
;
758 hr
= D3DXCheckTextureRequirements(device
, &size
, &size
, &mip_levels
,
759 D3DUSAGE_RENDERTARGET
, &format
, D3DPOOL_DEFAULT
);
760 if (FAILED(hr
)) return hr
;
762 render
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct render_to_envmap
));
763 if (!render
) return E_OUTOFMEMORY
;
765 render
->ID3DXRenderToEnvMap_iface
.lpVtbl
= &render_to_envmap_vtbl
;
768 render
->desc
.Size
= size
;
769 render
->desc
.MipLevels
= mip_levels
;
770 render
->desc
.Format
= format
;
771 render
->desc
.DepthStencil
= depth_stencil
;
772 render
->desc
.DepthStencilFormat
= depth_stencil_format
;
774 render
->state
= INITIAL
;
775 render
->render_target
= NULL
;
776 render
->depth_stencil
= NULL
;
777 render
->dst_cube_texture
= NULL
;
779 hr
= device_state_init(device
, &render
->previous_device_state
);
782 HeapFree(GetProcessHeap(), 0, render
);
786 IDirect3DDevice9_AddRef(device
);
787 render
->device
= device
;
789 *out
= &render
->ID3DXRenderToEnvMap_iface
;