Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenvertexbuffer.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
1.7.6.1
|