viewport.c 18.8 KB
Newer Older
1
/* Direct3D Viewport
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 * Copyright (c) 1998 Lionel ULMER
 *
 * This file contains the implementation of Direct3DViewport2.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
20

21 22 23 24
#include "config.h"

#include <stdarg.h>

25 26
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
27

28
#include "windef.h"
29
#include "winbase.h"
30
#include "winerror.h"
31
#include "objbase.h"
32
#include "wingdi.h"
33 34
#include "ddraw.h"
#include "d3d.h"
35
#include "wine/debug.h"
36 37 38

#include "d3d_private.h"

39
WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
40

41 42
static void activate(IDirect3DViewportImpl* This) {
    IDirect3DLightImpl* light;
43 44
    D3DVIEWPORT7 vp;
    
45 46
    /* Activate all the lights associated with this context */
    light = This->lights;
47

48 49 50 51
    while (light != NULL) {
        light->activate(light);
	light = light->next;
    }
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71

    /* And copy the values in the structure used by the device */
    if (This->use_vp2) {
        vp.dwX = This->viewports.vp2.dwX;
	vp.dwY = This->viewports.vp2.dwY;
	vp.dwHeight = This->viewports.vp2.dwHeight;
	vp.dwWidth = This->viewports.vp2.dwWidth;
	vp.dvMinZ = This->viewports.vp2.dvMinZ;
	vp.dvMaxZ = This->viewports.vp2.dvMaxZ;
    } else {
        vp.dwX = This->viewports.vp1.dwX;
	vp.dwY = This->viewports.vp1.dwY;
	vp.dwHeight = This->viewports.vp1.dwHeight;
	vp.dwWidth = This->viewports.vp1.dwWidth;
	vp.dvMinZ = This->viewports.vp1.dvMinZ;
	vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
    }
    
    /* And also set the viewport */
    IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
72
}
73

74

75 76 77 78 79 80 81 82 83 84 85 86
static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
{
    TRACE("    - dwSize = %ld   dwX = %ld   dwY = %ld\n",
	  lpvp->dwSize, lpvp->dwX, lpvp->dwY);
    TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
	  lpvp->dwWidth, lpvp->dwHeight);
    TRACE("    - dvScaleX = %f   dvScaleY = %f\n",
	  lpvp->dvScaleX, lpvp->dvScaleY);
    TRACE("    - dvMaxX = %f   dvMaxY = %f\n",
	  lpvp->dvMaxX, lpvp->dvMaxY);
    TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
	  lpvp->dvMinZ, lpvp->dvMaxZ);
87 88
}

89
static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp)
90
{
91 92 93 94 95 96 97 98 99 100
    TRACE("    - dwSize = %ld   dwX = %ld   dwY = %ld\n",
	  lpvp->dwSize, lpvp->dwX, lpvp->dwY);
    TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
	  lpvp->dwWidth, lpvp->dwHeight);
    TRACE("    - dvClipX = %f   dvClipY = %f\n",
	  lpvp->dvClipX, lpvp->dvClipY);
    TRACE("    - dvClipWidth = %f   dvClipHeight = %f\n",
	  lpvp->dvClipWidth, lpvp->dvClipHeight);
    TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
	  lpvp->dvMinZ, lpvp->dvMaxZ);
101 102
}

103 104 105 106
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
                                                REFIID riid,
                                                LPVOID* obp)
107
{
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);

    *obp = NULL;

    if ( IsEqualGUID(&IID_IUnknown,  riid) ||
	 IsEqualGUID(&IID_IDirect3DViewport, riid) ||
	 IsEqualGUID(&IID_IDirect3DViewport2, riid) ||
	 IsEqualGUID(&IID_IDirect3DViewport3, riid) ) {
        IDirect3DViewport3_AddRef(ICOM_INTERFACE(This, IDirect3DViewport3));
        *obp = ICOM_INTERFACE(This, IDirect3DViewport3);
	TRACE("  Creating IDirect3DViewport1/2/3 interface %p\n", *obp);
	return S_OK;
    }
    FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
    return OLE_E_ENUM_NOMORE;
124 125
}

126 127
ULONG WINAPI
Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
128
{
129
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
130 131 132 133 134
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);

    return ref;
135 136
}

137 138
ULONG WINAPI
Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
139
{
140
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
141 142 143 144 145
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);

    if (!ref) {
146 147 148
        HeapFree(GetProcessHeap(), 0, This);
	return 0;
    }
149
    return ref;
150 151 152
}


153 154 155
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
                                            LPDIRECT3D lpDirect3D)
156
{
157 158 159
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
    return DD_OK;
160 161
}

162 163 164
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
                                             LPD3DVIEWPORT lpData)
