- implement the texturing the D3D3 way
[wine] / dlls / ddraw / d3dvertexbuffer.c
1 /* Direct3D Viewport
2  * Copyright (c) 2002 Lionel ULMER
3  *
4  * This file contains the implementation of Direct3DVertexBuffer COM object
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "windef.h"
23 #include "winerror.h"
24 #include "wine/obj_base.h"
25 #include "ddraw.h"
26 #include "d3d.h"
27 #include "wine/debug.h"
28
29 #include "d3d_private.h"
30 #include "mesa_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
33
34 HRESULT WINAPI
35 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
36                                                    REFIID riid,
37                                                    LPVOID* obp)
38 {
39     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
40     TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
41
42     /* By default, set the object pointer to NULL */
43     *obp = NULL;
44       
45     if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
46         IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
47         *obp = iface;
48         TRACE("  Creating IUnknown interface at %p.\n", *obp);
49         return S_OK;
50     }
51     if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
52         IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
53         *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
54         TRACE("  Creating IDirect3DVertexBuffer interface %p\n", *obp);
55         return S_OK;
56     }
57     if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
58         IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
59         *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
60         TRACE("  Creating IDirect3DVertexBuffer7 interface %p\n", *obp);
61         return S_OK;
62     }
63     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
64     return OLE_E_ENUM_NOMORE;
65 }
66
67 ULONG WINAPI
68 Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
69 {
70     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
71     TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
72     return ++(This->ref);
73 }
74
75 ULONG WINAPI
76 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
77 {
78     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
79     TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
80     if (--(This->ref) == 0) {
81         HeapFree(GetProcessHeap(), 0, This);
82         return 0;
83     }
84     return This->ref;
85 }
86
87 HRESULT WINAPI
88 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
89                                          DWORD dwFlags,
90                                          LPVOID* lplpData,
91                                          LPDWORD lpdwSize)
92 {
93     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
94     TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
95
96     if (TRACE_ON(ddraw)) {
97         TRACE(" lock flags : ");
98         DDRAW_dump_lockflag(dwFlags);
99     }
100     
101     if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
102     *lplpData = This->vertices;
103     
104     return DD_OK;
105 }
106
107 HRESULT WINAPI
108 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
109 {
110     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
111     FIXME("(%p/%p)->(): stub!\n", This, iface);
112     return DD_OK;
113 }
114
115 HRESULT WINAPI
116 Main_IDirect3DVertexBufferImpl_7_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
117                                                  DWORD dwVertexOp,
118                                                  DWORD dwDestIndex,
119                                                  DWORD dwCount,
120                                                  LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
121                                                  DWORD dwSrcIndex,
122                                                  LPDIRECT3DDEVICE7 lpD3DDevice,
123                                                  DWORD dwFlags)
124 {
125     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
126     FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
127     return DD_OK;
128 }
129
130 HRESULT WINAPI
131 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
132                                                         LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
133 {
134     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
135     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DVertexBufferDesc);
136     return DD_OK;
137 }
138
139 HRESULT WINAPI
140 Main_IDirect3DVertexBufferImpl_7_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
141                                           LPDIRECT3DDEVICE7 lpD3DDevice,
142                                           DWORD dwFlags)
143 {
144     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
145     FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
146     return DD_OK;
147 }
148
149 HRESULT WINAPI
150 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
151                                                         DWORD dwVertexOp,
152                                                         DWORD dwDestIndex,
153                                                         DWORD dwCount,
154                                                         LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
155                                                         DWORD dwVertexTypeDesc,
156                                                         LPDIRECT3DDEVICE7 lpD3DDevice,
157                                                         DWORD dwFlags)
158 {
159     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
160     FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
161     return DD_OK;
162 }
163
164 HRESULT WINAPI
165 Main_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
166                                                  DWORD dwVertexOp,
167                                                  DWORD dwDestIndex,
168                                                  DWORD dwCount,
169                                                  LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
170                                                  DWORD dwSrcIndex,
171                                                  LPDIRECT3DDEVICE3 lpD3DDevice,
172                                                  DWORD dwFlags)
173 {
174     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
175     FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
176     return DD_OK;
177 }
178
179 HRESULT WINAPI
180 Main_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
181                                           LPDIRECT3DDEVICE3 lpD3DDevice,
182                                           DWORD dwFlags)
183 {
184     ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface);
185     FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
186     return DD_OK;
187 }
188
189 HRESULT WINAPI
190 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
191                                                  REFIID riid,
192                                                  LPVOID* obp)
193 {
194     TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
195     return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
196                                                  riid,
197                                                  obp);
198 }
199
200 ULONG WINAPI
201 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
202 {
203     TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
204     return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
205 }
206
207 ULONG WINAPI
208 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
209 {
210     TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
211     return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
212 }
213
214 HRESULT WINAPI
215 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
216                                        DWORD dwFlags,
217                                        LPVOID* lplpData,
218                                        LPDWORD lpdwSize)
219 {
220     TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
221     return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
222                                        dwFlags,
223                                        lplpData,
224                                        lpdwSize);
225 }
226
227 HRESULT WINAPI
228 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
229 {
230     TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
231     return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
232 }
233
234 HRESULT WINAPI
235 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
236                                                       LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
237 {
238     TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
239     return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
240                                                       lpD3DVertexBufferDesc);
241 }
242
243 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
244 # define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
245 #else
246 # define XCAST(fun)     (void*)
247 #endif
248
249 ICOM_VTABLE(IDirect3DVertexBuffer7) VTABLE_IDirect3DVertexBuffer7 =
250 {
251     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
252     XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
253     XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
254     XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
255     XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
256     XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
257     XCAST(ProcessVertices) Main_IDirect3DVertexBufferImpl_7_ProcessVertices,
258     XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
259     XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_Optimize,
260     XCAST(ProcessVerticesStrided) Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided,
261 };
262
263 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
264 #undef XCAST
265 #endif
266
267
268 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
269 # define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer.fun))
270 #else
271 # define XCAST(fun)     (void*)
272 #endif
273
274 ICOM_VTABLE(IDirect3DVertexBuffer) VTABLE_IDirect3DVertexBuffer =
275 {
276     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
277     XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
278     XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
279     XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
280     XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
281     XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
282     XCAST(ProcessVertices) Main_IDirect3DVertexBufferImpl_1_ProcessVertices,
283     XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
284     XCAST(Optimize) Main_IDirect3DVertexBufferImpl_1_Optimize,
285 };
286
287 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
288 #undef XCAST
289 #endif
290
291 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
292 {
293     IDirect3DVertexBufferImpl *object;
294     static const flag_info flags[] = {
295         FE(D3DVBCAPS_OPTIMIZED),
296         FE(D3DVBCAPS_SYSTEMMEMORY),
297         FE(D3DVBCAPS_WRITEONLY)
298     };
299
300     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferImpl));
301     if (object == NULL) return DDERR_OUTOFMEMORY;
302
303     object->ref = 1;
304     object->d3d = d3d;
305     object->desc = *lpD3DVertBufDesc;
306     object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
307     object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
308     
309     ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer,  VTABLE_IDirect3DVertexBuffer);
310     ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
311
312     *obj = object;
313
314     if (TRACE_ON(ddraw)) {
315         TRACE(" creating implementation at %p with description : \n", *obj);
316         TRACE("  - "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
317         TRACE("  - "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
318         TRACE("  - %ld\n", lpD3DVertBufDesc->dwNumVertices);
319     }
320     
321     
322     return D3D_OK;
323 }