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

vertexbuffer.c
Go to the documentation of this file.
00001 /* Direct3D Vertex Buffer
00002  * Copyright (c) 2002 Lionel ULMER
00003  * Copyright (c) 2006 Stefan DÖSINGER
00004  *
00005  * This file contains the implementation of Direct3DVertexBuffer COM object
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 static inline IDirect3DVertexBufferImpl *impl_from_IDirect3DVertexBuffer(IDirect3DVertexBuffer *iface)
00030 {
00031     return CONTAINING_RECORD(iface, IDirect3DVertexBufferImpl, IDirect3DVertexBuffer_iface);
00032 }
00033 
00034 static inline IDirect3DVertexBufferImpl *impl_from_IDirect3DVertexBuffer7(IDirect3DVertexBuffer7 *iface)
00035 {
00036     return CONTAINING_RECORD(iface, IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7_iface);
00037 }
00038 
00039 /*****************************************************************************
00040  * IUnknown Methods
00041  *****************************************************************************/
00042 
00043 /*****************************************************************************
00044  * IDirect3DVertexBuffer7::QueryInterface
00045  *
00046  * The QueryInterface Method for Vertex Buffers
00047  * For a link to QueryInterface rules, see IDirectDraw7::QueryInterface
00048  *
00049  * Params
00050  *  riid: Queried Interface id
00051  *  obj: Address to return the interface pointer
00052  *
00053  * Returns:
00054  *  S_OK on success
00055  *  E_NOINTERFACE if the interface wasn't found
00056  *
00057  *****************************************************************************/
00058 static HRESULT WINAPI IDirect3DVertexBufferImpl_QueryInterface(IDirect3DVertexBuffer7 *iface,
00059         REFIID riid, void  **obj)
00060 {
00061     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00062 
00063     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
00064 
00065     /* By default, set the object pointer to NULL */
00066     *obj = NULL;
00067 
00068     if ( IsEqualGUID( &IID_IUnknown,  riid ) )
00069     {
00070         IUnknown_AddRef(iface);
00071         *obj = iface;
00072         TRACE("  Creating IUnknown interface at %p.\n", *obj);
00073         return S_OK;
00074     }
00075     if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) )
00076     {
00077         IUnknown_AddRef(iface);
00078         *obj = &This->IDirect3DVertexBuffer_iface;
00079         TRACE("  Creating IDirect3DVertexBuffer interface %p\n", *obj);
00080         return S_OK;
00081     }
00082     if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) )
00083     {
00084         IUnknown_AddRef(iface);
00085         *obj = iface;
00086         TRACE("  Creating IDirect3DVertexBuffer7 interface %p\n", *obj);
00087         return S_OK;
00088     }
00089     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
00090     return E_NOINTERFACE;
00091 }
00092 
00093 static HRESULT WINAPI IDirect3DVertexBufferImpl_1_QueryInterface(IDirect3DVertexBuffer *iface,
00094         REFIID riid, void **obj)
00095 {
00096     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00097 
00098     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
00099 
00100     return IDirect3DVertexBuffer7_QueryInterface(&This->IDirect3DVertexBuffer7_iface, riid, obj);
00101 }
00102 
00103 /*****************************************************************************
00104  * IDirect3DVertexBuffer7::AddRef
00105  *
00106  * AddRef for Vertex Buffers
00107  *
00108  * Returns:
00109  *  The new refcount
00110  *
00111  *****************************************************************************/
00112 static ULONG WINAPI IDirect3DVertexBufferImpl_AddRef(IDirect3DVertexBuffer7 *iface)
00113 {
00114     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00115     ULONG ref = InterlockedIncrement(&This->ref);
00116 
00117     TRACE("%p increasing refcount to %u.\n", This, ref);
00118 
00119     return ref;
00120 }
00121 
00122 static ULONG WINAPI IDirect3DVertexBufferImpl_1_AddRef(IDirect3DVertexBuffer *iface)
00123 {
00124     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00125 
00126     TRACE("iface %p.\n", iface);
00127 
00128     return IDirect3DVertexBuffer7_AddRef(&This->IDirect3DVertexBuffer7_iface);
00129 }
00130 
00131 
00132 /*****************************************************************************
00133  * IDirect3DVertexBuffer7::Release
00134  *
00135  * Release for Vertex Buffers
00136  *
00137  * Returns:
00138  *  The new refcount
00139  *
00140  *****************************************************************************/
00141 static ULONG WINAPI IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface)
00142 {
00143     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00144     ULONG ref = InterlockedDecrement(&This->ref);
00145 
00146     TRACE("%p decreasing refcount to %u.\n", This, ref);
00147 
00148     if (ref == 0)
00149     {
00150         struct wined3d_buffer *curVB = NULL;
00151         UINT offset, stride;
00152 
00153         /* D3D7 Vertex buffers don't stay bound in the device, they are passed
00154          * as a parameter to drawPrimitiveVB. DrawPrimitiveVB sets them as the
00155          * stream source in wined3d, and they should get unset there before
00156          * they are destroyed. */
00157         wined3d_mutex_lock();
00158         wined3d_device_get_stream_source(This->ddraw->wined3d_device,
00159                 0, &curVB, &offset, &stride);
00160         if (curVB == This->wineD3DVertexBuffer)
00161             wined3d_device_set_stream_source(This->ddraw->wined3d_device, 0, NULL, 0, 0);
00162         if (curVB)
00163             wined3d_buffer_decref(curVB); /* For the GetStreamSource */
00164 
00165         wined3d_vertex_declaration_decref(This->wineD3DVertexDeclaration);
00166         wined3d_buffer_decref(This->wineD3DVertexBuffer);
00167         wined3d_mutex_unlock();
00168 
00169         HeapFree(GetProcessHeap(), 0, This);
00170 
00171         return 0;
00172     }
00173     return ref;
00174 }
00175 
00176 static ULONG WINAPI IDirect3DVertexBufferImpl_1_Release(IDirect3DVertexBuffer *iface)
00177 {
00178     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00179 
00180     TRACE("iface %p.\n", iface);
00181 
00182     return IDirect3DVertexBuffer7_Release(&This->IDirect3DVertexBuffer7_iface);
00183 }
00184 
00185 /*****************************************************************************
00186  * IDirect3DVertexBuffer Methods
00187  *****************************************************************************/
00188 
00189 /*****************************************************************************
00190  * IDirect3DVertexBuffer7::Lock
00191  *
00192  * Locks the vertex buffer and returns a pointer to the vertex data
00193  * Locking vertex buffers is similar to locking surfaces, because Windows
00194  * uses surfaces to store vertex data internally (According to the DX sdk)
00195  *
00196  * Params:
00197  *  Flags: Locking flags. Relevant here are DDLOCK_READONLY, DDLOCK_WRITEONLY,
00198  *         DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE.
00199  *  Data:  Returns a pointer to the vertex data
00200  *  Size:  Returns the size of the buffer if not NULL
00201  *
00202  * Returns:
00203  *  D3D_OK on success
00204  *  DDERR_INVALIDPARAMS if Data is NULL
00205  *  D3DERR_VERTEXBUFFEROPTIMIZED if called on an optimized buffer(WineD3D)
00206  *
00207  *****************************************************************************/
00208 static HRESULT WINAPI IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface, DWORD Flags,
00209         void **Data, DWORD *Size)
00210 {
00211     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00212     struct wined3d_resource_desc wined3d_desc;
00213     struct wined3d_resource *wined3d_resource;
00214     HRESULT hr;
00215     DWORD wined3d_flags = 0;
00216 
00217     TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, Flags, Data, Size);
00218 
00219     /* Writeonly: Pointless. Event: Unsupported by native according to the sdk
00220      * nosyslock: Not applicable
00221      */
00222     if(!(Flags & DDLOCK_WAIT))          wined3d_flags |= WINED3DLOCK_DONOTWAIT;
00223     if(Flags & DDLOCK_READONLY)         wined3d_flags |= WINED3DLOCK_READONLY;
00224     if(Flags & DDLOCK_NOOVERWRITE)      wined3d_flags |= WINED3DLOCK_NOOVERWRITE;
00225     if(Flags & DDLOCK_DISCARDCONTENTS)  wined3d_flags |= WINED3DLOCK_DISCARD;
00226 
00227     wined3d_mutex_lock();
00228     if(Size)
00229     {
00230         /* Get the size, for returning it, and for locking */
00231         wined3d_resource = wined3d_buffer_get_resource(This->wineD3DVertexBuffer);
00232         wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
00233         *Size = wined3d_desc.size;
00234     }
00235 
00236     hr = wined3d_buffer_map(This->wineD3DVertexBuffer, 0, 0, (BYTE **)Data, wined3d_flags);
00237     wined3d_mutex_unlock();
00238 
00239     return hr;
00240 }
00241 
00242 static HRESULT WINAPI IDirect3DVertexBufferImpl_1_Lock(IDirect3DVertexBuffer *iface, DWORD Flags,
00243         void **Data, DWORD *Size)
00244 {
00245     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00246 
00247     TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, Flags, Data, Size);
00248 
00249     return IDirect3DVertexBuffer7_Lock(&This->IDirect3DVertexBuffer7_iface, Flags, Data, Size);
00250 }
00251 
00252 /*****************************************************************************
00253  * IDirect3DVertexBuffer7::Unlock
00254  *
00255  * Unlocks a vertex Buffer
00256  *
00257  * Returns:
00258  *  D3D_OK on success
00259  *
00260  *****************************************************************************/
00261 static HRESULT WINAPI IDirect3DVertexBufferImpl_Unlock(IDirect3DVertexBuffer7 *iface)
00262 {
00263     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00264 
00265     TRACE("iface %p.\n", iface);
00266 
00267     wined3d_mutex_lock();
00268     wined3d_buffer_unmap(This->wineD3DVertexBuffer);
00269     wined3d_mutex_unlock();
00270 
00271     return D3D_OK;
00272 }
00273 
00274 static HRESULT WINAPI IDirect3DVertexBufferImpl_1_Unlock(IDirect3DVertexBuffer *iface)
00275 {
00276     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00277 
00278     TRACE("iface %p.\n", iface);
00279 
00280     return IDirect3DVertexBuffer7_Unlock(&This->IDirect3DVertexBuffer7_iface);
00281 }
00282 
00283 
00284 /*****************************************************************************
00285  * IDirect3DVertexBuffer7::ProcessVertices
00286  *
00287  * Processes untransformed Vertices into a transformed or optimized vertex
00288  * buffer. It can also perform other operations, such as lighting or clipping
00289  *
00290  * Params
00291  *  VertexOp: Operation(s) to perform: D3DVOP_CLIP, _EXTENTS, _LIGHT, _TRANSFORM
00292  *  DestIndex: Index in the destination buffer(This), where the vertices are
00293  *             placed
00294  *  Count: Number of Vertices in the Source buffer to process
00295  *  SrcBuffer: Source vertex buffer
00296  *  SrcIndex: Index of the first vertex in the src buffer to process
00297  *  D3DDevice: Device to use for transformation
00298  *  Flags: 0 for default, D3DPV_DONOTCOPYDATA to prevent copying
00299  *         unchaned vertices
00300  *
00301  * Returns:
00302  *  D3D_OK on success
00303  *  DDERR_INVALIDPARAMS If D3DVOP_TRANSFORM wasn't passed
00304  *
00305  *****************************************************************************/
00306 static HRESULT WINAPI IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface,
00307         DWORD VertexOp, DWORD DestIndex, DWORD Count, IDirect3DVertexBuffer7 *SrcBuffer,
00308         DWORD SrcIndex, IDirect3DDevice7 *device, DWORD Flags)
00309 {
00310     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00311     IDirect3DVertexBufferImpl *Src = unsafe_impl_from_IDirect3DVertexBuffer7(SrcBuffer);
00312     IDirect3DDeviceImpl *device_impl = unsafe_impl_from_IDirect3DDevice7(device);
00313     BOOL oldClip, doClip;
00314     HRESULT hr;
00315 
00316     TRACE("iface %p, vertex_op %#x, dst_idx %u, count %u, src_buffer %p, src_idx %u, device %p, flags %#x.\n",
00317             iface, VertexOp, DestIndex, Count, SrcBuffer, SrcIndex, device, Flags);
00318 
00319     /* Vertex operations:
00320      * D3DVOP_CLIP: Clips vertices outside the viewing frustrum. Needs clipping information
00321      * in the vertex buffer (Buffer may not be created with D3DVBCAPS_DONOTCLIP)
00322      * D3DVOP_EXTENTS: Causes the screen extents to be updated when rendering the vertices
00323      * D3DVOP_LIGHT: Lights the vertices
00324      * D3DVOP_TRANSFORM: Transform the vertices. This flag is necessary
00325      *
00326      * WineD3D only transforms and clips the vertices by now, so EXTENTS and LIGHT
00327      * are not implemented. Clipping is disabled ATM, because of unsure conditions.
00328      */
00329     if( !(VertexOp & D3DVOP_TRANSFORM) ) return DDERR_INVALIDPARAMS;
00330 
00331     wined3d_mutex_lock();
00332 
00333     /* WineD3D doesn't know d3d7 vertex operation, it uses
00334      * render states instead. Set the render states according to
00335      * the vertex ops
00336      */
00337     doClip = VertexOp & D3DVOP_CLIP ? TRUE : FALSE;
00338     wined3d_device_get_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, (DWORD *)&oldClip);
00339     if (doClip != oldClip)
00340         wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, doClip);
00341 
00342     wined3d_device_set_stream_source(device_impl->wined3d_device,
00343             0, Src->wineD3DVertexBuffer, 0, get_flexible_vertex_size(Src->fvf));
00344     wined3d_device_set_vertex_declaration(device_impl->wined3d_device, Src->wineD3DVertexDeclaration);
00345     hr = wined3d_device_process_vertices(device_impl->wined3d_device, SrcIndex, DestIndex,
00346             Count, This->wineD3DVertexBuffer, NULL, Flags, This->fvf);
00347 
00348     /* Restore the states if needed */
00349     if (doClip != oldClip)
00350         wined3d_device_set_render_state(device_impl->wined3d_device, WINED3D_RS_CLIPPING, oldClip);
00351 
00352     wined3d_mutex_unlock();
00353 
00354     return hr;
00355 }
00356 
00357 static HRESULT WINAPI IDirect3DVertexBufferImpl_1_ProcessVertices(IDirect3DVertexBuffer *iface,
00358         DWORD VertexOp, DWORD DestIndex, DWORD Count, IDirect3DVertexBuffer *SrcBuffer,
00359         DWORD SrcIndex, IDirect3DDevice3 *device, DWORD Flags)
00360 {
00361     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00362     IDirect3DVertexBufferImpl *Src = unsafe_impl_from_IDirect3DVertexBuffer(SrcBuffer);
00363     IDirect3DDeviceImpl *device_impl = unsafe_impl_from_IDirect3DDevice3(device);
00364 
00365     TRACE("iface %p, vertex_op %#x, dst_idx %u, count %u, src_buffer %p, src_idx %u, device %p, flags %#x.\n",
00366             iface, VertexOp, DestIndex, Count, SrcBuffer, SrcIndex, device, Flags);
00367 
00368     return IDirect3DVertexBuffer7_ProcessVertices(&This->IDirect3DVertexBuffer7_iface, VertexOp,
00369             DestIndex, Count, &Src->IDirect3DVertexBuffer7_iface, SrcIndex,
00370             device_impl ? &device_impl->IDirect3DDevice7_iface : NULL, Flags);
00371 }
00372 
00373 /*****************************************************************************
00374  * IDirect3DVertexBuffer7::GetVertexBufferDesc
00375  *
00376  * Returns the description of a vertex buffer
00377  *
00378  * Params:
00379  *  Desc: Address to write the description to
00380  *
00381  * Returns
00382  *  DDERR_INVALIDPARAMS if Desc is NULL
00383  *  D3D_OK on success
00384  *
00385  *****************************************************************************/
00386 static HRESULT WINAPI IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface,
00387         D3DVERTEXBUFFERDESC *Desc)
00388 {
00389     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00390     struct wined3d_resource_desc wined3d_desc;
00391     struct wined3d_resource *wined3d_resource;
00392 
00393     TRACE("iface %p, desc %p.\n", iface, Desc);
00394 
00395     if(!Desc) return DDERR_INVALIDPARAMS;
00396 
00397     wined3d_mutex_lock();
00398     wined3d_resource = wined3d_buffer_get_resource(This->wineD3DVertexBuffer);
00399     wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
00400     wined3d_mutex_unlock();
00401 
00402     /* Now fill the Desc structure */
00403     Desc->dwCaps = This->Caps;
00404     Desc->dwFVF = This->fvf;
00405     Desc->dwNumVertices = wined3d_desc.size / get_flexible_vertex_size(This->fvf);
00406 
00407     return D3D_OK;
00408 }
00409 
00410 static HRESULT WINAPI IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(IDirect3DVertexBuffer *iface,
00411         D3DVERTEXBUFFERDESC *Desc)
00412 {
00413     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00414 
00415     TRACE("iface %p, desc %p.\n", iface, Desc);
00416 
00417     return IDirect3DVertexBuffer7_GetVertexBufferDesc(&This->IDirect3DVertexBuffer7_iface, Desc);
00418 }
00419 
00420 
00421 /*****************************************************************************
00422  * IDirect3DVertexBuffer7::Optimize
00423  *
00424  * Converts an unoptimized vertex buffer into an optimized buffer
00425  *
00426  * Params:
00427  *  D3DDevice: Device for which this buffer is optimized
00428  *  Flags: Not used, should be set to 0
00429  *
00430  * Returns
00431  *  D3D_OK, because it's a stub
00432  *
00433  *****************************************************************************/
00434 static HRESULT WINAPI IDirect3DVertexBufferImpl_Optimize(IDirect3DVertexBuffer7 *iface,
00435         IDirect3DDevice7 *D3DDevice, DWORD Flags)
00436 {
00437     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
00438     static BOOL hide = FALSE;
00439 
00440     TRACE("iface %p, device %p, flags %#x.\n", iface, D3DDevice, Flags);
00441 
00442     if (!hide)
00443     {
00444         FIXME("iface %p, device %p, flags %#x stub!\n", iface, D3DDevice, Flags);
00445         hide = TRUE;
00446     }
00447 
00448     /* We could forward this call to WineD3D and take advantage
00449      * of it once we use OpenGL vertex buffers
00450      */
00451     wined3d_mutex_lock();
00452     This->Caps |= D3DVBCAPS_OPTIMIZED;
00453     wined3d_mutex_unlock();
00454 
00455     return DD_OK;
00456 }
00457 
00458 static HRESULT WINAPI IDirect3DVertexBufferImpl_1_Optimize(IDirect3DVertexBuffer *iface,
00459         IDirect3DDevice3 *device, DWORD Flags)
00460 {
00461     IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer(iface);
00462     IDirect3DDeviceImpl *device_impl = unsafe_impl_from_IDirect3DDevice3(device);
00463 
00464     TRACE("iface %p, device %p, flags %#x.\n", iface, device, Flags);
00465 
00466     return IDirect3DVertexBuffer7_Optimize(&This->IDirect3DVertexBuffer7_iface,
00467             device_impl ? &device_impl->IDirect3DDevice7_iface : NULL, Flags);
00468 }
00469 
00470 /*****************************************************************************
00471  * IDirect3DVertexBuffer7::ProcessVerticesStrided
00472  *
00473  * This method processes untransformed strided vertices into a processed
00474  * or optimized vertex buffer.
00475  *
00476  * For more details on the parameters, see
00477  * IDirect3DVertexBuffer7::ProcessVertices
00478  *
00479  * Params:
00480  *  VertexOp: Operations to perform
00481  *  DestIndex: Destination index to write the vertices to
00482  *  Count: Number of input vertices
00483  *  StrideData: Array containing the input vertices
00484  *  VertexTypeDesc: Vertex Description or source index?????????
00485  *  D3DDevice: IDirect3DDevice7 to use for processing
00486  *  Flags: Can be D3DPV_DONOTCOPYDATA to avoid copying unmodified vertices
00487  *
00488  * Returns
00489  *  D3D_OK on success, or DDERR_*
00490  *
00491  *****************************************************************************/
00492 static HRESULT WINAPI
00493 IDirect3DVertexBufferImpl_ProcessVerticesStrided(IDirect3DVertexBuffer7 *iface,
00494                                                  DWORD VertexOp,
00495                                                  DWORD DestIndex,
00496                                                  DWORD Count,
00497                                                  D3DDRAWPRIMITIVESTRIDEDDATA *StrideData,
00498                                                  DWORD VertexTypeDesc,
00499                                                  IDirect3DDevice7 *D3DDevice,
00500                                                  DWORD Flags)
00501 {
00502     FIXME("iface %p, vertex_op %#x, dst_idx %u, count %u, data %p, vertex_type %#x, device %p, flags %#x stub!\n",
00503             iface, VertexOp, DestIndex, Count, StrideData, VertexTypeDesc, D3DDevice, Flags);
00504 
00505     return DD_OK;
00506 }
00507 
00508 /*****************************************************************************
00509  * The VTables
00510  *****************************************************************************/
00511 
00512 static const struct IDirect3DVertexBuffer7Vtbl d3d_vertex_buffer7_vtbl =
00513 {
00514     /*** IUnknown Methods ***/
00515     IDirect3DVertexBufferImpl_QueryInterface,
00516     IDirect3DVertexBufferImpl_AddRef,
00517     IDirect3DVertexBufferImpl_Release,
00518     /*** IDirect3DVertexBuffer Methods ***/
00519     IDirect3DVertexBufferImpl_Lock,
00520     IDirect3DVertexBufferImpl_Unlock,
00521     IDirect3DVertexBufferImpl_ProcessVertices,
00522     IDirect3DVertexBufferImpl_GetVertexBufferDesc,
00523     IDirect3DVertexBufferImpl_Optimize,
00524     /*** IDirect3DVertexBuffer7 Methods ***/
00525     IDirect3DVertexBufferImpl_ProcessVerticesStrided
00526 };
00527 
00528 static const struct IDirect3DVertexBufferVtbl d3d_vertex_buffer1_vtbl =
00529 {
00530     /*** IUnknown Methods ***/
00531     IDirect3DVertexBufferImpl_1_QueryInterface,
00532     IDirect3DVertexBufferImpl_1_AddRef,
00533     IDirect3DVertexBufferImpl_1_Release,
00534     /*** IDirect3DVertexBuffer Methods ***/
00535     IDirect3DVertexBufferImpl_1_Lock,
00536     IDirect3DVertexBufferImpl_1_Unlock,
00537     IDirect3DVertexBufferImpl_1_ProcessVertices,
00538     IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
00539     IDirect3DVertexBufferImpl_1_Optimize
00540 };
00541 
00542 HRESULT d3d_vertex_buffer_create(IDirect3DVertexBufferImpl **vertex_buf, IDirectDrawImpl *ddraw,
00543         D3DVERTEXBUFFERDESC *desc)
00544 {
00545     IDirect3DVertexBufferImpl *buffer;
00546     DWORD usage;
00547     HRESULT hr = D3D_OK;
00548 
00549     TRACE("Vertex buffer description:\n");
00550     TRACE("    dwSize %u\n", desc->dwSize);
00551     TRACE("    dwCaps %#x\n", desc->dwCaps);
00552     TRACE("    FVF %#x\n", desc->dwFVF);
00553     TRACE("    dwNumVertices %u\n", desc->dwNumVertices);
00554 
00555     buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*buffer));
00556     if (!buffer)
00557         return DDERR_OUTOFMEMORY;
00558 
00559     buffer->IDirect3DVertexBuffer7_iface.lpVtbl = &d3d_vertex_buffer7_vtbl;
00560     buffer->IDirect3DVertexBuffer_iface.lpVtbl = &d3d_vertex_buffer1_vtbl;
00561     buffer->ref = 1;
00562 
00563     buffer->ddraw = ddraw;
00564     buffer->Caps = desc->dwCaps;
00565     buffer->fvf = desc->dwFVF;
00566 
00567     usage = desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0;
00568     usage |= WINED3DUSAGE_STATICDECL;
00569 
00570     wined3d_mutex_lock();
00571 
00572     hr = wined3d_buffer_create_vb(ddraw->wined3d_device,
00573             get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices,
00574             usage, desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3D_POOL_SYSTEM_MEM : WINED3D_POOL_DEFAULT,
00575             buffer, &ddraw_null_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
00576     if (FAILED(hr))
00577     {
00578         WARN("Failed to create wined3d vertex buffer, hr %#x.\n", hr);
00579         if (hr == WINED3DERR_INVALIDCALL)
00580             hr = DDERR_INVALIDPARAMS;
00581         goto end;
00582     }
00583 
00584     buffer->wineD3DVertexDeclaration = ddraw_find_decl(ddraw, desc->dwFVF);
00585     if (!buffer->wineD3DVertexDeclaration)
00586     {
00587         ERR("Failed to find vertex declaration for fvf %#x.\n", desc->dwFVF);
00588         wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
00589         hr = DDERR_INVALIDPARAMS;
00590         goto end;
00591     }
00592     wined3d_vertex_declaration_incref(buffer->wineD3DVertexDeclaration);
00593 
00594 end:
00595     wined3d_mutex_unlock();
00596     if (hr == D3D_OK)
00597         *vertex_buf = buffer;
00598     else
00599         HeapFree(GetProcessHeap(), 0, buffer);
00600 
00601     return hr;
00602 }
00603 
00604 IDirect3DVertexBufferImpl *unsafe_impl_from_IDirect3DVertexBuffer(IDirect3DVertexBuffer *iface)
00605 {
00606     if (!iface)
00607         return NULL;
00608     assert(iface->lpVtbl == &d3d_vertex_buffer1_vtbl);
00609 
00610     return impl_from_IDirect3DVertexBuffer(iface);
00611 }
00612 
00613 IDirect3DVertexBufferImpl *unsafe_impl_from_IDirect3DVertexBuffer7(IDirect3DVertexBuffer7 *iface)
00614 {
00615     if (!iface)
00616         return NULL;
00617     assert(iface->lpVtbl == &d3d_vertex_buffer7_vtbl);
00618 
00619     return impl_from_IDirect3DVertexBuffer7(iface);
00620 }

Generated on Fri May 25 2012 04:20:11 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.