165
{
166 167 168 169 170 171 172 173 174 175
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    DWORD dwSize;
    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
    if (This->use_vp2 != 0) {
        ERR("  Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
	return DDERR_INVALIDPARAMS;
    }
    dwSize = lpData->dwSize;
    memset(lpData, 0, dwSize);
    memcpy(lpData, &(This->viewports.vp1), dwSize);
176

177
    if (TRACE_ON(ddraw)) {
178
        TRACE("  returning D3DVIEWPORT :\n");
179 180 181 182
	_dump_D3DVIEWPORT(lpData);
    }
    
    return DD_OK;
183 184
}

185 186 187
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
                                             LPD3DVIEWPORT lpData)
188
{
189
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
190
    LPDIRECT3DVIEWPORT3 current_viewport;
191
    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
192

193 194 195 196
    if (TRACE_ON(ddraw)) {
        TRACE("  getting D3DVIEWPORT :\n");
	_dump_D3DVIEWPORT(lpData);
    }
197

198 199 200
    This->use_vp2 = 0;
    memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
    memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
201

202
    /* Tests on two games show that these values are never used properly so override
203 204 205 206
       them with proper ones :-)
    */
    This->viewports.vp1.dvMinZ = 0.0;
    This->viewports.vp1.dvMaxZ = 1.0;
207 208 209 210 211 212 213 214

    if (This->active_device) {
      IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
      if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
          This->activate(This);
      IDirect3DViewport3_Release(current_viewport);
    }

215 216
    return DD_OK;
}
217

218 219 220 221 222 223 224 225 226
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
                                                   DWORD dwVertexCount,
                                                   LPD3DTRANSFORMDATA lpData,
                                                   DWORD dwFlags,
                                                   LPDWORD lpOffScreen)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
227 228
    if (lpOffScreen)
	*lpOffScreen = 0;
229
    return DD_OK;
230 231
}

232 233 234 235
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
                                               DWORD dwElementCount,
                                               LPD3DLIGHTDATA lpData)
236
{
237 238 239 240
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
    return DD_OK;
}
241

242 243 244 245 246
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
                                               D3DMATERIALHANDLE hMat)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
247 248 249 250 251 252 253 254 255
    TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat);
    
    This->background = (IDirect3DMaterialImpl *) hMat;
    TRACE(" setting background color : %f %f %f %f\n",
	  This->background->mat.u.diffuse.u1.r,
	  This->background->mat.u.diffuse.u2.g,
	  This->background->mat.u.diffuse.u3.b,
	  This->background->mat.u.diffuse.u4.a);

256 257
    return DD_OK;
}
258

259 260 261 262 263 264 265 266 267
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
                                               LPD3DMATERIALHANDLE lphMat,
                                               LPBOOL lpValid)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
    return DD_OK;
}
268

269 270 271 272 273 274 275 276
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
                                                    LPDIRECTDRAWSURFACE lpDDSurface)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
    return DD_OK;
}
277

278 279 280 281 282 283 284 285
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
                                                    LPDIRECTDRAWSURFACE* lplpDDSurface,
                                                    LPBOOL lpValid)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
    return DD_OK;
286 287
}

288 289 290 291 292
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
                                       DWORD dwCount,
                                       LPD3DRECT lpRects,
                                       DWORD dwFlags)
293
{
294
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
295 296
    DWORD color = 0x00000000;
    
297 298 299 300 301
    TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
    if (This->active_device == NULL) {
        ERR(" Trying to clear a viewport not attached to a device !\n");
	return D3DERR_VIEWPORTHASNODEVICE;
    }
302 303 304 305 306 307 308 309 310 311 312 313 314 315
    if (dwFlags & D3DCLEAR_TARGET) {
        if (This->background == NULL) {
	    ERR(" Trying to clear the color buffer without background material !\n");
	} else {
	    color = 
	      ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
	      ((int) ((This->background->mat.u.diffuse.u2.g) * 255) <<  8) |
	      ((int) ((This->background->mat.u.diffuse.u3.b) * 255) <<  0) |
	      ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
	}
    }
    return This->active_device->clear(This->active_device, dwCount, lpRects, 
				      dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
				      color, 1.0, 0x00000000);
316
}
317

318 319 320 321 322 323
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
                                          LPDIRECT3DLIGHT lpDirect3DLight)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
324 325
    DWORD i = 0;
    DWORD map = This->map_lights;
326 327 328
    
    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
    
329 330 331 332 333 334 335 336 337 338 339 340
    if (This->num_lights >= 8)
        return DDERR_INVALIDPARAMS;

    /* Find a light number and update both light and viewports objects accordingly */
    while(map&1) {
        map>>=1;
	i++;
    }
    lpDirect3DLightImpl->dwLightIndex = i;
    This->num_lights++;
    This->map_lights |= 1<<i;

341 342 343 344
    /* Add the light in the 'linked' chain */
    lpDirect3DLightImpl->next = This->lights;
    This->lights = lpDirect3DLightImpl;

345 346 347
    /* Attach the light to the viewport */
    lpDirect3DLightImpl->active_viewport = This;
    
348 349 350 351 352 353
    /* If active, activate the light */
    if (This->active_device != NULL) {
        lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
    }
    
    return DD_OK;
