1 /* Direct3D ExecuteBuffer
2 * Copyright (c) 1998 Lionel ULMER
4 * This file contains the implementation of Direct3DExecuteBuffer.
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.
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.
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
27 #include "wine/obj_base.h"
30 #include "wine/debug.h"
32 #include "mesa_private.h"
34 #define D3DDPRIVATE(x) mesa_d3dd_private *odev=((mesa_d3dd_private*)(x)->private)
36 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
38 /* Structure to store the 'semi transformed' vertices */
66 static ICOM_VTABLE(IDirect3DExecuteBuffer) executebuffer_vtable;
68 /*******************************************************************************
69 * ExecuteBuffer static functions
71 void _dump_d3dstatus(LPD3DSTATUS lpStatus) {
75 void _dump_executedata(LPD3DEXECUTEDATA lpData) {
76 DPRINTF("dwSize : %ld\n", lpData->dwSize);
77 DPRINTF("Vertex Offset : %ld Count : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount);
78 DPRINTF("Instruction Offset : %ld Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength);
79 DPRINTF("HVertex Offset : %ld\n", lpData->dwHVertexOffset);
80 _dump_d3dstatus(&(lpData->dsStatus));
83 #define DO_VERTEX(index) \
85 glTexCoord2f(vx[index].u, \
87 glNormal3f(vx[index].nx, \
90 glVertex4f(vx[index].x, \
95 TRACE(" V: %f %f %f %f (%f %f %f) (%f %f)\n", \
96 vx[index].x, vx[index].y, vx[index].z, vx[index].w, \
97 vx[index].nx, vx[index].ny, vx[index].nz, \
98 vx[index].u, vx[index].v); \
101 #define DO_LVERTEX(index) \
103 DWORD col = l_vx[index].c; \
105 glColor3f(((col >> 16) & 0xFF) / 255.0, \
106 ((col >> 8) & 0xFF) / 255.0, \
107 ((col >> 0) & 0xFF) / 255.0); \
108 glTexCoord2f(l_vx[index].u, \
110 glVertex4f(l_vx[index].x, \
115 TRACE(" LV: %f %f %f %f (%02lx %02lx %02lx) (%f %f)\n", \
116 l_vx[index].x, l_vx[index].y, l_vx[index].z, l_vx[index].w, \
117 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
118 l_vx[index].u, l_vx[index].v); \
121 #define DO_TLVERTEX(index) \
123 D3DTLVERTEX *vx = &(tl_vx[index]); \
124 DWORD col = vx->u5.color; \
126 glColor3f(((col >> 16) & 0xFF) / 255.0, \
127 ((col >> 8) & 0xFF) / 255.0, \
128 ((col >> 0) & 0xFF) / 255.0); \
129 glTexCoord2f(vx->u7.tu, vx->u8.tv); \
130 if (vx->u4.rhw < 0.01) \
131 glVertex3f(vx->u1.sx, \
135 glVertex4f(vx->u1.sx / vx->u4.rhw, \
136 vx->u2.sy / vx->u4.rhw, \
137 vx->u3.sz / vx->u4.rhw, \
139 TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", \
140 vx->u1.sx, vx->u2.sy, vx->u3.sz, \
141 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
142 vx->u7.tu, vx->u8.tv, vx->u4.rhw); \
145 #define TRIANGLE_LOOP(macro) \
147 glBegin(GL_TRIANGLES); { \
148 for (i = 0; i < count; i++) { \
149 LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr; \
151 TRACE(" v1: %d v2: %d v3: %d\n", \
152 ci->u1.v1, ci->u2.v2, ci->u3.v3); \
153 TRACE(" Flags : "); \
154 if (TRACE_ON(ddraw)) { \
156 if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1) \
157 DPRINTF("EDGEENABLE1 "); \
158 if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2) \
159 DPRINTF("EDGEENABLE2 "); \
160 if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1) \
161 DPRINTF("EDGEENABLE3 "); \
163 /* Strips / Fans */ \
164 if (ci->wFlags == D3DTRIFLAG_EVEN) \
166 if (ci->wFlags == D3DTRIFLAG_ODD) \
168 if (ci->wFlags == D3DTRIFLAG_START) \
170 if ((ci->wFlags > 0) && (ci->wFlags < 30)) \
171 DPRINTF("STARTFLAT(%d) ", ci->wFlags); \
175 /* Draw the triangle */ \
186 static void execute(LPDIRECT3DEXECUTEBUFFER lpBuff,
187 LPDIRECT3DDEVICE dev,
188 LPDIRECT3DVIEWPORT vp) {
189 IDirect3DExecuteBufferImpl* ilpBuff=(IDirect3DExecuteBufferImpl*)lpBuff;
190 IDirect3DViewport2Impl* ivp=(IDirect3DViewport2Impl*)vp;
191 /* DWORD bs = ilpBuff->desc.dwBufferSize; */
192 DWORD vs = ilpBuff->data.dwVertexOffset;
193 /* DWORD vc = ilpBuff->data.dwVertexCount; */
194 DWORD is = ilpBuff->data.dwInstructionOffset;
195 /* DWORD il = ilpBuff->data.dwInstructionLength; */
197 void *instr = ilpBuff->desc.lpData + is;
198 D3DDPRIVATE((IDirect3DDeviceImpl*)dev);
200 TRACE("ExecuteData : \n");
202 _dump_executedata(&(ilpBuff->data));
207 LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr;
211 count = current->wCount;
212 size = current->bSize;
213 instr += sizeof(D3DINSTRUCTION);
215 switch (current->bOpcode) {
217 TRACE("POINT-s (%d)\n", count);
219 instr += count * size;
223 TRACE("LINE-s (%d)\n", count);
225 instr += count * size;
228 case D3DOP_TRIANGLE: {
230 float z_inv_matrix[16] = {
237 OGL_Vertex *vx = (OGL_Vertex *) ilpBuff->vertex_data;
238 OGL_LVertex *l_vx = (OGL_LVertex *) ilpBuff->vertex_data;
239 D3DTLVERTEX *tl_vx = (D3DTLVERTEX *) ilpBuff->vertex_data;
241 TRACE("TRIANGLE (%d)\n", count);
243 switch (ilpBuff->vertex_type) {
245 /* This time, there is lighting */
246 glEnable(GL_LIGHTING);
248 /* Use given matrixes */
249 glMatrixMode(GL_MODELVIEW);
250 glLoadIdentity(); /* The model transformation was done during the
251 transformation phase */
252 glMatrixMode(GL_PROJECTION);
253 TRACE(" Projection Matrix : (%p)\n", odev->proj_mat);
254 dump_mat(odev->proj_mat);
255 TRACE(" View Matrix : (%p)\n", odev->view_mat);
256 dump_mat(odev->view_mat);
258 glLoadMatrixf((float *) z_inv_matrix);
259 glMultMatrixf((float *) odev->proj_mat);
260 glMultMatrixf((float *) odev->view_mat);
265 glDisable(GL_LIGHTING);
267 /* Use given matrixes */
268 glMatrixMode(GL_MODELVIEW);
269 glLoadIdentity(); /* The model transformation was done during the
270 transformation phase */
271 glMatrixMode(GL_PROJECTION);
273 TRACE(" Projection Matrix : (%p)\n", odev->proj_mat);
274 dump_mat(odev->proj_mat);
275 TRACE(" View Matrix : (%p)\n", odev->view_mat);
276 dump_mat(odev->view_mat);
278 glLoadMatrixf((float *) z_inv_matrix);
279 glMultMatrixf((float *) odev->proj_mat);
280 glMultMatrixf((float *) odev->view_mat);
283 case D3DVT_TLVERTEX: {
284 GLdouble height, width, minZ, maxZ;
286 /* First, disable lighting */
287 glDisable(GL_LIGHTING);
289 /* Then do not put any transformation matrixes */
290 glMatrixMode(GL_MODELVIEW);
292 glMatrixMode(GL_PROJECTION);
296 ERR("No current viewport !\n");
297 /* Using standard values */
303 height = (GLdouble) ivp->viewport.vp1.dwHeight;
304 width = (GLdouble) ivp->viewport.vp1.dwWidth;
305 minZ = (GLdouble) ivp->viewport.vp1.dvMinZ;
306 maxZ = (GLdouble) ivp->viewport.vp1.dvMaxZ;
309 /* I do not know why, but many Dx 3.0 games have minZ = maxZ = 0.0 */
315 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
319 ERR("Unhandled vertex type !\n");
323 switch (ilpBuff->vertex_type) {
325 TRIANGLE_LOOP(DO_VERTEX);
329 TRIANGLE_LOOP(DO_LVERTEX);
333 TRIANGLE_LOOP(DO_TLVERTEX);
337 ERR("Unhandled vertex type !\n");
342 case D3DOP_MATRIXLOAD: {
343 TRACE("MATRIXLOAD-s (%d)\n", count);
345 instr += count * size;
348 case D3DOP_MATRIXMULTIPLY: {
350 TRACE("MATRIXMULTIPLY (%d)\n", count);
352 for (i = 0; i < count; i++) {
353 LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr;
354 LPD3DMATRIX a = (LPD3DMATRIX) ci->hDestMatrix;
355 LPD3DMATRIX b = (LPD3DMATRIX) ci->hSrcMatrix1;
356 LPD3DMATRIX c = (LPD3DMATRIX) ci->hSrcMatrix2;
358 TRACE(" Dest : %08lx Src1 : %08lx Src2 : %08lx\n",
359 ci->hDestMatrix, ci->hSrcMatrix1, ci->hSrcMatrix2);
361 /* Do the multiplication..
362 As I am VERY lazy, I let OpenGL do the multiplication for me */
363 glMatrixMode(GL_PROJECTION);
364 /* Save the current matrix */
366 /* Load Matrix one and do the multiplication */
367 glLoadMatrixf((float *) c);
368 glMultMatrixf((float *) b);
369 glGetFloatv(GL_PROJECTION_MATRIX, (float *) a);
370 /* Restore the current matrix */
377 case D3DOP_STATETRANSFORM: {
379 TRACE("STATETRANSFORM (%d)\n", count);
381 for (i = 0; i < count; i++) {
382 LPD3DSTATE ci = (LPD3DSTATE) instr;
384 /* Handle the state transform */
385 switch (ci->u1.dtstTransformStateType) {
386 case D3DTRANSFORMSTATE_WORLD: {
387 TRACE(" WORLD (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
388 odev->world_mat = (D3DMATRIX*) ci->u2.dwArg[0];
391 case D3DTRANSFORMSTATE_VIEW: {
392 TRACE(" VIEW (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
393 odev->view_mat = (D3DMATRIX*) ci->u2.dwArg[0];
396 case D3DTRANSFORMSTATE_PROJECTION: {
397 TRACE(" PROJECTION (%p)\n", (D3DMATRIX*) ci->u2.dwArg[0]);
398 odev->proj_mat = (D3DMATRIX*) ci->u2.dwArg[0];
402 ERR(" Unhandled state transformation !! (%d)\n", (int) ci->u1.dtstTransformStateType);
411 case D3DOP_STATELIGHT: {
413 TRACE("STATELIGHT (%d)\n", count);
415 for (i = 0; i < count; i++) {
416 LPD3DSTATE ci = (LPD3DSTATE) instr;
418 /* Handle the state transform */
419 switch (ci->u1.dlstLightStateType) {
420 case D3DLIGHTSTATE_MATERIAL: {
421 IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) ci->u2.dwArg[0];
422 TRACE(" MATERIAL\n");
427 TRACE(" bad Material Handle\n");
431 case D3DLIGHTSTATE_AMBIENT: {
433 DWORD dwLightState = ci->u2.dwArg[0];
436 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
437 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
438 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
440 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
442 TRACE(" R:%02lx G:%02lx B:%02lx A:%02lx\n",
443 ((dwLightState >> 16) & 0xFF),
444 ((dwLightState >> 8) & 0xFF),
445 ((dwLightState >> 0) & 0xFF),
446 ((dwLightState >> 24) & 0xFF));
449 case D3DLIGHTSTATE_COLORMODEL: {
450 TRACE(" COLORMODEL\n");
453 case D3DLIGHTSTATE_FOGMODE: {
457 case D3DLIGHTSTATE_FOGSTART: {
458 TRACE(" FOGSTART\n");
461 case D3DLIGHTSTATE_FOGEND: {
465 case D3DLIGHTSTATE_FOGDENSITY: {
466 TRACE(" FOGDENSITY\n");
470 ERR(" Unhandled light state !! (%d)\n", (int) ci->u1.dlstLightStateType);
477 case D3DOP_STATERENDER: {
479 TRACE("STATERENDER (%d)\n", count);
481 for (i = 0; i < count; i++) {
482 LPD3DSTATE ci = (LPD3DSTATE) instr;
484 /* Handle the state transform */
485 set_render_state(ci->u1.drstRenderStateType, ci->u2.dwArg[0], &(odev->rs));
491 case D3DOP_PROCESSVERTICES: {
493 TRACE("PROCESSVERTICES (%d)\n", count);
495 for (i = 0; i < count; i++) {
496 LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr;
498 TRACE(" Start : %d Dest : %d Count : %ld\n",
499 ci->wStart, ci->wDest, ci->dwCount);
501 if (TRACE_ON(ddraw)) {
502 if (ci->dwFlags & D3DPROCESSVERTICES_COPY)
504 if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR)
506 if (ci->dwFlags == D3DPROCESSVERTICES_OPMASK)
508 if (ci->dwFlags & D3DPROCESSVERTICES_TRANSFORM)
509 DPRINTF("TRANSFORM ");
510 if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT)
511 DPRINTF("TRANSFORMLIGHT ");
512 if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS)
513 DPRINTF("UPDATEEXTENTS ");
517 /* This is where doing Direct3D on top on OpenGL is quite difficult.
518 This method transforms a set of vertices using the CURRENT state
519 (lighting, projection, ...) but does not rasterize them.
520 They will only be put on screen later (with the POINT / LINE and
521 TRIANGLE op-codes). The problem is that you can have a triangle
522 with each point having been transformed using another state...
524 In this implementation, I will emulate only ONE thing : each
525 vertex can have its own "WORLD" transformation (this is used in the
526 TWIST.EXE demo of the 5.2 SDK). I suppose that all vertices of the
527 execute buffer use the same state.
529 If I find applications that change other states, I will try to do a
530 more 'fine-tuned' state emulation (but I may become quite tricky if
531 it changes a light position in the middle of a triangle).
533 In this case, a 'direct' approach (i.e. without using OpenGL, but
534 writing our own 3D rasterizer) would be easier. */
536 /* The current method (with the hypothesis that only the WORLD matrix
537 will change between two points) is like this :
538 - I transform 'manually' all the vertices with the current WORLD
539 matrix and store them in the vertex buffer
540 - during the rasterization phase, the WORLD matrix will be set to
541 the Identity matrix */
543 /* Enough for the moment */
544 if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORMLIGHT) {
546 D3DVERTEX *src = ((LPD3DVERTEX) (ilpBuff->desc.lpData + vs)) + ci->wStart;
547 OGL_Vertex *dst = ((OGL_Vertex *) (ilpBuff->vertex_data)) + ci->wDest;
548 D3DMATRIX *mat = odev->world_mat;
550 TRACE(" World Matrix : (%p)\n", mat);
553 ilpBuff->vertex_type = D3DVT_VERTEX;
555 for (nb = 0; nb < ci->dwCount; nb++) {
556 /* For the moment, no normal transformation... */
557 dst->nx = src->u4.nx;
558 dst->ny = src->u5.ny;
559 dst->nz = src->u6.nz;
564 /* Now, the matrix multiplication */
565 dst->x = (src->u1.x * mat->_11) + (src->u2.y * mat->_21) + (src->u3.z * mat->_31) + (1.0 * mat->_41);
566 dst->y = (src->u1.x * mat->_12) + (src->u2.y * mat->_22) + (src->u3.z * mat->_32) + (1.0 * mat->_42);
567 dst->z = (src->u1.x * mat->_13) + (src->u2.y * mat->_23) + (src->u3.z * mat->_33) + (1.0 * mat->_43);
568 dst->w = (src->u1.x * mat->_14) + (src->u2.y * mat->_24) + (src->u3.z * mat->_34) + (1.0 * mat->_44);
573 } else if (ci->dwFlags == D3DPROCESSVERTICES_TRANSFORM) {
575 D3DLVERTEX *src = ((LPD3DLVERTEX) (ilpBuff->desc.lpData + vs)) + ci->wStart;
576 OGL_LVertex *dst = ((OGL_LVertex *) (ilpBuff->vertex_data)) + ci->wDest;
577 D3DMATRIX *mat = odev->world_mat;
579 TRACE(" World Matrix : (%p)\n", mat);
582 ilpBuff->vertex_type = D3DVT_LVERTEX;
584 for (nb = 0; nb < ci->dwCount; nb++) {
585 dst->c = src->u4.color;
586 dst->sc = src->u5.specular;
590 /* Now, the matrix multiplication */
591 dst->x = (src->u1.x * mat->_11) + (src->u2.y * mat->_21) + (src->u3.z * mat->_31) + (1.0 * mat->_41);
592 dst->y = (src->u1.x * mat->_12) + (src->u2.y * mat->_22) + (src->u3.z * mat->_32) + (1.0 * mat->_42);
593 dst->z = (src->u1.x * mat->_13) + (src->u2.y * mat->_23) + (src->u3.z * mat->_33) + (1.0 * mat->_43);
594 dst->w = (src->u1.x * mat->_14) + (src->u2.y * mat->_24) + (src->u3.z * mat->_34) + (1.0 * mat->_44);
599 } else if (ci->dwFlags == D3DPROCESSVERTICES_COPY) {
600 D3DTLVERTEX *src = ((LPD3DTLVERTEX) (ilpBuff->desc.lpData + vs)) + ci->wStart;
601 D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (ilpBuff->vertex_data)) + ci->wDest;
603 ilpBuff->vertex_type = D3DVT_TLVERTEX;
605 memcpy(dst, src, ci->dwCount * sizeof(D3DTLVERTEX));
607 ERR("Unhandled vertex processing !\n");
614 case D3DOP_TEXTURELOAD: {
615 TRACE("TEXTURELOAD-s (%d)\n", count);
617 instr += count * size;
621 TRACE("EXIT (%d)\n", count);
622 /* We did this instruction */
628 case D3DOP_BRANCHFORWARD: {
630 TRACE("BRANCHFORWARD (%d)\n", count);
632 for (i = 0; i < count; i++) {
633 LPD3DBRANCH ci = (LPD3DBRANCH) instr;
635 if ((ilpBuff->data.dsStatus.dwStatus & ci->dwMask) == ci->dwValue) {
637 TRACE(" Should branch to %ld\n", ci->dwOffset);
641 TRACE(" Should branch to %ld\n", ci->dwOffset);
650 TRACE("SPAN-s (%d)\n", count);
652 instr += count * size;
655 case D3DOP_SETSTATUS: {
657 TRACE("SETSTATUS (%d)\n", count);
659 for (i = 0; i < count; i++) {
660 LPD3DSTATUS ci = (LPD3DSTATUS) instr;
662 ilpBuff->data.dsStatus = *ci;
669 ERR("Unhandled OpCode !!!\n");
670 /* Try to save ... */
671 instr += count * size;
680 /*******************************************************************************
681 * ExecuteBuffer Creation functions
683 LPDIRECT3DEXECUTEBUFFER d3dexecutebuffer_create(IDirect3DDeviceImpl* d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc)
685 IDirect3DExecuteBufferImpl* eb;
687 eb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DExecuteBufferImpl));
689 ICOM_VTBL(eb) = &executebuffer_vtable;
692 /* Initializes memory */
695 /* No buffer given */
696 if (!(eb->desc.dwFlags & D3DDEB_LPDATA))
697 eb->desc.lpData = NULL;
699 /* No buffer size given */
700 if (!(lpDesc->dwFlags & D3DDEB_BUFSIZE))
701 eb->desc.dwBufferSize = 0;
703 /* Create buffer if asked */
704 if ((eb->desc.lpData == NULL) && (eb->desc.dwBufferSize > 0)) {
705 eb->need_free = TRUE;
706 eb->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,eb->desc.dwBufferSize);
708 eb->need_free = FALSE;
711 /* No vertices for the moment */
712 eb->vertex_data = NULL;
714 eb->desc.dwFlags |= D3DDEB_LPDATA;
716 eb->execute = execute;
718 return (LPDIRECT3DEXECUTEBUFFER)eb;
721 /*******************************************************************************
722 * IDirect3ExecuteBuffer methods
725 static HRESULT WINAPI IDirect3DExecuteBufferImpl_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface,
729 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
731 FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
738 static ULONG WINAPI IDirect3DExecuteBufferImpl_AddRef(LPDIRECT3DEXECUTEBUFFER iface)
740 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
741 TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
743 return ++(This->ref);
748 static ULONG WINAPI IDirect3DExecuteBufferImpl_Release(LPDIRECT3DEXECUTEBUFFER iface)
750 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
751 FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
753 if (!--(This->ref)) {
754 if ((This->desc.lpData != NULL) && This->need_free)
755 HeapFree(GetProcessHeap(),0,This->desc.lpData);
757 if (This->vertex_data != NULL)
758 HeapFree(GetProcessHeap(),0,This->vertex_data);
760 HeapFree(GetProcessHeap(),0,This);
767 static HRESULT WINAPI IDirect3DExecuteBufferImpl_Initialize(LPDIRECT3DEXECUTEBUFFER iface,
768 LPDIRECT3DDEVICE lpDirect3DDevice,
769 LPD3DEXECUTEBUFFERDESC lpDesc)
771 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
772 FIXME("(%p)->(%p,%p): stub\n", This, lpDirect3DDevice, lpDesc);
777 static HRESULT WINAPI IDirect3DExecuteBufferImpl_Lock(LPDIRECT3DEXECUTEBUFFER iface,
778 LPD3DEXECUTEBUFFERDESC lpDesc)
780 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
781 TRACE("(%p)->(%p)\n", This, lpDesc);
783 /* Copies the buffer description */
784 *lpDesc = This->desc;
789 static HRESULT WINAPI IDirect3DExecuteBufferImpl_Unlock(LPDIRECT3DEXECUTEBUFFER iface)
791 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
792 TRACE("(%p)->()\n", This);
797 static HRESULT WINAPI IDirect3DExecuteBufferImpl_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
798 LPD3DEXECUTEDATA lpData)
800 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
803 TRACE("(%p)->(%p)\n", This, lpData);
805 This->data = *lpData;
807 /* Get the number of vertices in the execute buffer */
808 nbvert = This->data.dwVertexCount;
810 /* Prepares the transformed vertex buffer */
811 if (This->vertex_data != NULL)
812 HeapFree(GetProcessHeap(), 0, This->vertex_data);
813 This->vertex_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,nbvert * sizeof(OGL_Vertex));
816 if (TRACE_ON(ddraw)) {
817 _dump_executedata(lpData);
823 static HRESULT WINAPI IDirect3DExecuteBufferImpl_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface,
824 LPD3DEXECUTEDATA lpData)
826 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
827 TRACE("(%p)->(%p): stub\n", This, lpData);
829 *lpData = This->data;
834 static HRESULT WINAPI IDirect3DExecuteBufferImpl_Validate(LPDIRECT3DEXECUTEBUFFER iface,
836 LPD3DVALIDATECALLBACK lpFunc,
840 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
841 TRACE("(%p)->(%p,%p,%p,%lu)\n", This, lpdwOffset, lpFunc, lpUserArg, dwReserved);
846 static HRESULT WINAPI IDirect3DExecuteBufferImpl_Optimize(LPDIRECT3DEXECUTEBUFFER iface,
849 ICOM_THIS(IDirect3DExecuteBufferImpl,iface);
850 TRACE("(%p)->(%lu)\n", This, dwReserved);
856 /*******************************************************************************
857 * IDirect3DLight VTable
859 static ICOM_VTABLE(IDirect3DExecuteBuffer) executebuffer_vtable =
861 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
862 /*** IUnknown methods ***/
863 IDirect3DExecuteBufferImpl_QueryInterface,
864 IDirect3DExecuteBufferImpl_AddRef,
865 IDirect3DExecuteBufferImpl_Release,
866 /*** IDirect3DExecuteBuffer methods ***/
867 IDirect3DExecuteBufferImpl_Initialize,
868 IDirect3DExecuteBufferImpl_Lock,
869 IDirect3DExecuteBufferImpl_Unlock,
870 IDirect3DExecuteBufferImpl_SetExecuteData,
871 IDirect3DExecuteBufferImpl_GetExecuteData,
872 IDirect3DExecuteBufferImpl_Validate,
873 IDirect3DExecuteBufferImpl_Optimize