ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

viewport.c
Go to the documentation of this file.
00001 /* Direct3D Viewport
00002  * Copyright (c) 1998 Lionel ULMER
00003  * Copyright (c) 2006-2007 Stefan DÖSINGER
00004  *
00005  * This file contains the implementation of Direct3DViewport2.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "config.h"
00023 #include "wine/port.h"
00024 
00025 #include "ddraw_private.h"
00026 
00027 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
00028 
00029 /*****************************************************************************
00030  * Helper functions
00031  *****************************************************************************/
00032 
00033 static void update_clip_space(IDirect3DDeviceImpl *device,
00034         struct wined3d_vec3 *scale, struct wined3d_vec3 *offset)
00035 {
00036     D3DMATRIX clip_space =
00037     {
00038         scale->x,  0.0f,      0.0f,      0.0f,
00039         0.0f,      scale->y,  0.0f,      0.0f,
00040         0.0f,      0.0f,      scale->z,  0.0f,
00041         offset->x, offset->y, offset->z, 1.0f,
00042     };
00043     D3DMATRIX projection;
00044     HRESULT hr;
00045 
00046     multiply_matrix(&projection, &clip_space, &device->legacy_projection);
00047     hr = wined3d_device_set_transform(device->wined3d_device,
00048             WINED3D_TS_PROJECTION, (struct wined3d_matrix *)&projection);
00049     if (SUCCEEDED(hr))
00050         device->legacy_clipspace = clip_space;
00051 }
00052 
00053 /*****************************************************************************
00054  * viewport_activate
00055  *
00056  * activates the viewport using IDirect3DDevice7::SetViewport
00057  *
00058  *****************************************************************************/
00059 void viewport_activate(IDirect3DViewportImpl *This, BOOL ignore_lights)
00060 {
00061     struct wined3d_vec3 scale, offset;
00062     D3DVIEWPORT7 vp;
00063 
00064     if (!ignore_lights)
00065     {
00066         IDirect3DLightImpl *light;
00067 
00068         /* Activate all the lights associated with this context */
00069         LIST_FOR_EACH_ENTRY(light, &This->light_list, IDirect3DLightImpl, entry)
00070         {
00071             light_activate(light);
00072         }
00073     }
00074 
00075     /* And copy the values in the structure used by the device */
00076     if (This->use_vp2)
00077     {
00078         vp.dwX = This->viewports.vp2.dwX;
00079         vp.dwY = This->viewports.vp2.dwY;
00080         vp.dwHeight = This->viewports.vp2.dwHeight;
00081         vp.dwWidth = This->viewports.vp2.dwWidth;
00082         vp.dvMinZ = 0.0f;
00083         vp.dvMaxZ = 1.0f;
00084 
00085         scale.x = 2.0f / This->viewports.vp2.dvClipWidth;
00086         scale.y = 2.0f / This->viewports.vp2.dvClipHeight;
00087         scale.z = 1.0f / (This->viewports.vp2.dvMaxZ - This->viewports.vp2.dvMinZ);
00088         offset.x = -2.0f * This->viewports.vp2.dvClipX / This->viewports.vp2.dvClipWidth - 1.0f;
00089         offset.y = -2.0f * This->viewports.vp2.dvClipY / This->viewports.vp2.dvClipHeight + 1.0f;
00090         offset.z = -This->viewports.vp2.dvMinZ / (This->viewports.vp2.dvMaxZ - This->viewports.vp2.dvMinZ);
00091     }
00092     else
00093     {
00094         vp.dwX = This->viewports.vp1.dwX;
00095         vp.dwY = This->viewports.vp1.dwY;
00096         vp.dwHeight = This->viewports.vp1.dwHeight;
00097         vp.dwWidth = This->viewports.vp1.dwWidth;
00098         vp.dvMinZ = 0.0f;
00099         vp.dvMaxZ = 1.0f;
00100 
00101         scale.x = 2.0f * This->viewports.vp1.dvScaleX / This->viewports.vp1.dwWidth;
00102         scale.y = 2.0f * This->viewports.vp1.dvScaleY / This->viewports.vp1.dwHeight;
00103         scale.z = 1.0f;
00104         offset.x = 0.0f;
00105         offset.y = 0.0f;
00106         offset.z = 0.0f;
00107     }
00108 
00109     update_clip_space(This->active_device, &scale, &offset);
00110     IDirect3DDevice7_SetViewport(&This->active_device->IDirect3DDevice7_iface, &vp);
00111 }
00112 
00113 /*****************************************************************************
00114  * _dump_D3DVIEWPORT, _dump_D3DVIEWPORT2
00115  *
00116  * Writes viewport information to TRACE
00117  *
00118  *****************************************************************************/
00119 static void _dump_D3DVIEWPORT(const D3DVIEWPORT *lpvp)
00120 {
00121     TRACE("    - dwSize = %d   dwX = %d   dwY = %d\n",
00122             lpvp->dwSize, lpvp->dwX, lpvp->dwY);
00123     TRACE("    - dwWidth = %d   dwHeight = %d\n",
00124             lpvp->dwWidth, lpvp->dwHeight);
00125     TRACE("    - dvScaleX = %f   dvScaleY = %f\n",
00126             lpvp->dvScaleX, lpvp->dvScaleY);
00127     TRACE("    - dvMaxX = %f   dvMaxY = %f\n",
00128             lpvp->dvMaxX, lpvp->dvMaxY);
00129     TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
00130             lpvp->dvMinZ, lpvp->dvMaxZ);
00131 }
00132 
00133 static void _dump_D3DVIEWPORT2(const D3DVIEWPORT2 *lpvp)
00134 {
00135     TRACE("    - dwSize = %d   dwX = %d   dwY = %d\n",
00136             lpvp->dwSize, lpvp->dwX, lpvp->dwY);
00137     TRACE("    - dwWidth = %d   dwHeight = %d\n",
00138             lpvp->dwWidth, lpvp->dwHeight);
00139     TRACE("    - dvClipX = %f   dvClipY = %f\n",
00140             lpvp->dvClipX, lpvp->dvClipY);
00141     TRACE("    - dvClipWidth = %f   dvClipHeight = %f\n",
00142             lpvp->dvClipWidth, lpvp->dvClipHeight);
00143     TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
00144             lpvp->dvMinZ, lpvp->dvMaxZ);
00145 }
00146 
00147 static inline IDirect3DViewportImpl *impl_from_IDirect3DViewport3(IDirect3DViewport3 *iface)
00148 {
00149     return CONTAINING_RECORD(iface, IDirect3DViewportImpl, IDirect3DViewport3_iface);
00150 }
00151 
00152 /*****************************************************************************
00153  * IUnknown Methods.
00154  *****************************************************************************/
00155 
00156 /*****************************************************************************
00157  * IDirect3DViewport3::QueryInterface
00158  *
00159  * A normal QueryInterface. Can query all interface versions and the
00160  * IUnknown interface. The VTables of the different versions
00161  * are equal
00162  *
00163  * Params:
00164  *  refiid: Interface id queried for
00165  *  obj: Address to write the interface pointer to
00166  *
00167  * Returns:
00168  *  S_OK on success.
00169  *  E_NOINTERFACE if the requested interface wasn't found
00170  *
00171  *****************************************************************************/
00172 static HRESULT WINAPI IDirect3DViewportImpl_QueryInterface(IDirect3DViewport3 *iface, REFIID riid, void **object)
00173 {
00174     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
00175 
00176     if (IsEqualGUID(&IID_IDirect3DViewport3, riid)
00177             || IsEqualGUID(&IID_IDirect3DViewport2, riid)
00178             || IsEqualGUID(&IID_IDirect3DViewport, riid)
00179             || IsEqualGUID(&IID_IUnknown, riid))
00180     {
00181         IDirect3DViewport3_AddRef(iface);
00182         *object = iface;
00183         return S_OK;
00184     }
00185 
00186     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
00187 
00188     *object = NULL;
00189     return E_NOINTERFACE;
00190 }
00191 
00192 /*****************************************************************************
00193  * IDirect3DViewport3::AddRef
00194  *
00195  * Increases the refcount.
00196  *
00197  * Returns:
00198  *  The new refcount
00199  *
00200  *****************************************************************************/
00201 static ULONG WINAPI
00202 IDirect3DViewportImpl_AddRef(IDirect3DViewport3 *iface)
00203 {
00204     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00205     ULONG ref = InterlockedIncrement(&This->ref);
00206 
00207     TRACE("%p increasing refcount to %u.\n", This, ref);
00208 
00209     return ref;
00210 }
00211 
00212 /*****************************************************************************
00213  * IDirect3DViewport3::Release
00214  *
00215  * Reduces the refcount. If it falls to 0, the interface is released
00216  *
00217  * Returns:
00218  *  The new refcount
00219  *
00220  *****************************************************************************/
00221 static ULONG WINAPI
00222 IDirect3DViewportImpl_Release(IDirect3DViewport3 *iface)
00223 {
00224     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00225     ULONG ref = InterlockedDecrement(&This->ref);
00226 
00227     TRACE("%p decreasing refcount to %u.\n", This, ref);
00228 
00229     if (!ref) {
00230         HeapFree(GetProcessHeap(), 0, This);
00231         return 0;
00232     }
00233     return ref;
00234 }
00235 
00236 /*****************************************************************************
00237  * IDirect3DViewport Methods.
00238  *****************************************************************************/
00239 
00240 /*****************************************************************************
00241  * IDirect3DViewport3::Initialize
00242  *
00243  * No-op initialization.
00244  *
00245  * Params:
00246  *  Direct3D: The direct3D device this viewport is assigned to
00247  *
00248  * Returns:
00249  *  DDERR_ALREADYINITIALIZED
00250  *
00251  *****************************************************************************/
00252 static HRESULT WINAPI
00253 IDirect3DViewportImpl_Initialize(IDirect3DViewport3 *iface,
00254                                  IDirect3D *Direct3D)
00255 {
00256     TRACE("iface %p, d3d %p.\n", iface, Direct3D);
00257 
00258     return DDERR_ALREADYINITIALIZED;
00259 }
00260 
00261 /*****************************************************************************
00262  * IDirect3DViewport3::GetViewport
00263  *
00264  * Returns the viewport data assigned to this viewport interface
00265  *
00266  * Params:
00267  *  Data: Address to store the data
00268  *
00269  * Returns:
00270  *  D3D_OK on success
00271  *  DDERR_INVALIDPARAMS if Data is NULL
00272  *
00273  *****************************************************************************/
00274 static HRESULT WINAPI
00275 IDirect3DViewportImpl_GetViewport(IDirect3DViewport3 *iface,
00276                                   D3DVIEWPORT *lpData)
00277 {
00278     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00279     DWORD dwSize;
00280 
00281     TRACE("iface %p, data %p.\n", iface, lpData);
00282 
00283     wined3d_mutex_lock();
00284 
00285     dwSize = lpData->dwSize;
00286     memset(lpData, 0, dwSize);
00287     if (!This->use_vp2)
00288         memcpy(lpData, &(This->viewports.vp1), dwSize);
00289     else {
00290         D3DVIEWPORT vp1;
00291         vp1.dwSize = sizeof(vp1);
00292         vp1.dwX = This->viewports.vp2.dwX;
00293         vp1.dwY = This->viewports.vp2.dwY;
00294         vp1.dwWidth = This->viewports.vp2.dwWidth;
00295         vp1.dwHeight = This->viewports.vp2.dwHeight;
00296         vp1.dvMaxX = 0.0;
00297         vp1.dvMaxY = 0.0;
00298         vp1.dvScaleX = 0.0;
00299         vp1.dvScaleY = 0.0;
00300         vp1.dvMinZ = This->viewports.vp2.dvMinZ;
00301         vp1.dvMaxZ = This->viewports.vp2.dvMaxZ;
00302         memcpy(lpData, &vp1, dwSize);
00303     }
00304 
00305     if (TRACE_ON(ddraw))
00306     {
00307         TRACE("  returning D3DVIEWPORT :\n");
00308         _dump_D3DVIEWPORT(lpData);
00309     }
00310 
00311     wined3d_mutex_unlock();
00312 
00313     return DD_OK;
00314 }
00315 
00316 /*****************************************************************************
00317  * IDirect3DViewport3::SetViewport
00318  *
00319  * Sets the viewport information for this interface
00320  *
00321  * Params:
00322  *  lpData: Viewport to set
00323  *
00324  * Returns:
00325  *  D3D_OK on success
00326  *  DDERR_INVALIDPARAMS if Data is NULL
00327  *
00328  *****************************************************************************/
00329 static HRESULT WINAPI
00330 IDirect3DViewportImpl_SetViewport(IDirect3DViewport3 *iface,
00331                                   D3DVIEWPORT *lpData)
00332 {
00333     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00334     IDirect3DViewport3 *current_viewport;
00335 
00336     TRACE("iface %p, data %p.\n", iface, lpData);
00337 
00338     if (TRACE_ON(ddraw))
00339     {
00340         TRACE("  getting D3DVIEWPORT :\n");
00341         _dump_D3DVIEWPORT(lpData);
00342     }
00343 
00344     wined3d_mutex_lock();
00345 
00346     This->use_vp2 = 0;
00347     memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
00348     memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
00349 
00350     /* Tests on two games show that these values are never used properly so override
00351        them with proper ones :-)
00352     */
00353     This->viewports.vp1.dvMinZ = 0.0;
00354     This->viewports.vp1.dvMaxZ = 1.0;
00355 
00356     if (This->active_device) {
00357         IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
00358         IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
00359         if (current_viewport)
00360         {
00361             if (current_viewport == iface) viewport_activate(This, FALSE);
00362             IDirect3DViewport3_Release(current_viewport);
00363         }
00364     }
00365 
00366     wined3d_mutex_unlock();
00367 
00368     return DD_OK;
00369 }
00370 
00371 /*****************************************************************************
00372  * IDirect3DViewport3::TransformVertices
00373  *
00374  * Transforms vertices by the transformation matrix.
00375  *
00376  * This function is pretty similar to IDirect3DVertexBuffer7::ProcessVertices,
00377  * so it's tempting to forward it to there. However, there are some
00378  * tiny differences. First, the lpOffscreen flag that is reported back,
00379  * then there is the homogeneous vertex that is generated. Also there's a lack
00380  * of FVFs, but still a custom stride. Last, the d3d1 - d3d3 viewport has some
00381  * settings (scale) that d3d7 and wined3d do not have. All in all wrapping to
00382  * ProcessVertices doesn't pay of in terms of wrapper code needed and code
00383  * reused.
00384  *
00385  * Params:
00386  *  dwVertexCount: The number of vertices to be transformed
00387  *  lpData: Pointer to the vertex data
00388  *  dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED
00389  *  lpOffScreen: Set to the clipping plane clipping the vertex, if only one
00390  *               vertex is transformed and clipping is on. 0 otherwise
00391  *
00392  * Returns:
00393  *  D3D_OK on success
00394  *  D3DERR_VIEWPORTHASNODEVICE if the viewport is not assigned to a device
00395  *  DDERR_INVALIDPARAMS if no clipping flag is specified
00396  *
00397  *****************************************************************************/
00398 static HRESULT WINAPI
00399 IDirect3DViewportImpl_TransformVertices(IDirect3DViewport3 *iface,
00400                                         DWORD dwVertexCount,
00401                                         D3DTRANSFORMDATA *lpData,
00402                                         DWORD dwFlags,
00403                                         DWORD *lpOffScreen)
00404 {
00405     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00406     D3DMATRIX view_mat, world_mat, mat;
00407     float *in;
00408     float *out;
00409     float x, y, z, w;
00410     unsigned int i;
00411     D3DVIEWPORT vp = This->viewports.vp1;
00412     D3DHVERTEX *outH;
00413 
00414     TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, clip_plane %p.\n",
00415             iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
00416 
00417     /* Tests on windows show that Windows crashes when this occurs,
00418      * so don't return the (intuitive) return value
00419     if(!This->active_device)
00420     {
00421         WARN("No device active, returning D3DERR_VIEWPORTHASNODEVICE\n");
00422         return D3DERR_VIEWPORTHASNODEVICE;
00423     }
00424      */
00425 
00426     if(!(dwFlags & (D3DTRANSFORM_UNCLIPPED | D3DTRANSFORM_CLIPPED)))
00427     {
00428         WARN("No clipping flag passed, returning DDERR_INVALIDPARAMS\n");
00429         return DDERR_INVALIDPARAMS;
00430     }
00431 
00432 
00433     wined3d_mutex_lock();
00434     wined3d_device_get_transform(This->active_device->wined3d_device,
00435             D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat);
00436     wined3d_device_get_transform(This->active_device->wined3d_device,
00437             WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat);
00438     multiply_matrix(&mat, &view_mat, &world_mat);
00439     multiply_matrix(&mat, &This->active_device->legacy_projection, &mat);
00440 
00441     in = lpData->lpIn;
00442     out = lpData->lpOut;
00443     outH = lpData->lpHOut;
00444     for(i = 0; i < dwVertexCount; i++)
00445     {
00446         x = (in[0] * mat._11) + (in[1] * mat._21) + (in[2] * mat._31) + (1.0 * mat._41);
00447         y = (in[0] * mat._12) + (in[1] * mat._22) + (in[2] * mat._32) + (1.0 * mat._42);
00448         z = (in[0] * mat._13) + (in[1] * mat._23) + (in[2] * mat._33) + (1.0 * mat._43);
00449         w = (in[0] * mat._14) + (in[1] * mat._24) + (in[2] * mat._34) + (1.0 * mat._44);
00450 
00451         if(dwFlags & D3DTRANSFORM_CLIPPED)
00452         {
00453             /* If clipping is enabled, Windows assumes that outH is
00454              * a valid pointer
00455              */
00456             outH[i].u1.hx = x; outH[i].u2.hy = y; outH[i].u3.hz = z;
00457 
00458             outH[i].dwFlags = 0;
00459             if(x * vp.dvScaleX > ((float) vp.dwWidth * 0.5))
00460                 outH[i].dwFlags |= D3DCLIP_RIGHT;
00461             if(x * vp.dvScaleX <= -((float) vp.dwWidth) * 0.5)
00462                 outH[i].dwFlags |= D3DCLIP_LEFT;
00463             if(y * vp.dvScaleY > ((float) vp.dwHeight * 0.5))
00464                 outH[i].dwFlags |= D3DCLIP_TOP;
00465             if(y * vp.dvScaleY <= -((float) vp.dwHeight) * 0.5)
00466                 outH[i].dwFlags |= D3DCLIP_BOTTOM;
00467             if(z < 0.0)
00468                 outH[i].dwFlags |= D3DCLIP_FRONT;
00469             if(z > 1.0)
00470                 outH[i].dwFlags |= D3DCLIP_BACK;
00471 
00472             if(outH[i].dwFlags)
00473             {
00474                 /* Looks like native just drops the vertex, leaves whatever data
00475                  * it has in the output buffer and goes on with the next vertex.
00476                  * The exact scheme hasn't been figured out yet, but windows
00477                  * definitely writes something there.
00478                  */
00479                 out[0] = x;
00480                 out[1] = y;
00481                 out[2] = z;
00482                 out[3] = w;
00483                 in = (float *) ((char *) in + lpData->dwInSize);
00484                 out = (float *) ((char *) out + lpData->dwOutSize);
00485                 continue;
00486             }
00487         }
00488 
00489         w = 1 / w;
00490         x *= w; y *= w; z *= w;
00491 
00492         out[0] = vp.dwWidth / 2 + vp.dwX + x * vp.dvScaleX;
00493         out[1] = vp.dwHeight / 2 + vp.dwY - y * vp.dvScaleY;
00494         out[2] = z;
00495         out[3] = w;
00496         in = (float *) ((char *) in + lpData->dwInSize);
00497         out = (float *) ((char *) out + lpData->dwOutSize);
00498     }
00499 
00500     /* According to the d3d test, the offscreen flag is set only
00501      * if exactly one vertex is transformed. Its not documented,
00502      * but the test shows that the lpOffscreen flag is set to the
00503      * flag combination of clipping planes that clips the vertex.
00504      *
00505      * If clipping is requested, Windows assumes that the offscreen
00506      * param is a valid pointer.
00507      */
00508     if(dwVertexCount == 1 && dwFlags & D3DTRANSFORM_CLIPPED)
00509     {
00510         *lpOffScreen = outH[0].dwFlags;
00511     }
00512     else if(*lpOffScreen)
00513     {
00514         *lpOffScreen = 0;
00515     }
00516     wined3d_mutex_unlock();
00517 
00518     TRACE("All done\n");
00519     return DD_OK;
00520 }
00521 
00522 /*****************************************************************************
00523  * IDirect3DViewport3::LightElements
00524  *
00525  * The DirectX 5.0 sdk says that it's not implemented
00526  *
00527  * Params:
00528  *  ?
00529  *
00530  * Returns:
00531  *  DDERR_UNSUPPORTED
00532  *
00533  *****************************************************************************/
00534 static HRESULT WINAPI
00535 IDirect3DViewportImpl_LightElements(IDirect3DViewport3 *iface,
00536                                     DWORD dwElementCount,
00537                                     LPD3DLIGHTDATA lpData)
00538 {
00539     TRACE("iface %p, element_count %u, data %p.\n", iface, dwElementCount, lpData);
00540 
00541     return DDERR_UNSUPPORTED;
00542 }
00543 
00544 /*****************************************************************************
00545  * IDirect3DViewport3::SetBackground
00546  *
00547  * Sets tje background material
00548  *
00549  * Params:
00550  *  hMat: Handle from a IDirect3DMaterial interface
00551  *
00552  * Returns:
00553  *  D3D_OK on success
00554  *
00555  *****************************************************************************/
00556 static HRESULT WINAPI
00557 IDirect3DViewportImpl_SetBackground(IDirect3DViewport3 *iface,
00558                                     D3DMATERIALHANDLE hMat)
00559 {
00560     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00561     IDirect3DMaterialImpl *m;
00562 
00563     TRACE("iface %p, material %#x.\n", iface, hMat);
00564 
00565     wined3d_mutex_lock();
00566 
00567     if (!hMat)
00568     {
00569         This->background = NULL;
00570         TRACE("Setting background to NULL\n");
00571         wined3d_mutex_unlock();
00572         return D3D_OK;
00573     }
00574 
00575     m = ddraw_get_object(&This->ddraw->d3ddevice->handle_table, hMat - 1, DDRAW_HANDLE_MATERIAL);
00576     if (!m)
00577     {
00578         WARN("Invalid material handle.\n");
00579         wined3d_mutex_unlock();
00580         return DDERR_INVALIDPARAMS;
00581     }
00582 
00583     TRACE("Setting background color : %.8e %.8e %.8e %.8e.\n",
00584             m->mat.u.diffuse.u1.r, m->mat.u.diffuse.u2.g,
00585             m->mat.u.diffuse.u3.b, m->mat.u.diffuse.u4.a);
00586     This->background = m;
00587 
00588     wined3d_mutex_unlock();
00589 
00590     return D3D_OK;
00591 }
00592 
00593 /*****************************************************************************
00594  * IDirect3DViewport3::GetBackground
00595  *
00596  * Returns the material handle assigned to the background of the viewport
00597  *
00598  * Params:
00599  *  lphMat: Address to store the handle
00600  *  lpValid: is set to FALSE if no background is set, TRUE if one is set
00601  *
00602  * Returns:
00603  *  D3D_OK
00604  *
00605  *****************************************************************************/
00606 static HRESULT WINAPI
00607 IDirect3DViewportImpl_GetBackground(IDirect3DViewport3 *iface,
00608                                     D3DMATERIALHANDLE *lphMat,
00609                                     BOOL *lpValid)
00610 {
00611     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00612 
00613     TRACE("iface %p, material %p, valid %p.\n", iface, lphMat, lpValid);
00614 
00615     wined3d_mutex_lock();
00616     if(lpValid)
00617     {
00618         *lpValid = This->background != NULL;
00619     }
00620     if(lphMat)
00621     {
00622         if(This->background)
00623         {
00624             *lphMat = This->background->Handle;
00625         }
00626         else
00627         {
00628             *lphMat = 0;
00629         }
00630     }
00631     wined3d_mutex_unlock();
00632 
00633     return D3D_OK;
00634 }
00635 
00636 /*****************************************************************************
00637  * IDirect3DViewport3::SetBackgroundDepth
00638  *
00639  * Sets a surface that represents the background depth. It's contents are
00640  * used to set the depth buffer in IDirect3DViewport3::Clear
00641  *
00642  * Params:
00643  *  lpDDSurface: Surface to set
00644  *
00645  * Returns: D3D_OK, because it's a stub
00646  *
00647  *****************************************************************************/
00648 static HRESULT WINAPI
00649 IDirect3DViewportImpl_SetBackgroundDepth(IDirect3DViewport3 *iface,
00650                                          IDirectDrawSurface *lpDDSurface)
00651 {
00652     FIXME("iface %p, surface %p stub!\n", iface, lpDDSurface);
00653 
00654     return D3D_OK;
00655 }
00656 
00657 /*****************************************************************************
00658  * IDirect3DViewport3::GetBackgroundDepth
00659  *
00660  * Returns the surface that represents the depth field
00661  *
00662  * Params:
00663  *  lplpDDSurface: Address to store the interface pointer
00664  *  lpValid: Set to TRUE if a depth is assigned, FALSE otherwise
00665  *
00666  * Returns:
00667  *  D3D_OK, because it's a stub
00668  *  (DDERR_INVALIDPARAMS if DDSurface of Valid is NULL)
00669  *
00670  *****************************************************************************/
00671 static HRESULT WINAPI
00672 IDirect3DViewportImpl_GetBackgroundDepth(IDirect3DViewport3 *iface,
00673                                          IDirectDrawSurface **lplpDDSurface,
00674                                          LPBOOL lpValid)
00675 {
00676     FIXME("iface %p, surface %p, valid %p stub!\n", iface, lplpDDSurface, lpValid);
00677 
00678     return DD_OK;
00679 }
00680 
00681 /*****************************************************************************
00682  * IDirect3DViewport3::Clear
00683  *
00684  * Clears the render target and / or the z buffer
00685  *
00686  * Params:
00687  *  dwCount: The amount of rectangles to clear. If 0, the whole buffer is
00688  *           cleared
00689  *  lpRects: Pointer to the array of rectangles. If NULL, Count must be 0
00690  *  dwFlags: D3DCLEAR_ZBUFFER and / or D3DCLEAR_TARGET
00691  *
00692  * Returns:
00693  *  D3D_OK on success
00694  *  D3DERR_VIEWPORTHASNODEVICE if there's no active device
00695  *  The return value of IDirect3DDevice7::Clear
00696  *
00697  *****************************************************************************/
00698 static HRESULT WINAPI IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface,
00699         DWORD dwCount, D3DRECT *lpRects, DWORD dwFlags)
00700 {
00701     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00702     DWORD color = 0x00000000;
00703     HRESULT hr;
00704     IDirect3DViewport3 *current_viewport;
00705     IDirect3DDevice3 *d3d_device3;
00706 
00707     TRACE("iface %p, rect_count %u, rects %p, flags %#x.\n", iface, dwCount, lpRects, dwFlags);
00708 
00709     if (This->active_device == NULL) {
00710         ERR(" Trying to clear a viewport not attached to a device !\n");
00711         return D3DERR_VIEWPORTHASNODEVICE;
00712     }
00713     d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
00714 
00715     wined3d_mutex_lock();
00716 
00717     if (dwFlags & D3DCLEAR_TARGET) {
00718         if (This->background == NULL) {
00719             ERR(" Trying to clear the color buffer without background material !\n");
00720         }
00721         else
00722         {
00723             color = ((int)((This->background->mat.u.diffuse.u1.r) * 255) << 16)
00724                     | ((int) ((This->background->mat.u.diffuse.u2.g) * 255) <<  8)
00725                     | ((int) ((This->background->mat.u.diffuse.u3.b) * 255) <<  0)
00726                     | ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
00727         }
00728     }
00729 
00730     /* Need to temporarily activate viewport to clear it. Previously active one will be restored
00731         afterwards. */
00732     viewport_activate(This, TRUE);
00733 
00734     hr = IDirect3DDevice7_Clear(&This->active_device->IDirect3DDevice7_iface, dwCount, lpRects,
00735             dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET), color, 1.0, 0x00000000);
00736 
00737     IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
00738     if(current_viewport) {
00739         IDirect3DViewportImpl *vp = impl_from_IDirect3DViewport3(current_viewport);
00740         viewport_activate(vp, TRUE);
00741         IDirect3DViewport3_Release(current_viewport);
00742     }
00743 
00744     wined3d_mutex_unlock();
00745 
00746     return hr;
00747 }
00748 
00749 /*****************************************************************************
00750  * IDirect3DViewport3::AddLight
00751  *
00752  * Adds an light to the viewport
00753  *
00754  * Params:
00755  *  lpDirect3DLight: Interface of the light to add
00756  *
00757  * Returns:
00758  *  D3D_OK on success
00759  *  DDERR_INVALIDPARAMS if Direct3DLight is NULL
00760  *  DDERR_INVALIDPARAMS if there are 8 lights or more
00761  *
00762  *****************************************************************************/
00763 static HRESULT WINAPI IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface,
00764         IDirect3DLight *lpDirect3DLight)
00765 {
00766     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00767     IDirect3DLightImpl *lpDirect3DLightImpl = unsafe_impl_from_IDirect3DLight(lpDirect3DLight);
00768     DWORD i = 0;
00769     DWORD map = This->map_lights;
00770 
00771     TRACE("iface %p, light %p.\n", iface, lpDirect3DLight);
00772 
00773     wined3d_mutex_lock();
00774 
00775     if (This->num_lights >= 8)
00776     {
00777         wined3d_mutex_unlock();
00778         return DDERR_INVALIDPARAMS;
00779     }
00780 
00781     /* Find a light number and update both light and viewports objects accordingly */
00782     while (map & 1)
00783     {
00784         map >>= 1;
00785         ++i;
00786     }
00787     lpDirect3DLightImpl->dwLightIndex = i;
00788     This->num_lights++;
00789     This->map_lights |= 1<<i;
00790 
00791     /* Add the light in the 'linked' chain */
00792     list_add_head(&This->light_list, &lpDirect3DLightImpl->entry);
00793     IDirect3DLight_AddRef(lpDirect3DLight);
00794 
00795     /* Attach the light to the viewport */
00796     lpDirect3DLightImpl->active_viewport = This;
00797 
00798     /* If active, activate the light */
00799     if (This->active_device)
00800         light_activate(lpDirect3DLightImpl);
00801 
00802     wined3d_mutex_unlock();
00803 
00804     return D3D_OK;
00805 }
00806 
00807 /*****************************************************************************
00808  * IDirect3DViewport3::DeleteLight
00809  *
00810  * Deletes a light from the viewports' light list
00811  *
00812  * Params:
00813  *  lpDirect3DLight: Light to delete
00814  *
00815  * Returns:
00816  *  D3D_OK on success
00817  *  DDERR_INVALIDPARAMS if the light wasn't found
00818  *
00819  *****************************************************************************/
00820 static HRESULT WINAPI IDirect3DViewportImpl_DeleteLight(IDirect3DViewport3 *iface,
00821         IDirect3DLight *lpDirect3DLight)
00822 {
00823     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00824     IDirect3DLightImpl *l = unsafe_impl_from_IDirect3DLight(lpDirect3DLight);
00825 
00826     TRACE("iface %p, light %p.\n", iface, lpDirect3DLight);
00827 
00828     wined3d_mutex_lock();
00829 
00830     if (l->active_viewport != This)
00831     {
00832         WARN("Light %p active viewport is %p.\n", l, l->active_viewport);
00833         wined3d_mutex_unlock();
00834         return DDERR_INVALIDPARAMS;
00835     }
00836 
00837     light_deactivate(l);
00838     list_remove(&l->entry);
00839     l->active_viewport = NULL;
00840     IDirect3DLight_Release(lpDirect3DLight);
00841     --This->num_lights;
00842     This->map_lights &= ~(1 << l->dwLightIndex);
00843 
00844     wined3d_mutex_unlock();
00845 
00846     return D3D_OK;
00847 }
00848 
00849 /*****************************************************************************
00850  * IDirect3DViewport::NextLight
00851  *
00852  * Enumerates the lights associated with the viewport
00853  *
00854  * Params:
00855  *  lpDirect3DLight: Light to start with
00856  *  lplpDirect3DLight: Address to store the successor to
00857  *
00858  * Returns:
00859  *  D3D_OK, because it's a stub
00860  *
00861  *****************************************************************************/
00862 static HRESULT WINAPI IDirect3DViewportImpl_NextLight(IDirect3DViewport3 *iface,
00863         IDirect3DLight *lpDirect3DLight, IDirect3DLight **lplpDirect3DLight, DWORD dwFlags)
00864 {
00865     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00866     IDirect3DLightImpl *l = unsafe_impl_from_IDirect3DLight(lpDirect3DLight);
00867     struct list *entry;
00868     HRESULT hr;
00869 
00870     TRACE("iface %p, light %p, next_light %p, flags %#x.\n",
00871             iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
00872 
00873     if (!lplpDirect3DLight)
00874         return DDERR_INVALIDPARAMS;
00875 
00876     wined3d_mutex_lock();
00877 
00878     switch (dwFlags)
00879     {
00880         case D3DNEXT_NEXT:
00881             if (!l || l->active_viewport != This)
00882             {
00883                 if (l)
00884                     WARN("Light %p active viewport is %p.\n", l, l->active_viewport);
00885                 entry = NULL;
00886             }
00887             else
00888                 entry = list_next(&This->light_list, &l->entry);
00889             break;
00890 
00891         case D3DNEXT_HEAD:
00892             entry = list_head(&This->light_list);
00893             break;
00894 
00895         case D3DNEXT_TAIL:
00896             entry = list_tail(&This->light_list);
00897             break;
00898 
00899         default:
00900             entry = NULL;
00901             WARN("Invalid flags %#x.\n", dwFlags);
00902             break;
00903     }
00904 
00905     if (entry)
00906     {
00907         *lplpDirect3DLight = (IDirect3DLight *)LIST_ENTRY(entry, IDirect3DLightImpl, entry);
00908         IDirect3DLight_AddRef(*lplpDirect3DLight);
00909         hr = D3D_OK;
00910     }
00911     else
00912     {
00913         *lplpDirect3DLight = NULL;
00914         hr = DDERR_INVALIDPARAMS;
00915     }
00916 
00917     wined3d_mutex_unlock();
00918 
00919     return hr;
00920 }
00921 
00922 /*****************************************************************************
00923  * IDirect3DViewport2 Methods.
00924  *****************************************************************************/
00925 
00926 /*****************************************************************************
00927  * IDirect3DViewport3::GetViewport2
00928  *
00929  * Returns the currently set viewport in a D3DVIEWPORT2 structure.
00930  * Similar to IDirect3DViewport3::GetViewport
00931  *
00932  * Params:
00933  *  lpData: Pointer to the structure to fill
00934  *
00935  * Returns:
00936  *  D3D_OK on success
00937  *  DDERR_INVALIDPARAMS if the viewport was set with
00938  *                      IDirect3DViewport3::SetViewport
00939  *  DDERR_INVALIDPARAMS if Data is NULL
00940  *
00941  *****************************************************************************/
00942 static HRESULT WINAPI
00943 IDirect3DViewportImpl_GetViewport2(IDirect3DViewport3 *iface,
00944                                    D3DVIEWPORT2 *lpData)
00945 {
00946     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
00947     DWORD dwSize;
00948 
00949     TRACE("iface %p, data %p.\n", iface, lpData);
00950 
00951     wined3d_mutex_lock();
00952     dwSize = lpData->dwSize;
00953     memset(lpData, 0, dwSize);
00954     if (This->use_vp2)
00955         memcpy(lpData, &(This->viewports.vp2), dwSize);
00956     else {
00957         D3DVIEWPORT2 vp2;
00958         vp2.dwSize = sizeof(vp2);
00959         vp2.dwX = This->viewports.vp1.dwX;
00960         vp2.dwY = This->viewports.vp1.dwY;
00961         vp2.dwWidth = This->viewports.vp1.dwWidth;
00962         vp2.dwHeight = This->viewports.vp1.dwHeight;
00963         vp2.dvClipX = 0.0;
00964         vp2.dvClipY = 0.0;
00965         vp2.dvClipWidth = 0.0;
00966         vp2.dvClipHeight = 0.0;
00967         vp2.dvMinZ = This->viewports.vp1.dvMinZ;
00968         vp2.dvMaxZ = This->viewports.vp1.dvMaxZ;
00969         memcpy(lpData, &vp2, dwSize);
00970     }
00971 
00972     if (TRACE_ON(ddraw))
00973     {
00974         TRACE("  returning D3DVIEWPORT2 :\n");
00975         _dump_D3DVIEWPORT2(lpData);
00976     }
00977 
00978     wined3d_mutex_unlock();
00979 
00980     return D3D_OK;
00981 }
00982 
00983 /*****************************************************************************
00984  * IDirect3DViewport3::SetViewport2
00985  *
00986  * Sets the viewport from a D3DVIEWPORT2 structure
00987  *
00988  * Params:
00989  *  lpData: Viewport to set
00990  *
00991  * Returns:
00992  *  D3D_OK on success
00993  *
00994  *****************************************************************************/
00995 static HRESULT WINAPI
00996 IDirect3DViewportImpl_SetViewport2(IDirect3DViewport3 *iface,
00997                                    D3DVIEWPORT2 *lpData)
00998 {
00999     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
01000     IDirect3DViewport3 *current_viewport;
01001 
01002     TRACE("iface %p, data %p.\n", iface, lpData);
01003 
01004     if (TRACE_ON(ddraw))
01005     {
01006         TRACE("  getting D3DVIEWPORT2 :\n");
01007         _dump_D3DVIEWPORT2(lpData);
01008     }
01009 
01010     wined3d_mutex_lock();
01011 
01012     This->use_vp2 = 1;
01013     memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
01014     memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
01015 
01016     if (This->active_device) {
01017         IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
01018         IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
01019         if (current_viewport)
01020         {
01021             if (current_viewport == iface) viewport_activate(This, FALSE);
01022             IDirect3DViewport3_Release(current_viewport);
01023         }
01024     }
01025 
01026     wined3d_mutex_unlock();
01027 
01028     return D3D_OK;
01029 }
01030 
01031 /*****************************************************************************
01032  * IDirect3DViewport3 Methods.
01033  *****************************************************************************/
01034 
01035 /*****************************************************************************
01036  * IDirect3DViewport3::SetBackgroundDepth2
01037  *
01038  * Sets a IDirectDrawSurface4 surface as the background depth surface
01039  *
01040  * Params:
01041  *  lpDDS: Surface to set
01042  *
01043  * Returns:
01044  *  D3D_OK, because it's stub
01045  *
01046  *****************************************************************************/
01047 static HRESULT WINAPI
01048 IDirect3DViewportImpl_SetBackgroundDepth2(IDirect3DViewport3 *iface,
01049                                           IDirectDrawSurface4 *lpDDS)
01050 {
01051     FIXME("iface %p, surface %p stub!\n", iface, lpDDS);
01052 
01053     return D3D_OK;
01054 }
01055 
01056 /*****************************************************************************
01057  * IDirect3DViewport3::GetBackgroundDepth2
01058  *
01059  * Returns the IDirect3DSurface4 interface to the background depth surface
01060  *
01061  * Params:
01062  *  lplpDDS: Address to store the interface pointer at
01063  *  lpValid: Set to true if a surface is assigned
01064  *
01065  * Returns:
01066  *  D3D_OK because it's a stub
01067  *
01068  *****************************************************************************/
01069 static HRESULT WINAPI
01070 IDirect3DViewportImpl_GetBackgroundDepth2(IDirect3DViewport3 *iface,
01071                                           IDirectDrawSurface4 **lplpDDS,
01072                                           BOOL *lpValid)
01073 {
01074     FIXME("iface %p, surface %p, valid %p stub!\n", iface, lplpDDS, lpValid);
01075 
01076     return D3D_OK;
01077 }
01078 
01079 /*****************************************************************************
01080  * IDirect3DViewport3::Clear2
01081  *
01082  * Another clearing method
01083  *
01084  * Params:
01085  *  Count: Number of rectangles to clear
01086  *  Rects: Rectangle array to clear
01087  *  Flags: Some flags :)
01088  *  Color: Color to fill the render target with
01089  *  Z: Value to fill the depth buffer with
01090  *  Stencil: Value to fill the stencil bits with
01091  *
01092  * Returns:
01093  *
01094  *****************************************************************************/
01095 static HRESULT WINAPI
01096 IDirect3DViewportImpl_Clear2(IDirect3DViewport3 *iface,
01097                              DWORD dwCount,
01098                              LPD3DRECT lpRects,
01099                              DWORD dwFlags,
01100                              DWORD dwColor,
01101                              D3DVALUE dvZ,
01102                              DWORD dwStencil)
01103 {
01104     IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface);
01105     HRESULT hr;
01106     IDirect3DViewport3 *current_viewport;
01107     IDirect3DDevice3 *d3d_device3;
01108 
01109     TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, depth %.8e, stencil %u.\n",
01110             iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
01111 
01112     wined3d_mutex_lock();
01113 
01114     if (This->active_device == NULL) {
01115         ERR(" Trying to clear a viewport not attached to a device !\n");
01116         wined3d_mutex_unlock();
01117         return D3DERR_VIEWPORTHASNODEVICE;
01118     }
01119     d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
01120     /* Need to temporarily activate viewport to clear it. Previously active
01121      * one will be restored afterwards. */
01122     viewport_activate(This, TRUE);
01123 
01124     hr = IDirect3DDevice7_Clear(&This->active_device->IDirect3DDevice7_iface,
01125             dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
01126     IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
01127     if(current_viewport) {
01128         IDirect3DViewportImpl *vp = impl_from_IDirect3DViewport3(current_viewport);
01129         viewport_activate(vp, TRUE);
01130         IDirect3DViewport3_Release(current_viewport);
01131     }
01132 
01133     wined3d_mutex_unlock();
01134 
01135     return hr;
01136 }
01137 
01138 /*****************************************************************************
01139  * The VTable
01140  *****************************************************************************/
01141 
01142 static const struct IDirect3DViewport3Vtbl d3d_viewport_vtbl =
01143 {
01144     /*** IUnknown Methods ***/
01145     IDirect3DViewportImpl_QueryInterface,
01146     IDirect3DViewportImpl_AddRef,
01147     IDirect3DViewportImpl_Release,
01148     /*** IDirect3DViewport Methods */
01149     IDirect3DViewportImpl_Initialize,
01150     IDirect3DViewportImpl_GetViewport,
01151     IDirect3DViewportImpl_SetViewport,
01152     IDirect3DViewportImpl_TransformVertices,
01153     IDirect3DViewportImpl_LightElements,
01154     IDirect3DViewportImpl_SetBackground,
01155     IDirect3DViewportImpl_GetBackground,
01156     IDirect3DViewportImpl_SetBackgroundDepth,
01157     IDirect3DViewportImpl_GetBackgroundDepth,
01158     IDirect3DViewportImpl_Clear,
01159     IDirect3DViewportImpl_AddLight,
01160     IDirect3DViewportImpl_DeleteLight,
01161     IDirect3DViewportImpl_NextLight,
01162     /*** IDirect3DViewport2 Methods ***/
01163     IDirect3DViewportImpl_GetViewport2,
01164     IDirect3DViewportImpl_SetViewport2,
01165     /*** IDirect3DViewport3 Methods ***/
01166     IDirect3DViewportImpl_SetBackgroundDepth2,
01167     IDirect3DViewportImpl_GetBackgroundDepth2,
01168     IDirect3DViewportImpl_Clear2,
01169 };
01170 
01171 IDirect3DViewportImpl *unsafe_impl_from_IDirect3DViewport3(IDirect3DViewport3 *iface)
01172 {
01173     if (!iface) return NULL;
01174     assert(iface->lpVtbl == &d3d_viewport_vtbl);
01175     return CONTAINING_RECORD(iface, IDirect3DViewportImpl, IDirect3DViewport3_iface);
01176 }
01177 
01178 IDirect3DViewportImpl *unsafe_impl_from_IDirect3DViewport2(IDirect3DViewport2 *iface)
01179 {
01180     /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */
01181     if (!iface) return NULL;
01182     assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl);
01183     return CONTAINING_RECORD(iface, IDirect3DViewportImpl, IDirect3DViewport3_iface);
01184 }
01185 
01186 IDirect3DViewportImpl *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface)
01187 {
01188     /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */
01189     if (!iface) return NULL;
01190     assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl);
01191     return CONTAINING_RECORD(iface, IDirect3DViewportImpl, IDirect3DViewport3_iface);
01192 }
01193 
01194 void d3d_viewport_init(IDirect3DViewportImpl *viewport, IDirectDrawImpl *ddraw)
01195 {
01196     viewport->IDirect3DViewport3_iface.lpVtbl = &d3d_viewport_vtbl;
01197     viewport->ref = 1;
01198     viewport->ddraw = ddraw;
01199     viewport->use_vp2 = 0xff;
01200     list_init(&viewport->light_list);
01201 }

Generated on Sun May 27 2012 04:22:17 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.