354 355
}

356 357 358
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
                                             LPDIRECT3DLIGHT lpDirect3DLight)
359
{
360 361 362 363 364 365 366 367 368 369 370
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
    IDirect3DLightImpl *cur_light, *prev_light = NULL;
    
    TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
    cur_light = This->lights;
    while (cur_light != NULL) {
        if (cur_light == lpDirect3DLightImpl) {
	    lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
	    if (prev_light == NULL) This->lights = cur_light->next;
	    else prev_light->next = cur_light->next;
371 372 373 374
	    /* Detach the light to the viewport */
	    cur_light->active_viewport = NULL;
	    This->num_lights--;
	    This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
375 376 377 378 379 380 381
	    return DD_OK;
	}
	prev_light = cur_light;
	cur_light = cur_light->next;
    }
    return DDERR_INVALIDPARAMS;
}
382

383 384 385 386 387 388 389 390 391
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
                                           LPDIRECT3DLIGHT lpDirect3DLight,
                                           LPDIRECT3DLIGHT* lplpDirect3DLight,
                                           DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
    return DD_OK;
392 393
}

394 395 396
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
                                            LPD3DVIEWPORT2 lpData)
397
{
398 399 400 401 402 403 404 405 406 407
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    DWORD dwSize;
    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
    if (This->use_vp2 != 1) {
        ERR("  Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
	return DDERR_INVALIDPARAMS;
    }
    dwSize = lpData->dwSize;
    memset(lpData, 0, dwSize);
    memcpy(lpData, &(This->viewports.vp2), dwSize);
408

409
    if (TRACE_ON(ddraw)) {
410
        TRACE("  returning D3DVIEWPORT2 :\n");
411 412 413 414
	_dump_D3DVIEWPORT2(lpData);
    }
    
    return DD_OK;
415 416
}

417 418 419
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
                                            LPD3DVIEWPORT2 lpData)
420
{
421
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
422
    LPDIRECT3DVIEWPORT3 current_viewport;
423
    TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
424

425 426 427 428 429 430 431 432
    if (TRACE_ON(ddraw)) {
        TRACE("  getting D3DVIEWPORT2 :\n");
	_dump_D3DVIEWPORT2(lpData);
    }

    This->use_vp2 = 1;
    memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
    memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
433 434 435 436 437 438 439 440

    if (This->active_device) {
      IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
      if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
        This->activate(This);
      IDirect3DViewport3_Release(current_viewport);
    }

441
    return DD_OK;
442 443
}

444 445 446
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
                                                 LPDIRECTDRAWSURFACE4 lpDDS)
447
{
448 449 450
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
    return DD_OK;
451 452
}

453 454 455 456
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
                                                 LPDIRECTDRAWSURFACE4* lplpDDS,
                                                 LPBOOL lpValid)
457
{
458 459 460 461
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
    return DD_OK;
}
462

463 464 465 466 467 468 469 470 471 472 473
HRESULT WINAPI
Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
                                    DWORD dwCount,
                                    LPD3DRECT lpRects,
                                    DWORD dwFlags,
                                    DWORD dwColor,
                                    D3DVALUE dvZ,
                                    DWORD dwStencil)
{
    ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
    TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
474 475 476
    if (This->active_device == NULL) {
        ERR(" Trying to clear a viewport not attached to a device !\n");
	return D3DERR_VIEWPORTHASNODEVICE;
477
    }
478
    return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
479 480
}

481 482 483 484 485
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)     (typeof(VTABLE_IDirect3DViewport3.fun))
#else
# define XCAST(fun)     (void*)
#endif
486

487
static const IDirect3DViewport3Vtbl VTABLE_IDirect3DViewport3 =
488
{
489 490 491 492 493 494 495 496 497 498 499 500
    XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface,
    XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef,
    XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release,
    XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize,
    XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport,
    XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport,
    XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices,
    XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements,
    XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground,
    XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground,
    XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth,
    XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth,
501
    XCAST(Clear) Main_IDirect3DViewportImpl_3_2_1_Clear,
502 503 504 505 506 507 508
    XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight,
    XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight,
    XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight,
    XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2,
    XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2,
    XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2,
    XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2,
509
    XCAST(Clear2) Main_IDirect3DViewportImpl_3_Clear2,
510
};
511

512 513 514
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
#undef XCAST
#endif
515

516 517 518



519
HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d)
520
{
521
    IDirect3DViewportImpl *object;
522

523 524
    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
    if (object == NULL) return DDERR_OUTOFMEMORY;
525

526 527 528 529 530 531
    object->ref = 1;
    object->d3d = d3d;
    object->activate = activate;
    object->use_vp2 = 0xFF;
    object->next = NULL;
    object->lights = NULL;
532 533
    object->num_lights = 0;
    object->map_lights = 0;
534 535
    
    ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
536

537
    *obj = object;
538

539 540 541 542
    TRACE(" creating implementation at %p.\n", *obj);
    
    return D3D_OK;
}